When H264 stream PIC WIDTH is 360(0x168), the IPP will parse it as 0x170. It works perfect if use IPP decoder. However, when I record the stream as .mp4, VLC doesn't play the .mp4 file until I manually change the pic_width from 0x170 to 0x168.
Do you have any idea how to solve this?
The stream we are talking about is not regular. It use cropping feature of the standard. Thepoint is that the h264 decoder can handle data only on macroblock basis. It requires frame dimensions aligned to 16 pixels. To comporess a frame of arbitrary size the cropping is used. It is just 4 values in sequence header, describingindent from each side of the frame. But in fact the stream itself has dimension aligned to 16.
I believe this is not anissueof the decoder, but of the splitter. What tools do you use to pack h264 stream into .mp4 container?
I wrote the writer to pack
Thanks for your information. I parsed the sps and get
sps.frame_cropping_rect_bottom_offset = 4
sps.frame_cropping_rect_top_offset = 0
sps.frame_cropping_rect_left_offset = 0
sps.frame_cropping_rect_right_offset = 0
Because thepic_height of theencoder is set to 360(0x168), I simply add
if(sps.frame_cropping_rect_bottom_offset || sps.frame_cropping_rect_top_offset) pic_height -= 8;
if(sps.frame_cropping_rect_left_offset || sps.frame_cropping_rect_right_offset) pic_width -= 8;
It seems work now.But shouldn'tit be 0x16c instead of 0x168?
Have a good weekend!
it looks like few code lines are not quite correct. Let's look at the UMC code.
Ipp32u cropLeft, cropRight, cropTop, cropBottom;
// set initial cropping values
cropLeft = pSeqParamSet->frame_crop_left_offset;
cropRight = pSeqParamSet->frame_crop_right_offset;
cropTop = pSeqParamSet->frame_crop_top_offset * (2 - pSeqParamSet->frame_mbs_only_flag);
cropBottom = pSeqParamSet->frame_crop_bottom_offset * (2 - pSeqParamSet->frame_mbs_only_flag);
// adjust cropping values depending on chroma format
cropLeft *= 2;
cropRight *= 2;
cropTop *= 2;
cropBottom *= 2;
cropLeft *= 2;
cropRight *= 2;
And the final values cropLeft, cropRight, cropTop, cropBottom should be substructed form frame dimensions.
I found the code wherethe UMC splitter calculatesh264picturedimentions. I don't see how chroma format affects picture dimentions from this piece of code. But I guess that should work in my splitter too.
Thank for your information. It's very helpful.
void H264ParsingCore::GetInfo(VideoStreamInfo& info)
const Slice& sh = m_last.IsReady() ? m_last : m_prev;
const Sps& sps = sh.GetPps().GetSps();
info.stream_type = H264_VIDEO;
info.profile = sps.profile_idc;
info.level = sps.level_idc;
info.clip_info.width = 16 * sps.frame_width_in_mbs;
info.clip_info.width -= 2 * (sps.frame_cropping_rect_left_offset + sps.frame_cropping_rect_right_offset);
info.clip_info.height = 16 * sps.frame_height_in_mbs;
info.clip_info.height -= 2 * (sps.frame_cropping_rect_top_offset + sps.frame_cropping_rect_bottom_offset);
info.clip_info.height *= (2 - sps.frame_mbs_only_flag);
Hum, I'm able totrack the decoding process to here,
TimedColorConverter::GetFrame(UMC::MediaData *in, UMC::MediaData *out)
It seemssimple_player decodes everything into YUV420 first, and use TimedColorConverter to convert the YUV420 output to requested color space.Could it affect performance?