Tunnel mode播放片源黑屏

连续抓几次的systrace,每次queueBuffer都有被acquire,看不出

还是得加debug log,顺流程

queueBuffer之后会触发

SurfaceFlinger::handleMessageInvalidate

    -> handlePageFlip

        -> latchBuffer

            -> latchSidebandStream  返回true,直接return,导致没有执行到updateTexImage(预期这里会acquireBuffer),那么也就没有acquireBuffer了

                 -> updateTexImage 预期执行

                       -> acquireBuffer

而latchSidebandStream返回true,定位到是因为google在2020年上的一笔commit导致,sideBand不会去acquireBuffer,这属于google的限制,而且sideBand的buffer大小为1*1,不会被acquire,也合理

dequeueBuffer: w=1,h=1 format=0x2,usage=0x930

https://android-review.googlesource.com/c/platform/framework/native/+/1537923

-> solution: 使用non-tunnel mode或者看player那边是否有其它的方案 

### 检查 Android 中使用 MediaCodec 或 CCodec 时是否启用了 Tunnel Mode 在 Android 中使用 `MediaCodec` 或 `CCodec` 进行视频解码时,若需启用 Tunnel Mode 以确保 `audioSessionId` 正确绑定,可以通过以下方式进行验证和检查。 #### 1. 检查 `MediaFormat` 是否设置了 Tunnel Mode 标志 在配置 `MediaFormat` 时,必须显式启用 Tunnel Mode。可以通过调用 `setFeatureEnabled()` 方法并传入 `MediaCodecInfo.CodecCapabilities.FEATURE_TunneledPlayback` 来启用。验证是否设置了该标志: ```java MediaFormat format = MediaFormat.createVideoFormat("video/avc", width, height); format.setFeatureEnabled(MediaCodecInfo.CodecCapabilities.FEATURE_TunneledPlayback, true); ``` 若未调用 `setFeatureEnabled()` 或传入 `false`,则 Tunnel Mode 未启用,可能导致 `audioSessionId` 无法正确绑定[^1]。 #### 2. 检查 `MediaFormat` 是否设置了 `audioSessionId` 在启用 Tunnel Mode 的前提下,还需将 `audioSessionId` 设置到 `MediaFormat` 中。验证是否调用了 `setInteger()` 方法并传入了有效的 `audioSessionId`: ```java int sessionId = AudioTrack.generateAudioSessionId(); format.setInteger(MediaFormat.KEY_AUDIO_SESSION_ID, sessionId); ``` 若未设置 `audioSessionId`,或设置的值为默认值(如 0),则可能导致系统无法识别音频会话,进而影响 Tunnel Mode 的同步机制[^1]。 #### 3. 检查是否绑定了支持 Tunnel Mode 的 Surface Tunnel Mode 要求绑定一个支持 Tunnel 的 `Surface`。通常使用 `SurfaceView` 或 `TextureView` 提供的 `Surface` 对象。验证是否成功绑定: ```java MediaCodec codec = MediaCodec.createByCodecName(codecName); codec.configure(format, surface, null, 0); ``` 若 `surface` 未正确创建或未与 `SurfaceView` 关联,则 Tunnel Mode 无法正常工作,可能导致 `audioSessionId` 绑定失败[^1]。 #### 4. 检查 OMX 组件是否支持 Tunnel Mode 底层 OMX 组件负责将 `audioSessionId` 传递给 DSP 或视频输出模块。若 OMX 插件未正确实现 Tunnel Mode 的同步逻辑,可能导致 `audioSessionId` 被忽略或错误传递。可通过日志或调试工具(如 `logcat`)检查 OMX 组件是否成功接收并处理 `audioSessionId`: ```bash adb logcat -s OMX ``` 查看日志中是否包含 `audioSessionId` 的相关信息,确认 OMX 组件是否正常处理 Tunnel Mode 请求[^3]。 #### 5. 检查音频播放器是否使用相同的 `audioSessionId` 确保 `AudioTrack` 在创建时使用了与视频解码器相同的 `audioSessionId`。验证是否调用了 `new AudioTrack(..., sessionId)` 并传入了正确的 ID: ```java AudioTrack audioTrack = new AudioTrack( AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, bufferSize, AudioTrack.MODE_STREAM, sessionId ); ``` 若 `AudioTrack` 使用的 `audioSessionId` 与视频解码器不一致,则 Tunnel Mode 无法正确绑定音频与视频流,导致同步失败。 #### 6. 检查设备是否支持 Tunnel Mode 并非所有设备都支持 Tunnel Mode。可通过查询 `MediaCodecInfo` 来判断当前设备是否支持 Tunnel Mode: ```java MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i); if (info.isFeatureSupported(MediaCodecInfo.CodecCapabilities.FEATURE_TunneledPlayback)) { // 支持 Tunnel Mode } ``` 若设备不支持 Tunnel Mode,则即使配置了相关参数,也无法启用该功能,导致 `audioSessionId` 无法绑定。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值