コード例 #1
0
ファイル: field_encode.c プロジェクト: Brilon314/gpac
GF_Err gf_bifs_enc_field(GF_BifsEncoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field)
{
	assert(node);
	if (field->fieldType == GF_SG_VRML_UNKNOWN)
		return GF_NON_COMPLIANT_BITSTREAM;

	if (gf_sg_vrml_is_sf_field(field->fieldType)) {
		return gf_bifs_enc_sf_field(codec, bs, node, field);
	}

	/*TO DO : PMF support*/

	if (codec->info->config.UsePredictiveMFField) {
		GF_BIFS_WRITE_INT(codec, bs, 0, 1, "usePredictive", NULL);
	}
	return gf_bifs_enc_mf_field(codec, bs, node, field);
}
コード例 #2
0
ファイル: com_enc.c プロジェクト: bigbensk/gpac
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;
}