Android 视频解码器仅在棒棒糖上不绘制到 gles 表面

Posted

技术标签:

【中文标题】Android 视频解码器仅在棒棒糖上不绘制到 gles 表面【英文标题】:Android video decoder not drawing to gles surface on lollipop only 【发布时间】:2015-05-22 20:01:37 【问题描述】:

简而言之,我正在将两个开源应用程序组合成一个新的 VR 应用程序,因此它只能在使用 GearVR 耳机的 Note 4 和 S6 上运行。我的应用程序适用于 kitkat,但棒棒糖上的视频是黑色的。这两个源应用程序都可以在棒棒糖上正常运行。

我有一个由 gl 纹理创建的表面:

glGenTextures( 1, &textureId );
glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId);
glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);

这被放入一个 SurfaceTexture 中,然后被放入一个 Surface 中,被传递一点,然后发送到视频解码器:

videoDecoder = MediaCodec.createByCodecName(decoderName);
MediaFormat videoFormat = MediaFormat.createVideoFormat("video/avc", width, height);
videoDecoder.configure(videoFormat, ((SurfaceHolder)renderTarget).getSurface(), null, 0);
videoDecoder.setVideoScalingMode(MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT);

// OMX.qcom.video.decoder.avc gets picked for decodername
// Width and height at 1280x720 everywhere

纹理被更新并绑定到表面并被渲染。

这在 kitkat 上完美运行。在棒棒糖上,视频是全黑的。

您可以在此处查看原木的差异(良好的 kitkat 红色,不良的棒棒糖绿色):https://www.diffchecker.com/lxxopmhc

在我看来,没有什么特别能提供信息。 (我能找到的消息do not know color format 0x7fa30c04 = 2141391876只是来自将解码器ID转换为名称的东西,不应该影响任何东西。另一个解码器没有给出这个消息,但也不起作用。)

向 MediaFormat 添加显式颜色格式,并在其他任何地方使用颜色格式和图像大小没有任何效果(只有黑屏,没有错误)

我可以在表面上锁定一个画布并绘制ARGB(255,0,255,0),屏幕变绿。

我创建了一个表面子类,它记录了每个公共方法并将其传递给解码器,并且没有一个在 kitkat 或棒棒糖上被调用(除了我创建它时的初始化),工作与否,所以这告诉了我什么都没有。

用于设置视频解码器的代码来自 Moonlight,它在棒棒糖上运行良好: github.com/moonlight-stream/moonlight-android

另一半是 Oculus Cinema,它使用 android.media.MediaPlayer 在表面上显示,在棒棒糖上运行良好。

所以我的问题是棒棒糖发生了什么变化或者我做错了什么,我该如何进一步调试这个问题?

我的代码在这里:https://github.com/GTMoogle/StreamTheater

更新 6/2:

尝试按照http://bigflake.com/mediacodec/ 的 Q11 的建议设置缓冲区位置和限制,但仍然没有输出,尽管我可能实施不正确。还照顾了一些贬低的电话,也没有效果。

Up-Update:dequeueOutputBuffer 中的 BufferInfo 似乎总是大小为 8,偏移量为 0,没有设置标志。尚不确定健康的流是什么样的。

【问题讨论】:

【参考方案1】:

啊哈。终于找到了。

由于某种原因 updateTexImage 没有改变表面纹理的时间戳。 Mediacodec 是在 kitkat 上设置的,所以输入缓冲区没有正确设置时间戳并且 mediacodec 正在清理它,或者在更新纹理时 mediacodec 不再设置它?

我可以调试它,但至少目前我可以总是更新而不是检查时间戳是否更改。

【讨论】:

以上是关于Android 视频解码器仅在棒棒糖上不绘制到 gles 表面的主要内容,如果未能解决你的问题,请参考以下文章

当手机处于睡眠模式时,为什么用于来电的广播接收器在棒棒糖上不起作用

为啥使用 AlarmManager.setAlarmClock() 设置时仅在三星 Android 9 设备上不显示闹钟图标?

DisplayAlert 仅在 Xamarin 表单 ios 上不显示

android firebase后台通知仅在vivo设备上不起作用

用Python绘制棒棒糖图表,真的好看!

android下视频文件从解码到播放需要哪几步,请简述