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

📄 oci_codec.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 / MPEG-4 ObjectDescriptor sub-project * *  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/odf_dev.h>//from ODGF_Err gf_odf_write_descriptor_list(GF_BitStream *bs, GF_List *descList);GF_Err gf_odf_size_descriptor_list(GF_List *descList, u32 *outSize);GF_Err gf_odf_delete_descriptor(GF_Descriptor *desc);GF_Err gf_odf_parse_descriptor(GF_BitStream *bs, GF_Descriptor **desc, u32 *desc_size);s32 gf_odf_size_field_size(u32 size_desc);//max size of an OCI event#define OCI_MAX_EVENT_SIZE		1<<28 - 1#define MAX_OCIEVENT_ID		0x7FFFstruct __tag_oci_event{	u16 EventID;	u8 AbsoluteTimeFlag;	char StartingTime[4];	char duration[4];	GF_List *OCIDescriptors;};struct __tag_oci_codec {	//events	GF_List *OCIEvents;	//version, should always be one	u8 Version;	//encoder or decoder	u8 Mode;};GF_EXPORTOCIEvent *gf_oci_event_new(u16 EventID){	OCIEvent *tmp;	if (EventID > MAX_OCIEVENT_ID) return NULL;	tmp = (OCIEvent *)malloc(sizeof(OCIEvent));	if (!tmp) return NULL;	memset(tmp, 0, sizeof(OCIEvent));	tmp->EventID = EventID;	tmp->OCIDescriptors = gf_list_new();	return tmp;}GF_EXPORTvoid gf_oci_event_del(OCIEvent *event){	GF_Descriptor *desc;	if (!event) return;	while (gf_list_count(event->OCIDescriptors)) {		desc = (GF_Descriptor *)gf_list_get(event->OCIDescriptors, 0);		gf_list_rem(event->OCIDescriptors, 0);		gf_odf_delete_descriptor(desc);	}	gf_list_del(event->OCIDescriptors);	free(event);	}GF_EXPORTGF_Err gf_oci_event_set_start_time(OCIEvent *event, u8 Hours, u8 Minutes, u8 Seconds, u8 HundredSeconds, u8 IsAbsoluteTime){	if (!event || (Hours >= 100) || (Minutes >= 100) || (Seconds >= 100) || (HundredSeconds >= 100) )		return GF_BAD_PARAM;	event->AbsoluteTimeFlag = IsAbsoluteTime;	event->StartingTime[0] = Hours;	event->StartingTime[1] = Minutes;	event->StartingTime[2] = Seconds;	event->StartingTime[3] = HundredSeconds;	return GF_OK;}GF_EXPORTGF_Err gf_oci_event_set_duration(OCIEvent *event, u8 Hours, u8 Minutes, u8 Seconds, u8 HundredSeconds){	if (!event || (Hours >= 100) || (Minutes >= 100) || (Seconds >= 100) || (HundredSeconds >= 100) )		return GF_BAD_PARAM;	event->duration[0] = Hours;	event->duration[1] = Minutes;	event->duration[2] = Seconds;	event->duration[3] = HundredSeconds;	return GF_OK;}u8 OCI_IsOCIDesc(GF_Descriptor *oci_desc){	if (oci_desc->tag < GF_ODF_OCI_BEGIN_TAG) return 0;	if (oci_desc->tag > GF_ODF_OCI_END_TAG) return 0;	return 1;}GF_EXPORTGF_Err gf_oci_event_add_desc(OCIEvent *event, GF_Descriptor *oci_desc){	if (!event || !oci_desc) return GF_BAD_PARAM;	if (!OCI_IsOCIDesc(oci_desc)) return GF_ODF_INVALID_DESCRIPTOR;		gf_list_add(event->OCIDescriptors, oci_desc);	return GF_OK;}GF_EXPORTGF_Err gf_oci_event_get_id(OCIEvent *event, u16 *ID){	if (!event || !ID) return GF_BAD_PARAM;	*ID = event->EventID;	return GF_OK;}GF_EXPORTGF_Err gf_oci_event_get_start_time(OCIEvent *event, u8 *Hours, u8 *Minutes, u8 *Seconds, u8 *HundredSeconds, u8 *IsAbsoluteTime){	if (!event || !Hours || !Minutes || !Seconds || !HundredSeconds || !IsAbsoluteTime) 		return GF_BAD_PARAM;	*IsAbsoluteTime = event->AbsoluteTimeFlag;	*Hours = event->StartingTime[0];	*Minutes = event->StartingTime[1];	*Seconds = event->StartingTime[2];	*HundredSeconds = event->StartingTime[3];	return GF_OK;}GF_EXPORTGF_Err gf_oci_event_get_duration(OCIEvent *event, u8 *Hours, u8 *Minutes, u8 *Seconds, u8 *HundredSeconds){	if (!event || !Hours || !Minutes || !Seconds || !HundredSeconds) 		return GF_BAD_PARAM;	*Hours = event->duration[0];	*Minutes = event->duration[1];	*Seconds = event->duration[2];	*HundredSeconds = event->duration[3];	return GF_OK;}GF_EXPORTu32 gf_oci_event_get_desc_count(OCIEvent *event){	if (!event) return 0;	return gf_list_count(event->OCIDescriptors);}GF_EXPORTGF_Descriptor *gf_oci_event_get_desc(OCIEvent *event, u32 DescIndex){	if (!event || DescIndex >= gf_list_count(event->OCIDescriptors) ) return NULL;	return (GF_Descriptor *) gf_list_get(event->OCIDescriptors, DescIndex);}GF_EXPORTGF_Err gf_oci_event_rem_desc(OCIEvent *event, u32 DescIndex){	if (!event || DescIndex >= gf_list_count(event->OCIDescriptors) ) return GF_BAD_PARAM;	return gf_list_rem(event->OCIDescriptors, DescIndex);}//construction / destructionGF_EXPORTOCICodec *gf_oci_codec_new(u8 IsEncoder, u8 Version){	OCICodec *tmp;	if (Version != 0x01) return NULL;	tmp = (OCICodec *)malloc(sizeof(OCICodec));	if (!tmp) return NULL;	tmp->Mode = IsEncoder ? 1 : 0;	tmp->Version = 0x01;	tmp->OCIEvents = gf_list_new();	return tmp;}GF_EXPORTvoid gf_oci_codec_del(OCICodec *codec){	OCIEvent *ev;	if (!codec) return;	while (gf_list_count(codec->OCIEvents)) {		ev = (OCIEvent *)gf_list_get(codec->OCIEvents, 0);		gf_oci_event_del(ev);		gf_list_rem(codec->OCIEvents, 0);	}	gf_list_del(codec->OCIEvents);	free(codec);}GF_EXPORTGF_Err gf_oci_codec_add_event(OCICodec *codec, OCIEvent *event){	if (!codec || !codec->Mode || !event) return GF_BAD_PARAM;	return gf_list_add(codec->OCIEvents, event);}GF_Err WriteSevenBitLength(GF_BitStream *bs, u32 size){	u32 length;	unsigned char vals[4];	if (!bs || !size) return GF_BAD_PARAM;		length = size;	vals[3] = (unsigned char) (length & 0x7f);	length >>= 7;	vals[2] = (unsigned char) ((length & 0x7f) | 0x80); 	length >>= 7;	vals[1] = (unsigned char) ((length & 0x7f) | 0x80); 	length >>= 7;	vals[0] = (unsigned char) ((length & 0x7f) | 0x80);		if (size < 0x00000080) {		gf_bs_write_int(bs, vals[3], 8);	} else if (size < 0x00004000) {		gf_bs_write_int(bs, vals[2], 8);		gf_bs_write_int(bs, vals[3], 8);	} else if (size < 0x00200000) {		gf_bs_write_int(bs, vals[1], 8);		gf_bs_write_int(bs, vals[2], 8);		gf_bs_write_int(bs, vals[3], 8);	} else if (size < 0x10000000) {		gf_bs_write_int(bs, vals[0], 8);		gf_bs_write_int(bs, vals[1], 8);		gf_bs_write_int(bs, vals[2], 8);		gf_bs_write_int(bs, vals[3], 8);	} else {		return GF_ODF_INVALID_DESCRIPTOR;	}	return GF_OK;}GF_EXPORTGF_Err gf_oci_codec_encode(OCICodec *codec, char **outAU, u32 *au_length){	GF_BitStream *bs;	u32 i, size, desc_size;	GF_Err e;	OCIEvent *ev;		if (!codec || !codec->Mode || *outAU) return GF_BAD_PARAM;	bs = NULL;	size = 0;	//get the size of each event	i=0;	while ((ev = (OCIEvent *)gf_list_enum(codec->OCIEvents, &i))) {		//fixed size header		size += 10;		e = gf_odf_size_descriptor_list(codec->OCIEvents, &desc_size);		if (e) goto err_exit;		size += desc_size;	}	//encode	bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);	e = WriteSevenBitLength(bs, size);	if (e) goto err_exit;	//get one event, write it and delete it	while (gf_list_count(codec->OCIEvents)) {		ev = (OCIEvent *)gf_list_get(codec->OCIEvents, 0);		gf_list_rem(codec->OCIEvents, 0);		gf_bs_write_int(bs, ev->EventID, 15);		gf_bs_write_int(bs, ev->AbsoluteTimeFlag, 1);		gf_bs_write_data(bs, ev->StartingTime, 4);		gf_bs_write_data(bs, ev->duration, 4);				e = gf_odf_write_descriptor_list(bs, ev->OCIDescriptors);		gf_oci_event_del(ev);		if (e) goto err_exit;		//OCI Event is aligned		gf_bs_align(bs);	}	gf_bs_get_content(bs, outAU, au_length);	gf_bs_del(bs);	return GF_OK;err_exit:	if (bs) gf_bs_del(bs);	//delete everything	while (gf_list_count(codec->OCIEvents)) {		ev = (OCIEvent *)gf_list_get(codec->OCIEvents, 0);		gf_list_rem(codec->OCIEvents, 0);		gf_oci_event_del(ev);	}	return e;}GF_EXPORTGF_Err gf_oci_codec_decode(OCICodec *codec, char *au, u32 au_length){	OCIEvent *ev;	GF_BitStream *bs;	u32 size, hdrS, desc_size, tot_size, tmp_size, val;	GF_Descriptor *tmp;		GF_Err e;	//must be decoder	if (!codec || codec->Mode || !au) return GF_BAD_PARAM;	bs = gf_bs_new(au, au_length, GF_BITSTREAM_READ);	ev = 0;	tot_size = 0;	while (tot_size < au_length) {		//create an event		ev = gf_oci_event_new(0);		if (!ev) {			e = GF_OUT_OF_MEM;			goto err_exit;		}				//FIX IM1		gf_bs_read_int(bs, 8);		size = 0;		//get its size		hdrS = 0;		do {			val = gf_bs_read_int(bs, 8);			hdrS += 1;			size <<= 7;			size |= val & 0x7F;		} while ( val & 0x80 );				//parse event vars		ev->EventID = gf_bs_read_int(bs, 15);		ev->AbsoluteTimeFlag = gf_bs_read_int(bs, 1);		gf_bs_read_data(bs, ev->StartingTime, 4);		gf_bs_read_data(bs, ev->duration, 4);		desc_size = 0;		//parse descriptor list		while (desc_size < size - 10) {			e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size);			//RE-FIX IM1			if (e || !tmp) goto err_exit;			if (!OCI_IsOCIDesc(tmp)) {				gf_odf_delete_descriptor(tmp);				e = GF_ODF_INVALID_DESCRIPTOR;				goto err_exit;			}			gf_list_add(ev->OCIDescriptors, tmp);			desc_size += tmp_size + gf_odf_size_field_size(tmp_size);		}				if (desc_size != size - 10) {			e = GF_CORRUPTED_DATA;			goto err_exit;		}		gf_list_add(codec->OCIEvents, ev);		//FIX IM1		size += 1;		tot_size += size + hdrS;		ev = NULL;	}	if (tot_size != au_length) {		e = GF_CORRUPTED_DATA;		goto err_exit;	}	gf_bs_del(bs);	return GF_OK;err_exit:	gf_bs_del(bs);	if (ev) gf_oci_event_del(ev);	//delete everything	while (gf_list_count(codec->OCIEvents)) {		ev = (OCIEvent *)gf_list_get(codec->OCIEvents, 0);		gf_list_rem(codec->OCIEvents, 0);		gf_oci_event_del(ev);	}	return e;}GF_EXPORTOCIEvent *gf_oci_codec_get_event(OCICodec *codec){	OCIEvent *ev;	if (!codec ||codec->Mode) return NULL;	ev = (OCIEvent *)gf_list_get(codec->OCIEvents, 0);	gf_list_rem(codec->OCIEvents, 0);	return ev;}

⌨️ 快捷键说明

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