MediaCodec解码视频帧最快的在屏幕上显示方法是什么?

6
我正在寻找最快的方法,将从MediaCodec解码器接收到的图像帧绘制到Android设备屏幕上。以下是重要的约束和说明:
  1. 不能使用MediaPlayer。不允许使用中间应用程序。

  2. 必须尽可能快地将MediaCodec解码器的输出帧绘制到屏幕上(最小化延迟)。

  3. 可用的解码器输出格式如下:
    ColorFormat[0] 0x00000013 COLOR_FormatYUV420Planar
    ColorFormat[1] 0x00000015 COLOR_FormatYUV420SemiPlanar
    ColorFormat[2] 0x7F000001 OMX_SEC_COLOR_FormatNV12TPhysicalAddress
    ColorFormat[3] 0x7FC00002 OMX_SEC_COLOR_FormatNV12Tiled

  4. 视频分辨率以及每个输出帧的分辨率都为960x720。

  5. 目标平台是Galaxy Note II,方法可以针对该平台进行优化(例如利用可用的硬件功能)。这不需要在其他平台上运行或成为通用解决方案。

对于少于66ms的响应速度的方法是可以接受的。少于33ms的响应速度则更好。我的当前方法需要80-90ms,非常糟糕。(我不会描述它,因为我不想偏向任何特定的答案。)
1个回答

7
你最好直接解码到Surface。将解码到ByteBuffer会严重降低速度。在bigflake上有许多示例(例如ExtractMpegFramesTest)将解码器的输出发送到离屏表面并使用GLES检查它,但只需简单更改即可使其适用于屏幕上的SurfaceView更新:Grafika有两个不同的基于MediaCodec的视频播放器,分别将输出发送到SurfaceView和TextureView。

1
你可以尝试使用TextureView。代码的工作方式类似于ExtractMpegFramesTest,但是在CodecOutputSurface中创建SurfaceTexture的代替方法是直接使用从TextureView获取的SurfaceTexture。虽然无法完全避免GLES,但可以将其最小化。 - fadden
1
这意味着当前线程没有配置有效的EGLDisplay。每当调用updateTexImage()时,必须设置EGLDisplayEGLContext并且它们的值必须相同。这些是使用eglMakeCurrent()针对每个线程进行设置的。请参阅SurfaceTexture文档中的最后一段,特别注意不能直接从onFrameAvailable()回调中调用updateTexImage() - fadden
1
这是一个奇怪的消息 - 我只在 Mesa 代码中看到过这样的消息。你在使用模拟器吗?(我正在试图拼凑一个包含演示此问题的代码的 APK;可能还需要一天左右的时间。) - fadden
1
一个源代码片段暂时可以在这里找到:http://bigflake.com/mediacodec/PlayMovieActivity.java.txt。希望能够被完整的项目所替代。该活动具有一个带有“播放”按钮和TextureView的布局。电影被缩放到TextureView的大小,该大小由此示例中的视图布局确定,因此需要调整以使视频看起来正确。 - fadden
1
完整的SDK应用程序与“PlayMovieActivity”现已可用 - 请参见GitHub上的Grafika(https://github.com/google/grafika)。特别是,“播放视频(TextureView)”就是我上面所描述的内容。 - fadden
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接