Android Tunnel Mode

在最新的Android版本上(AndroidO)为了降低播放4K60FPS片源对整机性能的过度消耗,Android出现了一种新的视频播放模式Tunnel Mode。

下面是关键的几步适配Tunnel Mode的方式:

1.需要Audio SessionID,这个是由Audio Manager生成的

audioSessionId = ((AudioManager)ctx.getSystemService(Context.AUDIO_SERVICE)).generateAudioSessionId();

2.配置docoder尾tunnel mode模式

format.setFeatureEnabled(MediaCodecInfo.CodecCapabilities.FEATURE_TunneledPlayback, true);

3.通过audio sessionid来配置video decoder

format.setInteger(android.media.MediaFormat.KEY_AUDIO_SESSION_ID, audioSessionId);

4.通过SessionId创建Auditrack,同时设置FLAG_HW_AV_SYNC flag让底层知道需要硬件同步

AudioAttributes attr = new AudioAttributes.Builder()
 .setLegacyStreamType(AudioManager.STREAM_MUSIC)
 .setFlags(AudioAttributes.FLAG_HW_AV_SYNC)
 .build();
AudioFormat fmt = new AudioFormat.Builder()
 .setEncoding(targetEncoding)
 .setSampleRate(sampleRate)
 .setChannelMask(channelConfig)
 .build();
AudioTrack audioTrack = new android.media.AudioTrack(attr, fmt, bufferSize, 575 android.media.AudioTrack.MODE_STREAM, audioSessionId);

5.video decoder不需要调用dequeueOutputBuffer和releaseOutPutBuffer

6.需要在音频写入audiotrack的时候在头部插入一个16 byte的avsync header

private ByteBuffer avSyncHeader = null;
avSyncHeader = ByteBuffer.allocate(16);
avSyncHeader.order(ByteOrder.BIG_ENDIAN);
avSyncHeader.position(0);
avSyncHeader.order(ByteOrder.BIG_ENDIAN);
avSyncHeader.putInt(AVSYNC_START_CODE);
avSyncHeader.putInt(bufferBytesRemaining);
avSyncHeader.putLong(presentationTimeUs * 1000 );
avSyncHeader.position(0);

这个header包含一个起始码,pts(nano sec),和数据的size。再写入audio数据前先写入这个header data。

具体调试中还会有一些坑,这个得调试的过程中才能一一分析解决。

你可能感兴趣的:(多媒体)