📄 umc_mpeg4_pure_detect.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) 2003-2005 Intel Corporation. All Rights Reserved.//*/#include "umc_structures.h"#include "umc_mpeg4_pure_detect.h"static const int H263_width[5] = {128, 176, 352, 704, 1408};static const int H263_height[5] = {96, 144, 288, 576, 1152};#define MPEG4_VIDEO_OBJECT_MIN_SC 0x00#define MPEG4_VIDEO_OBJECT_MAX_SC 0x1F#define MPEG4_VIDEO_OBJECT_LAYER_MIN_SC 0x20#define MPEG4_VIDEO_OBJECT_LAYER_MAX_SC 0x2F#define MPEG4_ASPECT_RATIO_EXTPAR 15#define MPEG4_SHAPE_TYPE_RECTANGULAR 0#define MPEG4_SHAPE_TYPE_GRAYSCALE 3using namespace UMC;//commonIpp32u ParseHeader::NextBits(int n){ Ipp8u* ptr = decInfo.bufptr; Ipp32u tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]); tmp <<= decInfo.bitoff; tmp >>= 32 - n; return tmp;}void ParseHeader::FlushBits(int n){ n = n + decInfo.bitoff; decInfo.bufptr += n >> 3; decInfo.bitoff = n & 7;}Ipp32u ParseHeader::GetBits(int n){ Ipp32u tmp = NextBits(n); FlushBits(n); return tmp;}void ParseHeader::GetdecInfo(int& width, int& height){ width = decInfo.picture_width; height = decInfo.picture_height;}Status ParseHeader::Init(Ipp8u *pParam, int buflen){ decInfo.buflen = (Ipp32u)buflen; decInfo.buffer = (Ipp8u*)pParam; decInfo.bufptr = decInfo.buffer; decInfo.bitoff = 0; return UMC_OK;}// --------------------------- MPEG-4 --------------------------- //inline int ParseMP4Header::GetMarkerBit(){ return GetBits(1);}Status ParseMP4Header::Parse_VideoObjectLayer(){ Ipp32u code; int i; int video_object_layer_verid; int video_object_layer_shape; int vop_time_increment_resolution; int vop_time_increment_resolution_bits; code = NextBits(22); // check short_video_start_marker if (code == 32) { i = ((decInfo.bufptr[4] >> 2) & 0x7) - 1; decInfo.picture_width = H263_width[i]; decInfo.picture_height = H263_height[i]; if (i < 0 || i > 4) return UMC_BAD_STREAM; return UMC_OK; } code = NextBits(32); if (code < 256 + MPEG4_VIDEO_OBJECT_LAYER_MIN_SC || code > 256 + MPEG4_VIDEO_OBJECT_LAYER_MAX_SC) return UMC_BAD_STREAM; FlushBits(41); if (GetBits(1)) { video_object_layer_verid = GetBits(4); FlushBits(3); } else video_object_layer_verid = 1; if (GetBits(4) == MPEG4_ASPECT_RATIO_EXTPAR) FlushBits(16); if (GetBits(1)) { FlushBits(3); if (GetBits(1)) FlushBits(79); } video_object_layer_shape = GetBits(2); if (video_object_layer_verid != 1 && video_object_layer_shape == MPEG4_SHAPE_TYPE_GRAYSCALE) FlushBits(4); GetMarkerBit(); vop_time_increment_resolution = GetBits(16); GetMarkerBit(); // define number bits in vop_time_increment_resolution code = vop_time_increment_resolution - 1; i = 0; do { code >>= 1; i ++; } while (code); vop_time_increment_resolution_bits = i; if (GetBits(1)) FlushBits(vop_time_increment_resolution_bits); if (video_object_layer_shape == MPEG4_SHAPE_TYPE_RECTANGULAR) { GetMarkerBit(); decInfo.picture_width = GetBits(13); GetMarkerBit(); decInfo.picture_height = GetBits(13); GetMarkerBit(); if (!decInfo.picture_width || !decInfo.picture_height) return UMC_BAD_STREAM; } else { decInfo.picture_width = 320; decInfo.picture_height = 240; } return UMC_OK;}Ipp8u* ParseMP4Header::FindStartCode(){ int i, len = decInfo.buflen - (decInfo.bufptr - decInfo.buffer); for (i = 0; i < len - 3; i++) { // start code if (decInfo.bufptr[i] == 0 && decInfo.bufptr[i + 1] == 0 && decInfo.bufptr[i + 2] == 1) return decInfo.bufptr + i; // short_video_start_marker if (decInfo.bufptr[i] == 0 && decInfo.bufptr[i + 1] == 0 && (decInfo.bufptr[i + 2] & 0xFC) == 0x80) return decInfo.bufptr + i; } return NULL;}Ipp8u* ParseMP4Header::SeekStartCode(){ if (decInfo.bitoff) { decInfo.bufptr ++; decInfo.bitoff = 0; } decInfo.bufptr = FindStartCode(); return decInfo.bufptr;}Status ParseMP4Header::Init(Ipp8u *pParam, int buflen){ Status status; Ipp32u code; ParseHeader::Init(pParam, buflen); for (;;) { if (!SeekStartCode()) return UMC_BAD_STREAM; if ((decInfo.bufptr[2] & 0xFC) == 0x80) code = MPEG4_VIDEO_OBJECT_MIN_SC; else { code = decInfo.bufptr[3]; decInfo.bufptr += 4; } if (code <= MPEG4_VIDEO_OBJECT_MAX_SC) { if ((status = Parse_VideoObjectLayer()) != UMC_OK) return status; break; } } return UMC_OK;}// --------------------------- H.261 --------------------------- //Status ParseH261Header::Init(Ipp8u *pParam, int buflen){ ParseHeader::Init(pParam, buflen); // PSC if (GetBits(20) != 16) return UMC_BAD_STREAM; // TR FlushBits(5); // PTYPE if (GetBits(6) & 0x4) { decInfo.picture_width = 352; decInfo.picture_height = 288; } else { decInfo.picture_width = 176; decInfo.picture_height = 144; } return UMC_OK;}// --------------------------- H.263 --------------------------- //Status ParseH263Header::Init(Ipp8u *pParam, int buflen){ int source_format, ufep, pwi = 0, phi = 0; Ipp32u code; ParseHeader::Init(pParam, buflen); // PSC if (GetBits(22) != 32) return UMC_BAD_STREAM; // TR GetBits(8); // PTYPE code = GetBits(8); if ((code >> 6) != 2) return UMC_BAD_STREAM; source_format = code & 7; if (source_format == 0 || source_format == 6) return UMC_BAD_STREAM; // PLUSPTYPE if (source_format == 7) { ufep = GetBits(3); // ufep should be 1 in the first picture if (ufep != 1) return UMC_BAD_STREAM; // OPPTYPE code = GetBits(18); source_format = code >> 15; if (source_format == 0 || source_format == 7) return UMC_BAD_STREAM; // MPPTYPE GetBits(9); if (GetBits(1)) GetBits(2); // custom picture format if (source_format == 6) { code = GetBits(23); pwi = (code >> 10) & 511; phi = code & 511; } } if (source_format == 6) { decInfo.picture_height = (phi + 1) * 4; decInfo.picture_width = (pwi + 1) * 4; } else { decInfo.picture_height = H263_height[source_format - 1]; decInfo.picture_width = H263_width[source_format - 1]; } return UMC_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -