⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp4descriptors.c

📁 Sample code for use on smp 863x processor.
💻 C
字号:
/* * * Copyright (c) Sigma Designs, Inc. 2006. All rights reserved. * *//**   @file mp4descriptors.c   @brief IOD parsing for MP4 streams	   @author Yifan Liu   @ingroup dccsamplecode*/#include "../samples/sample_os.h"#define ALLOW_OS_CODE 1#include "../dcc/include/dcc.h"#include "../samples/common.h"#include "psfdemux_common.h"#include "mp4descriptors.h"#if 1#define CALLDBG ENABLE#else#define CALLDBG DISABLE#endif/*   Parameters   p - input stream   count - input stream length   *count - return the actually parsed length   *iod - a null pointer allocated with created objects   Return pointer for success, NULL for failures */struct MP4_IOD * CreateIODDescriptor(RMuint8 *p, RMuint16 * count ){	struct MP4_IOD * iod = NULL;	RMuint16 i;	RMuint16 acclength = 9; 	RMuint16 maxlength = *count;	RMDBGLOG((CALLDBG, "CreateIODDescriptor 0x%x, %02x %02x %02x %02x\n", *count, p[0], p[1], p[2], p[3] ));	if( maxlength < acclength ) {		RMDBGLOG((ENABLE, "Error: input stream not long enough\n" ));		return NULL;	}		iod = (struct MP4_IOD *)RMMalloc( sizeof(struct MP4_IOD) );	if( !iod ) {		RMDBGLOG((ENABLE, "Error: failed create iod \n" ));		return NULL;	}	RMMemset( iod, 0, sizeof(struct MP4_IOD) );		iod->tag = p[0];     /* 8 bits, default to 0x02 *///	assert( iod->tag == 0x02 );	iod->size = p[1];    /* 8 bits, spec says 16 bits */	iod->id = (((RMuint16)p[2] & 0xff)<<2) | (RMuint16)((p[3]>>6) & 0x3);     /* 10 bits */	iod->URL_flag = (p[3]>>5) & 0x1; /* 1 bit */	iod->includeInlineProfiles = (p[3]>>4) & 0x1;  /* 1 bit *///	assert( (p[3]& 0x0f) == 0x0f );/* 4 bits reserved default to 0b1111 */	iod->esDescrNum = 0;	for( i=0; i<256; i++ )		iod->esDescr[i] = NULL;			if( iod->URL_flag ) {		RMDBGLOG((ENABLE, "Error: does not parse URL_Flag == 1 \n" ));		DestoryIODDescriptor(iod);		return NULL;	}	else {		iod->profileLevelIndication1 = p[4];/* 8 bits */;		iod->sceneProfileLevelIndication = p[5];  /* 8 bits   0x01 */;		iod->audioProfileLevelIndication = p[6];  /* 8 bits   0x0c*/;		iod->visualProfileLevelIndication = p[7]; /* 8 bits */;		iod->graphicsProfileLevelIndication = p[8];/* 8 bits 0x04*/;				while( acclength < maxlength ) {			RMuint16 nextlength = p[acclength+1]+2;			iod->esDescr[iod->esDescrNum] = CreateDescriptor( (p+acclength), &nextlength );			if( iod->esDescr[iod->esDescrNum] == NULL ) {				RMDBGLOG((ENABLE, "Error: create descr failed %d\n", iod->esDescrNum ));				DestoryIODDescriptor(iod);				return NULL;			}			iod->esDescrNum ++;			acclength += nextlength;			RMDBGLOG((CALLDBG, "Accumulated : 0x%x\n", acclength )); 		}	}	/* possible extended descriptors here, assume none for now */	*count = acclength;	return iod;}void DestoryIODDescriptor(struct MP4_IOD * iod){	RMuint8 i;	for( i = 0; i < iod->esDescrNum; i++ )	{		DestoryDescriptor( (AnyDescriptor *)iod->esDescr[i] );	}	RMFree( iod );	return;}struct MP4_ES_Descriptor * CreateESDescriptor(RMuint8 *p, RMuint16 * count ){	struct MP4_ES_Descriptor * des = NULL;	RMuint16 i;	RMuint16 acclength = 5; 	RMuint16 maxlength = *count;	RMDBGLOG((CALLDBG, "CreateESDescriptor 0x%x,  %02x %02x %02x %02x\n", *count, p[0], p[1], p[2], p[3] ));	if( maxlength < acclength ) {		RMDBGLOG((ENABLE, "Error: input stream not long enough\n" ));		return NULL;	}		des = (struct MP4_ES_Descriptor *)RMMalloc( sizeof(struct MP4_ES_Descriptor) );	if( !des ) {		RMDBGLOG((ENABLE, "Error: failed create descriptor\n" ));		return NULL;	}	RMMemset( des, 0, sizeof(struct MP4_ES_Descriptor) );	des->tag = p[0];     /* 8 bits, default to 0x03 *///	assert( des->tag == 0x03 );	des->size = p[1];    /* 8 bits */	des->ES_id = (((RMuint16)p[2] & 0xff)<<8) | (RMuint16)(p[3]);     /* 16 bits */	RMDBGLOG((CALLDBG, "   ES_id = 0x%x\n", des->ES_id ));		des->streamDependentFlag = (p[4]>>7) & 0x01; /* 1 bit */	des->URL_flag = (p[4]>>6) & 0x01;            /* 1 bit */	des->OCRstreamFlag = (p[4]>>5) & 0x01;       /* 1 bit */	des->streamPriority = p[4] & 0x1f;      /* 5 bits */	acclength = 5;	if( des->streamDependentFlag ) {		des->dependsOn_ES_id = (  ((RMuint16)p[acclength] & 0xff)<<8)					 | (RMuint16)(p[acclength+1] );     /* 16 bits */		acclength += 2;	}	if( des->URL_flag ) {		RMuint8 j;		des->URLlength = p[acclength]; /* 8 bits */		acclength ++;		for( j=0; j<des->URLlength; j++ ) {			des->URLstring[j] = p[acclength ++];			//assert ( j < 256 )		}	}	if( des->OCRstreamFlag ) {		des->OCR_ES_id = (  ((RMuint16)p[acclength] & 0xff)<<8)					 | (RMuint16)(p[acclength+1] );     /* 16 bits */		acclength += 2;	}			des->esDescrNum = 0;	for( i=0; i<256; i++ )		des->esDescr[i] = NULL;	while( acclength < maxlength ) {		RMuint16 nextlength = p[acclength+1]+2;		des->esDescr[des->esDescrNum] = CreateDescriptor( (p+acclength), &nextlength );		if( des->esDescr[des->esDescrNum] == NULL ) {			RMDBGLOG((ENABLE, "Error: create descr failed %d\n", des->esDescrNum ));			DestoryESDescriptor( des );			return NULL;		}		des->esDescrNum ++;		acclength += nextlength;		RMDBGLOG((CALLDBG, "Accumulated : 0x%x\n", acclength )); 	}	*count = acclength;	return des;	}void DestoryESDescriptor(struct MP4_ES_Descriptor * des){	RMuint8 i;	for( i = 0; i < des->esDescrNum; i++ )	{		DestoryDescriptor( (AnyDescriptor *)des->esDescr[i] );	}	RMFree( des );	return;}struct MP4_DecoderConfigDescriptor * CreateDecoderConfigDescriptor(RMuint8 *p, RMuint16 * count){	struct MP4_DecoderConfigDescriptor * des = NULL;	RMuint16 acclength = 15; 	RMuint16 maxlength = *count;	RMDBGLOG((CALLDBG, "CreateDecoderConfigDescriptor 0x%x, %02x %02x %02x %02x\n", *count, p[0], p[1], p[2], p[3] ));	if( maxlength < acclength ) {		RMDBGLOG((ENABLE, "Error: input stream not long enough\n" ));		return NULL;	}		des = (struct MP4_DecoderConfigDescriptor *)RMMalloc( sizeof(struct MP4_DecoderConfigDescriptor) );	if( !des ) {		RMDBGLOG((ENABLE, "Error: failed create iod \n" ));		return NULL;	}	RMMemset( des, 0, sizeof(struct MP4_DecoderConfigDescriptor) );	des->tag = p[0];     /* 8 bits, default to 0x04 *///	assert( des->tag == 0x04 );	des->size = p[1];    /* 8 bits */	des->objectTypeIndication = p[2];  /* 8 bits */	RMDBGLOG((CALLDBG, "   objectTypeIndication = 0x%x\n", des->objectTypeIndication ));	des->streamType = (p[3]>>2) & 0x3f;  /* 6 bits */	RMDBGLOG((CALLDBG, "   streamType = 0x%x\n", des->streamType ));	des->upstream = (p[3]>>1) & 0x01;   /* 1 bit */	/* 1 bit reserved */	des->bufferSizeDB = (((RMuint32)p[4]<<16)&0x00ff0000) 			| (((RMuint32)p[5]<<8)&0x0000ff00) 			| ((RMuint32)p[6]&0x000000ff);   /* 24 bits */	des->maxBitrate = (((RMuint32)p[7]<<24)&0xff000000) 			| (((RMuint32)p[8]<<16)&0x00ff0000) 			| (((RMuint32)p[9]<< 8)&0x0000ff00) 			| ((RMuint32)p[10]&0x000000ff);     /* 32 bits */	des->avgBitrate = (((RMuint32)p[11]<<24)&0xff000000) 			| (((RMuint32)p[12]<<16)&0x00ff0000) 			| (((RMuint32)p[13]<< 8)&0x0000ff00) 			| ((RMuint32)p[14]&0x000000ff);      /* 32 bits */	*count = acclength;	return des;}void DestoryDecoderConfigDescriptor(struct MP4_DecoderConfigDescriptor * des){	RMFree( des );}/*static void print_sl_descr( struct MP4_SLConfigDescriptor * sl ){	RMDBGLOG((CALLDBG, "\nSLConfigDescriptor 0x%x, %02x %02x %02x% 02x\n", (int)sl ));	RMDBGLOG((CALLDBG, "tag (8 bits, default to 0x06) 0x%x \n", sl->tag ));	RMDBGLOG((CALLDBG, "size (8 bits) 0x%x \n", sl->size ));	RMDBGLOG((CALLDBG, "predefined (8 bits default 0) 0x%x\n", sl->predefined ));		RMDBGLOG((CALLDBG, "useAccessUnitStartFlag %d\n", sl->useAccessUnitStartFlag ));	RMDBGLOG((CALLDBG, "useAccessUnitEndFlag %d\n", sl->useAccessUnitEndFlag ));	RMDBGLOG((CALLDBG, "useRandomAccessPointFlag %d\n", sl->useRandomAccessPointFlag ));	RMDBGLOG((CALLDBG, "hasRandomAccessUnitsOnlyFlag %d\n", sl->hasRandomAccessUnitsOnlyFlag ));	RMDBGLOG((CALLDBG, "usePaddingFlag %d\n", sl->usePaddingFlag ));	RMDBGLOG((CALLDBG, "useTimeStampsFlag %d\n", sl->useTimeStampsFlag ));	RMDBGLOG((CALLDBG, "useIdleFlag %d\n", sl->useIdleFlag ));	RMDBGLOG((CALLDBG, "durationFlag %d\n", sl->durationFlag ));		RMDBGLOG((CALLDBG, "timeStampResolution (32 bits) 0x%08x (%d)\n", sl->timeStampResolution, sl->timeStampResolution ));	RMDBGLOG((CALLDBG, "OCRResolution (32 bits) 0x%08x (%d)\n", sl->OCRResolution, sl->OCRResolution ));	RMDBGLOG((CALLDBG, "timeStampLength (8 bits) 0x%x \n", sl->timeStampLength ));	RMDBGLOG((CALLDBG, "OCRLength (8 bits) 0x%x \n", sl->OCRLength ));	RMDBGLOG((CALLDBG, "AU_Length (8 bits) 0x%x \n", sl->AU_Length ));	RMDBGLOG((CALLDBG, "instantBitrateLength (8 bits) 0x%x \n", sl->instantBitrateLength ));	RMDBGLOG((CALLDBG, "degradationPriorityLength (4 bits) 0x%x \n", sl->degradationPriorityLength ));	RMDBGLOG((CALLDBG, "AU_seqNumLength (5 bits) 0x%x \n", sl->AU_seqNumLength ));	RMDBGLOG((CALLDBG, "packet_SeqNumLength (5 bits) 0x%x \n", sl->packet_SeqNumLength ));	return;	}*/struct MP4_SLConfigDescriptor * CreateSLConfigDescriptor(RMuint8 *p, RMuint16 * count){	struct MP4_SLConfigDescriptor * des = NULL;	RMuint16 acclength = 18; 	RMuint16 maxlength = *count;	RMDBGLOG((CALLDBG, "CreateSLConfigDescriptor 0x%x, %02x %02x %02x% 02x\n", *count, p[0], p[1], p[2], p[3] ));	if( maxlength < acclength ) {		fprintf( stderr, "Error: input stream not long enough\n" );		return NULL;	}		des = (struct MP4_SLConfigDescriptor *)RMMalloc( sizeof(struct MP4_SLConfigDescriptor) );	if( !des ) {		fprintf( stderr, "Error: failed create iod \n" );		return NULL;	}	RMMemset( des, 0, sizeof(struct MP4_SLConfigDescriptor) );	des->tag = p[0];     /* 8 bits, default to 0x06 *///	assert( des->tag == 0x06 );	des->size = p[1];    /* 8 bits */	des->predefined = p[2];  /* 8 bits *///	assert( des->predefined == 0 );//	if( des->predefined == 0 )	des->useAccessUnitStartFlag = (p[3]>>7) & 0x01;  /* 1 bit */	des->useAccessUnitEndFlag = (p[3]>>6) & 0x01;    /* 1 bit */	des->useRandomAccessPointFlag = (p[3]>>5) & 0x01;/* 1 bit */	des->hasRandomAccessUnitsOnlyFlag = (p[3]>>4) & 0x01; /* 1 bit */	des->usePaddingFlag = (p[3]>>3) & 0x01;          /* 1 bit */	des->useTimeStampsFlag = (p[3]>>2) & 0x01;       /* 1 bit */	des->useIdleFlag = (p[3]>>1) & 0x01;             /* 1 bit */	des->durationFlag = (p[3]) & 0x01;            /* 1 bit */		des->timeStampResolution = (((RMuint32)p[4]<<24)&0xff000000) 			| (((RMuint32)p[5]<<16)&0x00ff0000) 			| (((RMuint32)p[6]<< 8)&0x0000ff00) 			| ((RMuint32)p[7]&0x000000ff);     /* 32 bits */	des->OCRResolution = (((RMuint32)p[8]<<24)&0xff000000) 			| (((RMuint32)p[9]<<16)&0x00ff0000) 			| (((RMuint32)p[10]<< 8)&0x0000ff00) 			| ((RMuint32)p[11]&0x000000ff);          /* 32 bits */		des->timeStampLength = p[12];         /* 8 bits */	des->OCRLength = p[13];               /* 8 bits */	des->AU_Length = p[14];               /* 8 bits */	des->instantBitrateLength = p[15];    /* 8 bits */		des->degradationPriorityLength = (p[16]>>4) & 0x0f; /* 4 bits */	des->AU_seqNumLength = ((p[16]&0x0f) << 1) | ((p[17]>>7)& 0x01); /* 5 bits */	des->packet_SeqNumLength = ((p[17]>>2)& 0x1f);       /* 5 bits *///	assert( (p[17]&0x03) == 0x03 ); /* 2 bit reserved default 0b11 */	if( des->durationFlag ) {		des->timeScale = (((RMuint32)p[18]<<24)&0xff000000) 			| (((RMuint32)p[19]<<16)&0x00ff0000) 			| (((RMuint32)p[20]<< 8)&0x0000ff00) 			| ((RMuint32)p[21]&0x000000ff);          /* 32 bits */			des->accessUnitDuration = (((RMuint16)p[22]<<8)&0xff00) 			| ((RMuint16)p[23]&0x00ff) ;  /* 16 bits */		des->compositionUnitDuration = (((RMuint16)p[24]<<8)&0xff00) 			| ((RMuint16)p[25]&0x00ff) ;  /* 16 bits */	}//	if( ! des->useTimeStampsFlag ) {		// startDecodingTimeStamp;		// startCompositionTimeStamp;//	}	*count = acclength;//	print_sl_descr( des );	return des;}void DestorySLConfigDescriptor(struct MP4_SLConfigDescriptor * des){	RMFree( des );}/*   Parameters   p - input stream   count - input stream length   *count - return the actually parsed length   *des - a null pointer allocated with created objects   Return RM_OK for success, RM_ERROR for failures   Note, in case CreateDescriptor() encounters error DestoryDescriptor() must   be called to cover possible memory leaks  */AnyDescriptor * CreateDescriptor( RMuint8 * p, RMuint16* count ){//	RMDBGLOG((CALLDBG, "CreateDescriptor 0x%x %02x %x\n", des, *p, *count ));	switch( p[0] ) { /* use swtich based on the tag for now */		case 0x02:			return (AnyDescriptor * )CreateIODDescriptor(p, count);		case 0x03:			return (AnyDescriptor * )CreateESDescriptor(p, count);		case 0x04:			return (AnyDescriptor * )CreateDecoderConfigDescriptor(p, count);		case 0x06:			return (AnyDescriptor * )CreateSLConfigDescriptor(p, count);		default:			RMDBGLOG((CALLDBG, "unknown descriptor %d \n", (int)p[0] ));			return NULL;	};}void DestoryDescriptor( AnyDescriptor * des ){	struct MP4_IOD * d = (struct MP4_IOD *)des;	RMDBGLOG((CALLDBG, "DestoryDescriptor 0x%x\n", des));	if( ! des )		return;	switch( d->tag ) { /* use switch based on the tag for now */		case 0x02:			DestoryIODDescriptor((struct MP4_IOD *)des);			break;		case 0x03:			DestoryESDescriptor((struct MP4_ES_Descriptor *)des);			break;		case 0x04:			DestoryDecoderConfigDescriptor((struct MP4_DecoderConfigDescriptor *)des);			break;		case 0x06:			DestorySLConfigDescriptor((struct MP4_SLConfigDescriptor *)des);			break;		default:			fprintf( stderr, "unknown descriptor %d \n", (int)d->tag );	};	return;}void ParseIODDescriptor(RMuint8 *p, RMuint16 * bifs, RMuint16 * od  ){	struct MP4_IOD * iod = NULL;	RMuint16 i;	RMuint16 count = p[1]-2;	RMDBGLOG((CALLDBG, "parseIODDescriptor\n"));	if (p == NULL) 		return;	iod = (struct MP4_IOD *)CreateDescriptor( (p+4), &count );	/* now the BIFS and OD descriptors are inside the iod */	if( iod == NULL ) {	  	RMDBGLOG((ENABLE, "Cannot create IOD Descriptor\n"));		return;	}	for( i=0; i<iod->esDescrNum; i++ ) {		//fprintf( stdout, "i %d,  iod esDescrNum %d \n ", (int)i, (int)iod->esDescrNum );		struct MP4_ES_Descriptor * t = (struct MP4_ES_Descriptor *)iod->esDescr[i];		//fprintf( stdout, "tag %d,  \n ", (int)t->tag );		if( t->tag == 0x03 ) { /* it is an ES descriptor */			RMuint16 j ;			for( j=0; j<t->esDescrNum; j++ ) {				struct MP4_DecoderConfigDescriptor * tt					= (struct MP4_DecoderConfigDescriptor*)t->esDescr[j];				if( tt->tag == 0x04 ) { /* it is a decoderconfigdescriptor */					if( tt->streamType == 0x01 )						*od = t->ES_id;  /* ObjectDescriptorStream ID */					else if( tt->streamType == 0x03 )						*bifs = t->ES_id; /* SceneDescriptorStream ID */				}			}		}	}	DestoryDescriptor( (void*)iod );	return;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -