📄 umc_frame_constructor.cpp
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
// 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 + -