예제 #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, qp_local;
	Bool use_list, 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 = GF_FALSE;
	nbBits = gf_get_bit_size(nbF);
	if (nbBits + 5 > nbF + 1) use_list = GF_TRUE;

	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 = GF_FALSE;
	qp_local = 0;
	initial_qp = codec->ActiveQP ? GF_TRUE : GF_FALSE;
	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, node);

			/*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, GF_FALSE);
				e = gf_bifs_enc_qp_set(codec, list->node);
				if (e) return e;
				qp_on = GF_TRUE;
				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 = GF_FALSE;
			}
		}
	}

	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;
}
예제 #2
0
파일: com_enc.c 프로젝트: bigbensk/gpac
GF_Err gf_bifs_enc_commands(GF_BifsEncoder *codec, GF_List *comList, GF_BitStream *bs)
{
	u32 i;
	u32 count;
	GF_List *routes;
	GF_Err e = GF_OK;

	routes = NULL;

	codec->LastError = GF_OK;
	count = gf_list_count(comList);

	for (i=0; i<count; i++) {
		GF_Command *com = (GF_Command*)gf_list_get(comList, i);
		switch (com->tag) {
		case GF_SG_SCENE_REPLACE:
		{
			/*reset node context*/
			while (gf_list_count(codec->encoded_nodes)) gf_list_rem(codec->encoded_nodes, 0);
			GF_BIFS_WRITE_INT(codec, bs, 3, 2, "SceneReplace", NULL);
		
			if (!com->aggregated) {
				routes = gf_list_new();
				/*now the trick: get all following InsertRoutes and convert as routes*/
				for (; i<count-1; i++) {
					GF_Route *r;
					GF_Command *rcom = (GF_Command*)gf_list_get(comList, i+1);
					if (rcom->tag!=GF_SG_ROUTE_INSERT) break;
					GF_SAFEALLOC(r, GF_Route);
					r->FromField.fieldIndex = rcom->fromFieldIndex;
					r->FromNode = gf_sg_find_node(codec->scene_graph, rcom->fromNodeID);
					r->ToField.fieldIndex = rcom->toFieldIndex;
					r->ToNode = gf_sg_find_node(codec->scene_graph, rcom->toNodeID);
					r->ID = rcom->RouteID;
					r->name = rcom->def_name;
					gf_list_add(routes, r);
				}
				e = BE_SceneReplaceEx(codec, com, bs, routes);

				while (gf_list_count(routes)) {
					GF_Route *r = (GF_Route*)gf_list_get(routes, 0);
					gf_list_rem(routes, 0);
					gf_free(r);
				}
				gf_list_del(routes);
			} else {
				e = BE_SceneReplaceEx(codec, com, bs, codec->scene_graph->Routes);
			}
		}
			break;
		/*replace commands*/
		case GF_SG_NODE_REPLACE:
			GF_BIFS_WRITE_INT(codec, bs, 2, 2, "Replace", NULL);
			GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Node", NULL);
			e = BE_NodeReplace(codec, com, bs);
			break;
		case GF_SG_FIELD_REPLACE:
			GF_BIFS_WRITE_INT(codec, bs, 2, 2, "Replace", NULL);
			GF_BIFS_WRITE_INT(codec, bs, 1, 2, "Field", NULL);
			e = BE_FieldReplace(codec, com, bs);
			break;
		case GF_SG_INDEXED_REPLACE:
			GF_BIFS_WRITE_INT(codec, bs, 2, 2, "Replace", NULL);
			GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FieldIndex", NULL);
			e = BE_IndexFieldReplace(codec, com, bs);
			break;
		case GF_SG_ROUTE_REPLACE:
			GF_BIFS_WRITE_INT(codec, bs, 2, 2, "Replace", NULL);
			GF_BIFS_WRITE_INT(codec, bs, 3, 2, "Route", NULL);
			e = BE_RouteReplace(codec, com, bs, 0);
			break;
		case GF_SG_NODE_INSERT:
			GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Insert", NULL);
			GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Node", NULL);
			e = BE_NodeInsert(codec, com, bs);
			break;
		case GF_SG_INDEXED_INSERT:
			GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Insert", NULL);
			GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FieldIndex", NULL);
			e = BE_IndexInsert(codec, com, bs);
			break;
		case GF_SG_ROUTE_INSERT:
			GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Insert", NULL);
			GF_BIFS_WRITE_INT(codec, bs, 3, 2, "Route", NULL);
			e = BE_RouteReplace(codec, com, bs, 1);
			break;
		case GF_SG_NODE_DELETE:
			GF_BIFS_WRITE_INT(codec, bs, 1, 2, "Delete", NULL);
			GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Node", NULL);
			GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL);
			break;
		case GF_SG_INDEXED_DELETE:
			GF_BIFS_WRITE_INT(codec, bs, 1, 2, "Delete", NULL);
			GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FieldIndex", NULL);
			e = BE_IndexDelete(codec, com, bs);
			break;
		case GF_SG_ROUTE_DELETE:
			GF_BIFS_WRITE_INT(codec, bs, 1, 2, "Delete", NULL);
			GF_BIFS_WRITE_INT(codec, bs, 3, 2, "Route", NULL);
			GF_BIFS_WRITE_INT(codec, bs, com->RouteID - 1, codec->info->config.RouteIDBits, "RouteID", NULL);
			break;

		default:
			e = BE_ExtendedUpdate(codec, com, bs);
			break;
		}
		if (e) break;

		GF_BIFS_WRITE_INT(codec, bs, (i+1==count) ? 0 : 1, 1, "moreCommands", NULL);
	}

	while (gf_list_count(codec->QPs)) gf_bifs_enc_qp_remove(codec, 1);
	return e;
}