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

📄 field_decode.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005 *					All rights reserved * *  This file is part of GPAC / BIFS codec 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/bifs_dev.h>#include <gpac/internal/scenegraph_dev.h>#include "quant.h" #include "script.h" void SFCommandBufferChanged(GF_BifsDecoder * codec, GF_Node *node){	void Conditional_BufferReplaced(GF_BifsDecoder * codec, GF_Node *node);	switch (gf_node_get_tag(node)) {	case TAG_MPEG4_Conditional:		Conditional_BufferReplaced(codec, node);		break;	}}//startTimes, stopTimes and co are coded as relative to their AU timestamp when received//on the wire. If from scripts or within proto the offset doesn't applyvoid BD_OffsetSFTime(GF_BifsDecoder * codec, Double *time){	if ((!codec->is_com_dec && codec->pCurrentProto) || codec->dec_memory_mode) return;	*time += codec->cts_offset;}void BD_CheckSFTimeOffset(GF_BifsDecoder *codec, GF_Node *node, GF_FieldInfo *inf){	if (gf_node_get_tag(node) != TAG_ProtoNode) {		if (!stricmp(inf->name, "startTime") || !stricmp(inf->name, "stopTime")) 			BD_OffsetSFTime(codec,  (Double *)inf->far_ptr);	} else if (gf_sg_proto_field_is_sftime_offset(node, inf)) {		BD_OffsetSFTime(codec,  (Double *)inf->far_ptr);	}}Fixed BD_ReadSFFloat(GF_BifsDecoder * codec, GF_BitStream *bs){	if (codec->ActiveQP && codec->ActiveQP->useEfficientCoding) 		return gf_bifs_dec_mantissa_float(codec, bs);	return FLT2FIX(gf_bs_read_float(bs));}GF_Err gf_bifs_dec_sf_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field){	GF_Err e;	GF_Node *new_node;	u32 size, length, w, h, i;	char *buffer;	//blindly call unquantize. return is OK, error or GF_EOS	if (codec->ActiveQP && node) {		e = gf_bifs_dec_unquant_field(codec, bs, node, field);		if (e != GF_EOS) return e;	}	//not quantized, use normal scheme	switch (field->fieldType) {	case GF_SG_VRML_SFBOOL:		* ((SFBool *) field->far_ptr) = (SFBool) gf_bs_read_int(bs, 1);		break;	case GF_SG_VRML_SFCOLOR:		((SFColor *)field->far_ptr)->red = BD_ReadSFFloat(codec, bs);;		((SFColor *)field->far_ptr)->green = BD_ReadSFFloat(codec, bs);		((SFColor *)field->far_ptr)->blue = BD_ReadSFFloat(codec, bs);		break;	case GF_SG_VRML_SFFLOAT:		*((SFFloat *)field->far_ptr) = BD_ReadSFFloat(codec, bs);		break;	case GF_SG_VRML_SFINT32:		*((SFInt32 *)field->far_ptr) = (s32) gf_bs_read_int(bs, 32);		break;	case GF_SG_VRML_SFTIME:		*((SFTime *)field->far_ptr) = gf_bs_read_double(bs);		if (node) BD_CheckSFTimeOffset(codec, node, field);		break;	case GF_SG_VRML_SFVEC2F:		((SFVec2f *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs);		((SFVec2f *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs);		break;	case GF_SG_VRML_SFVEC3F:		((SFVec3f *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs);		((SFVec3f *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs);		((SFVec3f *)field->far_ptr)->z = BD_ReadSFFloat(codec, bs);		break;	case GF_SG_VRML_SFROTATION:		((SFRotation *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs);		((SFRotation *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs);		((SFRotation *)field->far_ptr)->z = BD_ReadSFFloat(codec, bs);		((SFRotation *)field->far_ptr)->q = BD_ReadSFFloat(codec, bs);		break;	case GF_SG_VRML_SFSTRING:		size = gf_bs_read_int(bs, 5);		length = gf_bs_read_int(bs, size);		if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM;		if ( ((SFString *)field->far_ptr)->buffer ) free( ((SFString *)field->far_ptr)->buffer);		((SFString *)field->far_ptr)->buffer = (char *)malloc(sizeof(char)*(length+1));		memset(((SFString *)field->far_ptr)->buffer , 0, length+1);		for (i=0; i<length; i++) {			 ((SFString *)field->far_ptr)->buffer[i] = gf_bs_read_int(bs, 8);		}		break;	case GF_SG_VRML_SFURL:	{		SFURL *url = (SFURL *) field->far_ptr;		size = gf_bs_read_int(bs, 1);		if (size) {			if (url->url) free(url->url );			url->url = NULL;			length = gf_bs_read_int(bs, 10);			url->OD_ID = length;		} else {			if ( url->OD_ID ) url->OD_ID = (u32) -1;			size = gf_bs_read_int(bs, 5);			length = gf_bs_read_int(bs, size);			if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM;			buffer = NULL;			if (length) {				buffer = (char *)malloc(sizeof(char)*(length+1));				memset(buffer, 0, length+1);				for (i=0; i<length; i++) buffer[i] = gf_bs_read_int(bs, 8);			}			if (url->url) free( url->url);			/*if URL is empty set it to NULL*/			if (buffer && strlen(buffer)) {				url->url = buffer;			} else {				free(buffer);				url->url = NULL;			}		}	}		break;	case GF_SG_VRML_SFIMAGE:		if (((SFImage *)field->far_ptr)->pixels) free(((SFImage *)field->far_ptr)->pixels);		w = gf_bs_read_int(bs, 12);		h = gf_bs_read_int(bs, 12);		length = gf_bs_read_int(bs, 2);		if (length > 3) length = 3;		length += 1;		size = w * h * length;		if (gf_bs_available(bs) < size) return GF_NON_COMPLIANT_BITSTREAM;		((SFImage *)field->far_ptr)->width = w;		((SFImage *)field->far_ptr)->height = h;		((SFImage *)field->far_ptr)->numComponents = length;		((SFImage *)field->far_ptr)->pixels = (unsigned char *)malloc(sizeof(char)*size);		//WARNING: Buffers are NOT ALIGNED IN THE BITSTREAM		for (i=0; i<size; i++) {			((SFImage *)field->far_ptr)->pixels[i] = gf_bs_read_int(bs, 8);		}		break;	case GF_SG_VRML_SFCOMMANDBUFFER:	{		SFCommandBuffer *sfcb = (SFCommandBuffer *)field->far_ptr;		if (sfcb->buffer) {			free(sfcb->buffer);					sfcb->buffer = NULL;		}		while (gf_list_count(sfcb->commandList)) {			GF_Command *com = (GF_Command*)gf_list_get(sfcb->commandList, 0);			gf_list_rem(sfcb->commandList, 0);			gf_sg_command_del(com);		}		size = gf_bs_read_int(bs, 5);		length = gf_bs_read_int(bs, size);		if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM;		sfcb->bufferSize = length;		if (length) {			sfcb->buffer = (unsigned char *)malloc(sizeof(char)*(length));			//WARNING Buffers are NOT ALIGNED IN THE BITSTREAM			for (i=0; i<length; i++) {				sfcb->buffer[i] = gf_bs_read_int(bs, 8);			}		}		//notify the node - this is needed in case an enhencement layer replaces the buffer, in which case 		//the # ID Bits may change		SFCommandBufferChanged(codec, node);		/*memory mode, register command buffer for later parsing*/		if (codec->dec_memory_mode) {			CommandBufferItem *cbi = (CommandBufferItem *)malloc(sizeof(CommandBufferItem));			cbi->node = node;			cbi->cb = sfcb;			gf_list_add(codec->command_buffers, cbi);		}		/*InputSensor only work on decompressed commands*/		else if (node->sgprivate->tag==TAG_MPEG4_InputSensor) {			GF_Err BM_ParseCommand(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list);			GF_BitStream *is_bs;			is_bs = gf_bs_new((char*)sfcb->buffer, sfcb->bufferSize, GF_BITSTREAM_READ);			e = BM_ParseCommand(codec, is_bs, sfcb->commandList);			gf_bs_del(is_bs);		}	} 		break;	case GF_SG_VRML_SFNODE:		//for nodes the field ptr is a ptr to the field, which is a node ptr ;)		new_node = gf_bifs_dec_node(codec, bs, field->NDTtype);		if (new_node) {			e = gf_node_register(new_node, node);			if (e) return e;		}		//it may happen that new_node is NULL (this is valid for a proto declaration)		*((GF_Node **) field->far_ptr) = new_node;		break;	case GF_SG_VRML_SFSCRIPT:		codec->LastError = SFScript_Parse(codec, (SFScript*)field->far_ptr, bs, node);		break;	default:		return GF_NON_COMPLIANT_BITSTREAM;	}	return codec->LastError;}GF_Err BD_DecMFFieldList(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field){	GF_Node *new_node;	GF_Err e;	u8 endFlag, qp_local, qp_on, initial_qp;	GF_ChildNodeItem *last = NULL;	u32 nbF;	GF_FieldInfo sffield;		memset(&sffield, 0, sizeof(GF_FieldInfo));	sffield.fieldIndex = field->fieldIndex;	sffield.fieldType = gf_sg_vrml_get_sf_type(field->fieldType);	sffield.NDTtype = field->NDTtype;	nbF = 0;	qp_on = qp_local = 0;	initial_qp = codec->ActiveQP ? 1 : 0;	endFlag = gf_bs_read_int(bs, 1);	while (!endFlag) {		e = GF_OK;;		if (field->fieldType != GF_SG_VRML_MFNODE) {			e = gf_sg_vrml_mf_append(field->far_ptr, field->fieldType, & sffield.far_ptr);			e = gf_bifs_dec_sf_field(codec, bs, node, &sffield);		} else {			new_node = gf_bifs_dec_node(codec, bs, field->NDTtype);			//append			if (new_node) {				e = gf_node_register(new_node, node);				if (e) return e;				//regular coding				if (node) {					//special case for QP, register as the current QP					if (gf_node_get_tag(new_node) == TAG_MPEG4_QuantizationParameter) {						qp_local = ((M_QuantizationParameter *)new_node)->isLocal;						//we have a QP in the same scope, remove previous						if (qp_on) gf_bifs_dec_qp_remove(codec, 0);						e = gf_bifs_dec_qp_set(codec, new_node);						if (e) return e;						qp_on = 1;						if (qp_local) qp_local = 2;						if (codec->force_keep_qp) {							e = gf_node_list_add_child_last( field->far_ptr, new_node, &last);						} else {							gf_node_register(new_node, NULL);							gf_node_unregister(new_node, node);						}					} else 						//this is generic MFNode container						e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);									}				//proto coding: directly add the child				else if (codec->pCurrentProto) {					//TO DO: what happens if this is a QP node on the interface ?					e = gf_node_list_add_child_last( (GF_ChildNodeItem **)field->far_ptr, new_node, &last);				}			} else {				return codec->LastError;			}		}		if (e) return e;		endFlag = gf_bs_read_int(bs, 1);		//according to the spec, the QP applies to the current node itself, 		//not just children. If IsLocal is TRUE remove the node		if (qp_on && qp_local) {			if (qp_local == 2) {				qp_local = 1;			} else {				//ask to get rid of QP and reactivate if we had a QP when entering				gf_bifs_dec_qp_remove(codec, initial_qp);				qp_local = 0;				qp_on = 0;			}		}		nbF += 1;	}	/*finally delete the QP if any (local or not) as we get out of this node	and reactivate previous one*/	if (qp_on) gf_bifs_dec_qp_remove(codec, initial_qp);	/*this is for QP 14*/	gf_bifs_dec_qp14_set_length(codec, nbF);	return GF_OK;}GF_Err BD_DecMFFieldVec(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field){	GF_Err e;	u32 NbBits, nbFields;	u32 i;	GF_ChildNodeItem *last;	u8 qp_local, qp_on, initial_qp;	GF_Node *new_node;	GF_FieldInfo sffield;		memset(&sffield, 0, sizeof(GF_FieldInfo));	sffield.fieldIndex = field->fieldIndex;	sffield.fieldType = gf_sg_vrml_get_sf_type(field->fieldType);	sffield.NDTtype = field->NDTtype;	initial_qp = qp_local = qp_on = 0;	//vector description - alloc the MF size before 	NbBits = gf_bs_read_int(bs, 5);	nbFields = gf_bs_read_int(bs, NbBits);	if (codec->ActiveQP) {		initial_qp = 1;		/*this is for QP 14*/		gf_bifs_dec_qp14_set_length(codec, nbFields);	}	if (field->fieldType != GF_SG_VRML_MFNODE) {		e = gf_sg_vrml_mf_alloc(field->far_ptr, field->fieldType, nbFields);		if (e) return e;		for (i=0;i<nbFields; i++) {			e = gf_sg_vrml_mf_get_item(field->far_ptr, field->fieldType, & sffield.far_ptr, i);			if (e) return e;			e = gf_bifs_dec_sf_field(codec, bs, node, &sffield);		}	} else {		last = NULL;		for (i=0;i<nbFields; i++) {			new_node = gf_bifs_dec_node(codec, bs, field->NDTtype);			if (new_node) {				e = gf_node_register(new_node, node);				if (e) return e;				if (node) {					/*special case for QP, register as the current QP*/					if (gf_node_get_tag(new_node) == TAG_MPEG4_QuantizationParameter) {						qp_local = ((M_QuantizationParameter *)new_node)->isLocal;						/*we have a QP in the same scope, remove previous						NB: we assume this is the right behaviour, the spec doesn't say 						whether QP is cumulative or not*/						if (qp_on) gf_bifs_dec_qp_remove(codec, 0);						e = gf_bifs_dec_qp_set(codec, new_node);						if (e) return e;						qp_on = 1;						if (qp_local) qp_local = 2;						if (codec->force_keep_qp) {							e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);						} else {							gf_node_register(new_node, NULL);							gf_node_unregister(new_node, node);						}					} else {						e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);					}				} 				/*proto coding*/				else if (codec->pCurrentProto) {					/*TO DO: what happens if this is a QP node on the interface ?*/					e = gf_node_list_add_child_last( (GF_ChildNodeItem **)field->far_ptr, new_node, &last);				}			} else {				return codec->LastError ? codec->LastError : GF_NON_COMPLIANT_BITSTREAM;			}		}		/*according to the spec, the QP applies to the current node itself, not just children. 		If IsLocal is TRUE remove the node*/		if (qp_on && qp_local) {			if (qp_local == 2) {				qp_local = 1;			} else {				//ask to get rid of QP and reactivate if we had a QP when entering the node				gf_bifs_dec_qp_remove(codec, initial_qp);				qp_local = 0;			}		}	}	/*finally delete the QP if any (local or not) as we get out of this node*/	if (qp_on) gf_bifs_dec_qp_remove(codec, 1);	return GF_OK;}void gf_bifs_check_field_change(GF_Node *node, GF_FieldInfo *field){	if ((field->fieldType==GF_SG_VRML_MFNODE) || (field->fieldType==GF_SG_VRML_MFNODE)) node->sgprivate->flags |= GF_SG_CHILD_DIRTY;	/*signal node modif*/	gf_node_changed(node, field);	/*Notify eventOut in all cases to handle protos*/	gf_node_event_out(node, field->fieldIndex);	/*and propagate eventIn if any*/	if (field->on_event_in) {		field->on_event_in(node);	} else if ((gf_node_get_tag(node) == TAG_MPEG4_Script) && (field->eventType==GF_SG_EVENT_IN)) {		gf_sg_script_event_in(node, field);	}}GF_Err gf_bifs_dec_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field){	GF_Err e;

⌨️ 快捷键说明

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