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

📄 odf_dec.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005  *					All rights reserved * *  This file is part of GPAC / OD decoder module * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include <gpac/internal/terminal_dev.h>#include <gpac/constants.h>typedef struct {	GF_InlineScene *scene;	u32 PL;} ODPriv;static GF_Err ODF_GetCapabilities(GF_BaseDecoder *plug, GF_CodecCapability *cap){	cap->cap.valueInt = 0;	return GF_NOT_SUPPORTED;}static GF_Err ODF_SetCapabilities(GF_BaseDecoder *plug, const GF_CodecCapability capability){	return GF_OK;}static GF_Err ODF_AttachScene(GF_SceneDecoder *plug, GF_InlineScene *scene, Bool is_inline_scene){	ODPriv *priv = (ODPriv *)plug->privateStack;	if (!priv->scene) priv->scene = scene;	return GF_OK;}static void ODS_SetupOD(GF_InlineScene *is, GF_ObjectDescriptor *od){	GF_ObjectManager *odm;	odm = gf_is_find_odm(is, od->objectDescriptorID);	/*remove the old OD*/	if (odm) gf_odm_disconnect(odm, 1);	odm = gf_odm_new();	odm->OD = od;	odm->term = is->root_od->term;	odm->parentscene = is;	gf_list_add(is->ODlist, odm);	/*locate service owner*/	gf_odm_setup_object(odm, is->root_od->net_service);}static GF_Err ODS_ODUpdate(ODPriv *priv, GF_ODUpdate *odU){	GF_ObjectDescriptor *od;	u32 count;	/*extract all our ODs and compare with what we already have...*/	count = gf_list_count(odU->objectDescriptors);	if (count > 255) return GF_ODF_INVALID_DESCRIPTOR;	while (count) {		od = (GF_ObjectDescriptor *)gf_list_get(odU->objectDescriptors, 0);		gf_list_rem(odU->objectDescriptors, 0);		count--;		ODS_SetupOD(priv->scene, od);	}	return GF_OK;}static GF_Err ODS_RemoveOD(ODPriv *priv, GF_ODRemove *odR){	u32 i;	for (i=0; i< odR->NbODs; i++) {		GF_ObjectManager *odm = gf_is_find_odm(priv->scene, odR->OD_ID[i]);		if (odm) gf_odm_disconnect(odm, 1);	}	return GF_OK;}static GF_Err ODS_UpdateESD(ODPriv *priv, GF_ESDUpdate *ESDs){	GF_ESD *esd, *prev;	GF_ObjectManager *odm;	u32 count, i;	odm = gf_is_find_odm(priv->scene, ESDs->ODID);	/*spec: "ignore"*/	if (!odm) return GF_OK;	count = gf_list_count(ESDs->ESDescriptors);	while (count) {		esd = (GF_ESD*)gf_list_get(ESDs->ESDescriptors, 0);		/*spec: "ES_Descriptors with ES_IDs that have already been received within the same name scope shall be ignored."*/		prev = NULL;		i=0;		while ((prev = (GF_ESD*)gf_list_enum(odm->OD->ESDescriptors, &i))) {			if (prev->ESID == esd->ESID) break;		}		if (prev) {			gf_odf_desc_del((GF_Descriptor *)esd);		} else {			/*and register new stream*/			gf_list_add(odm->OD->ESDescriptors, esd);			gf_odm_setup_es(odm, esd, odm->net_service, NULL);		}		/*remove the desc from the AU*/		gf_list_rem(ESDs->ESDescriptors, 0);		count--;	}	/*resetup object since a new ES has been inserted 	(typically an empty object first sent, then a stream added - cf how ogg demuxer works)*/	gf_is_setup_object(priv->scene, odm);	return GF_OK;}static GF_Err ODS_RemoveESD(ODPriv *priv, GF_ESDRemove *ESDs){	GF_ObjectManager *odm;	u32 i;	odm = gf_is_find_odm(priv->scene, ESDs->ODID);	/*spec: "ignore"*/	if (!odm) return GF_OK;	for (i=0; i<ESDs->NbESDs; i++) {		/*blindly call remove*/		gf_odm_remove_es(odm, ESDs->ES_ID[i]);	}	return GF_OK;}static GF_Err ODF_AttachStream(GF_BaseDecoder *plug, 									 u16 ES_ID, 									 char *decSpecInfo, 									 u32 decSpecInfoSize, 									 u16 DependsOnES_ID,									 u32 objectTypeIndication, 									 Bool Upstream){	return Upstream ? GF_NOT_SUPPORTED : GF_OK;}static GF_Err ODF_DetachStream(GF_BaseDecoder *plug, u16 ES_ID){	return GF_OK;}static GF_Err ODF_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inBufferLength, 							u16 ES_ID, u32 AU_time, u32 mmlevel){	GF_Err e;	GF_ODCom *com;	GF_ODCodec *oddec;	ODPriv *priv = (ODPriv *)plug->privateStack;		oddec = gf_odf_codec_new();	e = gf_odf_codec_set_au(oddec, inBuffer, inBufferLength);	if (!e)  e = gf_odf_codec_decode(oddec);	if (e) goto err_exit;	//3- process all the commands in this AU, in order	while (1) {		com = gf_odf_codec_get_com(oddec);		if (!com) break;		//ok, we have a command		switch (com->tag) {		case GF_ODF_OD_UPDATE_TAG:			e = ODS_ODUpdate(priv, (GF_ODUpdate *) com);			break;		case GF_ODF_OD_REMOVE_TAG:			e = ODS_RemoveOD(priv, (GF_ODRemove *) com);			break;		case GF_ODF_ESD_UPDATE_TAG:			e = ODS_UpdateESD(priv, (GF_ESDUpdate *)com);			break;		case GF_ODF_ESD_REMOVE_TAG:			e = ODS_RemoveESD(priv, (GF_ESDRemove *)com);			break;		case GF_ODF_IPMP_UPDATE_TAG:#if 0		{			GF_IPMPUpdate *ipmpU = (GF_IPMPUpdate *)com;			while (gf_list_count(ipmpU->IPMPDescList)) {				GF_IPMP_Descriptor *ipmp = gf_list_get(ipmpU->IPMPDescList, 0);				gf_list_rem(ipmpU->IPMPDescList, 0);				IS_UpdateIPMP(priv->scene, ipmp);			}			e = GF_OK;		}#else			e = GF_OK;#endif			break;		case GF_ODF_IPMP_REMOVE_TAG:			e = GF_NOT_SUPPORTED;			break;		/*should NEVER exist outside the file format*/		case GF_ODF_ESD_REMOVE_REF_TAG:			e = GF_NON_COMPLIANT_BITSTREAM;			break;		default:			if (com->tag >= GF_ODF_COM_ISO_BEGIN_TAG && com->tag <= GF_ODF_COM_ISO_END_TAG) {				e = GF_ODF_FORBIDDEN_DESCRIPTOR;			} else {				/*we don't process user commands*/				e = GF_OK;			}			break;		}		gf_odf_com_del(&com);		if (e) break;	}err_exit:	gf_odf_codec_del(oddec);	return e;}Bool ODF_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, u32 ObjectType, char *decSpecInfo, u32 decSpecInfoSize, u32 PL){	ODPriv *priv = (ODPriv *)ifce->privateStack;	if (StreamType==GF_STREAM_OD) {		priv->PL = PL;		return 1;	}	return 0;}void DeleteODDec(GF_BaseDecoder *plug){	ODPriv *priv = (ODPriv *)plug->privateStack;	free(priv);	free(plug);}GF_BaseDecoder *NewODDec(){	GF_SceneDecoder *tmp;	ODPriv *priv;		GF_SAFEALLOC(tmp, GF_SceneDecoder);	if (!tmp) return NULL;	GF_SAFEALLOC(priv, ODPriv);	tmp->privateStack = priv;	tmp->AttachStream = ODF_AttachStream;	tmp->DetachStream = ODF_DetachStream;	tmp->GetCapabilities = ODF_GetCapabilities;	tmp->SetCapabilities = ODF_SetCapabilities;	tmp->ProcessData = ODF_ProcessData;	tmp->AttachScene = ODF_AttachScene;	tmp->CanHandleStream = ODF_CanHandleStream;	GF_REGISTER_MODULE_INTERFACE(tmp, GF_SCENE_DECODER_INTERFACE, "GPAC OD Decoder", "gpac distribution")	return (GF_BaseDecoder *) tmp;}GF_EXPORTBool QueryInterface(u32 InterfaceType){	switch (InterfaceType) {	case GF_SCENE_DECODER_INTERFACE:		return 1;	default:		return 0;	}}GF_EXPORTGF_BaseInterface *LoadInterface(u32 InterfaceType){	switch (InterfaceType) {	case GF_SCENE_DECODER_INTERFACE:		return (GF_BaseInterface *)NewODDec();	default:		return NULL;	}}GF_EXPORTvoid ShutdownInterface(GF_BaseInterface *ifce){	switch (ifce->InterfaceType) {	case GF_SCENE_DECODER_INTERFACE:		DeleteODDec((GF_BaseDecoder *)ifce);		break;	}}

⌨️ 快捷键说明

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