1 /*
2  *			GPAC - Multimedia Framework C SDK
3  *
4  *			Authors: Jean Le Feuvre
5  *			Copyright (c) Telecom ParisTech 2000-2012
6  *					All rights reserved
7  *
8  *  This file is part of GPAC / BIFS codec sub-project
9  *
10  *  GPAC is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU Lesser General Public License as published by
12  *  the Free Software Foundation; either version 2, or (at your option)
13  *  any later version.
14  *
15  *  GPAC is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU Lesser General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Lesser General Public
21  *  License along with this library; see the file COPYING.  If not, write to
22  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  */
25 
26 
27 #include <gpac/internal/bifs_dev.h>
28 #include "quant.h"
29 
30 
31 #ifndef GPAC_DISABLE_BIFS
32 
33 GF_Err ParseMFFieldList(GF_BifsDecoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field);
34 GF_Err ParseMFFieldVec(GF_BifsDecoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field);
35 
36 
BM_SetCommandNode(GF_Command * com,GF_Node * node)37 static void BM_SetCommandNode(GF_Command *com, GF_Node *node)
38 {
39 	com->node = node;
40 	gf_node_register(node, NULL);
41 }
42 
BM_ParseMultipleIndexedReplace(GF_BifsDecoder * codec,GF_BitStream * bs,GF_List * com_list)43 static GF_Err BM_ParseMultipleIndexedReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
44 {
45 	u32 ID, ind, field_ind, NumBits, lenpos, lennum, count;
46 	GF_Node *node;
47 	GF_Err e;
48 	GF_Command *com;
49 	GF_CommandField *inf;
50 	GF_FieldInfo field;
51 
52 	ID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
53 	node = gf_sg_find_node(codec->current_graph, ID);
54 	if (!node) return GF_NON_COMPLIANT_BITSTREAM;
55 	NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN)-1);
56 	ind = gf_bs_read_int(bs, NumBits);
57 	e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind);
58 	if (e) return e;
59 	e = gf_node_get_field(node, field_ind, &field);
60 	if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;
61 
62 	lenpos = gf_bs_read_int(bs, 5);
63 	lennum = gf_bs_read_int(bs, 5);
64 	count = gf_bs_read_int(bs, lennum);
65 
66 	com = gf_sg_command_new(codec->current_graph, GF_SG_MULTIPLE_INDEXED_REPLACE);
67 	BM_SetCommandNode(com, node);
68 	field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
69 
70 	while (count) {
71 		inf = gf_sg_command_field_new(com);
72 		inf->pos = gf_bs_read_int(bs, lenpos);
73 		inf->fieldIndex = field.fieldIndex;
74 		inf->fieldType = field.fieldType;
75 
76 		if (field.fieldType==GF_SG_VRML_SFNODE) {
77 			inf->new_node = gf_bifs_dec_node(codec, bs, field.NDTtype);
78 			if (codec->LastError) goto err;
79 			inf->field_ptr = &inf->new_node;
80 			gf_node_register(inf->new_node, NULL);
81 		} else {
82 			field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType);
83 			e = gf_bifs_dec_sf_field(codec, bs, node, &field, GF_TRUE);
84 			if (e) goto err;
85 		}
86 		count--;
87 	}
88 err:
89 	if (e) gf_sg_command_del(com);
90 	else gf_list_add(com_list, com);
91 	return e;
92 }
93 
BM_ParseMultipleReplace(GF_BifsDecoder * codec,GF_BitStream * bs,GF_List * com_list)94 static GF_Err BM_ParseMultipleReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
95 {
96 	u32 i, numFields, index, flag, nbBits, field_ref, fieldind;
97 	GF_Err e;
98 	GF_FieldInfo field;
99 	u32 NodeID;
100 	GF_Node *node;
101 	GF_Command *com;
102 	GF_CommandField *inf;
103 
104 	NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
105 	node = gf_sg_find_node(codec->current_graph, NodeID);
106 	if (!node) return GF_NON_COMPLIANT_BITSTREAM;
107 
108 	e = GF_OK;
109 	com = gf_sg_command_new(codec->current_graph, GF_SG_MULTIPLE_REPLACE);
110 	BM_SetCommandNode(com, node);
111 	flag = gf_bs_read_int(bs, 1);
112 	if (flag) {
113 		numFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF);
114 		for (i=0; i<numFields; i++) {
115 			flag = gf_bs_read_int(bs, 1);
116 			if (!flag) continue;
117 			gf_bifs_get_field_index(node, i, GF_SG_FIELD_CODING_DEF, &index);
118 			e = gf_node_get_field(node, index, &field);
119 			if (e) goto exit;
120 			inf = gf_sg_command_field_new(com);
121 			inf->fieldType = field.fieldType;
122 			inf->fieldIndex = field.fieldIndex;
123 			if (inf->fieldType==GF_SG_VRML_SFNODE) {
124 				field.far_ptr = inf->field_ptr = &inf->new_node;
125 			} else if (inf->fieldType==GF_SG_VRML_MFNODE) {
126 				field.far_ptr = inf->field_ptr = &inf->node_list;
127 			} else {
128 				field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType);
129 			}
130 			e = gf_bifs_dec_field(codec, bs, node, &field, GF_TRUE);
131 			if (e) goto exit;
132 		}
133 	} else {
134 		flag = gf_bs_read_int(bs, 1);
135 		nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF)-1);
136 		while (!flag && (codec->LastError>=0)) {
137 			field_ref = gf_bs_read_int(bs, nbBits);
138 			e = gf_bifs_get_field_index(node, field_ref, GF_SG_FIELD_CODING_DEF, &fieldind);
139 			if (e) goto exit;
140 			e = gf_node_get_field(node, fieldind, &field);
141 			if (e) goto exit;
142 			inf = gf_sg_command_field_new(com);
143 			inf->fieldType = field.fieldType;
144 			inf->fieldIndex = field.fieldIndex;
145 			if (inf->fieldType==GF_SG_VRML_SFNODE) {
146 				field.far_ptr = inf->field_ptr = &inf->new_node;
147 			} else if (inf->fieldType==GF_SG_VRML_MFNODE) {
148 				field.far_ptr = inf->field_ptr = &inf->node_list;
149 			} else {
150 				field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType);
151 			}
152 			e = gf_bifs_dec_field(codec, bs, node, &field, GF_TRUE);
153 			if (e) goto exit;
154 			flag = gf_bs_read_int(bs, 1);
155 		}
156 	}
157 
158 
159 exit:
160 	if (e) gf_sg_command_del(com);
161 	else gf_list_add(com_list, com);
162 	return e;
163 }
164 
BM_ParseGlobalQuantizer(GF_BifsDecoder * codec,GF_BitStream * bs,GF_List * com_list)165 static GF_Err BM_ParseGlobalQuantizer(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
166 {
167 	GF_Node *node;
168 	GF_Command *com;
169 	GF_CommandField *inf;
170 	node = gf_bifs_dec_node(codec, bs, NDT_SFWorldNode);
171 	if (!node) return GF_NON_COMPLIANT_BITSTREAM;
172 
173 	/*reset global QP*/
174 	if (codec->scenegraph->global_qp) {
175 		gf_node_unregister(codec->scenegraph->global_qp, NULL);
176 	}
177 	codec->ActiveQP = NULL;
178 	codec->scenegraph->global_qp = NULL;
179 
180 	if (gf_node_get_tag(node) != TAG_MPEG4_QuantizationParameter) {
181 		gf_node_unregister(node, NULL);
182 		return GF_NON_COMPLIANT_BITSTREAM;
183 	}
184 
185 	/*register global QP*/
186 	codec->ActiveQP = (M_QuantizationParameter *) node;
187 	codec->ActiveQP->isLocal = 0;
188 	codec->scenegraph->global_qp = node;
189 
190 	/*register TWICE: once for the command, and for the scenegraph globalQP*/
191 	node->sgprivate->num_instances = 2;
192 
193 	com = gf_sg_command_new(codec->current_graph, GF_SG_GLOBAL_QUANTIZER);
194 	inf = gf_sg_command_field_new(com);
195 	inf->new_node = node;
196 	inf->field_ptr = &inf->new_node;
197 	inf->fieldType = GF_SG_VRML_SFNODE;
198 	gf_list_add(com_list, com);
199 	return GF_OK;
200 }
201 
BM_ParseProtoDelete(GF_BifsDecoder * codec,GF_BitStream * bs,GF_List * com_list)202 static GF_Err BM_ParseProtoDelete(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
203 {
204 	u32 flag, count;
205 	GF_Command *com = gf_sg_command_new(codec->current_graph, GF_SG_PROTO_DELETE);
206 	flag = gf_bs_read_int(bs, 1);
207 	if (flag) {
208 		count = 0;
209 		flag = gf_bs_read_int(bs, 1);
210 		while (flag) {
211 			com->del_proto_list = (u32*)gf_realloc(com->del_proto_list, sizeof(u32) * (com->del_proto_list_size+1));
212 			com->del_proto_list[count] = gf_bs_read_int(bs, codec->info->config.ProtoIDBits);
213 			com->del_proto_list_size++;
214 			flag = gf_bs_read_int(bs, 1);
215 		}
216 	} else {
217 		flag = gf_bs_read_int(bs, 5);
218 		com->del_proto_list_size = gf_bs_read_int(bs, flag);
219 		com->del_proto_list = (u32*)gf_realloc(com->del_proto_list, sizeof(u32) * (com->del_proto_list_size));
220 		flag = 0;
221 		while (flag<com->del_proto_list_size) {
222 			com->del_proto_list[flag] = gf_bs_read_int(bs, codec->info->config.ProtoIDBits);
223 			flag++;
224 		}
225 	}
226 	gf_list_add(com_list, com);
227 	return GF_OK;
228 }
229 
BM_XReplace(GF_BifsDecoder * codec,GF_BitStream * bs,GF_List * com_list)230 static GF_Err BM_XReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
231 {
232 	GF_FieldInfo targetField, fromField, decfield;
233 	GF_Node *target, *fromNode;
234 	s32 pos = -2;
235 	u32 id, nbBits, ind, aind;
236 	GF_Err e;
237 	GF_Command *com;
238 	GF_CommandField *inf;
239 
240 	id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
241 	target = gf_sg_find_node(codec->current_graph, id);
242 	if (!target) return GF_SG_UNKNOWN_NODE;
243 
244 	com = gf_sg_command_new(codec->current_graph, GF_SG_XREPLACE);
245 	BM_SetCommandNode(com, target);
246 	gf_list_add(com_list, com);
247 
248 	nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(target, GF_SG_FIELD_CODING_IN)-1);
249 	ind = gf_bs_read_int(bs, nbBits);
250 	e = gf_bifs_get_field_index(target, ind, GF_SG_FIELD_CODING_IN, &aind);
251 	if (e) return e;
252 	e = gf_node_get_field(target, aind, &targetField);
253 	if (e) return e;
254 
255 	inf = gf_sg_command_field_new(com);
256 	inf->fieldIndex = aind;
257 
258 	if (!gf_sg_vrml_is_sf_field(targetField.fieldType)) {
259 		/*this is indexed replacement*/
260 		if (gf_bs_read_int(bs, 1)) {
261 			/*index is dynamic*/
262 			if (gf_bs_read_int(bs, 1)) {
263 				GF_Node *n;
264 				id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
265 				n = gf_sg_find_node(codec->current_graph, id);
266 				if (!n) return GF_SG_UNKNOWN_NODE;
267 				com->toNodeID = id;
268 
269 				nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_DEF)-1);
270 				ind = gf_bs_read_int(bs, nbBits);
271 				e = gf_bifs_get_field_index(n, ind, GF_SG_FIELD_CODING_DEF, &aind);
272 				if (e) return e;
273 				e = gf_node_get_field(n, aind, &fromField);
274 				if (e) return e;
275 				com->toFieldIndex = aind;
276 			} else {
277 				u32 type = gf_bs_read_int(bs, 2);
278 				switch (type) {
279 				case 0:
280 					pos = gf_bs_read_int(bs, 16);
281 					break;
282 				case 2:
283 					pos = 0;
284 					break;
285 				case 3:
286 					pos = -1;
287 					break;
288 				}
289 			}
290 		}
291 		if (targetField.fieldType==GF_SG_VRML_MFNODE) {
292 			if (gf_bs_read_int(bs, 1)) {
293 				target = gf_node_list_get_child(*(GF_ChildNodeItem **)targetField.far_ptr, pos);
294 				if (!target) return GF_SG_UNKNOWN_NODE;
295 
296 				nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(target, GF_SG_FIELD_CODING_IN)-1);
297 				ind = gf_bs_read_int(bs, nbBits);
298 				e = gf_bifs_get_field_index(target, ind, GF_SG_FIELD_CODING_IN, &aind);
299 				if (e) return e;
300 				e = gf_node_get_field(target, aind, &targetField);
301 				if (e) return e;
302 				pos = -2;
303 				com->child_field = aind;
304 				com->ChildNodeTag = gf_node_get_tag(target);
305 				if (com->ChildNodeTag == TAG_ProtoNode) {
306 					s32 p_id = gf_sg_proto_get_id(gf_node_get_proto(target));
307 					com->ChildNodeTag = -p_id;
308 				}
309 			}
310 		}
311 		inf->pos = pos;
312 	}
313 
314 	fromNode = NULL;
315 	if (gf_bs_read_int(bs, 1)) {
316 		id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
317 		fromNode = gf_sg_find_node(codec->current_graph, id);
318 		if (!fromNode) return GF_SG_UNKNOWN_NODE;
319 		com->fromNodeID = id;
320 
321 		nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(fromNode, GF_SG_FIELD_CODING_DEF)-1);
322 		ind = gf_bs_read_int(bs, nbBits);
323 		e = gf_bifs_get_field_index(fromNode, ind, GF_SG_FIELD_CODING_DEF, &aind);
324 		if (e) return e;
325 		e = gf_node_get_field(fromNode, aind, &fromField);
326 		if (e) return e;
327 		com->fromFieldIndex = aind;
328 
329 		return GF_OK;
330 	}
331 
332 
333 	if (pos>= -1) {
334 		inf->fieldType = gf_sg_vrml_get_sf_type(targetField.fieldType);
335 	} else {
336 		inf->fieldType = targetField.fieldType;
337 	}
338 	decfield.fieldIndex = inf->fieldIndex;
339 	decfield.fieldType = inf->fieldType;
340 
341 	if (inf->fieldType==GF_SG_VRML_SFNODE) {
342 		decfield.far_ptr = inf->field_ptr = &inf->new_node;
343 	} else if (inf->fieldType==GF_SG_VRML_MFNODE) {
344 		decfield.far_ptr = inf->field_ptr = &inf->node_list;
345 	} else {
346 		decfield.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType);
347 	}
348 	e = gf_bifs_dec_sf_field(codec, bs, target, &decfield, GF_TRUE);
349 	return e;
350 }
351 
BM_ParseExtendedUpdates(GF_BifsDecoder * codec,GF_BitStream * bs,GF_List * com_list)352 static GF_Err BM_ParseExtendedUpdates(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
353 {
354 	u32 type = gf_bs_read_int(bs, 8);
355 	GF_Err e;
356 
357 	switch (type) {
358 	case 0:
359 	{
360 		GF_Command *com = gf_sg_command_new(codec->current_graph, GF_SG_PROTO_INSERT);
361 		e = gf_bifs_dec_proto_list(codec, bs, com->new_proto_list);
362 		if (e) gf_sg_command_del(com);
363 		else gf_list_add(com_list, com);
364 	}
365 	return e;
366 	case 1:
367 		return BM_ParseProtoDelete(codec, bs, com_list);
368 	case 2:
369 	{
370 		GF_Command *com = gf_sg_command_new(codec->current_graph, GF_SG_PROTO_DELETE_ALL);
371 		return gf_list_add(com_list, com);
372 	}
373 	case 3:
374 		return BM_ParseMultipleIndexedReplace(codec, bs, com_list);
375 	case 4:
376 		return BM_ParseMultipleReplace(codec, bs, com_list);
377 	case 5:
378 		return BM_ParseGlobalQuantizer(codec, bs, com_list);
379 	case 6:
380 	{
381 		GF_Command *com;
382 		u32 ID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
383 		GF_Node *n = gf_sg_find_node(codec->current_graph, ID);
384 		if (!n) return GF_OK;
385 		com = gf_sg_command_new(codec->current_graph, GF_SG_NODE_DELETE_EX);
386 		BM_SetCommandNode(com, n);
387 		gf_list_add(com_list, com);
388 	}
389 	return GF_OK;
390 	case 7:
391 		return BM_XReplace(codec, bs, com_list);
392 
393 	default:
394 		return GF_BIFS_UNKNOWN_VERSION;
395 	}
396 }
397 
398 /*inserts a node in a container (node.children)*/
BM_ParseNodeInsert(GF_BifsDecoder * codec,GF_BitStream * bs,GF_List * com_list)399 GF_Err BM_ParseNodeInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
400 {
401 	u32 NodeID, NDT;
402 	GF_CommandField *inf;
403 	s32 type, pos;
404 	GF_Node *node, *def;
405 
406 	NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
407 	def = gf_sg_find_node(codec->current_graph, NodeID);
408 	if (!def) return GF_NON_COMPLIANT_BITSTREAM;
409 	NDT = gf_bifs_get_child_table(def);
410 	if (!NDT) return GF_NON_COMPLIANT_BITSTREAM;
411 
412 	type = gf_bs_read_int(bs, 2);
413 	switch (type) {
414 	case 0:
415 		pos = gf_bs_read_int(bs, 8);
416 		break;
417 	case 2:
418 		pos = 0;
419 		break;
420 	case 3:
421 		/*-1 means append*/
422 		pos = -1;
423 		break;
424 	default:
425 		return GF_NON_COMPLIANT_BITSTREAM;
426 	}
427 	node = gf_bifs_dec_node(codec, bs, NDT);
428 	if (!codec->LastError) {
429 		GF_Command *com = gf_sg_command_new(codec->current_graph, GF_SG_NODE_INSERT);
430 		BM_SetCommandNode(com, def);
431 		inf = gf_sg_command_field_new(com);
432 		inf->pos = pos;
433 		inf->new_node = node;
434 		inf->field_ptr = &inf->new_node;
435 		inf->fieldType = GF_SG_VRML_SFNODE;
436 		gf_list_add(com_list, com);
437 		/*register*/
438 		gf_node_register(node, NULL);
439 	}
440 	return codec->LastError;
441 }
442 
443 /*NB This can insert a node as well (but usually not in the .children field)*/
BM_ParseIndexInsert(GF_BifsDecoder * codec,GF_BitStream * bs,GF_List * com_list)444 GF_Err BM_ParseIndexInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
445 {
446 	GF_Err e;
447 	u32 NodeID;
448 	u32 NumBits, ind, field_ind;
449 	u8 type;
450 	GF_Command *com;
451 	GF_CommandField *inf;
452 	s32 pos;
453 	GF_Node *def, *node;
454 	GF_FieldInfo field, sffield;
455 
456 	NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
457 	def = gf_sg_find_node(codec->current_graph, NodeID);
458 	if (!def) return GF_NON_COMPLIANT_BITSTREAM;
459 	/*index insertion uses IN mode for field index*/
460 	NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(def, GF_SG_FIELD_CODING_IN)-1);
461 	ind = gf_bs_read_int(bs, NumBits);
462 
463 	e = gf_bifs_get_field_index(def, ind, GF_SG_FIELD_CODING_IN, &field_ind);
464 	if (e) return e;
465 
466 	type = gf_bs_read_int(bs, 2);
467 	switch (type) {
468 	case 0:
469 		pos = gf_bs_read_int(bs, 16);
470 		break;
471 	case 2:
472 		pos = 0;
473 		break;
474 	case 3:
475 		pos = -1;
476 		break;
477 	default:
478 		return GF_NON_COMPLIANT_BITSTREAM;
479 	}
480 
481 	e = gf_node_get_field(def, field_ind, &field);
482 	if (e) return e;
483 	if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;
484 
485 	memcpy(&sffield, &field, sizeof(GF_FieldInfo));
486 	sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
487 
488 	/*rescale the MFField and parse the SFField*/
489 	if (field.fieldType==GF_SG_VRML_MFNODE) {
490 		node = gf_bifs_dec_node(codec, bs, field.NDTtype);
491 		if (!codec->LastError) {
492 			com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_INSERT);
493 			BM_SetCommandNode(com, def);
494 			inf = gf_sg_command_field_new(com);
495 			inf->pos = pos;
496 			inf->fieldIndex = field_ind;
497 			inf->fieldType = sffield.fieldType;
498 			inf->new_node = node;
499 			inf->field_ptr = &inf->new_node;
500 			gf_list_add(com_list, com);
501 			/*register*/
502 			gf_node_register(node, NULL);
503 		}
504 	} else {
505 		com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_INSERT);
506 		BM_SetCommandNode(com, def);
507 		inf = gf_sg_command_field_new(com);
508 		inf->pos = pos;
509 		inf->fieldIndex = field_ind;
510 		inf->fieldType = sffield.fieldType;
511 		sffield.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(sffield.fieldType);
512 		codec->LastError = gf_bifs_dec_sf_field(codec, bs, def, &sffield, GF_TRUE);
513 		gf_list_add(com_list, com);
514 	}
515 	return codec->LastError;
516 }
517 
518 
BM_ParseRouteInsert(GF_BifsDecoder * codec,GF_BitStream * bs,GF_List * com_list)519 GF_Err BM_ParseRouteInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
520 {
521 	GF_Err e;
522 	u8 flag;
523 	GF_Command *com;
524 	GF_Node *InNode, *OutNode;
525 	u32 RouteID, outField, inField, numBits, ind, node_id;
526 	char name[1000];
527 
528 	RouteID = 0;
529 
530 	flag = gf_bs_read_int(bs, 1);
531 	/*def'ed route*/
532 	if (flag) {
533 		RouteID = 1 + gf_bs_read_int(bs, codec->info->config.RouteIDBits);
534 		if (codec->UseName) gf_bifs_dec_name(bs, name);
535 	}
536 	/*origin*/
537 	node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
538 	OutNode = gf_sg_find_node(codec->current_graph, node_id);
539 	if (!OutNode) return GF_SG_UNKNOWN_NODE;
540 
541 	numBits = gf_node_get_num_fields_in_mode(OutNode, GF_SG_FIELD_CODING_OUT) - 1;
542 	numBits = gf_get_bit_size(numBits);
543 	ind = gf_bs_read_int(bs, numBits);
544 	e = gf_bifs_get_field_index(OutNode, ind, GF_SG_FIELD_CODING_OUT, &outField);
545 	if (e) return e;
546 
547 	/*target*/
548 	node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
549 	InNode = gf_sg_find_node(codec->current_graph, node_id);
550 	if (!InNode) return GF_SG_UNKNOWN_NODE;
551 
552 	numBits = gf_node_get_num_fields_in_mode(InNode, GF_SG_FIELD_CODING_IN) - 1;
553 	numBits = gf_get_bit_size(numBits);
554 	ind = gf_bs_read_int(bs, numBits);
555 	e = gf_bifs_get_field_index(InNode, ind, GF_SG_FIELD_CODING_IN, &inField);
556 	if (e) return e;
557 
558 	com = gf_sg_command_new(codec->current_graph, GF_SG_ROUTE_INSERT);
559 	com->RouteID = RouteID;
560 	if (codec->UseName) com->def_name = gf_strdup( name);
561 	com->fromNodeID = gf_node_get_id(OutNode);
562 	com->fromFieldIndex = outField;
563 	com->toNodeID = gf_node_get_id(InNode);
564 	com->toFieldIndex = inField;
565 	gf_list_add(com_list, com);
566 	return codec->LastError;
567 }
568 
569 
BM_ParseInsert(GF_BifsDecoder * codec,GF_BitStream * bs,GF_List * com_list)570 GF_Err BM_ParseInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
571 {
572 	u8 type;
573 
574 	type = gf_bs_read_int(bs, 2);
575 	switch (type) {
576 	case 0:
577 		return BM_ParseNodeInsert(codec, bs, com_list);
578 	case 1:
579 		return BM_ParseExtendedUpdates(codec, bs, com_list);
580 	case 2:
581 		return BM_ParseIndexInsert(codec, bs, com_list);
582 	case 3:
583 		return BM_ParseRouteInsert(codec, bs, com_list);
584 	default:
585 		return GF_NON_COMPLIANT_BITSTREAM;
586 	}
587 }
588 
589 
BM_ParseIndexDelete(GF_BifsDecoder * codec,GF_BitStream * bs,GF_List * com_list)590 GF_Err BM_ParseIndexDelete(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
591 {
592 	u32 NodeID, NumBits, ind, field_ind;
593 	s32 pos;
594 	GF_Command *com;
595 	u8 type;
596 	GF_Node *node;
597 	GF_Err e;
598 	GF_CommandField *inf;
599 	GF_FieldInfo field;
600 
601 	NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
602 	node = gf_sg_find_node(codec->current_graph, NodeID);
603 	if (!node) return GF_NON_COMPLIANT_BITSTREAM;
604 
605 	NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN) - 1);
606 	ind = gf_bs_read_int(bs, NumBits);
607 
608 	type = gf_bs_read_int(bs, 2);
609 	switch (type) {
610 	case 0:
611 		pos = (u32) gf_bs_read_int(bs, 16);
612 		break;
613 	case 2:
614 		pos = 0;
615 		break;
616 	case 3:
617 		pos = -1;
618 		break;
619 	default:
620 		return GF_NON_COMPLIANT_BITSTREAM;
621 	}
622 	e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind);
623 	if (e) return e;
624 	e = gf_node_get_field(node, field_ind, &field);
625 	if (e) return e;
626 	if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;
627 	com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_DELETE);
628 	BM_SetCommandNode(com, node);
629 	inf = gf_sg_command_field_new(com);
630 	inf->pos = pos;
631 	inf->fieldIndex = field.fieldIndex;
632 	inf->fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
633 	gf_list_add(com_list, com);
634 	return codec->LastError;
635 }
636 
637 
638 
BM_ParseDelete(GF_BifsDecoder * codec,GF_BitStream * bs,GF_List * com_list)639 GF_Err BM_ParseDelete(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
640 {
641 	u8 type;
642 	u32 ID;
643 	GF_Command *com;
644 	GF_Node *n;
645 
646 	type = gf_bs_read_int(bs, 2);
647 	switch (type) {
648 	case 0:
649 		ID = 1+gf_bs_read_int(bs, codec->info->config.NodeIDBits);
650 		n = gf_sg_find_node(codec->current_graph, ID);
651 		if (!n) return GF_OK;
652 		com = gf_sg_command_new(codec->current_graph, GF_SG_NODE_DELETE);
653 		BM_SetCommandNode(com, n);
654 		gf_list_add(com_list, com);
655 		return GF_OK;
656 	case 2:
657 		return BM_ParseIndexDelete(codec, bs, com_list);
658 	case 3:
659 		com = gf_sg_command_new(codec->current_graph, GF_SG_ROUTE_DELETE);
660 		com->RouteID = 1+gf_bs_read_int(bs, codec->info->config.RouteIDBits);
661 		gf_list_add(com_list, com);
662 		return GF_OK;
663 	default:
664 		return GF_NON_COMPLIANT_BITSTREAM;
665 	}
666 	return GF_OK;
667 }
668 
669 
BM_ParseNodeReplace(GF_BifsDecoder * codec,GF_BitStream * bs,GF_List * com_list)670 GF_Err BM_ParseNodeReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
671 {
672 	u32 NodeID;
673 	GF_Command *com;
674 	GF_Node *node;
675 	GF_CommandField *inf;
676 
677 	NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
678 	/*this is delete / new on a DEF node: replace ALL instances*/
679 	node = gf_sg_find_node(codec->current_graph, NodeID);
680 	if (!node) return GF_NON_COMPLIANT_BITSTREAM;
681 
682 	com = gf_sg_command_new(codec->current_graph, GF_SG_NODE_REPLACE);
683 	BM_SetCommandNode(com, node);
684 	inf = gf_sg_command_field_new(com);
685 	inf->new_node = gf_bifs_dec_node(codec, bs, NDT_SFWorldNode);
686 	inf->fieldType = GF_SG_VRML_SFNODE;
687 	inf->field_ptr = &inf->new_node;
688 	gf_list_add(com_list, com);
689 	gf_node_register(inf->new_node, NULL);
690 	return codec->LastError;
691 }
692 
BM_ParseFieldReplace(GF_BifsDecoder * codec,GF_BitStream * bs,GF_List * com_list)693 GF_Err BM_ParseFieldReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
694 {
695 	GF_Err e;
696 	GF_Command *com;
697 	u32 NodeID, ind, field_ind, NumBits;
698 	GF_Node *node;
699 	GF_FieldInfo field;
700 	GF_CommandField *inf;
701 
702 	NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
703 	node = gf_sg_find_node(codec->current_graph, NodeID);
704 	if (!node) return GF_NON_COMPLIANT_BITSTREAM;
705 	NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN)-1);
706 	ind = gf_bs_read_int(bs, NumBits);
707 	e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind);
708 	if (e) return e;
709 
710 	e = gf_node_get_field(node, field_ind, &field);
711 	if (e) return e;
712 
713 	com = gf_sg_command_new(codec->current_graph, GF_SG_FIELD_REPLACE);
714 	BM_SetCommandNode(com, node);
715 	inf = gf_sg_command_field_new(com);
716 	inf->fieldIndex = field_ind;
717 	inf->fieldType = field.fieldType;
718 	if (inf->fieldType == GF_SG_VRML_SFNODE) {
719 		field.far_ptr = inf->field_ptr = &inf->new_node;
720 	} else if (inf->fieldType == GF_SG_VRML_MFNODE) {
721 		field.far_ptr = inf->field_ptr = &inf->node_list;
722 	} else {
723 		field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(field.fieldType);
724 	}
725 	/*parse the field*/
726 	codec->LastError = gf_bifs_dec_field(codec, bs, node, &field, GF_TRUE);
727 
728 	gf_list_add(com_list, com);
729 	return codec->LastError;
730 }
731 
BM_ParseIndexValueReplace(GF_BifsDecoder * codec,GF_BitStream * bs,GF_List * com_list)732 GF_Err BM_ParseIndexValueReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
733 {
734 	u32 NodeID, ind, field_ind, NumBits;
735 	s32 type, pos;
736 	GF_Command *com;
737 	GF_Node *node;
738 	GF_Err e;
739 	GF_FieldInfo field, sffield;
740 	GF_CommandField *inf;
741 
742 	/*get the node*/
743 	NodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
744 
745 	node = gf_sg_find_node(codec->current_graph, NodeID);
746 	if (!node) return GF_NON_COMPLIANT_BITSTREAM;
747 	NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_IN)-1);
748 	ind = gf_bs_read_int(bs, NumBits);
749 	e = gf_bifs_get_field_index(node, ind, GF_SG_FIELD_CODING_IN, &field_ind);
750 	if (e) return e;
751 
752 	e = gf_node_get_field(node, field_ind, &field);
753 	if (e) return e;
754 	if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;
755 
756 	type = gf_bs_read_int(bs, 2);
757 	switch (type) {
758 	case 0:
759 		pos = gf_bs_read_int(bs, 16);
760 		break;
761 	case 2:
762 		pos = 0;
763 		break;
764 	case 3:
765 		pos = ((GenMFField *) field.far_ptr)->count - 1;
766 		break;
767 	default:
768 		return GF_NON_COMPLIANT_BITSTREAM;
769 	}
770 
771 	com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_REPLACE);
772 	BM_SetCommandNode(com, node);
773 	inf = gf_sg_command_field_new(com);
774 	inf->fieldIndex = field.fieldIndex;
775 	inf->pos = pos;
776 
777 	if (field.fieldType == GF_SG_VRML_MFNODE) {
778 		inf->fieldType = GF_SG_VRML_SFNODE;
779 		inf->new_node = gf_bifs_dec_node(codec, bs, field.NDTtype);
780 		inf->field_ptr = &inf->new_node;
781 		if (inf->new_node) gf_node_register(inf->new_node, NULL);
782 	} else {
783 		memcpy(&sffield, &field, sizeof(GF_FieldInfo));
784 		sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
785 		inf->fieldType = sffield.fieldType;
786 		sffield.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(sffield.fieldType);
787 		codec->LastError = gf_bifs_dec_sf_field(codec, bs, node, &sffield, GF_TRUE);
788 	}
789 	gf_list_add(com_list, com);
790 	return codec->LastError;
791 }
792 
BM_ParseRouteReplace(GF_BifsDecoder * codec,GF_BitStream * bs,GF_List * com_list)793 GF_Err BM_ParseRouteReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
794 {
795 	GF_Err e;
796 	GF_Command *com;
797 	u32 RouteID, numBits, ind, node_id, fromID, toID;
798 	GF_Node *OutNode, *InNode;
799 
800 	RouteID = 1+gf_bs_read_int(bs, codec->info->config.RouteIDBits);
801 
802 	/*origin*/
803 	node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
804 	OutNode = gf_sg_find_node(codec->current_graph, node_id);
805 	if (!OutNode) return GF_NON_COMPLIANT_BITSTREAM;
806 	numBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(OutNode, GF_SG_FIELD_CODING_OUT) - 1);
807 	ind = gf_bs_read_int(bs, numBits);
808 	e = gf_bifs_get_field_index(OutNode, ind, GF_SG_FIELD_CODING_OUT, &fromID);
809 	if (e) return e;
810 
811 	/*target*/
812 	node_id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
813 	InNode = gf_sg_find_node(codec->current_graph, node_id);
814 	if (!InNode) return GF_NON_COMPLIANT_BITSTREAM;
815 	numBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(InNode, GF_SG_FIELD_CODING_IN) - 1);
816 	ind = gf_bs_read_int(bs, numBits);
817 	e = gf_bifs_get_field_index(InNode, ind, GF_SG_FIELD_CODING_IN, &toID);
818 	if (e) return e;
819 
820 	com = gf_sg_command_new(codec->current_graph, GF_SG_ROUTE_REPLACE);
821 	com->RouteID = RouteID;
822 	com->fromNodeID = gf_node_get_id(OutNode);
823 	com->fromFieldIndex = fromID;
824 	com->toNodeID = gf_node_get_id(InNode);
825 	com->toFieldIndex = toID;
826 	gf_list_add(com_list, com);
827 	return codec->LastError;
828 }
829 
830 
BM_ParseReplace(GF_BifsDecoder * codec,GF_BitStream * bs,GF_List * com_list)831 GF_Err BM_ParseReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
832 {
833 	u8 type;
834 	type = gf_bs_read_int(bs, 2);
835 	switch (type) {
836 	case 0:
837 		return BM_ParseNodeReplace(codec, bs, com_list);
838 	case 1:
839 		return BM_ParseFieldReplace(codec, bs, com_list);
840 	case 2:
841 		return BM_ParseIndexValueReplace(codec, bs, com_list);
842 	case 3:
843 		return BM_ParseRouteReplace(codec, bs, com_list);
844 	}
845 	return GF_OK;
846 }
847 
BM_SceneReplace(GF_BifsDecoder * codec,GF_BitStream * bs,GF_List * com_list)848 GF_Err BM_SceneReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
849 {
850 	GF_Command *com;
851 	GF_Node *backup_root;
852 	GF_List *backup_routes;
853 	GF_Err BD_DecSceneReplace(GF_BifsDecoder * codec, GF_BitStream *bs, GF_List *proto_list);
854 
855 	backup_routes = codec->scenegraph->Routes;
856 	backup_root = codec->scenegraph->RootNode;
857 	com = gf_sg_command_new(codec->current_graph, GF_SG_SCENE_REPLACE);
858 	codec->scenegraph->Routes = gf_list_new();
859 	codec->current_graph = codec->scenegraph;
860 	codec->LastError = BD_DecSceneReplace(codec, bs, com->new_proto_list);
861 	com->use_names = codec->UseName;
862 
863 	/*restore*/
864 	com->node = codec->scenegraph->RootNode;
865 	codec->scenegraph->RootNode = backup_root;
866 	gf_list_add(com_list, com);
867 	/*insert routes*/
868 	while (gf_list_count(codec->scenegraph->Routes)) {
869 		GF_Route *r = (GF_Route*)gf_list_get(codec->scenegraph->Routes, 0);
870 		GF_Command *ri = gf_sg_command_new(codec->current_graph, GF_SG_ROUTE_INSERT);
871 		gf_list_rem(codec->scenegraph->Routes, 0);
872 		ri->fromFieldIndex = r->FromField.fieldIndex;
873 		ri->fromNodeID = gf_node_get_id(r->FromNode);
874 		ri->toFieldIndex = r->ToField.fieldIndex;
875 		ri->toNodeID = gf_node_get_id(r->ToNode);
876 		if (r->ID) ri->RouteID = r->ID;
877 		ri->def_name = r->name ? gf_strdup(r->name) : NULL;
878 		gf_list_add(com_list, ri);
879 		gf_sg_route_del(r);
880 	}
881 	gf_list_del(codec->scenegraph->Routes);
882 	codec->scenegraph->Routes = backup_routes;
883 	return codec->LastError;
884 }
885 
886 
BM_ParseCommand(GF_BifsDecoder * codec,GF_BitStream * bs,GF_List * com_list)887 GF_Err BM_ParseCommand(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list)
888 {
889 	u8 go, type;
890 	GF_Err e;
891 	go = 1;
892 	e = GF_OK;
893 
894 	codec->LastError = GF_OK;
895 	while (go) {
896 		type = gf_bs_read_int(bs, 2);
897 		switch (type) {
898 		case 0:
899 			e = BM_ParseInsert(codec, bs, com_list);
900 			break;
901 		case 1:
902 			e = BM_ParseDelete(codec, bs, com_list);
903 			break;
904 		case 2:
905 			e = BM_ParseReplace(codec, bs, com_list);
906 			break;
907 		case 3:
908 			e = BM_SceneReplace(codec, bs, com_list);
909 			break;
910 		}
911 		if (e) return e;
912 		go = gf_bs_read_int(bs, 1);
913 	}
914 	while (gf_list_count(codec->QPs)) {
915 		gf_bifs_dec_qp_remove(codec, GF_TRUE);
916 	}
917 	return GF_OK;
918 }
919 
BM_EndOfStream(void * co)920 void BM_EndOfStream(void *co)
921 {
922 	((GF_BifsDecoder *) co)->LastError = GF_IO_ERR;
923 }
924 
925 void gf_bs_set_eos_callback(GF_BitStream *bs, void (*EndOfStream)(void *par), void *par);
926 
927 
gf_bifs_flush_command_list(GF_BifsDecoder * codec)928 GF_Err gf_bifs_flush_command_list(GF_BifsDecoder *codec)
929 {
930 	GF_BitStream *bs;
931 	GF_Err e;
932 	CommandBufferItem *cbi;
933 	u32 NbPass = gf_list_count(codec->command_buffers);
934 	GF_List *nextPass = gf_list_new();
935 	while (NbPass) {
936 		while (gf_list_count(codec->command_buffers)) {
937 			cbi = (CommandBufferItem *)gf_list_get(codec->command_buffers, 0);
938 			gf_list_rem(codec->command_buffers, 0);
939 			codec->current_graph = gf_node_get_graph(cbi->node);
940 			e = GF_OK;
941 			if (cbi->cb->bufferSize) {
942 				bs = gf_bs_new((char*)cbi->cb->buffer, cbi->cb->bufferSize, GF_BITSTREAM_READ);
943 				gf_bs_set_eos_callback(bs, BM_EndOfStream, codec);
944 				e = BM_ParseCommand(codec, bs, cbi->cb->commandList);
945 				gf_bs_del(bs);
946 			}
947 			if (!e) {
948 				gf_free(cbi);
949 				continue;
950 			}
951 			/*this may be an error or a dependency pb - reset coimmand list and move to next pass*/
952 			while (gf_list_count(cbi->cb->commandList)) {
953 				u32 i;
954 				GF_CommandField *cf;
955 				GF_Command *com = (GF_Command *)gf_list_get(cbi->cb->commandList, 0);
956 				gf_list_rem(cbi->cb->commandList, 0);
957 				cf = (GF_CommandField *) gf_list_get(com->command_fields, 0);
958 				if (cf && cf->fieldType==GF_SG_VRML_SFCOMMANDBUFFER) {
959 					for (i=0; i<gf_list_count(codec->command_buffers); i++) {
960 						CommandBufferItem *cbi2 = (CommandBufferItem *)gf_list_get(codec->command_buffers, i);
961 						if (cbi2->cb == cf->field_ptr) {
962 							gf_free(cbi2);
963 							gf_list_rem(codec->command_buffers, i);
964 							i--;
965 						}
966 					}
967 				}
968 				gf_sg_command_del(com);
969 			}
970 			gf_list_add(nextPass, cbi);
971 		}
972 		if (!gf_list_count(nextPass)) break;
973 		/*prepare next pass*/
974 		while (gf_list_count(nextPass)) {
975 			cbi = (CommandBufferItem *)gf_list_get(nextPass, 0);
976 			gf_list_rem(nextPass, 0);
977 			gf_list_add(codec->command_buffers, cbi);
978 		}
979 		NbPass --;
980 		if (NbPass > gf_list_count(codec->command_buffers)) NbPass = gf_list_count(codec->command_buffers);
981 		codec->LastError = GF_OK;
982 	}
983 	gf_list_del(nextPass);
984 	return GF_OK;
985 }
986 
987 GF_EXPORT
gf_bifs_decode_command_list(GF_BifsDecoder * codec,u16 ESID,u8 * data,u32 data_length,GF_List * com_list)988 GF_Err gf_bifs_decode_command_list(GF_BifsDecoder *codec, u16 ESID, u8 *data, u32 data_length, GF_List *com_list)
989 {
990 	GF_BitStream *bs;
991 	GF_Err e;
992 
993 	if (!codec || !data || !codec->dec_memory_mode || !com_list) return GF_BAD_PARAM;
994 
995 	codec->info = gf_bifs_dec_get_stream(codec, ESID);
996 	if (!codec->info) return GF_BAD_PARAM;
997 	if (codec->info->config.elementaryMasks ) return GF_NOT_SUPPORTED;
998 
999 	/*root parse (not conditionals)*/
1000 	assert(codec->scenegraph);
1001 	/*setup current scene graph*/
1002 	codec->current_graph = codec->scenegraph;
1003 
1004 	codec->ActiveQP = (M_QuantizationParameter*) codec->scenegraph->global_qp;
1005 
1006 	bs = gf_bs_new(data, data_length, GF_BITSTREAM_READ);
1007 	gf_bs_set_eos_callback(bs, BM_EndOfStream, codec);
1008 
1009 	e = BM_ParseCommand(codec, bs, com_list);
1010 	gf_bs_del(bs);
1011 
1012 	/*decode conditionals / input sensors*/
1013 	if (!e) {
1014 		gf_bifs_flush_command_list(codec);
1015 	}
1016 	/*if err or not reset conditionals*/
1017 	while (gf_list_count(codec->command_buffers)) {
1018 		CommandBufferItem *cbi = (CommandBufferItem *)gf_list_get(codec->command_buffers, 0);
1019 		gf_free(cbi);
1020 		gf_list_rem(codec->command_buffers, 0);
1021 	}
1022 
1023 	/*reset current config*/
1024 	codec->info = NULL;
1025 	codec->current_graph = NULL;
1026 
1027 
1028 
1029 //	gf_mx_v(codec->mx);
1030 	return e;
1031 }
1032 
1033 #endif /*GPAC_DISABLE_BIFS*/
1034 
1035