隧道模式播放(仅适用于 4K @ 60 FPS Fire TV 设备)


隧道模式播放(仅适用于 4K @ 60 FPS Fire TV 设备)

某些 Fire TV 设备的硬件解码器支持以 60 FPS 速度播放 4K 内容。要播放 4K @ 60 FPS,媒体管道的定时要求非常激进,由于内核的线程和进程调度限制,应用可能无法以 16 毫秒间隔渲染 4K 帧。这可能会导致丢帧和低于一般标准的电影体验。要充分利用硬件,请使用隧道模式播放。

如何支持隧道模式播放

支持隧道模式播放所需的主要更改如下:

  1. 从 AudioManager 生成 AudioTrack 会话 ID。

    audioSessionId = ((AudioManager)ctx.getSystemService(Context.AUDIO_SERVICE)).generateAudioSessionId();
    
  2. 为隧道模式配置视频解码器:

    format.setFeatureEnabled(MediaCodecInfo.CodecCapabilities.FEATURE_TunneledPlayback, true);
    
  3. 使用 AudioTrack 会话 ID 配置视频解码器。

    format.setInteger(android.media.MediaFormat.KEY_AUDIO_SESSION_ID, audioSessionId);
    
  4. 使用从 AudioManager 生成的会话 ID 创建 AudioTrack,并设置 Flag_HW_AV_SYNC 标记。

    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. 不要为视频解码器调用 dequeueOutputBufferreleaseOutputBuffer
  6. 将 16 字节的 AV 同步标头插入到正在写入 AudioTrack 的音频数据。

    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);
    

此标头包含开始代码、演示时间(以纳秒为单位)和数据大小。在将音频数据写入音轨之前写入此数据。

有关隧道模式播放的更多详细信息

有关更多详细信息,请参阅 Exoplayer 2 中的隧道模式播放实现: