Media Codec 解码器可以输出类似 RGB 的格式吗?
Can the Media Codec decoders output RGB-like formats?
我正在尝试使用 Android 媒体编解码器转换 VP9 视频。当我设置
KEY_COLOR_FORMAT 格式转换为 YUV 格式以外的格式,我收到以下错误:
"[OMX.qcom.video.decoder.vp9] 不支持颜色格式 XXXX。"
例如 COLOR_FormatSurface 格式似乎不受支持。或者我做错了什么。
我需要手动执行 YUV 到 RGB 转换吗?如果是,能够为编解码器提供 Surfacetexture 的目的是什么?
这里是示例代码:
public class VideoDecoder
{
private MediaCodec mVideoCodec = null;
private ByteBuffer[] mInputBuffers;
private ByteBuffer[] mOutputBuffers;
public VideoDecoder(int width, int height)
{
try
{
// Media settings
MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_VP9,
width,
height);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
// COLOR_FormatYUV420Flexible
// Configure the decoder
mVideoCodec = MediaCodec.createDecoderByType(MediaFormat.MIMETYPE_VIDEO_VP9);
mVideoCodec.configure(format,
null,
null,
0);
// Start the decoder
mVideoCodec.start();
mInputBuffers = mVideoCodec.getInputBuffers();
mOutputBuffers = mVideoCodec.getOutputBuffers();
}
catch(Exception e)
{
Log.e("VideoDecoder", "CreateCodec failed message =" + e.getMessage());
}
}
public void release()
{
mVideoCodec.stop();
mVideoCodec.release();
}
public void decode(byte[] rawBuffer, int frameSize)
{
//todo
}
}
谢谢!
从媒体编解码器 documentation 开始,方法是使用 Surface。它可以隐式地进行从编解码器输出到其纹理(BGRA)的转换。所以流程会像:
1) 在收到 onFrameAvailable 回调时调用 Surface.updateTexImage()。需要在拥有当前图形上下文的线程上调用。
2) 将纹理数据复制到另一个纹理。将需要使用着色器根据表面变换矩阵变换纹理坐标。
3) 如果需要,在 CPU 上读回结果。对于 gles20.glreadpixels
的前任
我正在尝试使用 Android 媒体编解码器转换 VP9 视频。当我设置 KEY_COLOR_FORMAT 格式转换为 YUV 格式以外的格式,我收到以下错误: "[OMX.qcom.video.decoder.vp9] 不支持颜色格式 XXXX。"
例如 COLOR_FormatSurface 格式似乎不受支持。或者我做错了什么。 我需要手动执行 YUV 到 RGB 转换吗?如果是,能够为编解码器提供 Surfacetexture 的目的是什么?
这里是示例代码:
public class VideoDecoder
{
private MediaCodec mVideoCodec = null;
private ByteBuffer[] mInputBuffers;
private ByteBuffer[] mOutputBuffers;
public VideoDecoder(int width, int height)
{
try
{
// Media settings
MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_VP9,
width,
height);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
// COLOR_FormatYUV420Flexible
// Configure the decoder
mVideoCodec = MediaCodec.createDecoderByType(MediaFormat.MIMETYPE_VIDEO_VP9);
mVideoCodec.configure(format,
null,
null,
0);
// Start the decoder
mVideoCodec.start();
mInputBuffers = mVideoCodec.getInputBuffers();
mOutputBuffers = mVideoCodec.getOutputBuffers();
}
catch(Exception e)
{
Log.e("VideoDecoder", "CreateCodec failed message =" + e.getMessage());
}
}
public void release()
{
mVideoCodec.stop();
mVideoCodec.release();
}
public void decode(byte[] rawBuffer, int frameSize)
{
//todo
}
}
谢谢!
从媒体编解码器 documentation 开始,方法是使用 Surface。它可以隐式地进行从编解码器输出到其纹理(BGRA)的转换。所以流程会像:
1) 在收到 onFrameAvailable 回调时调用 Surface.updateTexImage()。需要在拥有当前图形上下文的线程上调用。
2) 将纹理数据复制到另一个纹理。将需要使用着色器根据表面变换矩阵变换纹理坐标。
3) 如果需要,在 CPU 上读回结果。对于 gles20.glreadpixels
的前任