📄 umc_mp4_video_parser.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) 2007 Intel Corporation. All Rights Reserved.
//
// Description: MPEG-4 video headers parsing.
//
*/
#include "umc_mp4_video_parser.h"
#include "umc_mp4_spl.h"
#include "umc_automatic_mutex.h"
using namespace UMC;
const Ipp8u mp4_aux_comp_count[MP4_SHAPE_EXT_NUM+1] = {1, 1, 2, 2, 3, 1, 2, 1, 1, 2, 3, 2, 3, 0};
Ipp32u mp4_ShowBits(mp4_Info* pInfo, Ipp32s n)
{
Ipp8u* ptr = pInfo->bufptr;
Ipp32u tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
tmp <<= pInfo->bitoff;
tmp >>= 32 - n;
return tmp;
}
Ipp32u mp4_ShowBit(mp4_Info* pInfo)
{
Ipp32u tmp = pInfo->bufptr[0];
tmp >>= 7 - pInfo->bitoff;
return (tmp & 1);
}
Ipp32u mp4_ShowBits9(mp4_Info* pInfo, Ipp32s n)
{
Ipp8u* ptr = pInfo->bufptr;
Ipp32u tmp = (ptr[0] << 8) | ptr[1];
tmp <<= (pInfo->bitoff + 16);
tmp >>= 32 - n;
return tmp;
}
void mp4_FlushBits(mp4_Info* pInfo, Ipp32s n)
{
n = n + pInfo->bitoff;
pInfo->bufptr += n >> 3;
pInfo->bitoff = n & 7;
}
Ipp32u mp4_GetBits(mp4_Info* pInfo, Ipp32s n)
{
Ipp8u* ptr = pInfo->bufptr;
Ipp32u tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
tmp <<= pInfo->bitoff;
tmp >>= 32 - n;
n = n + pInfo->bitoff;
pInfo->bufptr += n >> 3;
pInfo->bitoff = n & 7;
return tmp;
}
Ipp32u mp4_GetBit(mp4_Info* pInfo)
{
Ipp32u tmp = pInfo->bufptr[0];
if (pInfo->bitoff == 7) {
pInfo->bitoff = 0;
pInfo->bufptr ++;
} else {
tmp >>= 7 - pInfo->bitoff;
pInfo->bitoff ++;
}
return (tmp & 1);
}
Ipp32u mp4_GetBits9(mp4_Info* pInfo, Ipp32s n)
{
Ipp8u* ptr = pInfo->bufptr;
Ipp32u tmp = (ptr[0] << 8) | ptr[1];
tmp <<= (pInfo->bitoff + 16);
tmp >>= 32 - n;
n = n + pInfo->bitoff;
pInfo->bufptr += n >> 3;
pInfo->bitoff = n & 7;
return tmp;
}
Ipp32s mp4_GetMarkerBit(mp4_Info* pInfo) {
if (!mp4_GetBit(pInfo)) {
mp4_Error("Error: wrong marker bit");
return 0;
}
return 1;
}
mp4_Status mp4_Parse_VisualObject(mp4_Info* pInfo)
{
mp4_VisualObject *VO = &pInfo->VisualObject;
VO->is_identifier = mp4_GetBit(pInfo);
if (VO->is_identifier) {
VO->verid = mp4_GetBits9(pInfo, 4);
if ((VO->verid != 1) && (VO->verid != 2) && (VO->verid != 4) && (VO->verid != 5)) {
VO->verid = 1;
mp4_Error("Warning: invalid version number in VO");
}
VO->priority = mp4_GetBits9(pInfo, 3);
} else
VO->verid = 1;
VO->type = mp4_GetBits9(pInfo, 4);
if (VO->type != MP4_VISUAL_OBJECT_TYPE_VIDEO) {
mp4_Error("Error: Unsupported object: visual_object_type != video ID");
return MP4_STATUS_NOTSUPPORT;
}
VO->VideoSignalType.video_range = 0;
VO->VideoSignalType.matrix_coefficients = MP4_VIDEO_COLORS_ITU_R_BT_709;
if (VO->type == MP4_VISUAL_OBJECT_TYPE_VIDEO || VO->type == MP4_VISUAL_OBJECT_TYPE_TEXTURE) {
VO->VideoSignalType.is_video_signal_type = mp4_GetBit(pInfo);
if (VO->VideoSignalType.is_video_signal_type) {
VO->VideoSignalType.video_format = mp4_GetBits9(pInfo, 3);
VO->VideoSignalType.video_range = mp4_GetBit(pInfo);
VO->VideoSignalType.is_colour_description = mp4_GetBit(pInfo);
if (VO->VideoSignalType.is_colour_description) {
VO->VideoSignalType.colour_primaries = mp4_GetBits9(pInfo, 8);
VO->VideoSignalType.transfer_characteristics = mp4_GetBits9(pInfo, 8);
VO->VideoSignalType.matrix_coefficients = mp4_GetBits9(pInfo, 8);
}
}
}
return MP4_STATUS_OK;
}
static mp4_Status mp4_Parse_QuantMatrix(mp4_Info* pInfo)
{
Ipp32u code;
Ipp32s i;
for (i = 0; i < 64; i ++) {
code = mp4_GetBits9(pInfo, 8);
if (code == 0) break;
}
return MP4_STATUS_OK;
}
mp4_Status mp4_Parse_VideoObject(mp4_Info* pInfo)
{
Ipp32u code;
Ipp32s i;
mp4_VisualObject *VO = &pInfo->VisualObject;
mp4_VideoObject *VOL = &pInfo->VisualObject.VideoObject;
VOL->short_video_header = 0;
VOL->random_accessible_vol = mp4_GetBit(pInfo);
VOL->type_indication = mp4_GetBits9(pInfo, 8);
VOL->is_identifier = mp4_GetBit(pInfo);
if (VOL->is_identifier) {
VOL->verid = mp4_GetBits9(pInfo, 4);
if ((VOL->verid != 1) && (VOL->verid != 2) && (VOL->verid != 4) && (VOL->verid != 5)) {
mp4_Error("Warning: invalid version number in VOL");
VOL->verid = VO->verid;
}
VOL->priority = mp4_GetBits9(pInfo, 3);
} else
VOL->verid = VO->verid;
VOL->aspect_ratio_info = mp4_GetBits9(pInfo, 4);
if (VOL->aspect_ratio_info == MP4_ASPECT_RATIO_EXTPAR) {
VOL->aspect_ratio_info_par_width = mp4_GetBits9(pInfo, 8);
VOL->aspect_ratio_info_par_height = mp4_GetBits9(pInfo, 8);
}
VOL->is_vol_control_parameters = mp4_GetBit(pInfo);
if (VOL->is_vol_control_parameters) {
VOL->VOLControlParameters.chroma_format = mp4_GetBits9(pInfo, 2);
if (VOL->VOLControlParameters.chroma_format != MP4_CHROMA_FORMAT_420) {
mp4_Error("Error: vol_control_parameters.chroma_format != 4:2:0");
return MP4_STATUS_PARSE_ERROR;
}
VOL->VOLControlParameters.low_delay = mp4_GetBit(pInfo);
VOL->VOLControlParameters.vbv_parameters = mp4_GetBit(pInfo);
if (VOL->VOLControlParameters.vbv_parameters) {
VOL->VOLControlParameters.bit_rate = mp4_GetBits(pInfo, 15) << 15;
if (!mp4_GetMarkerBit(pInfo)) return MP4_STATUS_PARSE_ERROR;
VOL->VOLControlParameters.bit_rate += mp4_GetBits(pInfo, 15);
if (!mp4_GetMarkerBit(pInfo)) return MP4_STATUS_PARSE_ERROR;
if (VOL->VOLControlParameters.bit_rate == 0) {
mp4_Error("Error: vbv_parameters bit_rate == 0");
return MP4_STATUS_PARSE_ERROR;
}
VOL->VOLControlParameters.vbv_buffer_size = mp4_GetBits(pInfo, 15) << 3;
if (!mp4_GetMarkerBit(pInfo)) return MP4_STATUS_PARSE_ERROR;
VOL->VOLControlParameters.vbv_buffer_size += mp4_GetBits9(pInfo, 3);
if (VOL->VOLControlParameters.vbv_buffer_size == 0) {
mp4_Error("Error: vbv_parameters vbv_buffer_size == 0");
return MP4_STATUS_PARSE_ERROR;
}
VOL->VOLControlParameters.vbv_occupancy = mp4_GetBits(pInfo, 11) << 15;
if (!mp4_GetMarkerBit(pInfo)) return MP4_STATUS_PARSE_ERROR;
VOL->VOLControlParameters.vbv_occupancy += mp4_GetBits(pInfo, 15);
if (!mp4_GetMarkerBit(pInfo)) return MP4_STATUS_PARSE_ERROR;
}
}
VOL->shape = mp4_GetBits9(pInfo, 2);
if (VOL->shape != MP4_SHAPE_TYPE_RECTANGULAR) {
mp4_Error("Error: video_object_layer_shape != rectangular (not supported)");
return MP4_STATUS_NOTSUPPORT;
}
if (VOL->verid != 1 && VOL->shape == MP4_SHAPE_TYPE_GRAYSCALE) {
VOL->shape_extension = mp4_GetBits9(pInfo, 4);
if (VOL->shape_extension >= MP4_SHAPE_EXT_NUM) {
mp4_Error("Error: wrong value for video_object_layer_shape_extension");
return MP4_STATUS_PARSE_ERROR;
}
} else
VOL->shape_extension = MP4_SHAPE_EXT_NUM;
if (!mp4_GetMarkerBit(pInfo)) return MP4_STATUS_PARSE_ERROR;
VOL->vop_time_increment_resolution = mp4_GetBits(pInfo, 16);
if (VOL->vop_time_increment_resolution == 0) {
mp4_Error("Error: wrong value for vop_time_increment_resolution");
return MP4_STATUS_PARSE_ERROR;
}
if (!mp4_GetMarkerBit(pInfo)) return MP4_STATUS_PARSE_ERROR;
// define number bits in vop_time_increment_resolution
code = VOL->vop_time_increment_resolution - 1;
i = 0;
do {
code >>= 1;
i ++;
} while (code);
VOL->vop_time_increment_resolution_bits = i;
VOL->fixed_vop_rate = mp4_GetBit(pInfo);
if (VOL->fixed_vop_rate) {
VOL->fixed_vop_time_increment = mp4_GetBits(pInfo, VOL->vop_time_increment_resolution_bits);
}
if (VOL->shape != MP4_SHAPE_TYPE_BINARYONLY) {
if (VOL->shape == MP4_SHAPE_TYPE_RECTANGULAR) {
if (!mp4_GetMarkerBit(pInfo)) return MP4_STATUS_PARSE_ERROR;
VOL->width = mp4_GetBits(pInfo, 13);
if (!mp4_GetMarkerBit(pInfo)) return MP4_STATUS_PARSE_ERROR;
VOL->height = mp4_GetBits(pInfo, 13);
if (!mp4_GetMarkerBit(pInfo)) return MP4_STATUS_PARSE_ERROR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -