Beispiel #1
0
GF_Err gf_bifs_dec_node_mask(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, Bool is_proto)
{
	u32 i, numFields, numProtoFields, index, flag, nbBits;
	GF_Err e;
	GF_FieldInfo field;

	//proto coding
	if (codec->pCurrentProto) {
		numFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL);
		numProtoFields = gf_sg_proto_get_field_count(codec->pCurrentProto);
		nbBits = gf_get_bit_size(numProtoFields-1);

		for (i=0; i<numFields; i++) {
			flag = gf_bs_read_int(bs, 1);
			if (!flag) continue;
			flag = gf_bs_read_int(bs, 1);
			//IS'ed field, create route for binding to Proto declaration
			if (flag) {
				//reference index of our IS'ed proto field
				flag = gf_bs_read_int(bs, nbBits);
				e = gf_node_get_field(node, i, &field);
				if (e) return e;
				e = BD_SetProtoISed(codec, flag, node, i);
			}
			//regular field, parse it (nb: no contextual coding for protos in maskNode,
			//all node fields are coded
			else {
				e = gf_node_get_field(node, i, &field);
				if (e) return e;
				e = gf_bifs_dec_field(codec, bs, node, &field, 0);
			}
			if (e) return e;
		}
	}
	//regular coding
	else {
		numFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF);
		for (i=0; i<numFields; i++) {
			flag = gf_bs_read_int(bs, 1);
			if (!flag) continue;
			gf_bifs_get_field_index(node, i, GF_SG_FIELD_CODING_DEF, &index);
			e = gf_node_get_field(node, index, &field);
			if (e) return e;
			e = gf_bifs_dec_field(codec, bs, node, &field, 0);
			if (e) return e;

			if (is_proto) gf_sg_proto_mark_field_loaded(node, &field);
		}
	}
	return GF_OK;
}
Beispiel #2
0
GF_Err gf_bifs_dec_node_list(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, Bool is_proto)
{
	u8 flag;
	GF_Err e;
	u32 numBitsALL, numBitsDEF, field_all, field_ref, numProtoBits;
	GF_FieldInfo field;

	e = GF_OK;

	numProtoBits = numBitsALL = 0;
	if (codec->pCurrentProto) {
		numProtoBits = gf_get_bit_size(gf_sg_proto_get_field_count(codec->pCurrentProto) - 1);
		numBitsALL = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL)-1);
	}
	numBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF)-1);

	flag = gf_bs_read_int(bs, 1);
	while (!flag && (codec->LastError>=0)) {
		if (codec->pCurrentProto) {
			//IS'ed flag
			flag = gf_bs_read_int(bs, 1);
			if (flag) {
				//get field index in ALL mode for node
				field_ref = gf_bs_read_int(bs, numBitsALL);
				//get field index in ALL mode for proto
				field_all = gf_bs_read_int(bs, numProtoBits);
				e = gf_node_get_field(node, field_ref, &field);
				if (e) return e;
				e = BD_SetProtoISed(codec, field_all, node, field_ref);
				if (e) return e;
				flag = gf_bs_read_int(bs, 1);
				continue;
			}
		}

		//fields are coded in DEF mode
		field_ref = gf_bs_read_int(bs, numBitsDEF);
		e = gf_bifs_get_field_index(node, field_ref, GF_SG_FIELD_CODING_DEF, &field_all);
		if (e) return e;
		e = gf_node_get_field(node, field_all, &field);
		if (e) return e;
		e = gf_bifs_dec_field(codec, bs, node, &field, 0);
		if (e) return e;
		flag = gf_bs_read_int(bs, 1);

		if (is_proto) gf_sg_proto_mark_field_loaded(node, &field);
	}
	return codec->LastError;
}
Beispiel #3
0
GF_Err ParseScriptField(ScriptParser *parser)
{
	GF_ScriptField *field;
	GF_Err e;
	u32 eventType, fieldType;
	char name[1000];
	GF_FieldInfo info;

	eventType = gf_bs_read_int(parser->bs, 2);
	fieldType = gf_bs_read_int(parser->bs, 6);
	gf_bifs_dec_name(parser->bs, name);
	field = gf_sg_script_field_new(parser->script, eventType, fieldType, name);
	if (!field) return GF_NON_COMPLIANT_BITSTREAM;

	//save the name in the list of identifiers
	gf_list_add(parser->identifiers, gf_strdup(name));

	if (parser->codec->pCurrentProto) {
		Bool isISfield = gf_bs_read_int(parser->bs, 1);
		if (isISfield) {
			u32 numProtoField = gf_sg_proto_get_field_count(parser->codec->pCurrentProto);
			u32 numBits = gf_get_bit_size(numProtoField - 1);
			u32 field_all = gf_bs_read_int(parser->bs, numBits);
			e = gf_sg_script_field_get_info(field, &info);
			if (e) return e;
			e = gf_sg_proto_field_set_ised(parser->codec->pCurrentProto, field_all, parser->script, info.fieldIndex);
			return e;
		}
	}
	/*get default value*/
	if (eventType == GF_SG_SCRIPT_TYPE_FIELD) {
		if (gf_bs_read_int(parser->bs, 1)) {
			e = gf_sg_script_field_get_info(field, &info);
			if (e) return e;
			gf_bifs_dec_field(parser->codec, parser->bs, parser->script, &info);
		}
	}

	return parser->codec->LastError;
}
Beispiel #4
0
GF_Err EncNodeFields(GF_BifsEncoder * codec, GF_BitStream *bs, GF_Node *node)
{
	u8 mode;
	GF_Route *isedField;
	GF_Node *clone;
	GF_Err e;
	s32 *enc_fields;
	u32 numBitsALL, numBitsDEF, allInd, count, i, nbBitsProto, nbFinal;
	Bool use_list, nodeIsFDP = GF_FALSE;
	GF_FieldInfo field, clone_field;

	e = GF_OK;

	if (codec->encoding_proto) {
		mode = GF_SG_FIELD_CODING_ALL;
		nbBitsProto = gf_get_bit_size(gf_sg_proto_get_field_count(codec->encoding_proto) - 1);
		numBitsALL = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL) - 1);
	} else {
		mode = GF_SG_FIELD_CODING_DEF;
		nbBitsProto = 0;
		numBitsALL = 0;
	}
	count = gf_node_get_num_fields_in_mode(node, mode);
	if (node->sgprivate->tag==TAG_MPEG4_Script) count = 3;

	if (!count) {
		GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isMask", NULL);
		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);
		return GF_OK;
	}

	if (node->sgprivate->tag == TAG_ProtoNode) {
		clone = gf_sg_proto_create_instance(node->sgprivate->scenegraph, ((GF_ProtoInstance *)node)->proto_interface);;
	} else {
		clone = gf_node_new(node->sgprivate->scenegraph, node->sgprivate->tag);
	}
	if (clone) gf_node_register(clone, NULL);

	numBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF) - 1);

	enc_fields = (s32*)gf_malloc(sizeof(s32) * count);
	nbFinal = 0;
	for (i=0; i<count; i++) {
		enc_fields[i] = -1;
		/*get field in ALL mode*/
		if (mode == GF_SG_FIELD_CODING_ALL) {
			allInd = i;
		} else {
			gf_bifs_get_field_index(node, i, GF_SG_FIELD_CODING_DEF, &allInd);
		}

		/*encode proto code*/
		if (codec->encoding_proto) {
			isedField = gf_bifs_enc_is_field_ised(codec, node, allInd);
			if (isedField) {
				enc_fields[i] = allInd;
				nbFinal ++;
				continue;
			}
		}
		/*common case*/
		gf_node_get_field(node, allInd, &field);
		/*if event don't encode (happens when encoding protos)*/
		if ((field.eventType == GF_SG_EVENT_IN) || (field.eventType == GF_SG_EVENT_OUT)) continue;
		/*if field is default skip*/
		switch (field.fieldType) {
		case GF_SG_VRML_SFNODE:
			if (* (GF_Node **) field.far_ptr) {
				enc_fields[i] = allInd;
				nbFinal++;
			}
			break;
		case GF_SG_VRML_MFNODE:
			if (* (GF_ChildNodeItem **) field.far_ptr) {
				enc_fields[i] = allInd;
				nbFinal++;
			}
			break;
		case GF_SG_VRML_SFCOMMANDBUFFER:
		{
			SFCommandBuffer *cb = (SFCommandBuffer *)field.far_ptr;
			if (gf_list_count(cb->commandList)) {
				enc_fields[i] = allInd;
				nbFinal++;
			}
		}
		break;
		case GF_SG_VRML_MFSCRIPT:
			enc_fields[i] = allInd;
			nbFinal++;
			break;
		default:
			gf_node_get_field(clone, allInd, &clone_field);
			if (!gf_sg_vrml_field_equal(clone_field.far_ptr, field.far_ptr, field.fieldType)) {
				enc_fields[i] = allInd;
				nbFinal++;
			}
			break;
		}
	}
	if (clone) gf_node_unregister(clone, NULL);

	use_list = GF_TRUE;
	/* patch for FDP node : */
	/* cannot use default field sorting due to spec "mistake", so use list to imply inversion between field 2 and field 3 of FDP*/
	if (node->sgprivate->tag == TAG_MPEG4_FDP) {
		s32 s4SwapValue = enc_fields[2];
		enc_fields[2] = enc_fields[3];
		enc_fields[3] = s4SwapValue;
		nodeIsFDP = GF_TRUE;
		use_list = GF_TRUE;
	}
	/*number of bits in mask node is count*1, in list node is 1+nbFinal*(1+numBitsDEF) */
	else if (count < 1+nbFinal*(1+numBitsDEF))
		use_list = GF_FALSE;

	GF_BIFS_WRITE_INT(codec, bs, use_list ? 0 : 1, 1, "isMask", NULL);

	for (i=0; i<count; i++) {
		if (enc_fields[i] == -1) {
			if (!use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "Mask", NULL);
			continue;
		}
		allInd = (u32) enc_fields[i];

		/*encode proto code*/
		if (codec->encoding_proto) {
			isedField = gf_bifs_enc_is_field_ised(codec, node, allInd);
			if (isedField) {
				if (use_list) {
					GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL);
				} else {
					GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL);
				}
				GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isedField", NULL);
				if (use_list) GF_BIFS_WRITE_INT(codec, bs, allInd, numBitsALL, "nodeField", NULL);

				if (isedField->ToNode == node) {
					GF_BIFS_WRITE_INT(codec, bs, isedField->FromField.fieldIndex, nbBitsProto, "protoField", NULL);
				} else {
					GF_BIFS_WRITE_INT(codec, bs, isedField->ToField.fieldIndex, nbBitsProto, "protoField", NULL);
				}
				continue;
			}
		}
		/*common case*/
		gf_node_get_field(node, allInd, &field);
		if (use_list) {
			/*not end flag*/
			GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL);
		} else {
			/*mask flag*/
			GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL);
		}
		/*not ISed field*/
		if (codec->encoding_proto) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isedField", NULL);
		if (use_list) {
			if (codec->encoding_proto || nodeIsFDP) {
				u32 ind=0;
				/*for proto, we're in ALL mode and we need DEF mode*/
				/*for FDP, encoding requires to get def id from all id as fields 2 and 3 are reversed*/
				gf_bifs_field_index_by_mode(node, allInd, GF_SG_FIELD_CODING_DEF, &ind);
				GF_BIFS_WRITE_INT(codec, bs, ind, numBitsDEF, "field", (char*)field.name);
			} else {
				GF_BIFS_WRITE_INT(codec, bs, i, numBitsDEF, "field", (char*)field.name);
			}
		}
		e = gf_bifs_enc_field(codec, bs, node, &field);
		if (e) goto exit;
	}
	/*end flag*/
	if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);
exit:
	gf_free(enc_fields);
	return e;
}
Beispiel #5
0
static GF_Err EncScriptFields(ScriptEnc *sc_enc)
{
	u32 nbFields, nbBits, eType, nbBitsProto, i;
	Bool use_list;
	GF_Err e;
	GF_FieldInfo info;

	nbFields = gf_node_get_num_fields_in_mode(sc_enc->script, GF_SG_FIELD_CODING_ALL) - 3;
	use_list = 1;
	nbBits = gf_get_bit_size(nbFields);
	if (nbFields+1 > 4 + gf_get_bit_size(nbFields)) use_list = 0;
	if (!nbFields) {
		GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "Script::isList", NULL);
		GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "end", NULL);
		return GF_OK;
	}
	GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, use_list ? 1 : 0, 1, "Script::isList", NULL);
	if (!use_list) {
		GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, nbBits, 4, "nbBits", NULL);
		GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, nbFields, nbBits, "count", NULL);
	}

	nbBitsProto = 0;
	if (sc_enc->codec->encoding_proto) nbBitsProto = gf_get_bit_size(gf_sg_proto_get_field_count(sc_enc->codec->encoding_proto) - 1);

	for (i=0; i<nbFields; i++) {
		if (use_list) GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "end", NULL);

		gf_node_get_field(sc_enc->script, i+3, &info);
		switch (info.eventType) {
		case GF_SG_EVENT_IN:
			eType = GF_SG_SCRIPT_TYPE_EVENT_IN;
			break;
		case GF_SG_EVENT_OUT:
			eType = GF_SG_SCRIPT_TYPE_EVENT_OUT;
			break;
		default:
			eType = GF_SG_SCRIPT_TYPE_FIELD;
			break;
		}
		GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, eType, 2, "eventType", NULL);
		GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, info.fieldType, 6, "fieldType", NULL);
		gf_bifs_enc_name(sc_enc->codec, sc_enc->bs, (char *) info.name);
		/*this is an identifier for script*/
		gf_list_add(sc_enc->identifiers, gf_strdup(info.name));

		if (sc_enc->codec->encoding_proto) {
			GF_Route *isedField = gf_bifs_enc_is_field_ised(sc_enc->codec, sc_enc->script, i+3);
			if (isedField) {
				GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "isedField", NULL);

				if (isedField->ToNode == sc_enc->script) {
					GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, isedField->FromField.fieldIndex, nbBitsProto, "protoField", NULL);
				} else {
					GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, isedField->ToField.fieldIndex, nbBitsProto, "protoField", NULL);
				}
				continue;
			}
			GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "isedField", NULL);
		}
		/*default value*/
		if (eType == GF_SG_SCRIPT_TYPE_FIELD) {
			GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, (info.far_ptr) ? 1 : 0, 1, "hasInitialValue", NULL);
			if (info.far_ptr) {
				e = gf_bifs_enc_field(sc_enc->codec, sc_enc->bs, sc_enc->script, &info);
				if (e) return e;
			}
		}
	}
	if (use_list) GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "end", NULL);
	return GF_OK;
}
Beispiel #6
0
GF_Err BE_EncProtoList(GF_BifsEncoder *codec, GF_List *protoList, GF_BitStream *bs)
{
	u8 useQuant, useAnim;
	u32 i, j, nbRoutes, nbBits, numProtos, numFields, count;
	GF_Node *node;
	GF_ProtoFieldInterface *proto_field;
	GF_Proto *proto, *prev_proto;
	GF_Route *r;
	GF_Err e;
	GF_SceneGraph *rootSG;
	GF_FieldInfo field;

	e = GF_OK;
	if (!protoList || !gf_list_count(protoList)) {
		GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreProto", NULL);
		return GF_OK;
	}
	if (!codec->info->config.ProtoIDBits) 
		return GF_NON_COMPLIANT_BITSTREAM;

	/*store state*/
	rootSG = codec->current_proto_graph;
	prev_proto = codec->encoding_proto;

	numProtos = gf_list_count(protoList);
	for (i=0; i<numProtos; i++) {
		proto = (GF_Proto*)gf_list_get(protoList, i);
		useQuant = useAnim = 0;
		/*set current proto state*/
		codec->encoding_proto = proto;
		codec->current_proto_graph = proto->sub_graph;

		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "moreProto", NULL);

		/*1- proto interface declaration*/
		GF_BIFS_WRITE_INT(codec, bs, proto->ID, codec->info->config.ProtoIDBits, "protoID", NULL);

		if (codec->UseName) gf_bifs_enc_name(codec, bs, proto->Name);

		numFields = gf_list_count(proto->proto_fields);
		for (j=0; j<numFields; j++) {
			proto_field = (GF_ProtoFieldInterface*)gf_list_get(proto->proto_fields, j);

			GF_BIFS_WRITE_INT(codec, bs, 1, 1, "moreField", NULL);
			GF_BIFS_WRITE_INT(codec, bs, proto_field->EventType, 2, "eventType", NULL);
			GF_BIFS_WRITE_INT(codec, bs, proto_field->FieldType, 6, "fieldType", NULL);
			
			if (codec->UseName) gf_bifs_enc_name(codec, bs, proto_field->FieldName);
			switch (proto_field->EventType) {
			case GF_SG_EVENT_EXPOSED_FIELD:
			case GF_SG_EVENT_FIELD:
				gf_sg_proto_field_get_field(proto_field, &field);
				if (gf_sg_vrml_is_sf_field(field.fieldType)) {
					e = gf_bifs_enc_sf_field(codec, bs, NULL, &field);
				} else {
					if (codec->info->config.UsePredictiveMFField) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "usePredictive", NULL);
					e = gf_bifs_enc_mf_field(codec, bs, NULL, &field);
				}
				if (e) goto exit;
				break;
			}
			if (proto_field->QP_Type) useQuant = 1;
			if (proto_field->Anim_Type) useAnim = 1;
		}
		GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreField", NULL);
		
		GF_BIFS_WRITE_INT(codec, bs, proto->ExternProto.count ? 1 : 0, 1, "externProto", NULL);
		/*externProto*/
		if (proto->ExternProto.count) {
			memset(&field, 0, sizeof(GF_FieldInfo));
			field.far_ptr = &proto->ExternProto;
			field.fieldType = GF_SG_VRML_MFURL;
			field.name = "ExternProto";

			if (codec->info->config.UsePredictiveMFField) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "usePredictive", NULL);
			e = gf_bifs_enc_mf_field(codec, bs, NULL, &field);
			if (e) goto exit;
		} else {
			/*encode sub-proto list*/
			e = BE_EncProtoList(codec, proto->sub_graph->protos, bs);
			if (e) goto exit;

			count = gf_list_count(proto->node_code);
			/*BIFS cannot encode empty protos ! We therefore encode a NULL node instead*/
			if (!count) {
				gf_bifs_enc_node(codec, NULL, NDT_SFWorldNode, bs);
				GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreNodes", NULL);
			} else {
				for (j=0; j<count; j++) {
					/*parse all nodes in SFWorldNode table*/
					node = (GF_Node*)gf_list_get(proto->node_code, j);
					e = gf_bifs_enc_node(codec, node, NDT_SFWorldNode, bs);
					if (e) goto exit;
					GF_BIFS_WRITE_INT(codec, bs, (j+1==count) ? 0 : 1, 1, "moreNodes", NULL);
				}
			}

			/*encode routes routes*/
			nbRoutes = count = gf_list_count(proto->sub_graph->Routes);
			for (j=0; j<count; j++) {
				r = (GF_Route*)gf_list_get(proto->sub_graph->Routes, j);
				if (r->IS_route) nbRoutes--;
			}

			GF_BIFS_WRITE_INT(codec, bs, nbRoutes ? 1 : 0, 1, "hasRoute", NULL);
			if (nbRoutes) {
				nbBits = gf_get_bit_size(nbRoutes);
				if (nbBits + 5 > nbRoutes) {
					GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL);
					/*list*/
					for (j=0; j<count; j++) {
						r = (GF_Route*)gf_list_get(proto->sub_graph->Routes, j);
						if (r->IS_route) continue;
						e = gf_bifs_enc_route(codec, r, bs);
						if (e) goto exit;
						nbRoutes--;
						GF_BIFS_WRITE_INT(codec, bs, nbRoutes ? 1 : 0, 1, "moreRoute", NULL);
					}
				} else {
					GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isList", NULL);
					GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL);
					GF_BIFS_WRITE_INT(codec, bs, nbRoutes, nbBits, "length", NULL);
					for (j=0; j<count; j++) {
						r = (GF_Route*)gf_list_get(proto->sub_graph->Routes, j);
						if (r->IS_route) continue;
						e = gf_bifs_enc_route(codec, r, bs);
						if (e) goto exit;
					}
				}
			}
		}

		/*anim and Quantization stuff*/
		GF_BIFS_WRITE_INT(codec, bs, useQuant, 1, "useQuant", NULL);
		GF_BIFS_WRITE_INT(codec, bs, useAnim, 1, "useAnim", NULL);

		if (!useAnim && !useQuant) continue;

		count = gf_sg_proto_get_field_count(proto);
		for (j=0; j<count; j++) {
			proto_field = gf_sg_proto_field_find(proto, j);
			gf_sg_proto_field_get_field(proto_field, &field);

			/*quant*/
			if (useQuant && ( (field.eventType == GF_SG_EVENT_FIELD) || (field.eventType == GF_SG_EVENT_EXPOSED_FIELD) )) {
				GF_BIFS_WRITE_INT(codec, bs, proto_field->QP_Type, 4, "QPType", NULL);
				if (proto_field->QP_Type==QC_LINEAR_SCALAR) GF_BIFS_WRITE_INT(codec, bs, proto_field->NumBits, 5, "nbBits", NULL);
				GF_BIFS_WRITE_INT(codec, bs, proto_field->hasMinMax, 1, "hasMinMax", NULL);
				if (proto_field->hasMinMax) {
					field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
					switch (field.fieldType) {
					case GF_SG_VRML_SFINT32:
					case GF_SG_VRML_SFTIME:
						break;
					default:
						field.fieldType = GF_SG_VRML_SFFLOAT;
						break;
					}
					field.name = "QPMinValue";
					field.far_ptr = proto_field->qp_min_value;
					gf_bifs_enc_sf_field(codec, bs, NULL, &field);

					field.name = "QPMaxValue";
					field.far_ptr = proto_field->qp_max_value;
					gf_bifs_enc_sf_field(codec, bs, NULL, &field);
				}
			}

			/*anim - not supported yet*/
			if (useAnim && ( (field.eventType == GF_SG_EVENT_IN) || (field.eventType == GF_SG_EVENT_EXPOSED_FIELD) )) {
				e = GF_NOT_SUPPORTED;
				goto exit;
			}
		}
	}
	GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreProto", NULL);

exit:
	/*restore scene graph state*/
	codec->encoding_proto = prev_proto;
	codec->current_proto_graph = rootSG;
	return e;
}