📄 swdec_headers.c
字号:
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- In the event of publication, the following notice is applicable: --
-- --
-- (C) COPYRIGHT 2004 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced on all copies. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Decode stream headers
--
-------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of contents
1. Include headers
2. External identifiers
3. Module defines
4. Module identifiers
5. Fuctions
5.1 SwDec_DecodeHeaders
5.2 SwDec_DecodeGovHeader
5.3 SwDec_DefineVopComplexityEstimation
5.4 SwDec_SaveUserData
5.5 SwDec_ClearHeaders
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "SwDec_Headers.h"
#include "SwDec_Utils.h"
#include "MP4SwDecApi.h"
/*------------------------------------------------------------------------------
2. External identifiers
------------------------------------------------------------------------------*/
#ifndef MP4DEC_H263_ONLY
/*------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
enum {
VIDEO_ID = 1
};
/* aspect ratio info */
enum {
EXTENDED_PAR = 15
};
enum {
RECTANGULAR = 0
};
enum {
VERSION1 = 0,
VERSION2 = 1
};
STATIC u32 SwDec_DefineVopComplexityEstimation(decContainer_t *pDecContainer);
/*------------------------------------------------------------------------------
4. Module indentifiers
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
5.1 Function name:
SwDec_DecodeHeaders
Purpose:
Decodes MPEG-4 higher level (Up to VOL) headers from
input stream
Input:
pointer to decContainer_t, name of first header to decode
Output:
status (HANTRO_OK/HANTRO_NOK/END_OF_STREAM/... enum in .h file!)
------------------------------------------------------------------------------*/
u32 SwDec_DecodeHeaders(decContainer_t *pDecContainer,u32 mode)
{
u32 tmp;
u32 markerBit;
ASSERT(pDecContainer);
ASSERT((mode == SC_VOS_START) || (mode == SC_VISO_START) ||
(mode == SC_VO_START) || (mode == SC_VOL_START) );
/* headers locked -> just search next start code */
if (pDecContainer->Hdrs.lock)
{
while ((mode == SC_VOS_START) || (mode == SC_VISO_START) ||
(mode == SC_VO_START) || (mode == SC_VOL_START) )
{
mode = SwDec_FindSync(pDecContainer);
}
if (mode == SC_SV_START)
{
SwDec_UnFlushBits(pDecContainer,22);
}
else if (mode == SC_RESYNC)
{
SwDec_UnFlushBits(pDecContainer,
pDecContainer->StrmStorage.resyncMarkerLength);
}
else if (mode != END_OF_STREAM)
{
SwDec_UnFlushBits(pDecContainer,32);
}
return(HANTRO_OK);
}
/* in following switch case syntax, the mode is used only to decide
* from which header the decoding starts. After that the decoding will
* run through all headers and will break after the VOL header is decoded,
* stream ends or error is found. */
switch(mode){
case SC_VOS_START:
/* visual object sequence */
tmp = SwDec_GetBits(pDecContainer,8);
CHECK_END_OF_STREAM(tmp);
pDecContainer->Hdrs.profileAndLevelIndication = tmp;
/* if profile_and_level_indication == 11100001-11101000
* we return error. Studio profiles are not supported */
if ( (tmp >= 0xE1) && (tmp <= 0xE8) )
return (VOS_STUDIO_PROFILE);
pDecContainer->Hdrs.lastHeaderType = SC_VOS_START;
tmp = SwDec_SaveUserData(pDecContainer,SC_VOS_START);
if ( tmp==HANTRO_NOK )
return(HANTRO_NOK);
if ( IS_END_OF_STREAM(pDecContainer) )
return(HANTRO_OK);
tmp = SwDec_ShowBits(pDecContainer,32);
if( tmp!=SC_VISO_START )
return(HANTRO_NOK);
SwDec_FlushBits(pDecContainer,32);
/* fallthrough */
case SC_VISO_START:
/* visual object */
tmp = pDecContainer->Hdrs.isVisualObjectIdentifier =
SwDec_GetOneBit(pDecContainer);
if ( tmp ){
tmp = pDecContainer->Hdrs.visualObjectVerid =
SwDec_GetBits(pDecContainer,4);
pDecContainer->Hdrs.visualObjectPriority =
SwDec_GetBits(pDecContainer,3);
} else
pDecContainer->Hdrs.visualObjectVerid = 0x1;
tmp = pDecContainer->Hdrs.visualObjectType =
SwDec_GetBits(pDecContainer,4);
if ( (tmp!=VIDEO_ID) && (tmp!=END_OF_STREAM))
return(VISUAL_OBJECT_TYPE);
tmp = pDecContainer->Hdrs.videoSignalType =
SwDec_GetOneBit(pDecContainer);
if ( tmp ){
pDecContainer->Hdrs.videoFormat =
SwDec_GetBits(pDecContainer,3);
pDecContainer->Hdrs.videoRange =
SwDec_GetOneBit(pDecContainer);
tmp = pDecContainer->Hdrs.colourDescription =
SwDec_GetOneBit(pDecContainer);
if ( tmp ) {
tmp = pDecContainer->Hdrs.colourPrimaries =
SwDec_GetBits(pDecContainer,8);
if ( tmp==0 )
return(HANTRO_NOK);
tmp = pDecContainer->Hdrs.transferCharacteristics =
SwDec_GetBits(pDecContainer,8);
if ( tmp==0 )
return(HANTRO_NOK);
tmp = pDecContainer->Hdrs.matrixCoefficients =
SwDec_GetBits(pDecContainer,8);
if ( tmp==0 )
return(HANTRO_NOK);
}
}
CHECK_END_OF_STREAM(tmp);
/* stuffing */
tmp = SwDec_GetBits(pDecContainer,
8-pDecContainer->StrmDesc.bitPosInWord);
CHECK_END_OF_STREAM(tmp);
pDecContainer->Hdrs.lastHeaderType = SC_VISO_START;
/* user data */
tmp = SwDec_SaveUserData(pDecContainer,SC_VISO_START);
if ( tmp==HANTRO_NOK )
return(HANTRO_NOK);
if ( IS_END_OF_STREAM(pDecContainer) )
return(HANTRO_OK);
tmp = SwDec_ShowBits(pDecContainer,32);
if ( (tmp&0xFFFFFFE0)!=SC_VO_START )
return(HANTRO_NOK);
SwDec_FlushBits(pDecContainer,32);
/* fallthrough */
case SC_VO_START:
/* video object */
if ( IS_END_OF_STREAM(pDecContainer) )
return(HANTRO_OK);
tmp = SwDec_ShowBits(pDecContainer,32);
if ( (tmp>>10) == SC_SV_START )
return(HANTRO_OK);
else if ((tmp&0xFFFFFFF0) != SC_VOL_START)
return(HANTRO_NOK);
SwDec_FlushBits(pDecContainer,32);
/* fallthrough */
case SC_VOL_START:
/* video object layer */
pDecContainer->Hdrs.randomAccessibleVol =
SwDec_GetOneBit(pDecContainer);
pDecContainer->Hdrs.videoObjectTypeIndication =
SwDec_GetBits(pDecContainer,8);
/* NOTE: video_object_type cannot be checked if we want to be
* able to decode conformance test streams (they contain
* streams where type is e.g. main). However streams do not
* utilize all tools of "higher" profiles and can be decoded
* by our codec, even though we only support objects of type
* simple. */
tmp = pDecContainer->Hdrs.isObjectLayerIdentifier =
SwDec_GetOneBit(pDecContainer);
if ( tmp ){
pDecContainer->Hdrs.videoObjectLayerVerid =
SwDec_GetBits(pDecContainer,4);
pDecContainer->Hdrs.videoObjectLayerPriority =
SwDec_GetBits(pDecContainer,3);
} else {
pDecContainer->Hdrs.videoObjectLayerVerid =
pDecContainer->Hdrs.visualObjectVerid;
}
tmp = pDecContainer->Hdrs.aspectRatioInfo =
SwDec_GetBits(pDecContainer,4);
if ( tmp==EXTENDED_PAR ){
tmp = pDecContainer->Hdrs.parWidth =
SwDec_GetBits(pDecContainer,8);
if ( tmp==0 )
return(HANTRO_NOK);
tmp = pDecContainer->Hdrs.parHeight =
SwDec_GetBits(pDecContainer,8);
if ( tmp==0 )
return(HANTRO_NOK);
} else if ( tmp==0 )
return(HANTRO_NOK);
tmp = pDecContainer->Hdrs.volControlParameters =
SwDec_GetOneBit(pDecContainer);
if ( tmp ){
pDecContainer->Hdrs.chromaFormat =
SwDec_GetBits(pDecContainer,2);
tmp = pDecContainer->Hdrs.lowDelay =
SwDec_GetOneBit(pDecContainer);
tmp = pDecContainer->Hdrs.vbvParameters =
SwDec_GetOneBit(pDecContainer);
if ( tmp ){
tmp = pDecContainer->Hdrs.firstHalfBitRate =
SwDec_GetBits(pDecContainer,15);
tmp <<= 15;
markerBit = SwDec_GetOneBit(pDecContainer);
if ( !markerBit )
return(HANTRO_NOK);
tmp |= pDecContainer->Hdrs.latterHalfBitRate =
SwDec_GetBits(pDecContainer,15);
if ( tmp==0 )
return(HANTRO_NOK);
markerBit = SwDec_GetOneBit(pDecContainer);
if ( !markerBit )
return(HANTRO_NOK);
tmp = pDecContainer->Hdrs.firstHalfVbvBufferSize =
SwDec_GetBits(pDecContainer,15);
tmp <<= 3;
markerBit = SwDec_GetOneBit(pDecContainer);
if ( !markerBit )
return(HANTRO_NOK);
tmp |= pDecContainer->Hdrs.latterHalfVbvBufferSize =
SwDec_GetBits(pDecContainer,3);
if ( tmp==0 )
return(HANTRO_NOK);
pDecContainer->Hdrs.firstHalfVbvOccupancy =
SwDec_GetBits(pDecContainer,11);
markerBit = SwDec_GetOneBit(pDecContainer);
if ( !markerBit )
return(HANTRO_NOK);
pDecContainer->Hdrs.latterHalfVbvOccupancy =
SwDec_GetBits(pDecContainer,15);
markerBit = SwDec_GetOneBit(pDecContainer);
if ( !markerBit )
return(HANTRO_NOK);
}
}
tmp = pDecContainer->Hdrs.videoObjectLayerShape =
SwDec_GetBits(pDecContainer,2);
if ( (tmp!=RECTANGULAR) && (tmp!=END_OF_STREAM))
return(VIDEO_OBJECT_LAYER_SHAPE);
markerBit = SwDec_GetOneBit(pDecContainer);
if ( !markerBit )
return(HANTRO_NOK);
tmp = pDecContainer->Hdrs.vopTimeIncrementResolution =
SwDec_GetBits(pDecContainer,16);
if (tmp == END_OF_STREAM) return (END_OF_STREAM);
if ( tmp==0 )
return(HANTRO_NOK);
markerBit = SwDec_GetOneBit(pDecContainer);
if ( !markerBit )
return(HANTRO_NOK);
tmp = pDecContainer->Hdrs.fixedVopRate =
SwDec_GetOneBit(pDecContainer);
if ( tmp ){
tmp = SwDec_NumBits(
pDecContainer->Hdrs.vopTimeIncrementResolution-1);
tmp = pDecContainer->Hdrs.fixedVopTimeIncrement =
SwDec_GetBits(pDecContainer,tmp);
if ((tmp == 0) ||
(tmp >= pDecContainer->Hdrs.vopTimeIncrementResolution))
return(HANTRO_NOK);
}
/* marker bit after if video_object_layer==rectangular */
markerBit = SwDec_GetOneBit(pDecContainer);
if ( !markerBit )
return(HANTRO_NOK);
tmp = pDecContainer->Hdrs.videoObjectLayerWidth =
SwDec_GetBits(pDecContainer,13);
if ( tmp==0 )
return(HANTRO_NOK);
markerBit = SwDec_GetOneBit(pDecContainer);
if ( !markerBit )
return(HANTRO_NOK);
tmp = pDecContainer->Hdrs.videoObjectLayerHeight =
SwDec_GetBits(pDecContainer,13);
if ( tmp==0 )
return(HANTRO_NOK);
markerBit = SwDec_GetOneBit(pDecContainer);
if ( !markerBit )
return(HANTRO_NOK);
tmp = pDecContainer->Hdrs.interlaced =
SwDec_GetOneBit(pDecContainer);
if (tmp == 1)
return(INTERLACED);
tmp = pDecContainer->Hdrs.obmcDisable =
SwDec_GetOneBit(pDecContainer);
if ( !tmp )
return(OBMC_DISABLED);
if ( pDecContainer->Hdrs.videoObjectLayerVerid==1 ){
tmp = pDecContainer->Hdrs.spriteEnable =
SwDec_GetOneBit(pDecContainer);
} else {
tmp = pDecContainer->Hdrs.spriteEnable =
SwDec_GetBits(pDecContainer,2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -