我有一个 H264 流,想要使用 MediaCodec 将其解码以显示。
因为我只是解码,并且希望定位尽可能多的设备,所以我支持 API 16 并使用 ExtractMpegFrames 测试作为参考。http://bigflake.com/mediacodec/ExtractMpegFramesTest.java.txt http://bigflake.com/mediacodec/ExtractMpegFramesTest.java.txt
当调用 dequeOutputBuffers(info,timeout); 时info.size 始终为零。如果我硬编码releaseOutputBuffer(index,true);我得到了显示(取决于我如何设置表面...在主活动 onCreate 中创建一个表面并将其传递给配置工作,使用 extractmpegframes 中的表面概念不会...可能会调试它)。
无论我使用基于 info.size 的布尔值还是硬编码“true”......我都会得到很多
“SEC_VIDEO_DEC(1840):输出缓冲区小于解码数据大小输出长度”(在三星 Galaxy Note 10.1 上),在谷歌搜索后我发现:https://gitorious.org/replicant/device_samsung_aries-common/source/9ff4c660a554dc2816db67004fccb10f6ad0e0fa:aries/sec_mm/sec_omx/sec_omx_component/video/dec/SEC_OMX_Vdec.c#L849 https://gitorious.org/replicant/device_samsung_aries-common/source/9ff4c660a554dc2816db67004fccb10f6ad0e0fa%3aaries/sec_mm/sec_omx/sec_omx_component/video/dec/SEC_OMX_Vdec.c#L849849线
在这个设备上,由于似乎有大量的分配和随后的垃圾收集,我有很多口吃。
Surface 绝对不为空...三星平板电脑是 4.1.2..
还尝试过新的 Lenovo Yoga 10 HD(4.2 版,平板电脑现已上市),视频也有卡顿,尺寸不为零,但与手机相比“小”
问题:
1. 为什么在Note平板电脑上尺寸总是为零,而在Galaxy S3手机上却不然?
2. 有没有办法解决平板电脑尺寸为零的问题?
3. 我应该检查一些东西来确定设备是否不支持我正在做的事情? (即使它处于据称支持的 sdk 级别)
4. 我是否需要捕获变化的 sps/pps 中流并停止解码器、重新配置并重新启动它?
解码器设置现在正在解析来自第一个 AU 的 sps/pps:
private final String MIME_TYPE = "video/avc"; // H.264 Advanced Video Coding
//set width and height
//cropping parameters should be used only when [frame_cropping_flag] is enabled in SPS.
if (h.sps.frame_cropping_flag == 1)
{
mWidth = ((h.sps.pic_width_in_mbs_minus1 + 1) * 16) - h.sps.frame_crop_left_offset * 2 - h.sps.frame_crop_right_offset * 2;
mHeight= ((2 - h.sps.frame_mbs_only_flag)* (h.sps.pic_height_in_map_units_minus1 +1) * 16) - (h.sps.frame_crop_top_offset * 2) - (h.sps.frame_crop_bottom_offset * 2);
}
else
{
mWidth = ((h.sps.pic_width_in_mbs_minus1 + 1) * 16);
mHeight= ((2 - h.sps.frame_mbs_only_flag)* (h.sps.pic_height_in_map_units_minus1 +1) * 16);
}
MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 1920 * 1080);
format.setInteger(MediaFormat.KEY_MAX_WIDTH,1920);
format.setInteger(MediaFormat.KEY_MAX_HEIGHT,1080);
format.setInteger(MediaFormat.KEY_PUSH_BLANK_BUFFERS_ON_STOP,1);
//we know we have Codec-Sepcific Data if we got here
format.setByteBuffer("csd-0", sps);
if (ppsOffset != -1)
{
format.setByteBuffer("csd-1", pps);
}
else
{
//can this happen?
Log.d(s_logTag, "UpdateInput - did not find PPS data");
}
// Create a MediaCodec for the desired codec using the format variable we just created along with the surface passed to us in the constructor
mDecoder = MediaCodec.createDecoderByType(MIME_TYPE);
mDecoder.configure(format, mSurface, null, 0); //not an encoder so pass 0 instead of flag: MediaCodec.CONFIGURE_FLAG_ENCODE);
mDecoder.start();