⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umc_frame_constructor.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:

    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 + -