Exemplo n.º 1
0
GF_Err gf_bifs_enc_mf_field(GF_BifsEncoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field)
{
	GF_ChildNodeItem *list = NULL;
	GF_Err e;
	u32 nbBits;
	Bool use_list;
	Bool qp_local, qp_on, initial_qp;
	u32 nbF, i;
	GF_FieldInfo sffield;
		
	nbF = 0;
	if (field->fieldType != GF_SG_VRML_MFNODE) {
		nbF = field->far_ptr ? ((GenMFField *)field->far_ptr)->count : 0;
		if (!nbF && (field->fieldType == GF_SG_VRML_MFSCRIPT))
			nbF = 1;
	} else if (field->far_ptr) {
		list = *((GF_ChildNodeItem **)field->far_ptr);
		nbF = gf_node_list_get_count(list);
	}
	/*reserved*/
	GF_BIFS_WRITE_INT(codec, bs, 0, 1, "reserved", NULL);
	if (!nbF) {
		/*is list*/
		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL);
		/*end flag*/
		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);
		return GF_OK;
	}

	/*do we work in list or vector*/
	use_list = 0;
	nbBits = gf_get_bit_size(nbF);
	if (nbBits + 5 > nbF + 1) use_list = 1;

	GF_BIFS_WRITE_INT(codec, bs, use_list, 1, "isList", NULL);
	if (!use_list) {
		GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL);
		GF_BIFS_WRITE_INT(codec, bs, nbF, nbBits, "length", NULL);
	}

	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_on = qp_local = 0;
	initial_qp = codec->ActiveQP ? 1 : 0;
	for (i=0; i<nbF; i++) {

		if (use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL);

		if (field->fieldType != GF_SG_VRML_MFNODE) {
			gf_sg_vrml_mf_get_item(field->far_ptr, field->fieldType, &sffield.far_ptr, i);
			e = gf_bifs_enc_sf_field(codec, bs, node, &sffield);
		} else {
			assert(list);
			e = gf_bifs_enc_node(codec, list->node, field->NDTtype, bs);

			/*activate QP*/
			if (list->node->sgprivate->tag == TAG_MPEG4_QuantizationParameter) {
				qp_local = ((M_QuantizationParameter *)list->node)->isLocal;
				if (qp_on) gf_bifs_enc_qp_remove(codec, 0);
				e = gf_bifs_enc_qp_set(codec, list->node);
				if (e) return e;
				qp_on = 1;
				if (qp_local) qp_local = 2;
			}
			list = list->next;
		}
		
		if (e) return e;

		if (qp_on && qp_local) {
			if (qp_local == 2) qp_local -= 1;
			else {
				gf_bifs_enc_qp_remove(codec, initial_qp);
				qp_local = qp_on = 0;
			}
		}
	}

	if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);
	if (qp_on) gf_bifs_enc_qp_remove(codec, initial_qp);
	/*for QP14*/
	gf_bifs_enc_qp14_set_length(codec, nbF);
	return GF_OK;
}
Exemplo n.º 2
0
GF_Err gf_bifs_enc_node(GF_BifsEncoder * codec, GF_Node *node, u32 NDT_Tag, GF_BitStream *bs, GF_Node *parent_node)
{
	u32 NDTBits, node_type, node_tag, BVersion, node_id;
	const char *node_name;
	Bool flag, reset_qp14;
	GF_Node *new_node;
	GF_Err e;

	assert(codec->info);
	GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[BIFS] Encode node %s\n", gf_node_get_class_name(node) ));

	/*NULL node is a USE of maxID*/
	if (!node) {
		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "USE", NULL);
		GF_BIFS_WRITE_INT(codec, bs, (1<<codec->info->config.NodeIDBits) - 1 , codec->info->config.NodeIDBits, "NodeID", "NULL");
		return GF_OK;
	}

	flag = BE_NodeIsUSE(codec, node);
	GF_BIFS_WRITE_INT(codec, bs, flag ? 1 : 0, 1, "USE", (char*)gf_node_get_class_name(node));

	if (flag) {
		gf_bs_write_int(bs, gf_node_get_id(node) - 1, codec->info->config.NodeIDBits);
		new_node = gf_bifs_enc_find_node(codec, gf_node_get_id(node) );
		if (!new_node)
			return codec->LastError = GF_SG_UNKNOWN_NODE;

		/*restore QP14 length*/
		switch (gf_node_get_tag(new_node)) {
		case TAG_MPEG4_Coordinate:
		{
			u32 nbCoord = ((M_Coordinate *)new_node)->point.count;
			gf_bifs_enc_qp14_enter(codec, 1);
			gf_bifs_enc_qp14_set_length(codec, nbCoord);
			gf_bifs_enc_qp14_enter(codec, 0);
		}
		break;
		case TAG_MPEG4_Coordinate2D:
		{
			u32 nbCoord = ((M_Coordinate2D *)new_node)->point.count;
			gf_bifs_enc_qp14_enter(codec, 1);
			gf_bifs_enc_qp14_set_length(codec, nbCoord);
			gf_bifs_enc_qp14_enter(codec, 0);
		}
		break;
		}
		return GF_OK;
	}

	BVersion = GF_BIFS_V1;
	node_tag = node->sgprivate->tag;
	while (1) {
		node_type = gf_bifs_get_node_type(NDT_Tag, node_tag, BVersion);
		NDTBits = gf_bifs_get_ndt_bits(NDT_Tag, BVersion);
		if (BVersion==2 && (node_tag==TAG_ProtoNode)) node_type = 1;
		GF_BIFS_WRITE_INT(codec, bs, node_type, NDTBits, "ndt", NULL);
		if (node_type) break;

		BVersion += 1;
		if (BVersion > GF_BIFS_NUM_VERSION) {
			if (parent_node) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot encode node %s as a child of %s\n", gf_node_get_class_name(node), gf_node_get_class_name(parent_node) ));
			} else {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot encode node %s in the SFWorldNode context\n", gf_node_get_class_name(node) ));
			}
			return codec->LastError = GF_BIFS_UNKNOWN_VERSION;
		}
	}
	if (BVersion==2 && node_type==1) {
		GF_Proto *proto = ((GF_ProtoInstance *)node)->proto_interface;
		GF_BIFS_WRITE_INT(codec, bs, proto->ID, codec->info->config.ProtoIDBits, "protoID", NULL);
	}

	/*special handling of 3D mesh*/

	/*DEF'd node*/
	node_name = gf_node_get_name_and_id(node, &node_id);
	GF_BIFS_WRITE_INT(codec, bs, node_id ? 1 : 0, 1, "DEF", NULL);
	if (node_id) {
		GF_BIFS_WRITE_INT(codec, bs, node_id - 1, codec->info->config.NodeIDBits, "NodeID", NULL);
		if (codec->UseName) gf_bifs_enc_name(codec, bs, (char*) node_name );
	}

	/*no updates of time fields for now - NEEDED FOR A LIVE ENCODER*/

	/*if coords were not stored for QP14 before coding this node, reset QP14 it when leaving*/
	reset_qp14 = !codec->coord_stored;

	/*QP14 case*/
	switch (node_tag) {
	case TAG_MPEG4_Coordinate:
	case TAG_MPEG4_Coordinate2D:
		gf_bifs_enc_qp14_enter(codec, 1);
	}

	e = EncNodeFields(codec, bs, node);
	if (e) return e;

	if (codec->coord_stored && reset_qp14)
		gf_bifs_enc_qp14_reset(codec);

	switch (node_tag) {
	case TAG_MPEG4_Coordinate:
	case TAG_MPEG4_Coordinate2D:
		gf_bifs_enc_qp14_enter(codec, 0);
		break;
	}
	return GF_OK;
}