📄 umc_frame_constructor.cpp
字号:
vInfo.stream_type = MPEG4_VIDEO;
if (pInfo)
{ // if pointer to info passed, fill it
pInfo->m_Type = TRACK_MPEG4V;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->aspect_ratio_width = vInfo.aspect_ratio_width;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->aspect_ratio_height = vInfo.aspect_ratio_height;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->framerate = vInfo.framerate;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->clip_info = vInfo.clip_info;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->interlace_type = vInfo.interlace_type;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->stream_type = vInfo.stream_type;
}
return UMC_OK;
}
Status H261FrameConstructor::ParseHeader(Ipp8u *buf, Ipp32s iLen, Mpeg2TrackInfo *pInfo)
{
VideoStreamInfo vInfo;
ippsZero_8u((Ipp8u *)&vInfo, sizeof(VideoStreamInfo));
BitstreamReader bs;
bs.Init(buf);
// 4 bytes are enough for header
if (iLen >= 0 && iLen < 4)
return UMC_ERR_NOT_ENOUGH_DATA;
bs.SkipBits(20); // skip short_video_start_marker
bs.SkipBits(5); // skip temporal_reference
bs.SkipBits(3); // skip flags
if (bs.GetBits(1))
{ // CIF
vInfo.clip_info.width = 352;
vInfo.clip_info.height = 288;
}
else
{ // QCIF
vInfo.clip_info.width = 176;
vInfo.clip_info.height = 144;
}
vInfo.aspect_ratio_width = 12;
vInfo.aspect_ratio_height = 11;
vInfo.framerate = 30000 / 1001.;
vInfo.stream_type = H261_VIDEO;
if (pInfo)
{ // if pointer to info passed, fill it
pInfo->m_Type = TRACK_H261;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->aspect_ratio_width = vInfo.aspect_ratio_width;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->aspect_ratio_height = vInfo.aspect_ratio_height;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->clip_info = vInfo.clip_info;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->framerate = vInfo.framerate;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->stream_type = vInfo.stream_type;
}
return UMC_OK;
}
Status H263FrameConstructor::ParseHeader(Ipp8u *buf, Ipp32s iLen, Mpeg2TrackInfo *pInfo)
{
VideoStreamInfo vInfo;
ippsZero_8u((Ipp8u *)&vInfo, sizeof(VideoStreamInfo));
BitstreamReader bs;
bs.Init(buf);
Ipp8u pixel_aspect_ratio_code = 2;
Ipp8u source_format;
// 14 bytes are enough for header
if (iLen >= 0 && iLen < 14)
return UMC_ERR_NOT_ENOUGH_DATA;
bs.SkipBits(22); // skip short_video_start_marker
bs.SkipBits(8); // skip temporal_reference
Ipp32u marker_bit = bs.GetBits(1);
if (0 == marker_bit)
return UMC_ERR_INVALID_STREAM;
Ipp32u zero_bit = bs.GetBits(1);
if (1 == zero_bit) // zero_bit
return UMC_ERR_INVALID_STREAM;
bs.SkipBits(3); // skip bits
source_format = (Ipp8u)bs.GetBits(3);
if (0 == source_format || 6 == source_format)
return UMC_ERR_INVALID_STREAM;
vInfo.framerate = 30000 / 1001.;
vInfo.aspect_ratio_width = Mpeg4FrameConstructor::AspectRatio[2][0];
vInfo.aspect_ratio_height = Mpeg4FrameConstructor::AspectRatio[2][1];
// PLUSPTYPE
if (7 == source_format)
{
Ipp8u ufep = (Ipp8u)bs.GetBits(3);
Ipp8u custom_PCF = 0;
if (0x01 == ufep)
{ // OPPTYPE
source_format = (Ipp8u)bs.GetBits(3);
if (0 == source_format || 7 == source_format)
return UMC_ERR_FAILED;
custom_PCF = (Ipp8u)bs.GetBits(1);
bs.SkipBits(10);
if (0x08 != bs.GetBits(4))
return UMC_ERR_FAILED;
}
// MPPTYPE
if (bs.GetBits(3) > 5) // picture_coding_type
return UMC_ERR_FAILED;
bs.SkipBits(3); // flags (RPR, RRU, RTYPE)
if (0x01 != bs.GetBits(3)) // should be '001'
return UMC_ERR_FAILED;
// If PLUSPTYPE is present, then CPM follows immediately after PLUSPTYPE in the picture header.
if (bs.GetBits(1)) // CPM
bs.SkipBits(2); // PSBI
if (0x01 == ufep)
{
if (6 == source_format)
{ // custom picture format (CPFMT)
pixel_aspect_ratio_code = (Ipp8u)bs.GetBits(4);
if (0 == pixel_aspect_ratio_code || (6 <= pixel_aspect_ratio_code && pixel_aspect_ratio_code <= 14))
return UMC_ERR_FAILED;
vInfo.clip_info.width = (bs.GetBits(9) + 1) * 4;
if (1 != bs.GetBits(1))
return UMC_ERR_FAILED;
vInfo.clip_info.height = bs.GetBits(9) * 4;
if (1 * 4 == vInfo.clip_info.height || vInfo.clip_info.height > 288 * 4)
return UMC_ERR_FAILED;
if (0x0F == pixel_aspect_ratio_code)
{ // Extended Pixel Aspect Ratio (EPAR)
vInfo.aspect_ratio_width = bs.GetBits(8);
vInfo.aspect_ratio_height = bs.GetBits(8);
if (0 == vInfo.aspect_ratio_width || 0 == vInfo.aspect_ratio_height)
return UMC_ERR_FAILED;
}
else
{
vInfo.aspect_ratio_width = Mpeg4FrameConstructor::AspectRatio[pixel_aspect_ratio_code][0];
vInfo.aspect_ratio_height = Mpeg4FrameConstructor::AspectRatio[pixel_aspect_ratio_code][1];
}
}
if (1 == custom_PCF)
{ // Custom Picture Clock Frequency Code (CPCFC)
Ipp8u clock_conversion_factor = 1000 + (Ipp8u)bs.GetBits(1);
Ipp8u clock_divisor = (Ipp8u)bs.GetBits(7);
if (0 == clock_divisor)
return UMC_ERR_FAILED;
vInfo.framerate = 1800000. / (clock_divisor * clock_conversion_factor);
}
}
}
if (1 <= source_format && source_format <= 5)
{
vInfo.clip_info.width = PictureSize[source_format][0];
vInfo.clip_info.height = PictureSize[source_format][1];
}
vInfo.stream_type = H263_VIDEO;
if (pInfo)
{ // if pointer to info passed, fill it
pInfo->m_Type = TRACK_H263;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->aspect_ratio_width = vInfo.aspect_ratio_width;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->aspect_ratio_height = vInfo.aspect_ratio_height;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->clip_info = vInfo.clip_info;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->framerate = vInfo.framerate;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->stream_type = vInfo.stream_type;
}
return UMC_OK;
}
Status H264FrameConstructor::ParseSequenceParameterSet(Ipp8u *buf, Ipp32s iLen, H264HeaderSet *pHeaders, Mpeg2TrackInfo *pInfo)
{
iLen;
VideoStreamInfo vInfo;
ippsZero_8u((Ipp8u *)&vInfo, sizeof(VideoStreamInfo));
Ipp32s i, j;
H264BitstreamReader bs;
bs.Init(buf);
// Crucial elements of SPS
Ipp8u uiSPSId;
Ipp8u frame_width_in_mbs;
Ipp8u frame_height_in_mbs;
Ipp8u frame_cropping_rect_left_offset = 0;
Ipp8u frame_cropping_rect_right_offset = 0;
Ipp8u frame_cropping_rect_top_offset = 0;
Ipp8u frame_cropping_rect_bottom_offset = 0;
Ipp32u num_units_in_tick = 1;
Ipp32u time_scale = 30;
Ipp16u sar_width = 1;
Ipp16u sar_height = 1;
while (0 == bs.GetBits(8)); // skip all zeroes and one
bs.GetBits(8); // skip nal_ref_idc and nal_unit_type
Ipp8u profile_idc = (Ipp8u)bs.GetBits(8);
bs.GetBits(8); // skip flags
bs.GetBits(8); // skip level_idc
uiSPSId = (Ipp8u)bs.GetUE();
if (uiSPSId > MAX_NUM_SPS_PARSETS)
return UMC_ERR_INVALID_STREAM;
FCH264SeqParSet *pSPS = &pHeaders->m_SPS[uiSPSId];
if (100 == profile_idc || 110 == profile_idc || 122 == profile_idc || 144 == profile_idc)
{
if (3 == bs.GetUE()) // chroma_format_idc
bs.GetBit(); // residue_transform_flag
Ipp8u value = (Ipp8u)bs.GetUE(); // bit_depth_luma_minus8
if (value > 4)
return UMC_ERR_INVALID_STREAM;
value = (Ipp8u)bs.GetUE(); // bit_depth_chroma_minus8
if (value > 4)
return UMC_ERR_INVALID_STREAM;
bs.GetBit(); // qpprime_y_zero_transform_bypass_flag
if (bs.GetBit()) // seq_scaling_matrix_present_flag
{
for (i = 0; i < 8; i++)
{
if (bs.GetBit()) // presented_flag[i]
{
// pass scaling_lists
Ipp32u lastScale = 8;
Ipp32u nextScale = 8;
Ipp32s maxnum = i < 6 ? 16 : 64;
for (j = 0; j < maxnum; j++)
{
if (0 != nextScale)
{
Ipp32s delta_scale = bs.GetSE();
if (delta_scale < -128 || delta_scale > 127)
return UMC_ERR_INVALID_STREAM;
nextScale = (lastScale + delta_scale + 256) & 0xff;
}
lastScale = ( nextScale == 0 ) ? lastScale : nextScale;;
}
}
}
}
}
pSPS->log2_max_frame_num = (Ipp8u)bs.GetUE() + 4;
pSPS->pic_order_cnt_type = (Ipp8u)bs.GetUE();
if (0 == pSPS->pic_order_cnt_type)
{
pSPS->log2_max_pic_order_cnt_lsb = (Ipp8u)bs.GetUE() + 4;
if (pSPS->log2_max_pic_order_cnt_lsb < 4 || pSPS->log2_max_pic_order_cnt_lsb > 16)
return UMC_ERR_INVALID_STREAM;
}
else if (1 == pSPS->pic_order_cnt_type)
{
pSPS->delta_pic_order_always_zero_flag = (Ipp8u)bs.GetBit();
bs.GetSE(); // offset_for_non_ref_pic
bs.GetSE(); // offset_for_top_to_bottom_field
Ipp32u num_ref_frames_in_pic_order_cnt_cycle = bs.GetUE();
for (i = 0; i < (Ipp32s)num_ref_frames_in_pic_order_cnt_cycle; i++)
bs.GetSE(); // offset_for_ref_frame[i]
}
else if (pSPS->pic_order_cnt_type > 2)
return UMC_ERR_INVALID_STREAM;
bs.GetUE(); // num_ref_frames
bs.GetBit(); // gaps_in_frame_num_value_allowed_flag
frame_width_in_mbs = (Ipp8u)bs.GetUE() + 1;
frame_height_in_mbs = (Ipp8u)bs.GetUE() + 1;
pSPS->frame_mbs_only_flag = (Ipp8u)bs.GetBit();
if (0 == pSPS->frame_mbs_only_flag)
{
vInfo.interlace_type = INTERLEAVED_TOP_FIELD_FIRST;
bs.GetBit(); // mb_adaptive_frame_field_flag
}
bs.GetBit(); // direct_8x8_inference_flag
if (bs.GetBit()) // frame_cropping_flag
{
frame_cropping_rect_left_offset = (Ipp8u)bs.GetUE();
frame_cropping_rect_right_offset = (Ipp8u)bs.GetUE();
frame_cropping_rect_top_offset = (Ipp8u)bs.GetUE();
frame_cropping_rect_bottom_offset = (Ipp8u)bs.GetUE();
}
if (bs.GetBit()) // vui_parameters_present_flag
{
if (bs.GetBit()) // aspect_ratio_present_flag
{
Ipp8u aspect_ratio_idc = (Ipp8u)bs.GetBits(8);
if (255 == aspect_ratio_idc)
{ // EXTENDED_SAR
sar_width = (Ipp16u)bs.GetBits(16);
sar_height = (Ipp16u)bs.GetBits(16);
}
else if (0 < aspect_ratio_idc && aspect_ratio_idc < 14)
{
sar_width = AspectRatio[aspect_ratio_idc][0];
sar_height = AspectRatio[aspect_ratio_idc][1];
}
else
return UMC_ERR_INVALID_STREAM;
}
if (bs.GetBit()) // overscan_info_present_flag
bs.GetBit(); // overscan_appropriate_flag
if (bs.GetBit()) // video_signal_type_present_flag
{
bs.GetBits(3); // video_format
bs.GetBit(); // video_full_range_flag
if (bs.GetBit()) // colour_description_present_flag
{
bs.GetBits(8); // colour_primaries
bs.GetBits(8); // transfer_characteristics
bs.GetBits(8); // matrix_coefficients
}
}
if (bs.GetBit()) // chroma_loc_info_present_flag
{
bs.GetUE(); // chroma_sample_loc_type_top_field
bs.GetUE(); // chroma_sample_loc_type_bottom_field
}
if (bs.GetBit()) // timing_info_present_flag
{
num_units_in_tick = (bs.GetBits(16)) << 16;
num_units_in_tick += bs.GetBits(16);
if (0 == num_units_in_tick)
return UMC_ERR_INVALID_STREAM;
time_scale = (bs.GetBits(16)) << 16;
time_scale += bs.GetBits(16);
if (0 == time_scale)
return UMC_ERR_INVALID_STREAM;
}
}
vInfo.clip_info.width = 16 * frame_width_in_mbs;
vInfo.clip_info.width -= 2 * (frame_cropping_rect_left_offset + frame_cropping_rect_right_offset);
vInfo.clip_info.height = 16 * frame_height_in_mbs;
vInfo.clip_info.height -= 2 * (frame_cropping_rect_top_offset + frame_cropping_rect_bottom_offset);
vInfo.clip_info.height *= (2 - pSPS->frame_mbs_only_flag);
vInfo.aspect_ratio_width = sar_width * vInfo.clip_info.width;
vInfo.aspect_ratio_height = sar_height * vInfo.clip_info.height;
vInfo.framerate = time_scale / num_units_in_tick;
vInfo.stream_type = H264_VIDEO;
if (pInfo)
{ // if pointer to info passed, fill it
pInfo->m_Type = TRACK_H264;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->aspect_ratio_width = vInfo.aspect_ratio_width;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->aspect_ratio_height = vInfo.aspect_ratio_height;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->clip_info = vInfo.clip_info;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->framerate = vInfo.framerate;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->interlace_type = vInfo.interlace_type;
((VideoStreamInfo *)pInfo->m_pStreamInfo)->stream_type = vInfo.stream_type;
}
// if no error validate SPS
pSPS->seq_parameter_set_id = uiSPSId;
return UMC_OK;
}
Status H264FrameConstructor::ParsePictureParameterSet(Ipp8u *buf, Ipp32s iLen, H264HeaderSet *pHeaders)
{
iLen;
H264BitstreamReader bs;
bs.Init(buf);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -