问题
I've got an H264 stream and want to use MediaCodec to decode it to surface to display.
Because I'm only decoding, and want to target as many devices as possible, I'm supporting API 16 and used the ExtractMpegFrames test as reference. http://bigflake.com/mediacodec/ExtractMpegFramesTest.java.txt
When calling dequeOutputBuffers(info,timeout); the info.size is always zero. If I hardcode releaseOutputBuffer(index,true); i get the display (depending on how i set up surface... creating a surface in main activity onCreate and passing it to configure works, using the surface concept from the extractmpegframes does not...might debug that).
Regardless if i use a boolean based on info.size or if i hardcode the "true"...i get a lot of "SEC_VIDEO_DEC(1840): output buffer is smaller than decoded data size Out Length" (on samsung galaxy note 10.1) which after googling led me to: 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 line 849 and on this device i have a lot of stuttering due to what appears to be a large amount of allocations and subsequent garbage collection.
surface is definitely not null...Samsung tablet is 4.1.2..
have also tried on a new Lenovo Yoga 10 HD (4.2 pretty sure, tablet is out right now) and also have stuttering video, size is not zero, but is "small" compared to phone
questions:
1. why is size always zero on the note tablet but not on galaxyS3 phone?
2. is there a way around the zero size for the tablet?
3. is there something i should check to determine if a device won't support what i'm doing? (even if it is at a supposedly supported sdk level)
4. do i need to catch a changing sps/pps midstream and stop the decoder, reconfigure it and restart it?
decoder setup is now parsing sps/pps from first AU:
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();
来源:https://stackoverflow.com/questions/23643307/decoding-h264-stream-bufferinfo-size-is-always-zero