📄 qt_parse.c
字号:
/*-----------------------------------------------------------------------------\
@ModuleName :: qt.c
@Description :: Quick Time Wrapper for MJPEG , H263, MPEG-4 bitstream
For info about Quick Time File Format see QTFF reference at
http://developer.apple.com/techpubs/quicktime/qtdevdocs/QTFF/qtff.html
@Copyright :: Copyright 2001- Texas Instruments, Inc.
@History ::
-------------------------------------------------------------------------------
Dec. 26, 2001 Kedar C (kedarc@ti.com) Start
\-----------------------------------------------------------------------------*/
/* include files */
#include <string.h>
#include <qtff/qt.h>
#include <qtff/qt_parse.h>
/* Module Routines */
/*-----------------------------------------------------------------------------\
@RoutineName :: QTShowParams
@Description ::
Display the MOOV_Info struct on stdout
@Parameters ::
MOOV_Info *moov :: QT Configuration structure to be displayed
@Return ::
E_PASS, success
E_DEVICE, failure
\-----------------------------------------------------------------------------*/
STATUS QTShowParams(QTParams *prmQT) {
printf("\n");
printf("\n QuickTime File Format Parameters :");
printf("\n ==================================");
printf("\n");
#if QT_DEBUG
printf("\n Videosize : %ld", prmQT->Videosize );
#endif
printf("\n DataFormat : %c%c%c%c",
(char)( prmQT->DataFormat >> 24) , (char)( prmQT->DataFormat >> 16 ) & 0xFF ,
(char)( prmQT->DataFormat >> 8 ) & 0xFF, (char)prmQT->DataFormat & 0xFF );
printf("\n Duration : %ld.%ld secs", prmQT->Scount / prmQT->FrameRate,
(prmQT->Scount % prmQT->FrameRate)*( 60 / prmQT->FrameRate ) );
printf("\n Sample Count : %ld", prmQT->Scount );
printf("\n SampleDuration : %ld", prmQT->SampleDuration );
printf("\n Timescale : %ld", prmQT->Timescale );
printf("\n FrameRate : %ld", prmQT->FrameRate );
printf("\n Width : %d", prmQT->Width );
printf("\n Height : %d", prmQT->Height );
#if QT_DEBUG
printf("\n MediaTime : %ld", prmQT->MediaTime );
printf("\n MediaRate : %d.%d", (Uint16)(prmQT->MediaRate >> 16), (Uint16)(prmQT->MediaRate & 0xFFFF ));
printf("\n GraphicsMode : 0x%x", prmQT->GraphicsMode );
printf("\n TemporalQuality : %ld", prmQT->TemporalQuality );
printf("\n SpatialQuality : %ld", prmQT->SpatialQuality );
printf("\n Hres (pixels/inch) : %d.0", prmQT->Hres );
printf("\n Vres (pixels/inch) : %d.0", prmQT->Vres );
printf("\n FramePerSample : %d", prmQT->FramePerSample );
printf("\n ColorDepth : %d-bit", prmQT->ColorDepth );
printf("\n FieldCount : %d", prmQT->FieldCount );
printf("\n FieldOrdering : %d", prmQT->FieldOrdering );
printf("\n KeyFrameInterval : %d", prmQT->KeyFrameInterval );
#endif
printf("\n Video Chunk Offset : %ld", prmQT->ChunkOffset);
if( prmQT->SsizeConst == FALSE ) {
#if QT_DEBUG
Uint32 i;
printf("\n Sample size Array ( hex ):");
for( i=0; i<prmQT->Scount; i++) {
if( i%10 == 0 )
printf("\n ");
printf("%6lx ", prmQT->Ssize[i]);
}
#endif
} else {
printf("\n Const SampleSize : 0x%lx", prmQT->Ssize[0] );
}
if( prmQT->audioPrmQT.IncludeAudio) {
#if QT_DEBUG
printf("\n Audio data size : %d", prmQT->audioPrmQT.AudioDataSize);
printf("\n Audio Sampling Rate : %d", prmQT->audioPrmQT.SamplingRate);
printf("\n Audio Channels : %d", prmQT->audioPrmQT.AudioChannels);
#endif
printf("\n Audio Chunk Offset : %ld", prmQT->audioPrmQT.ChunkOffset);
}
printf("\n");
printf("\n");
return E_PASS;
}
/*-----------------------------------------------------------------------------\
QT Parser Routines
\-----------------------------------------------------------------------------*/
static MOOV_Info moov;
/*-----------------------------------------------------------------------------\
@RoutineName :: QTParseMOOVAtom
@Description ::
Parse the Movie Atom
@Parameters ::
Uint8 *start :: Pointer to start of MOOV Atom
Uint32 size :: Size of MOOV Atom
MOOV_Info *moov :: QT Configuration structure
@Return ::
E_PASS, success
E_DEVICE, failure
\-----------------------------------------------------------------------------*/
STATUS QTParseMOOVAtom(Uint8 *start, Uint32 size, QTParams *prmQT) {
Uint32 tag;
Uint8 *cur;
Uint8 *end;
Uint8 i;
size = get_word32( start );
tag = get_word32( start + 4 );
if( tag != QT_MOOV_TAG )
return E_DEVICE;
end = start + size;
cur = start + 8;
i = 0;
moov.trak[0].mdia.minf.stbl.stsz.sampleSizeTable = prmQT->Ssize;
moov.trak[1].mdia.minf.stbl.stsz.sampleSizeTable = prmQT->Ssize;
while(cur < end) {
size = get_word32( cur );
tag = get_word32( cur + 4 );
switch( tag ) {
case QT_MVHD_TAG :
QTParseMVHDAtom( cur , size, &moov.mvhd );
break;
case QT_TRAK_TAG :
if(i<MAX_TRAK_ATOMS) {
QTParseTRAKAtom( cur , size, &moov.trak[i]);
i++;
}
break;
default :
/* tag not supported or no useful info in tag */
break;
}
cur += size;
}
// fill prmQT based on MOOV_Info data
prmQT->audioPrmQT.IncludeAudio = FALSE;
{
Uint8 j;
prmQT->Timescale = moov.mvhd.timescale;
prmQT->Duration = moov.mvhd.duration;
for(j=0; j<i; j++) {
TRAK_Info *trak;
STBL_Info *stbl;
trak = &moov.trak[j];
stbl = &trak->mdia.minf.stbl;
if(trak->mdia.hdlr.compSubType==COMP_SUB_TYPE_VIDE) {
prmQT->Width = trak->tkhd.width;
prmQT->Height= trak->tkhd.height;
prmQT->DataFormat = stbl->stsd.dataformat;
prmQT->Scount = stbl->stsz.sampleCount;
prmQT->SsizeConst = (BOOL)stbl->stsz.sampleSizeConst;
prmQT->ChunkOffset = stbl->stco.chunkOffset;
}
if(trak->mdia.hdlr.compSubType==COMP_SUB_TYPE_SOUN) {
prmQT->audioPrmQT.IncludeAudio = TRUE;
prmQT->audioPrmQT.ChunkOffset = stbl->stco.chunkOffset;
}
}
}
if(prmQT->Scount==0)
prmQT->Scount=1;
prmQT->SampleDuration = prmQT->Duration/prmQT->Scount;
if(prmQT->SampleDuration==0)
prmQT->SampleDuration=1;
prmQT->FrameRate = prmQT->Timescale/prmQT->SampleDuration;
if(prmQT->FrameRate==0)
prmQT->FrameRate=1;
return E_PASS;
}
/*-----------------------------------------------------------------------------\
@RoutineName :: QTParseMVHDAtom
@Description ::
Parse the Movie Header Atom
@Parameters ::
Uint8 *start :: Pointer to start of Atom
Uint32 size :: Size of Atom
MVHD_Info *mvhd :: MVHD Info
@Return ::
E_PASS, success
E_DEVICE, failure
\-----------------------------------------------------------------------------*/
STATUS QTParseMVHDAtom( Uint8 *start , Uint32 size, MVHD_Info *mvhd) {
mvhd->timescale = get_word32( start + QT_TIMESCALE_OFFSET );
mvhd->duration = get_word32( start + QT_DURATION_OFFSET );
return E_PASS;
}
/*-----------------------------------------------------------------------------\
@RoutineName :: QTParseTRAKAtom
@Description ::
Parse the Track Atom
@Parameters ::
Uint8 *start :: Pointer to start of Atom
Uint32 size :: Size of Atom
TRAK_Info *trak :: TRAK Info
@Return ::
E_PASS, success
E_DEVICE, failure
\-----------------------------------------------------------------------------*/
STATUS QTParseTRAKAtom( Uint8 *start , Uint32 size, TRAK_Info *trak) {
Uint32 tag;
Uint8 *cur;
Uint8 *end;
end = start + size;
cur = start + 8;
while(cur < end) {
size = get_word32( cur );
tag = get_word32( cur + 4 );
switch( tag ) {
case QT_TKHD_TAG :
QTParseTKHDAtom( cur , size, &trak->tkhd);
break;
case QT_MDIA_TAG :
QTParseMDIAAtom( cur , size, &trak->mdia);
break;
default :
/* tag not supported or no useful info in tag */
break;
}
cur += size;
}
return E_PASS;
}
/*-----------------------------------------------------------------------------\
@RoutineName :: QTParseTKHDAtom
@Description ::
Parse the Track Header Atom
@Parameters ::
Uint8 *start :: Pointer to start of Atom
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -