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 #ifndef GPAC_DISABLE_BIFS_ENC
31 
32 GF_Err BE_EncProtoList(GF_BifsEncoder *codec, GF_List *protoList, GF_BitStream *bs);
33 
34 
gf_bifs_enc_name(GF_BifsEncoder * codec,GF_BitStream * bs,char * name)35 void gf_bifs_enc_name(GF_BifsEncoder *codec, GF_BitStream *bs, char *name)
36 {
37 	u32 i = 0;
38 	if (!name) {
39 		GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[BIFS] Coding IDs using names but no name is specified\n"));
40 		i = 1;
41 	} else {
42 		while (name[i]) {
43 			gf_bs_write_int(bs, name[i], 8);
44 			i++;
45 		}
46 	}
47 	gf_bs_write_int(bs, 0, 8);
48 	GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] DEF\t\t%d\t\t%s\n", 8*i, name));
49 }
50 
BE_XReplace(GF_BifsEncoder * codec,GF_Command * com,GF_BitStream * bs)51 static GF_Err BE_XReplace(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs)
52 {
53 	u32 i,nbBits;
54 	GF_FieldInfo field;
55 	GF_Err e;
56 	GF_CommandField *inf;
57 	if (!gf_list_count(com->command_fields)) return GF_BAD_PARAM;
58 	inf = (GF_CommandField *)gf_list_get(com->command_fields, 0);
59 
60 
61 	gf_bs_write_int(bs, gf_node_get_id(com->node)-1, codec->info->config.NodeIDBits);
62 	nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1);
63 	gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &i);
64 	GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "field", NULL);
65 
66 	gf_node_get_field(com->node, inf->fieldIndex, &field);
67 	if (!gf_sg_vrml_is_sf_field(field.fieldType)) {
68 		if ((inf->pos != -2) || com->toNodeID) {
69 			GF_BIFS_WRITE_INT(codec, bs, 1, 1, "indexedReplacement", NULL);
70 			if (com->toNodeID) {
71 				GF_Node *n = gf_bifs_enc_find_node(codec, com->toNodeID);
72 				GF_BIFS_WRITE_INT(codec, bs, 1, 1, "dynamicIndex", NULL);
73 				GF_BIFS_WRITE_INT(codec, bs, com->toNodeID-1, codec->info->config.NodeIDBits, "idxNodeID", NULL);
74 				nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_DEF)-1);
75 				gf_bifs_field_index_by_mode(n, com->toFieldIndex, GF_SG_FIELD_CODING_DEF, &i);
76 				GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "idxField", NULL);
77 			} else {
78 				GF_BIFS_WRITE_INT(codec, bs, 0, 1, "dynamicIndex", NULL);
79 				if (inf->pos==-1) {
80 					GF_BIFS_WRITE_INT(codec, bs, 3, 2, "replacementPosition", NULL);
81 				} else if (inf->pos==0) {
82 					GF_BIFS_WRITE_INT(codec, bs, 2, 2, "replacementPosition", NULL);
83 				} else {
84 					GF_BIFS_WRITE_INT(codec, bs, 0, 2, "replacementPosition", NULL);
85 					GF_BIFS_WRITE_INT(codec, bs, inf->pos, 16, "position", NULL);
86 				}
87 			}
88 		} else {
89 			GF_BIFS_WRITE_INT(codec, bs, 0, 1, "indexedReplacement", NULL);
90 		}
91 	}
92 	if (field.fieldType==GF_SG_VRML_MFNODE) {
93 		if (com->ChildNodeTag) {
94 			GF_Node *n;
95 			if (com->ChildNodeTag>0) {
96 				n = gf_node_new(codec->scene_graph, com->ChildNodeTag);
97 			} else {
98 				GF_Proto *proto = gf_sg_find_proto(codec->scene_graph, -com->ChildNodeTag , NULL);
99 				if (!proto) return GF_SG_UNKNOWN_NODE;
100 				n = gf_sg_proto_create_instance(codec->scene_graph, proto);
101 			}
102 			if (!n) return GF_SG_UNKNOWN_NODE;
103 			gf_node_register(n, NULL);
104 
105 			GF_BIFS_WRITE_INT(codec, bs, 1, 1, "childField", NULL);
106 
107 			nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_IN)-1);
108 			gf_bifs_field_index_by_mode(n, com->child_field, GF_SG_FIELD_CODING_IN, &i);
109 			GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "childField", NULL);
110 			gf_node_unregister(n, NULL);
111 		} else {
112 			GF_BIFS_WRITE_INT(codec, bs, 0, 1, "childField", NULL);
113 		}
114 	}
115 	if (com->fromNodeID) {
116 		GF_Node *n = gf_bifs_enc_find_node(codec, com->fromNodeID);
117 		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "valueFromNode", NULL);
118 
119 		GF_BIFS_WRITE_INT(codec, bs, com->fromNodeID-1, codec->info->config.NodeIDBits, "sourceNodeID", NULL);
120 		nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_DEF)-1);
121 		gf_bifs_field_index_by_mode(n, com->fromFieldIndex, GF_SG_FIELD_CODING_DEF, &i);
122 		GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "sourceField", NULL);
123 
124 		return GF_OK;
125 	}
126 
127 	GF_BIFS_WRITE_INT(codec, bs, 0, 1, "valueFromNode", NULL);
128 
129 	field.far_ptr = inf->field_ptr;
130 	field.fieldType = inf->fieldType;
131 	e = gf_bifs_enc_field(codec, bs, com->node, &field);
132 	return e;
133 }
134 
BE_MultipleIndexedReplace(GF_BifsEncoder * codec,GF_Command * com,GF_BitStream * bs)135 static GF_Err BE_MultipleIndexedReplace(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs)
136 {
137 	u32 i,nbBits, count, maxPos, nbBitsPos;
138 	GF_FieldInfo field;
139 	GF_Err e;
140 	GF_CommandField *inf;
141 	if (!gf_list_count(com->command_fields)) return GF_OK;
142 	inf = (GF_CommandField *)gf_list_get(com->command_fields, 0);
143 
144 
145 	gf_bs_write_int(bs, gf_node_get_id(com->node)-1, codec->info->config.NodeIDBits);
146 	nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1);
147 	gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &i);
148 	GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "field", NULL);
149 
150 	gf_node_get_field(com->node, inf->fieldIndex, &field);
151 	field.fieldType = inf->fieldType;
152 
153 	count = gf_list_count(com->command_fields);
154 	maxPos = 0;
155 	for (i=0; i<count; i++) {
156 		inf = (GF_CommandField *)gf_list_get(com->command_fields, i);
157 		if (maxPos < (u32) inf->pos) maxPos = inf->pos;
158 	}
159 	nbBitsPos = gf_get_bit_size(maxPos);
160 	GF_BIFS_WRITE_INT(codec, bs, nbBitsPos, 5, "nbBitsPos", NULL);
161 
162 	nbBits = gf_get_bit_size(count);
163 	GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL);
164 	GF_BIFS_WRITE_INT(codec, bs, count, nbBits, "count", NULL);
165 
166 	for (i=0; i<count; i++) {
167 		inf = (GF_CommandField *)gf_list_get(com->command_fields, i);
168 		GF_BIFS_WRITE_INT(codec, bs, inf->pos, nbBitsPos, "idx", NULL);
169 		field.far_ptr = inf->field_ptr;
170 		e = gf_bifs_enc_field(codec, bs, com->node, &field);
171 		if (e) return e;
172 	}
173 	return GF_OK;
174 }
175 
BE_MultipleReplace(GF_BifsEncoder * codec,GF_Command * com,GF_BitStream * bs)176 static GF_Err BE_MultipleReplace(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs)
177 {
178 	u32 i, j, nbBits, count, numFields, allField;
179 	Bool use_list;
180 	GF_FieldInfo field;
181 	GF_Err e;
182 
183 	gf_bs_write_int(bs, gf_node_get_id(com->node)-1, codec->info->config.NodeIDBits);
184 
185 	count = gf_list_count(com->command_fields);
186 	use_list = GF_TRUE;
187 	numFields = gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_DEF);
188 	nbBits = gf_get_bit_size(numFields - 1);
189 	if (count < 1+count*(1+nbBits)) use_list = GF_FALSE;
190 	GF_BIFS_WRITE_INT(codec, bs, use_list ? 0 : 1, 1, "isMask", NULL);
191 
192 	for (i=0; i<numFields; i++) {
193 		GF_CommandField *inf = NULL;
194 		gf_bifs_get_field_index(com->node, i, GF_SG_FIELD_CODING_DEF, &allField);
195 		for (j=0; j<count; j++) {
196 			inf = (GF_CommandField *)gf_list_get(com->command_fields, j);
197 			if (inf->fieldIndex==allField) break;
198 			inf = NULL;
199 		}
200 		if (!inf) {
201 			if (!use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "Mask", NULL);
202 			continue;
203 		}
204 		/*common case*/
205 		gf_node_get_field(com->node, inf->fieldIndex, &field);
206 		if (use_list) {
207 			/*not end flag*/
208 			GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL);
209 		} else {
210 			/*mask flag*/
211 			GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL);
212 		}
213 		if (use_list) GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "field", (char*)field.name);
214 		field.far_ptr = inf->field_ptr;
215 		e = gf_bifs_enc_field(codec, bs, com->node, &field);
216 		if (e) return e;
217 	}
218 	/*end flag*/
219 	if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);
220 	return GF_OK;
221 }
222 
BE_GlobalQuantizer(GF_BifsEncoder * codec,GF_Command * com,GF_BitStream * bs)223 static GF_Err BE_GlobalQuantizer(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs)
224 {
225 	GF_Err e;
226 	GF_CommandField *inf;
227 	if (!gf_list_count(com->command_fields)) return GF_OK;
228 	inf = (GF_CommandField *)gf_list_get(com->command_fields, 0);
229 	if (inf->new_node) ((M_QuantizationParameter *)inf->new_node)->isLocal = 0;
230 	e = gf_bifs_enc_node(codec, inf->new_node, NDT_SFWorldNode, bs, NULL);
231 	if (e) return e;
232 
233 	/*reset global QP*/
234 	if (codec->scene_graph->global_qp) {
235 		gf_node_unregister(codec->scene_graph->global_qp, NULL);
236 		codec->scene_graph->global_qp = NULL;
237 	}
238 	codec->ActiveQP = NULL;
239 
240 	/*no QP*/
241 	if (!inf->new_node) return GF_OK;
242 
243 	/*register global QP*/
244 	codec->scene_graph->global_qp = inf->new_node;
245 	gf_node_register(inf->new_node, NULL);
246 	codec->ActiveQP = (M_QuantizationParameter *) inf->new_node;
247 	codec->ActiveQP->isLocal = 0;
248 	return GF_OK;
249 }
250 
BE_EncProtoDelete(GF_BifsEncoder * codec,GF_Command * com,GF_BitStream * bs)251 static GF_Err BE_EncProtoDelete(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs)
252 {
253 	u32 nbBits, i;
254 	Bool use_list = GF_FALSE;
255 	nbBits = gf_get_bit_size(com->del_proto_list_size);
256 	if (nbBits+5>com->del_proto_list_size) use_list = GF_TRUE;
257 	GF_BIFS_WRITE_INT(codec, bs, use_list, 1, "isList", NULL);
258 	if (!use_list) {
259 		GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "len", NULL);
260 		GF_BIFS_WRITE_INT(codec, bs, com->del_proto_list_size, nbBits, "len", NULL);
261 	}
262 	for (i=0; i<com->del_proto_list_size; i++) {
263 		if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "moreProto", NULL);
264 		GF_BIFS_WRITE_INT(codec, bs, com->del_proto_list[i], codec->info->config.ProtoIDBits, "protoID", NULL);
265 	}
266 	if (use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreProto", NULL);
267 	return GF_OK;
268 }
269 
BE_ExtendedUpdate(GF_BifsEncoder * codec,GF_Command * com,GF_BitStream * bs)270 static GF_Err BE_ExtendedUpdate(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs)
271 {
272 	GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Insert", NULL);
273 	GF_BIFS_WRITE_INT(codec, bs, 1, 2, "ExtendedUpdate", NULL);
274 	switch (com->tag) {
275 	case GF_SG_PROTO_INSERT:
276 		GF_BIFS_WRITE_INT(codec, bs, 0, 8, "MultipleReplace", NULL);
277 		return BE_EncProtoList(codec, com->new_proto_list, bs);
278 	case GF_SG_PROTO_DELETE:
279 		GF_BIFS_WRITE_INT(codec, bs, 1, 8, "ProtoDelete", NULL);
280 		return BE_EncProtoDelete(codec, com, bs);
281 	case GF_SG_PROTO_DELETE_ALL:
282 		GF_BIFS_WRITE_INT(codec, bs, 2, 8, "DeleteAllProtos", NULL);
283 		return GF_OK;
284 	case GF_SG_MULTIPLE_INDEXED_REPLACE:
285 		GF_BIFS_WRITE_INT(codec, bs, 3, 8, "MultipleReplace", NULL);
286 		return BE_MultipleIndexedReplace(codec, com, bs);
287 	case GF_SG_MULTIPLE_REPLACE:
288 		GF_BIFS_WRITE_INT(codec, bs, 4, 8, "MultipleReplace", NULL);
289 		return BE_MultipleReplace(codec, com, bs);
290 	case GF_SG_GLOBAL_QUANTIZER:
291 		GF_BIFS_WRITE_INT(codec, bs, 5, 8, "GlobalQuantizer", NULL);
292 		return BE_GlobalQuantizer(codec, com, bs);
293 	case GF_SG_NODE_DELETE_EX:
294 		GF_BIFS_WRITE_INT(codec, bs, 6, 8, "MultipleReplace", NULL);
295 		GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL);
296 		return GF_OK;
297 	case GF_SG_XREPLACE:
298 		GF_BIFS_WRITE_INT(codec, bs, 7, 8, "XReplace", NULL);
299 		return BE_XReplace(codec, com, bs);
300 	default:
301 		return GF_BAD_PARAM;
302 	}
303 }
304 
305 /*inserts a node in a container (node.children)*/
BE_NodeInsert(GF_BifsEncoder * codec,GF_Command * com,GF_BitStream * bs)306 GF_Err BE_NodeInsert(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs)
307 {
308 	u32 NDT;
309 	GF_CommandField *inf;
310 	if (!gf_list_count(com->command_fields)) return GF_OK;
311 	inf = (GF_CommandField *)gf_list_get(com->command_fields, 0);
312 
313 	GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL);
314 
315 	NDT = gf_bifs_get_child_table(com->node);
316 
317 	switch (inf->pos) {
318 	case 0:
319 		GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FIRST", "idx");
320 		break;
321 	case -1:
322 		GF_BIFS_WRITE_INT(codec, bs, 3, 2, "LAST", "idx");
323 		break;
324 	default:
325 		GF_BIFS_WRITE_INT(codec, bs, 0, 2, "pos", "idx");
326 		GF_BIFS_WRITE_INT(codec, bs, inf->pos, 8, "pos", NULL);
327 		break;
328 	}
329 	return gf_bifs_enc_node(codec, inf->new_node, NDT, bs, NULL);
330 }
331 
BE_IndexInsert(GF_BifsEncoder * codec,GF_Command * com,GF_BitStream * bs)332 GF_Err BE_IndexInsert(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs)
333 {
334 	GF_Err e;
335 	u32 NumBits, ind;
336 	GF_FieldInfo field, sffield;
337 	GF_CommandField *inf;
338 	if (!gf_list_count(com->command_fields)) return GF_OK;
339 	inf = (GF_CommandField *)gf_list_get(com->command_fields, 0);
340 
341 	GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL);
342 
343 	/*index insertion uses IN mode for field index*/
344 	NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1);
345 	gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &ind);
346 	GF_BIFS_WRITE_INT(codec, bs, ind, NumBits, "field", NULL);
347 
348 	switch (inf->pos) {
349 	case 0:
350 		GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FIRST", "idx");
351 		break;
352 	case -1:
353 		GF_BIFS_WRITE_INT(codec, bs, 3, 2, "LAST", "idx");
354 		break;
355 	default:
356 		GF_BIFS_WRITE_INT(codec, bs, 0, 2, "pos", "idx");
357 		GF_BIFS_WRITE_INT(codec, bs, inf->pos, 16, "pos", NULL);
358 		break;
359 	}
360 	e = gf_node_get_field(com->node, inf->fieldIndex, &field);
361 	if (e) return e;
362 	if (gf_sg_vrml_is_sf_field(field.fieldType))
363 		return GF_NON_COMPLIANT_BITSTREAM;
364 
365 	memcpy(&sffield, &field, sizeof(GF_FieldInfo));
366 	sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
367 	sffield.far_ptr = inf->field_ptr;
368 
369 	/*rescale the MFField and parse the SFField*/
370 	if (field.fieldType==GF_SG_VRML_MFNODE) {
371 		return gf_bifs_enc_node(codec, inf->new_node, field.NDTtype, bs, com->node);
372 	} else {
373 		return gf_bifs_enc_sf_field(codec, bs, com->node, &sffield);
374 	}
375 }
376 
377 
BE_IndexDelete(GF_BifsEncoder * codec,GF_Command * com,GF_BitStream * bs)378 GF_Err BE_IndexDelete(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs)
379 {
380 	u32 NumBits, ind;
381 	GF_Err e;
382 	GF_CommandField *inf;
383 	if (!gf_list_count(com->command_fields)) return GF_OK;
384 	inf = (GF_CommandField *)gf_list_get(com->command_fields, 0);
385 
386 	GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL);
387 
388 	NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN) - 1);
389 	e = gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &ind);
390 	if (e) return e;
391 	GF_BIFS_WRITE_INT(codec, bs, ind, NumBits, "field", NULL);
392 
393 	switch (inf->pos) {
394 	case 0:
395 		GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FIRST", "idw");
396 		break;
397 	case -1:
398 		GF_BIFS_WRITE_INT(codec, bs, 3, 2, "LAST", "idx");
399 		break;
400 	default:
401 		GF_BIFS_WRITE_INT(codec, bs, 0, 2, "pos", "idx");
402 		GF_BIFS_WRITE_INT(codec, bs, inf->pos, 16, "pos", NULL);
403 		break;
404 	}
405 	return GF_OK;
406 }
407 
408 
BE_NodeReplace(GF_BifsEncoder * codec,GF_Command * com,GF_BitStream * bs)409 GF_Err BE_NodeReplace(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs)
410 {
411 	GF_Node *new_node = NULL;
412 	if (gf_list_count(com->command_fields)) {
413 		GF_CommandField *inf = (GF_CommandField *)gf_list_get(com->command_fields, 0);
414 		if (inf) new_node = inf->new_node;
415 	}
416 	GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL);
417 	return gf_bifs_enc_node(codec, new_node, NDT_SFWorldNode, bs, NULL);
418 }
419 
BE_FieldReplace(GF_BifsEncoder * codec,GF_Command * com,GF_BitStream * bs)420 GF_Err BE_FieldReplace(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs)
421 {
422 	GF_Err e;
423 	u32 ind, NumBits;
424 	GF_FieldInfo field;
425 	GF_CommandField *inf;
426 	if (!gf_list_count(com->command_fields)) return GF_OK;
427 	inf = (GF_CommandField *)gf_list_get(com->command_fields, 0);
428 
429 	GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL);
430 
431 	NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1);
432 	gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &ind);
433 	GF_BIFS_WRITE_INT(codec, bs, ind, NumBits, "field", NULL);
434 
435 	e = gf_node_get_field(com->node, inf->fieldIndex, &field);
436 	if (e) return e;
437 	field.far_ptr = inf->field_ptr;
438 
439 	/* Warning: To be changed when proper solution is found */
440 	if (gf_sg_vrml_get_sf_type(field.fieldType) == GF_SG_VRML_SFSCRIPT) codec->is_encoding_command = GF_TRUE;
441 
442 	e = gf_bifs_enc_field(codec, bs, com->node, &field);
443 
444 	codec->is_encoding_command = GF_FALSE;
445 	return e;
446 }
447 
BE_IndexFieldReplace(GF_BifsEncoder * codec,GF_Command * com,GF_BitStream * bs)448 GF_Err BE_IndexFieldReplace(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs)
449 {
450 	u32 ind, NumBits;
451 	GF_Err e;
452 	GF_FieldInfo field, sffield;
453 	GF_CommandField *inf;
454 	if (!gf_list_count(com->command_fields)) return GF_OK;
455 	inf = (GF_CommandField *)gf_list_get(com->command_fields, 0);
456 
457 	GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL);
458 	NumBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1);
459 	gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &ind);
460 	GF_BIFS_WRITE_INT(codec, bs, ind, NumBits, "field", NULL);
461 
462 	e = gf_node_get_field(com->node, inf->fieldIndex, &field);
463 	if (e) return e;
464 	if (gf_sg_vrml_is_sf_field(field.fieldType))
465 		return GF_NON_COMPLIANT_BITSTREAM;
466 
467 	switch (inf->pos) {
468 	case 0:
469 		GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FIRST", "idx");
470 		break;
471 	case -1:
472 		GF_BIFS_WRITE_INT(codec, bs, 3, 2, "LAST", "idx");
473 		break;
474 	default:
475 		GF_BIFS_WRITE_INT(codec, bs, 0, 2, "pos", "idx");
476 		GF_BIFS_WRITE_INT(codec, bs, inf->pos, 16, "pos", NULL);
477 		break;
478 	}
479 
480 	if (field.fieldType == GF_SG_VRML_MFNODE) {
481 		e = gf_bifs_enc_node(codec, inf->new_node, field.NDTtype, bs, com->node);
482 	} else {
483 		memcpy(&sffield, &field, sizeof(GF_FieldInfo));
484 		sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
485 		sffield.far_ptr = inf->field_ptr;
486 		e = gf_bifs_enc_sf_field(codec, bs, com->node, &sffield);
487 	}
488 	return e;
489 }
490 
BE_RouteReplace(GF_BifsEncoder * codec,GF_Command * com,GF_BitStream * bs,Bool isInsert)491 GF_Err BE_RouteReplace(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs, Bool isInsert)
492 {
493 	GF_Err e;
494 	GF_Node *n;
495 	u32 numBits, ind;
496 
497 	if (isInsert) {
498 		GF_BIFS_WRITE_INT(codec, bs, com->RouteID ? 1 : 0, 1, "isDEF", NULL);
499 		if (com->RouteID) {
500 			GF_BIFS_WRITE_INT(codec, bs, com->RouteID-1, codec->info->config.RouteIDBits, "RouteID", NULL);
501 			if (codec->UseName) gf_bifs_enc_name(codec, bs, com->def_name);
502 		}
503 	} else {
504 		GF_BIFS_WRITE_INT(codec, bs, com->RouteID - 1, codec->info->config.RouteIDBits, "RouteID", NULL);
505 	}
506 
507 	/*origin*/
508 	GF_BIFS_WRITE_INT(codec, bs, com->fromNodeID - 1, codec->info->config.NodeIDBits, "outNodeID", NULL);
509 	n = gf_bifs_enc_find_node(codec, com->fromNodeID);
510 	numBits = gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_OUT) - 1;
511 	numBits = gf_get_bit_size(numBits);
512 	e = gf_bifs_field_index_by_mode(n, com->fromFieldIndex, GF_SG_FIELD_CODING_OUT, &ind);
513 	if (e) return e;
514 	GF_BIFS_WRITE_INT(codec, bs, ind, numBits, "outField", NULL);
515 
516 	/*target*/
517 	GF_BIFS_WRITE_INT(codec, bs, com->toNodeID - 1, codec->info->config.NodeIDBits, "inNodeID", NULL);
518 	n = gf_bifs_enc_find_node(codec, com->toNodeID);
519 	numBits = gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_IN) - 1;
520 	numBits = gf_get_bit_size(numBits);
521 	e = gf_bifs_field_index_by_mode(n, com->toFieldIndex, GF_SG_FIELD_CODING_IN, &ind);
522 	GF_BIFS_WRITE_INT(codec, bs, ind, numBits, "inField", NULL);
523 	return e;
524 }
525 
526 
BE_EncProtoList(GF_BifsEncoder * codec,GF_List * protoList,GF_BitStream * bs)527 GF_Err BE_EncProtoList(GF_BifsEncoder *codec, GF_List *protoList, GF_BitStream *bs)
528 {
529 	u8 useQuant, useAnim;
530 	u32 i, j, nbRoutes, nbBits, numProtos, numFields, count;
531 	GF_Node *node;
532 	GF_ProtoFieldInterface *proto_field;
533 	GF_Proto *proto, *prev_proto;
534 	GF_Route *r;
535 	GF_Err e;
536 	GF_SceneGraph *rootSG;
537 	GF_FieldInfo field;
538 
539 	e = GF_OK;
540 	if (!protoList || !gf_list_count(protoList)) {
541 		GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreProto", NULL);
542 		return GF_OK;
543 	}
544 	if (!codec->info->config.ProtoIDBits)
545 		return GF_NON_COMPLIANT_BITSTREAM;
546 
547 	/*store state*/
548 	rootSG = codec->current_proto_graph;
549 	prev_proto = codec->encoding_proto;
550 
551 	numProtos = gf_list_count(protoList);
552 	for (i=0; i<numProtos; i++) {
553 		proto = (GF_Proto*)gf_list_get(protoList, i);
554 		useQuant = useAnim = 0;
555 		/*set current proto state*/
556 		codec->encoding_proto = proto;
557 		codec->current_proto_graph = proto->sub_graph;
558 
559 		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "moreProto", NULL);
560 
561 		/*1- proto interface declaration*/
562 		GF_BIFS_WRITE_INT(codec, bs, proto->ID, codec->info->config.ProtoIDBits, "protoID", NULL);
563 
564 		if (codec->UseName) gf_bifs_enc_name(codec, bs, proto->Name);
565 
566 		numFields = gf_list_count(proto->proto_fields);
567 		for (j=0; j<numFields; j++) {
568 			proto_field = (GF_ProtoFieldInterface*)gf_list_get(proto->proto_fields, j);
569 
570 			GF_BIFS_WRITE_INT(codec, bs, 1, 1, "moreField", NULL);
571 			GF_BIFS_WRITE_INT(codec, bs, proto_field->EventType, 2, "eventType", NULL);
572 			GF_BIFS_WRITE_INT(codec, bs, proto_field->FieldType, 6, "fieldType", NULL);
573 
574 			if (codec->UseName) gf_bifs_enc_name(codec, bs, proto_field->FieldName);
575 			switch (proto_field->EventType) {
576 			case GF_SG_EVENT_EXPOSED_FIELD:
577 			case GF_SG_EVENT_FIELD:
578 				gf_sg_proto_field_get_field(proto_field, &field);
579 				if (gf_sg_vrml_is_sf_field(field.fieldType)) {
580 					e = gf_bifs_enc_sf_field(codec, bs, NULL, &field);
581 				} else {
582 					if (codec->info->config.UsePredictiveMFField) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "usePredictive", NULL);
583 					e = gf_bifs_enc_mf_field(codec, bs, NULL, &field);
584 				}
585 				if (e) goto exit;
586 				break;
587 			}
588 			if (proto_field->QP_Type) useQuant = 1;
589 			if (proto_field->Anim_Type) useAnim = 1;
590 		}
591 		GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreField", NULL);
592 
593 		GF_BIFS_WRITE_INT(codec, bs, proto->ExternProto.count ? 1 : 0, 1, "externProto", NULL);
594 		/*externProto*/
595 		if (proto->ExternProto.count) {
596 			memset(&field, 0, sizeof(GF_FieldInfo));
597 			field.far_ptr = &proto->ExternProto;
598 			field.fieldType = GF_SG_VRML_MFURL;
599 			field.name = "ExternProto";
600 
601 			if (codec->info->config.UsePredictiveMFField) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "usePredictive", NULL);
602 			e = gf_bifs_enc_mf_field(codec, bs, NULL, &field);
603 			if (e) goto exit;
604 		} else {
605 			/*encode sub-proto list*/
606 			e = BE_EncProtoList(codec, proto->sub_graph->protos, bs);
607 			if (e) goto exit;
608 
609 			count = gf_list_count(proto->node_code);
610 			/*BIFS cannot encode empty protos ! We therefore encode a NULL node instead*/
611 			if (!count) {
612 				gf_bifs_enc_node(codec, NULL, NDT_SFWorldNode, bs, NULL);
613 				GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreNodes", NULL);
614 			} else {
615 				for (j=0; j<count; j++) {
616 					/*parse all nodes in SFWorldNode table*/
617 					node = (GF_Node*)gf_list_get(proto->node_code, j);
618 					e = gf_bifs_enc_node(codec, node, NDT_SFWorldNode, bs, NULL);
619 					if (e) goto exit;
620 					GF_BIFS_WRITE_INT(codec, bs, (j+1==count) ? 0 : 1, 1, "moreNodes", NULL);
621 				}
622 			}
623 
624 			/*encode routes routes*/
625 			nbRoutes = count = gf_list_count(proto->sub_graph->Routes);
626 			for (j=0; j<count; j++) {
627 				r = (GF_Route*)gf_list_get(proto->sub_graph->Routes, j);
628 				if (r->IS_route) nbRoutes--;
629 			}
630 
631 			GF_BIFS_WRITE_INT(codec, bs, nbRoutes ? 1 : 0, 1, "hasRoute", NULL);
632 			if (nbRoutes) {
633 				nbBits = gf_get_bit_size(nbRoutes);
634 				if (nbBits + 5 > nbRoutes) {
635 					GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL);
636 					/*list*/
637 					for (j=0; j<count; j++) {
638 						r = (GF_Route*)gf_list_get(proto->sub_graph->Routes, j);
639 						if (r->IS_route) continue;
640 						e = gf_bifs_enc_route(codec, r, bs);
641 						if (e) goto exit;
642 						nbRoutes--;
643 						GF_BIFS_WRITE_INT(codec, bs, nbRoutes ? 1 : 0, 1, "moreRoute", NULL);
644 					}
645 				} else {
646 					GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isList", NULL);
647 					GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL);
648 					GF_BIFS_WRITE_INT(codec, bs, nbRoutes, nbBits, "length", NULL);
649 					for (j=0; j<count; j++) {
650 						r = (GF_Route*)gf_list_get(proto->sub_graph->Routes, j);
651 						if (r->IS_route) continue;
652 						e = gf_bifs_enc_route(codec, r, bs);
653 						if (e) goto exit;
654 					}
655 				}
656 			}
657 		}
658 
659 		/*anim and Quantization stuff*/
660 		GF_BIFS_WRITE_INT(codec, bs, useQuant, 1, "useQuant", NULL);
661 		GF_BIFS_WRITE_INT(codec, bs, useAnim, 1, "useAnim", NULL);
662 
663 		if (!useAnim && !useQuant) continue;
664 
665 		count = gf_sg_proto_get_field_count(proto);
666 		for (j=0; j<count; j++) {
667 			proto_field = gf_sg_proto_field_find(proto, j);
668 			gf_sg_proto_field_get_field(proto_field, &field);
669 
670 			/*quant*/
671 			if (useQuant && ( (field.eventType == GF_SG_EVENT_FIELD) || (field.eventType == GF_SG_EVENT_EXPOSED_FIELD) )) {
672 				GF_BIFS_WRITE_INT(codec, bs, proto_field->QP_Type, 4, "QPType", NULL);
673 				if (proto_field->QP_Type==QC_LINEAR_SCALAR) GF_BIFS_WRITE_INT(codec, bs, proto_field->NumBits, 5, "nbBits", NULL);
674 				GF_BIFS_WRITE_INT(codec, bs, proto_field->hasMinMax, 1, "hasMinMax", NULL);
675 				if (proto_field->hasMinMax) {
676 					field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType);
677 					switch (field.fieldType) {
678 					case GF_SG_VRML_SFINT32:
679 					case GF_SG_VRML_SFTIME:
680 						break;
681 					default:
682 						field.fieldType = GF_SG_VRML_SFFLOAT;
683 						break;
684 					}
685 					field.name = "QPMinValue";
686 					field.far_ptr = proto_field->qp_min_value;
687 					gf_bifs_enc_sf_field(codec, bs, NULL, &field);
688 
689 					field.name = "QPMaxValue";
690 					field.far_ptr = proto_field->qp_max_value;
691 					gf_bifs_enc_sf_field(codec, bs, NULL, &field);
692 				}
693 			}
694 
695 			/*anim - not supported yet*/
696 			if (useAnim && ( (field.eventType == GF_SG_EVENT_IN) || (field.eventType == GF_SG_EVENT_EXPOSED_FIELD) )) {
697 				e = GF_NOT_SUPPORTED;
698 				goto exit;
699 			}
700 		}
701 	}
702 	GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreProto", NULL);
703 
704 exit:
705 	/*restore scene graph state*/
706 	codec->encoding_proto = prev_proto;
707 	codec->current_proto_graph = rootSG;
708 	return e;
709 }
710 
711 
712 
gf_bifs_enc_route(GF_BifsEncoder * codec,GF_Route * r,GF_BitStream * bs)713 GF_Err gf_bifs_enc_route(GF_BifsEncoder *codec, GF_Route *r, GF_BitStream *bs)
714 {
715 	GF_Err e;
716 	u32 numBits, ind;
717 
718 	if (!r) return GF_BAD_PARAM;
719 
720 	GF_BIFS_WRITE_INT(codec, bs, r->ID ? 1: 0, 1, "isDEF", NULL);
721 	/*def'ed route*/
722 	if (r->ID) {
723 		GF_BIFS_WRITE_INT(codec, bs, r->ID-1, codec->info->config.RouteIDBits, "routeID", NULL);
724 		if (codec->UseName) gf_bifs_enc_name(codec, bs, r->name);
725 	}
726 	/*origin*/
727 	GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(r->FromNode) - 1, codec->info->config.NodeIDBits, "outNodeID", NULL);
728 	numBits = gf_node_get_num_fields_in_mode(r->FromNode, GF_SG_FIELD_CODING_OUT) - 1;
729 	numBits = gf_get_bit_size(numBits);
730 	e = gf_bifs_field_index_by_mode(r->FromNode, r->FromField.fieldIndex, GF_SG_FIELD_CODING_OUT, &ind);
731 	if (e) return e;
732 	GF_BIFS_WRITE_INT(codec, bs, ind, numBits, "outField", NULL);
733 
734 	/*target*/
735 	GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(r->ToNode) - 1, codec->info->config.NodeIDBits, "inNodeID", NULL);
736 	numBits = gf_node_get_num_fields_in_mode(r->ToNode, GF_SG_FIELD_CODING_IN) - 1;
737 	numBits = gf_get_bit_size(numBits);
738 	e = gf_bifs_field_index_by_mode(r->ToNode, r->ToField.fieldIndex, GF_SG_FIELD_CODING_IN, &ind);
739 	GF_BIFS_WRITE_INT(codec, bs, ind, numBits, "inField", NULL);
740 	return e;
741 }
742 
BE_SceneReplaceEx(GF_BifsEncoder * codec,GF_Command * com,GF_BitStream * bs,GF_List * routes)743 GF_Err BE_SceneReplaceEx(GF_BifsEncoder *codec, GF_Command *com, GF_BitStream *bs, GF_List *routes)
744 {
745 	u32 i, nbR, nbBits;
746 	GF_Err e;
747 
748 	/*reserved*/
749 	GF_BIFS_WRITE_INT(codec, bs, 0, 6, "reserved", NULL);
750 	GF_BIFS_WRITE_INT(codec, bs, codec->UseName ? 1 : 0, 1, "useName", NULL);
751 
752 	if (gf_list_count(com->new_proto_list)) {
753 		e = BE_EncProtoList(codec, com->new_proto_list, bs);
754 		if (e) goto exit;
755 	} else {
756 		e = BE_EncProtoList(codec, com->in_scene->protos, bs);
757 		if (e) goto exit;
758 	}
759 
760 	/*NULL root is valid for ProtoLibraries*/
761 	e = gf_bifs_enc_node(codec, com->node, NDT_SFTopNode, bs, NULL);
762 	if (e || !gf_list_count(routes) ) {
763 		GF_BIFS_WRITE_INT(codec, bs, 0, 1, "hasRoute", NULL);
764 		return codec->LastError = e;
765 	}
766 	GF_BIFS_WRITE_INT(codec, bs, 1, 1, "hasRoute", NULL);
767 	nbR = gf_list_count(routes);
768 	nbBits = gf_get_bit_size(nbR);
769 	if (nbBits + 5 > nbR) {
770 		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL);
771 		/*list*/
772 		for (i=0; i<nbR; i++) {
773 			e = gf_bifs_enc_route(codec, (GF_Route*)gf_list_get(routes, i), bs);
774 			if (e) goto exit;
775 			GF_BIFS_WRITE_INT(codec, bs, (i+1==nbR) ? 0 : 1, 1, "moreRoute", NULL);
776 		}
777 	} else {
778 		GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isList", NULL);
779 		GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL);
780 		GF_BIFS_WRITE_INT(codec, bs, nbR, nbBits, "nbRoutes", NULL);
781 		for (i=0; i<nbR; i++) {
782 			e = gf_bifs_enc_route(codec, (GF_Route*)gf_list_get(routes, i), bs);
783 			if (e) goto exit;
784 		}
785 	}
786 
787 exit:
788 	return codec->LastError = e;
789 }
790 
791 
BE_SceneReplace(GF_BifsEncoder * codec,GF_SceneGraph * graph,GF_BitStream * bs)792 GF_Err BE_SceneReplace(GF_BifsEncoder *codec, GF_SceneGraph *graph, GF_BitStream *bs)
793 {
794 	u32 i, nbR, nbBits;
795 	GF_Err e;
796 
797 	/*reserved*/
798 	GF_BIFS_WRITE_INT(codec, bs, 0, 6, "reserved", NULL);
799 	GF_BIFS_WRITE_INT(codec, bs, codec->UseName ? 1 : 0, 1, "useName", NULL);
800 
801 	/*assign current graph*/
802 	codec->scene_graph = graph;
803 
804 	e = BE_EncProtoList(codec, codec->scene_graph ? codec->scene_graph->protos : NULL, bs);
805 	if (e) goto exit;
806 
807 	/*NULL root is valid for ProtoLibraries*/
808 	e = gf_bifs_enc_node(codec, graph ? graph->RootNode : NULL, NDT_SFTopNode, bs, NULL);
809 	if (e || !graph || !gf_list_count(graph->Routes) ) {
810 		GF_BIFS_WRITE_INT(codec, bs, 0, 1, "hasRoute", NULL);
811 		return codec->LastError = e;
812 	}
813 	GF_BIFS_WRITE_INT(codec, bs, 1, 1, "hasRoute", NULL);
814 	nbR = gf_list_count(graph->Routes);
815 	nbBits = gf_get_bit_size(nbR);
816 	if (nbBits + 5 > nbR) {
817 		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL);
818 		/*list*/
819 		for (i=0; i<nbR; i++) {
820 			e = gf_bifs_enc_route(codec, (GF_Route*)gf_list_get(graph->Routes, i), bs);
821 			if (e) goto exit;
822 			GF_BIFS_WRITE_INT(codec, bs, (i+1==nbR) ? 0 : 1, 1, "moreRoute", NULL);
823 		}
824 	} else {
825 		GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isList", NULL);
826 		GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL);
827 		GF_BIFS_WRITE_INT(codec, bs, nbR, nbBits, "nbRoutes", NULL);
828 		for (i=0; i<nbR; i++) {
829 			e = gf_bifs_enc_route(codec, (GF_Route*)gf_list_get(graph->Routes, i), bs);
830 			if (e) goto exit;
831 		}
832 	}
833 
834 exit:
835 	return codec->LastError = e;
836 }
837 
838 
gf_bifs_enc_commands(GF_BifsEncoder * codec,GF_List * comList,GF_BitStream * bs)839 GF_Err gf_bifs_enc_commands(GF_BifsEncoder *codec, GF_List *comList, GF_BitStream *bs)
840 {
841 	u32 i;
842 	u32 count;
843 	GF_List *routes;
844 	GF_Err e = GF_OK;
845 
846 	routes = NULL;
847 
848 	codec->LastError = GF_OK;
849 	count = gf_list_count(comList);
850 
851 	for (i=0; i<count; i++) {
852 		GF_Command *com = (GF_Command*)gf_list_get(comList, i);
853 		switch (com->tag) {
854 		case GF_SG_SCENE_REPLACE:
855 		{
856 			/*reset node context*/
857 			while (gf_list_count(codec->encoded_nodes)) gf_list_rem(codec->encoded_nodes, 0);
858 			GF_BIFS_WRITE_INT(codec, bs, 3, 2, "SceneReplace", NULL);
859 
860 			if (!com->aggregated) {
861 				routes = gf_list_new();
862 				/*now the trick: get all following InsertRoutes and convert as routes*/
863 				for (; i<count-1; i++) {
864 					GF_Route *r;
865 					GF_Command *rcom = (GF_Command*)gf_list_get(comList, i+1);
866 					if (rcom->tag!=GF_SG_ROUTE_INSERT) break;
867 					GF_SAFEALLOC(r, GF_Route);
868 					if (!r) {
869 						GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot allocate route\n"));
870 						continue;
871 					}
872 					r->FromField.fieldIndex = rcom->fromFieldIndex;
873 					r->FromNode = gf_sg_find_node(codec->scene_graph, rcom->fromNodeID);
874 					r->ToField.fieldIndex = rcom->toFieldIndex;
875 					r->ToNode = gf_sg_find_node(codec->scene_graph, rcom->toNodeID);
876 					r->ID = rcom->RouteID;
877 					r->name = rcom->def_name;
878 					gf_list_add(routes, r);
879 				}
880 				e = BE_SceneReplaceEx(codec, com, bs, routes);
881 
882 				while (gf_list_count(routes)) {
883 					GF_Route *r = (GF_Route*)gf_list_get(routes, 0);
884 					gf_list_rem(routes, 0);
885 					gf_free(r);
886 				}
887 				gf_list_del(routes);
888 			} else {
889 				e = BE_SceneReplaceEx(codec, com, bs, codec->scene_graph->Routes);
890 			}
891 		}
892 		break;
893 		/*replace commands*/
894 		case GF_SG_NODE_REPLACE:
895 			GF_BIFS_WRITE_INT(codec, bs, 2, 2, "Replace", NULL);
896 			GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Node", NULL);
897 			e = BE_NodeReplace(codec, com, bs);
898 			break;
899 		case GF_SG_FIELD_REPLACE:
900 			GF_BIFS_WRITE_INT(codec, bs, 2, 2, "Replace", NULL);
901 			GF_BIFS_WRITE_INT(codec, bs, 1, 2, "Field", NULL);
902 			e = BE_FieldReplace(codec, com, bs);
903 			break;
904 		case GF_SG_INDEXED_REPLACE:
905 			GF_BIFS_WRITE_INT(codec, bs, 2, 2, "Replace", NULL);
906 			GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FieldIndex", NULL);
907 			e = BE_IndexFieldReplace(codec, com, bs);
908 			break;
909 		case GF_SG_ROUTE_REPLACE:
910 			GF_BIFS_WRITE_INT(codec, bs, 2, 2, "Replace", NULL);
911 			GF_BIFS_WRITE_INT(codec, bs, 3, 2, "Route", NULL);
912 			e = BE_RouteReplace(codec, com, bs, GF_FALSE);
913 			break;
914 		case GF_SG_NODE_INSERT:
915 			GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Insert", NULL);
916 			GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Node", NULL);
917 			e = BE_NodeInsert(codec, com, bs);
918 			break;
919 		case GF_SG_INDEXED_INSERT:
920 			GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Insert", NULL);
921 			GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FieldIndex", NULL);
922 			e = BE_IndexInsert(codec, com, bs);
923 			break;
924 		case GF_SG_ROUTE_INSERT:
925 			GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Insert", NULL);
926 			GF_BIFS_WRITE_INT(codec, bs, 3, 2, "Route", NULL);
927 			e = BE_RouteReplace(codec, com, bs, GF_TRUE);
928 			break;
929 		case GF_SG_NODE_DELETE:
930 			GF_BIFS_WRITE_INT(codec, bs, 1, 2, "Delete", NULL);
931 			GF_BIFS_WRITE_INT(codec, bs, 0, 2, "Node", NULL);
932 			GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL);
933 			break;
934 		case GF_SG_INDEXED_DELETE:
935 			GF_BIFS_WRITE_INT(codec, bs, 1, 2, "Delete", NULL);
936 			GF_BIFS_WRITE_INT(codec, bs, 2, 2, "FieldIndex", NULL);
937 			e = BE_IndexDelete(codec, com, bs);
938 			break;
939 		case GF_SG_ROUTE_DELETE:
940 			GF_BIFS_WRITE_INT(codec, bs, 1, 2, "Delete", NULL);
941 			GF_BIFS_WRITE_INT(codec, bs, 3, 2, "Route", NULL);
942 			GF_BIFS_WRITE_INT(codec, bs, com->RouteID - 1, codec->info->config.RouteIDBits, "RouteID", NULL);
943 			break;
944 
945 		default:
946 			e = BE_ExtendedUpdate(codec, com, bs);
947 			break;
948 		}
949 		if (e) break;
950 
951 		GF_BIFS_WRITE_INT(codec, bs, (i+1==count) ? 0 : 1, 1, "moreCommands", NULL);
952 	}
953 
954 	while (gf_list_count(codec->QPs)) gf_bifs_enc_qp_remove(codec, GF_TRUE);
955 	return e;
956 }
957 
958 
959 GF_EXPORT
gf_bifs_encoder_get_rap(GF_BifsEncoder * codec,u8 ** out_data,u32 * out_data_length)960 GF_Err gf_bifs_encoder_get_rap(GF_BifsEncoder *codec, u8 **out_data, u32 *out_data_length)
961 {
962 	GF_BitStream *bs;
963 	GF_Err e;
964 	GF_List *ctx_bck;
965 
966 	/*reset context for RAP encoding*/
967 	ctx_bck = codec->encoded_nodes;
968 	codec->encoded_nodes = gf_list_new();
969 
970 	if (!codec->info) codec->info = (BIFSStreamInfo*)gf_list_get(codec->streamInfo, 0);
971 
972 	bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
973 	GF_BIFS_WRITE_INT(codec, bs, 3, 2, "SceneReplace", NULL);
974 	e = BE_SceneReplace(codec, codec->scene_graph, bs);
975 	if (e == GF_OK) {
976 		GF_BIFS_WRITE_INT(codec, bs, 0, 1, "moreCommands", NULL);
977 		gf_bs_get_content(bs, out_data, out_data_length);
978 	}
979 	gf_bs_del(bs);
980 
981 	/*restore context*/
982 	gf_list_del(codec->encoded_nodes);
983 	codec->encoded_nodes = ctx_bck;
984 
985 	return e;
986 }
987 
988 #endif	/*GPAC_DISABLE_BIFS_ENC*/
989