将专用的NV12视频帧转换为RGB

3
我有一个使用Android MediaCodec解码的H264流。当我查询输出MediaFormat时,颜色格式为2141391875。显然,这是一种名为HAL_PIXEL_FORMAT_NV12_ADRENO_TILED的专门NV12变体。这是在Nexus 7(2013)上进行的。
我想将这些数据转换为RGB,以便创建位图。我已经找到了将其他格式转换为RGB的StackOverflow帖子,但没有找到该格式的转换方法。我尝试了那些帖子中的代码,结果只有彩色条纹。(为了查看位图,我在与Surface相关联的Canvas上绘制,以及将其写出为JPEG - 在两种情况下它看起来都一样。)
如何将这个特定的数据转换为RGB?

请查看这个问题:https://dev59.com/i2LVa4cB1Zd3GeqPwXJ5。在www.videolan.org/developers/vlc/modules/codec/omxil/qcom.c上有一个可用的转换器。 - Ganesh
1个回答

1

2141391875的十进制表示为0x7FA30C03的十六进制,根据此头文件,它是OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka。这与您找到的常量相同:这是一种专有的高通颜色格式。

最简单(也是最快)的方法是让OpenGL ES为您完成转换。例如,请参见ExtractMpegFramesTest,该测试将视频帧解码为SurfaceTexture,将纹理渲染到离屏表面,然后使用glReadPixels()读取像素。GLES驱动程序将为您处理RGB转换。

如果要自己进行转换,则需要反向工程颜色格式或找到已经完成此操作并愿意共享的人。


2
这里有两个代码链接,分别是 https://gitorious.org/atrix-aosp/frameworks_base/source/8f901240ab7c98ad48542b99342d02ed84937395:media/libstagefright/colorconversion/ColorConverter.cpp 和 http://git.videolan.org/?p=vlc.git;a=blob;f=modules/codec/omxil/qcom.c ,它们展示了如何解释这种格式。 - mstorsjo
抱歉,我看错了,我本应该看的是EncodeDecodeTest而不是ExtractMpegFramesTest,后者可能正好符合我的需求。 - Paul Steckler
在ExtractMpegFramesTest中,有一个带有关联Surface的SurfaceTexture,代码使用OpenGL ES写入SurfaceTexture。这种方法使得可以使用glReadPixel,并最终将该帧保存到图像文件中。如果我只想将该帧呈现到屏幕上,那么使用OpenGL ES是否比在SurfaceView中创建Surface更有优势?查看MediaCodec.java时,发现它在这种情况下使用了称为SoftwareRenderer的本地代码。 - Paul Steckler
请参见 https://source.android.com/devices/graphics/architecture.html 了解完整的信息。 - fadden
MediaCodec 到 SurfaceView surface 是最有效的路径 - 应该是零拷贝。对于受 DRM 保护的内容,这是唯一可能的路径。MediaCodec 到 SurfaceTexture 然后在 SurfaceView surface 上使用 GLES 渲染添加了 YUV 到 RGB 转换,可能还有一个缩放 blit,这使它变慢,但也允许更多灵活性,以便每个帧如何呈现。如果你只想播放视频,你应该直接将它发送到 SurfaceView。 - fadden
显示剩余4条评论

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