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

📄 umc_frame_constructor.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
//                  INTEL CORPORATION PROPRIETARY INFORMATION
//     This software is supplied under the terms of a license agreement or
//     nondisclosure agreement with Intel Corporation and may not be copied
//     or disclosed except in accordance with the terms of that agreement.
//          Copyright(c) 2005-2007 Intel Corporation. All Rights Reserved.
//
*/

#include <ipps.h>
#include "umc_automatic_mutex.h"
#include "umc_default_memory_allocator.h"
#include "umc_frame_constructor.h"

namespace UMC
{

const Ipp64f Mpeg2FrameConstructor::FrameRate[9] = {
    0., 24000 / 1001., 24., 25., 30000 / 1001., 30., 50., 60000 / 1001., 60.
};

const Ipp64f Mpeg2FrameConstructor::AspectRatioMp1[15] = {
    0.0000, 1.0000, 0.6735, 0.7031, 0.7615,
    0.8055, 0.8437, 0.8437, 0.9375, 0.9815,
    1.0255, 1.0695, 1.1250, 1.1575, 1.2015
};

const Ipp32s Mpeg2FrameConstructor::AspectRatioMp2[5][2] = {
    {1, 1}, {1, 1}, {4, 3}, {16, 9}, {221, 100}
};

const Ipp32s Mpeg4FrameConstructor::AspectRatio[6][2] = {
    {0, 0}, {1, 1}, {12, 11}, {10, 11}, {16, 11}, {40, 33}
};

const Ipp16s H263FrameConstructor::PictureSize[6][2] = {
    {0, 0}, {128, 96}, {176, 144}, {352, 288}, {704, 576}, {1408, 1152}
};

const FrameType H264FrameConstructor::SliceType[10] = {
    P_PICTURE, B_PICTURE, I_PICTURE, P_PICTURE, I_PICTURE,
    P_PICTURE, B_PICTURE, I_PICTURE, P_PICTURE, I_PICTURE
};

const Ipp16u H264FrameConstructor::AspectRatio[14][2] = {
    { 1,  1}, { 1,  1}, {12, 11}, {10, 11}, {16, 11}, {40, 33}, { 24, 11},
    {20, 11}, {32, 11}, {80, 33}, {18, 11}, {15, 11}, {64, 33}, {160, 99}
};

const AudioStreamType AudioFrameConstructor::MpegAStreamType[2][3] = {
    {MP2L1_AUDIO, MP2L2_AUDIO, MP2L3_AUDIO},
    {MP1L1_AUDIO, MP1L2_AUDIO, MP1L3_AUDIO}
};

const Ipp32s AudioFrameConstructor::MpegAFrequency[3][4] = {
    {22050, 24000, 16000, 0}, /* MPEG 1 */
    {44100, 48000, 32000, 0}, /* MPEG 2 */
    {11025, 12000,  8000, 0}  /* MPEG 2.5 */
};

const Ipp32s AudioFrameConstructor::MpegABitrate[2][3][15] = {
    { /* MPEG 2 */
        {0, 32, 48, 56,  64,  80,  96, 112, 128, 144, 160, 176, 192, 224, 256}, /* Layer 1 */
        {0,  8, 16, 24,  32,  40,  48,  56,  64,  80,  96, 112, 128, 144, 160}, /* Layer 2 */
        {0,  8, 16, 24,  32,  40,  48,  56,  64,  80,  96, 112, 128, 144, 160}  /* Layer 3 */
    },
    { /* MPEG 1 */
        {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448}, /* Layer 1 */
        {0, 32, 48, 56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320, 384}, /* Layer 2 */
        {0, 32, 40, 48,  56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320}  /* Layer 3 */
    }
};

const Ipp32s AudioFrameConstructor::MpegAChannels[4] = {
    2, 2, 2, 1
};

const Ipp32f AudioFrameConstructor::MpegAFramesize[2][4] = {
    { 0.0f, 384.0f, 1152.0f,  576.0f }, /* MPEG 2 */
    { 0.0f, 384.0f, 1152.0f, 1152.0f }  /* MPEG 1 */
};

const Ipp32s AudioFrameConstructor::AACFrequency[16] = {
    96000, 88200, 64000, 48000, 44100, 32000, 24000,
    22050, 16000, 12000, 11025, 8000, 7350, 0, 0, 0
};

const Ipp32s AudioFrameConstructor::AACChannels[16] = {
    0, 1, 2, 3, 4, 5, 6, 8, 0, 0, 0, 0, 0, 0, 0, 0
};

const Ipp32s AudioFrameConstructor::AC3Frequency[3] = {
    48000, 44100, 32000
};

const Ipp32s AudioFrameConstructor::AC3FrequencyExt[8] = {
    48000, 44100, 32000, 0, 48000, 48000, 44100, 48000
};

const Ipp32s AudioFrameConstructor::AC3BitRate[19] = {
     32000,  40000,  48000,  56000,  64000,  80000,  96000, 112000, 128000, 160000,
    192000, 224000, 256000, 320000, 384000, 448000, 512000, 576000, 640000
};

const Ipp32s AudioFrameConstructor::AC3NumChannels[] = {
    2, 1, 2, 3, 3, 4, 4, 5, 1, 2, 3, 4, 5, 6
};

const Ipp32s AudioFrameConstructor::DTSChannels[16] = {
    1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8
};

const Ipp32s AudioFrameConstructor::DTSFrequency[16] = {
    0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0, 12000, 24000, 48000, 0, 0
};

const Ipp32s AudioFrameConstructor::DTSBitrate[32] = {
      32000,   56000,   64000,   96000,  112000,  128000,  192000,  224000,
     256000,  320000,  384000,  448000,  512000,  576000,  640000,  768000,
     960000, 1024000, 1152000, 1280000, 1344000, 1408000, 1411200, 1472000,
    1536000, 1920000, 2048000, 3072000, 3840000,       0,       0,       0
};

const Ipp32s AudioFrameConstructor::LPCMChannels[16] = {
    1, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0
};

Status Mpeg2FrameConstructor::ParseSequenceHeader(Ipp8u *buf, Ipp32s iLen, Mpeg2TrackInfo *pInfo)
{
    VideoStreamInfo vInfo;
    ippsZero_8u((Ipp8u *)&vInfo, sizeof(VideoStreamInfo));

    Ipp32s uiHeaderSizeEstimation = 17;
    if (iLen >= 0 && uiHeaderSizeEstimation > iLen)
        return UMC_ERR_NOT_ENOUGH_DATA;

    BitstreamReader bs;
    bs.Init(buf);
    bs.SkipBits(32); // skip sequence header

    vInfo.clip_info.width = (Ipp16u)bs.GetBits(12);
    if (0 == vInfo.clip_info.width)
        return UMC_ERR_INVALID_STREAM;

    vInfo.clip_info.height = (Ipp16u)bs.GetBits(12);
    if (0 == vInfo.clip_info.height)
        return UMC_ERR_INVALID_STREAM;

    // aspect_ratio_information will be checked separately for MPEG1 and MPEG2
    // because this field has different sematics
    Ipp8u aspect_ratio_information = (Ipp8u)bs.GetBits(4);
    Ipp8u frame_rate_code = (Ipp8u)bs.GetBits(4);
    if (0 == frame_rate_code || frame_rate_code > 8)
        return UMC_ERR_INVALID_STREAM;
    vInfo.framerate = FrameRate[frame_rate_code];

    vInfo.bitrate = 400 * bs.GetBits(18);

    bs.GetBits(1); // marker_bit
    bs.SkipBits(10); // vbv_buffer_size_value
    bs.SkipBits(1); // constrained_parameters_flag

    if (bs.GetBits(1)) //load_intra_quantiser_matrix
    {
        uiHeaderSizeEstimation += 64;
        if (iLen >= 0 && uiHeaderSizeEstimation > iLen)
            return UMC_ERR_NOT_ENOUGH_DATA;
        bs.SkipBits(64 * 8);
    }

    if (bs.GetBits(1)) // load_non_intra_quantiser_matrix
    {
        uiHeaderSizeEstimation += 64;
        if (iLen >= 0 && uiHeaderSizeEstimation > iLen)
            return UMC_ERR_NOT_ENOUGH_DATA;
        bs.SkipBits(64 * 8);
    }

    TrackType trackType;
    Ipp32u code = bs.GetBits(32);
    if (0x1B5 == code && 0x01 == bs.GetBits(4))
    { // presence sequence_extension indicates MPEG2
        trackType = TRACK_MPEG2V;
        vInfo.stream_type = MPEG2_VIDEO;
        // check aspect_ratio_information for MPEG2.
        if (0 == aspect_ratio_information || aspect_ratio_information > 4)
            return UMC_ERR_FAILED;

        if (1 == aspect_ratio_information)
        { // pixel aspect ratio (square pixels)
            vInfo.aspect_ratio_width = vInfo.clip_info.width;
            vInfo.aspect_ratio_height = vInfo.clip_info.height;
        }
        else
        { // display aspect ratio
            vInfo.aspect_ratio_width = AspectRatioMp2[aspect_ratio_information][0];
            vInfo.aspect_ratio_height = AspectRatioMp2[aspect_ratio_information][1];
        }

        bs.SkipBits(8); //profile_and_level_indication
        if (!bs.GetBits(1)) //progressive_sequence
        {
            // top-first is a temporary it will be defined exactly from first picture header
            vInfo.interlace_type = INTERLEAVED_TOP_FIELD_FIRST;
        }
    }
    else
    { // absence of sequence_extension indicates MPEG1
        trackType = TRACK_MPEG1V;
        vInfo.stream_type = MPEG1_VIDEO;
        // check aspect_ratio_information for MPEG1
        if (0 == aspect_ratio_information || aspect_ratio_information == 15)
            return UMC_ERR_FAILED;

        // MPEG1 specifies pixel aspect ratio
        vInfo.aspect_ratio_width = vInfo.clip_info.width;
        vInfo.aspect_ratio_height = (Ipp32s)(vInfo.clip_info.height * AspectRatioMp1[aspect_ratio_information]);
    }

    if (pInfo)
    { // if pointer to info passed, fill it
        pInfo->m_Type = trackType;
        ((VideoStreamInfo *)pInfo->m_pStreamInfo)->aspect_ratio_height = vInfo.aspect_ratio_height;
        ((VideoStreamInfo *)pInfo->m_pStreamInfo)->aspect_ratio_width = vInfo.aspect_ratio_width;
        ((VideoStreamInfo *)pInfo->m_pStreamInfo)->bitrate = vInfo.bitrate;
        ((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;
        ((VideoStreamInfo *)pInfo->m_pStreamInfo)->interlace_type = vInfo.interlace_type;
    }

    return UMC_OK;
}

Status Mpeg2FrameConstructor::ParsePictureHeader(Ipp8u *buf, Ipp32s iLen, Mpeg2TrackInfo *pInfo)
{
    InterlaceType interlace_type = PROGRESSIVE;

    // Find first picture coding extension
    Ipp32s offset = 0;
    while ((iLen < 0 || offset < iLen - 8) && !(IS_CODE(&buf[offset], 0xb5) && (buf[offset + 4] & 0xf0) == 0x80))
        offset++;
    if (iLen >= 0 && offset >= iLen - 8)
        return UMC_ERR_NOT_ENOUGH_DATA;

    BitstreamReader bs;
    bs.Init(&buf[offset]);

    // start_code, start_code_identifier, f_codes, intra_dc_precision
    bs.SkipBits(32 + 4 + 4 + 4 + 4 + 4 + 2);
    Ipp32u picture_structure = bs.GetBits(2);
    Ipp32u top_field_first = bs.GetBits(1);
    // frame_pred_frame_dct, concealment_motion_vectors, q_scale_type, intra_vlc_format
    // alternate_scan, repeat_first_field, chroma_420_type
    bs.SkipBits(1 + 1 + 1 + 1 + 1 + 1 + 1);

    Ipp32u progressive_frame = bs.GetBits(1);
    if (1 == progressive_frame)
        interlace_type = PROGRESSIVE;
    else
    {
        if (1 == picture_structure) // Field
            interlace_type = INTERLEAVED_TOP_FIELD_FIRST;
        else if (2 == picture_structure) // Bottom Field
            interlace_type = INTERLEAVED_BOTTOM_FIELD_FIRST;
        else if (3 == picture_structure) // Frame-picture
            interlace_type = (top_field_first) ? INTERLEAVED_TOP_FIELD_FIRST : INTERLEAVED_BOTTOM_FIELD_FIRST;
    }

    if (pInfo)
        ((VideoStreamInfo *)pInfo->m_pStreamInfo)->interlace_type = interlace_type;
    return UMC_OK;
}

Status Mpeg4FrameConstructor::ParseVideoObjectLayer(Ipp8u *buf, Ipp32s iLen, Mpeg2TrackInfo *pInfo)
{
    VideoStreamInfo vInfo;
    ippsZero_8u((Ipp8u *)&vInfo, sizeof(VideoStreamInfo));

    Ipp32s pos = 0;
    while ((iLen < 0 || pos < iLen - 3) && !IS_CODE_INT(&buf[pos], 0x20, 0x2f))
        pos++;
    if (iLen > 0 && pos >= iLen - 3)
        return UMC_ERR_NOT_ENOUGH_DATA;

    // 28 bytes is enough for header
    Ipp32s iEstimatedHeaderSize = 28;
    if (iLen > 0 && pos + iEstimatedHeaderSize >= iLen)
        return UMC_ERR_NOT_ENOUGH_DATA;

    BitstreamReader bs;
    bs.Init(&buf[pos + 4]);
    bs.GetBits(1); // random_accessible_vol
    Ipp32u video_object_type_indication = bs.GetBits(8);
    if (0x12 == video_object_type_indication) // "Fine Granularity Scalable"
        return UMC_ERR_INVALID_STREAM;

    Ipp32u video_object_layer_verid;
    Ipp32u is_object_layer_identifier = bs.GetBits(1);
    if (is_object_layer_identifier)
    {
        video_object_layer_verid = bs.GetBits(4);
        bs.GetBits(3); // video_object_layer_priority
    }
    else
        video_object_layer_verid = 1;

    if (0x01 != video_object_layer_verid && 0x02 != video_object_layer_verid &&
        0x04 != video_object_layer_verid && 0x05 != video_object_layer_verid)
        return UMC_ERR_INVALID_STREAM;

    Ipp32u aspect_ratio_info = (Ipp8u)bs.GetBits(4);
    if (0x0F == aspect_ratio_info)
    { // "extended_PAR"
        vInfo.aspect_ratio_width = bs.GetBits(8);
        vInfo.aspect_ratio_height = bs.GetBits(8);
        if (0x00 == vInfo.aspect_ratio_width || 0x00 == vInfo.aspect_ratio_height)
            return UMC_ERR_INVALID_STREAM;
    }
    else if (1 <= aspect_ratio_info && aspect_ratio_info <= 5)
    {
        vInfo.aspect_ratio_width = AspectRatio[aspect_ratio_info][0];
        vInfo.aspect_ratio_height = AspectRatio[aspect_ratio_info][1];
    }
    else // forbidden or reserved values
        return UMC_ERR_INVALID_STREAM;

    if (bs.GetBits(1)) // vol_control_parameters
    {
        bs.GetBits(3); // skip chroma_format, low_delay
        if (bs.GetBits(1)) // vbv_parameters
            bs.SkipBits(79); // skip vbv_parameters
    }

    Ipp32u video_object_layer_shape = bs.GetBits(2);
    if (0x03 == video_object_layer_verid && 0x01 != video_object_layer_shape)
        bs.GetBits(4); // skip video_object_layer_shape_extension

    if (1 != bs.GetBits(1)) // marker_bit
        return UMC_ERR_INVALID_STREAM;

    Ipp32u vop_time_increment_resolution = bs.GetBits(16);
    if (0x00 == vop_time_increment_resolution)
        return UMC_ERR_INVALID_STREAM;

    if (1 != bs.GetBits(1)) // marker_bit
        return UMC_ERR_INVALID_STREAM;

    Ipp8u uiBitCount = 0;
    while (vop_time_increment_resolution >> uiBitCount)
        uiBitCount++;

    vInfo.framerate = 0.0;
    if (bs.GetBits(1)) // fixed_vop_rate
    {
        Ipp32u fixed_vop_time_increment = bs.GetBits(uiBitCount);
        if (0x00 == fixed_vop_time_increment)
            return UMC_ERR_INVALID_STREAM;
        vInfo.framerate = vop_time_increment_resolution / fixed_vop_time_increment;
    }

    if (0x00 != video_object_layer_shape) // "rectangular"
        return UMC_ERR_INVALID_STREAM;

    if (1 != bs.GetBits(1)) // marker_bit
        return UMC_ERR_INVALID_STREAM;

    vInfo.clip_info.width = bs.GetBits(13);
    if (0 == vInfo.clip_info.width)
        return UMC_ERR_INVALID_STREAM;

    if (1 != bs.GetBits(1)) // marker_bit
        return UMC_ERR_INVALID_STREAM;

    vInfo.clip_info.height = bs.GetBits(13);
    if (0 == vInfo.clip_info.height)
        return UMC_ERR_INVALID_STREAM;

    if (1 != bs.GetBits(1)) // marker_bit
        return UMC_ERR_INVALID_STREAM;

    if (bs.GetBits(1)) // interlaced
        vInfo.interlace_type = INTERLEAVED_TOP_FIELD_FIRST;
    else
        vInfo.interlace_type = PROGRESSIVE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -