我有一个H264流,想要使用MediaCodec将其解码到表面进行显示。
由于我只是解码,并且希望定位尽可能多的设备,因此我支持API 16并使用ExtractMpegFrames测试作为参考。 http://bigflake.com/mediacodec/ExtractMpegFramesTest.java.txt
调用dequeOutputBuffers(info,timeout)时; info.size始终为零。如果我硬编码releaseOutputBuffer(index,true);我得到显示(取决于我如何设置表面...在主要活动onCreate中创建一个表面并将其传递给配置工作,使用来自extractmpegframes的表面概念...可能会调试它。)
无论我使用基于info.size的布尔值还是我硬编码" true" ...我得到了很多 " SEC_VIDEO_DEC(1840):输出缓冲器小于解码数据大小Out Length" (在三星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 849行 在这个设备上我有很多口吃,因为看起来是大量的分配和随后的垃圾收集。
表面肯定不是空的...三星平板电脑是4.1.2 ..
还尝试了新的联想瑜伽10高清(4.2非常肯定,平板电脑现在已经出局)并且还有口吃视频,大小不是零,但是"小"与手机相比
问题:
1.为什么笔记本平板电脑的尺寸始终为零而不是galaxyS3手机的尺寸?
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();