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
28 #include <gpac/internal/bifs_dev.h>
29 #include <gpac/scene_manager.h>
30 #include "quant.h"
31 #include "script.h"
32
33 #ifndef GPAC_DISABLE_BIFS
34
SFCommandBufferChanged(GF_BifsDecoder * codec,GF_Node * node)35 void SFCommandBufferChanged(GF_BifsDecoder * codec, GF_Node *node)
36 {
37 void Conditional_BufferReplaced(GF_BifsDecoder * codec, GF_Node *node);
38
39 switch (gf_node_get_tag(node)) {
40 case TAG_MPEG4_Conditional:
41 Conditional_BufferReplaced(codec, node);
42 break;
43 }
44 }
45
46
47 //startTimes, stopTimes and co are coded as relative to their AU timestamp when received
48 //on the wire. If from scripts or within proto the offset doesn't apply
BD_OffsetSFTime(GF_BifsDecoder * codec,Double * time)49 void BD_OffsetSFTime(GF_BifsDecoder * codec, Double *time)
50 {
51 if ((!codec->is_com_dec && codec->pCurrentProto) || codec->dec_memory_mode) return;
52 *time += codec->cts_offset;
53 }
54
BD_CheckSFTimeOffset(GF_BifsDecoder * codec,GF_Node * node,GF_FieldInfo * inf)55 void BD_CheckSFTimeOffset(GF_BifsDecoder *codec, GF_Node *node, GF_FieldInfo *inf)
56 {
57 if (gf_node_get_tag(node) != TAG_ProtoNode) {
58 if (!stricmp(inf->name, "startTime") || !stricmp(inf->name, "stopTime"))
59 BD_OffsetSFTime(codec, (Double *)inf->far_ptr);
60 } else if (gf_sg_proto_field_is_sftime_offset(node, inf)) {
61 BD_OffsetSFTime(codec, (Double *)inf->far_ptr);
62 }
63 }
64
65
BD_ReadSFFloat(GF_BifsDecoder * codec,GF_BitStream * bs)66 Fixed BD_ReadSFFloat(GF_BifsDecoder * codec, GF_BitStream *bs)
67 {
68 if (codec->ActiveQP && codec->ActiveQP->useEfficientCoding)
69 return gf_bifs_dec_mantissa_float(codec, bs);
70
71 return FLT2FIX(gf_bs_read_float(bs));
72 }
73
74
gf_bifs_dec_sf_field(GF_BifsDecoder * codec,GF_BitStream * bs,GF_Node * node,GF_FieldInfo * field,Bool is_mem_com)75 GF_Err gf_bifs_dec_sf_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field, Bool is_mem_com)
76 {
77 GF_Err e;
78 GF_Node *new_node;
79 u32 size, length, w, h, i;
80 char *buffer;
81
82 //blindly call unquantize. return is OK, error or GF_EOS
83 if (codec->ActiveQP && node) {
84 e = gf_bifs_dec_unquant_field(codec, bs, node, field);
85 if (e != GF_EOS) return e;
86 }
87 //not quantized, use normal scheme
88 switch (field->fieldType) {
89 case GF_SG_VRML_SFBOOL:
90 * ((SFBool *) field->far_ptr) = (SFBool) gf_bs_read_int(bs, 1);
91 break;
92 case GF_SG_VRML_SFCOLOR:
93 ((SFColor *)field->far_ptr)->red = BD_ReadSFFloat(codec, bs);
94 ((SFColor *)field->far_ptr)->green = BD_ReadSFFloat(codec, bs);
95 ((SFColor *)field->far_ptr)->blue = BD_ReadSFFloat(codec, bs);
96 break;
97 case GF_SG_VRML_SFFLOAT:
98 *((SFFloat *)field->far_ptr) = BD_ReadSFFloat(codec, bs);
99 break;
100 case GF_SG_VRML_SFINT32:
101 *((SFInt32 *)field->far_ptr) = (s32) gf_bs_read_int(bs, 32);
102 break;
103 case GF_SG_VRML_SFTIME:
104 *((SFTime *)field->far_ptr) = gf_bs_read_double(bs);
105 if (node) BD_CheckSFTimeOffset(codec, node, field);
106 break;
107 case GF_SG_VRML_SFVEC2F:
108 ((SFVec2f *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs);
109 ((SFVec2f *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs);
110 break;
111 case GF_SG_VRML_SFVEC3F:
112 ((SFVec3f *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs);
113 ((SFVec3f *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs);
114 ((SFVec3f *)field->far_ptr)->z = BD_ReadSFFloat(codec, bs);
115 break;
116 case GF_SG_VRML_SFROTATION:
117 ((SFRotation *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs);
118 ((SFRotation *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs);
119 ((SFRotation *)field->far_ptr)->z = BD_ReadSFFloat(codec, bs);
120 ((SFRotation *)field->far_ptr)->q = BD_ReadSFFloat(codec, bs);
121 break;
122 case GF_SG_VRML_SFSTRING:
123 size = gf_bs_read_int(bs, 5);
124 length = gf_bs_read_int(bs, size);
125 if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM;
126
127 if (node && (node->sgprivate->tag==TAG_MPEG4_CacheTexture) && (field->fieldIndex<=2)) {
128 M_CacheTexture *ct = (M_CacheTexture *) node;
129 ct->data_len = length;
130 if (ct->data) gf_free(ct->data);
131 ct->data = (u8*)gf_malloc(sizeof(char)*length);
132 gf_bs_read_data(bs, (char*)ct->data, length);
133 } else if (node && (node->sgprivate->tag==TAG_MPEG4_BitWrapper) ) {
134 M_BitWrapper *bw = (M_BitWrapper*) node;
135 if (bw->buffer.buffer) gf_free(bw->buffer.buffer);
136 bw->buffer_len = length;
137 bw->buffer.buffer = (char*)gf_malloc(sizeof(char)*length);
138 gf_bs_read_data(bs, (char*)bw->buffer.buffer, length);
139 } else {
140 if ( ((SFString *)field->far_ptr)->buffer ) gf_free( ((SFString *)field->far_ptr)->buffer);
141 ((SFString *)field->far_ptr)->buffer = (char *)gf_malloc(sizeof(char)*(length+1));
142 memset(((SFString *)field->far_ptr)->buffer , 0, length+1);
143 for (i=0; i<length; i++) {
144 ((SFString *)field->far_ptr)->buffer[i] = gf_bs_read_int(bs, 8);
145 }
146 }
147 break;
148 case GF_SG_VRML_SFURL:
149 {
150 SFURL *url = (SFURL *) field->far_ptr;
151 size = gf_bs_read_int(bs, 1);
152 if (size) {
153 if (url->url) gf_free(url->url );
154 url->url = NULL;
155 length = gf_bs_read_int(bs, 10);
156 url->OD_ID = length;
157 } else {
158 if ( url->OD_ID ) url->OD_ID = (u32) -1;
159 size = gf_bs_read_int(bs, 5);
160 length = gf_bs_read_int(bs, size);
161 if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM;
162 buffer = NULL;
163 if (length) {
164 buffer = (char *)gf_malloc(sizeof(char)*(length+1));
165 memset(buffer, 0, length+1);
166 for (i=0; i<length; i++) buffer[i] = gf_bs_read_int(bs, 8);
167 }
168 if (url->url) gf_free( url->url);
169 /*if URL is empty set it to NULL*/
170 if (buffer && strlen(buffer)) {
171 url->url = buffer;
172 } else {
173 gf_free(buffer);
174 url->url = NULL;
175 }
176 }
177 }
178 break;
179 case GF_SG_VRML_SFIMAGE:
180 if (((SFImage *)field->far_ptr)->pixels) gf_free(((SFImage *)field->far_ptr)->pixels);
181 w = gf_bs_read_int(bs, 12);
182 h = gf_bs_read_int(bs, 12);
183 length = gf_bs_read_int(bs, 2);
184
185 if (length > 3) length = 3;
186 length += 1;
187 size = w * h * length;
188 if (gf_bs_available(bs) < size) return GF_NON_COMPLIANT_BITSTREAM;
189 ((SFImage *)field->far_ptr)->width = w;
190 ((SFImage *)field->far_ptr)->height = h;
191 ((SFImage *)field->far_ptr)->numComponents = length;
192 ((SFImage *)field->far_ptr)->pixels = (unsigned char *)gf_malloc(sizeof(char)*size);
193 //WARNING: Buffers are NOT ALIGNED IN THE BITSTREAM
194 for (i=0; i<size; i++) {
195 ((SFImage *)field->far_ptr)->pixels[i] = gf_bs_read_int(bs, 8);
196 }
197 break;
198 case GF_SG_VRML_SFCOMMANDBUFFER:
199 {
200 SFCommandBuffer *sfcb = (SFCommandBuffer *)field->far_ptr;
201 if (!node) return GF_BAD_PARAM;
202 if (sfcb->buffer) {
203 gf_free(sfcb->buffer);
204 sfcb->buffer = NULL;
205 }
206 while (gf_list_count(sfcb->commandList)) {
207 GF_Command *com = (GF_Command*)gf_list_get(sfcb->commandList, 0);
208 gf_list_rem(sfcb->commandList, 0);
209 gf_sg_command_del(com);
210 }
211
212 size = gf_bs_read_int(bs, 5);
213 length = gf_bs_read_int(bs, size);
214 if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM;
215
216 sfcb->bufferSize = length;
217 if (length) {
218 sfcb->buffer = (unsigned char *)gf_malloc(sizeof(char)*(length));
219 //WARNING Buffers are NOT ALIGNED IN THE BITSTREAM
220 for (i=0; i<length; i++) {
221 sfcb->buffer[i] = gf_bs_read_int(bs, 8);
222 }
223 }
224 //notify the node - this is needed in case an enhencement layer replaces the buffer, in which case
225 //the # ID Bits may change
226 SFCommandBufferChanged(codec, node);
227
228 /*
229 1 - memory mode, register command buffer for later parsing
230 2 - InputSensor only works on decompressed commands
231 */
232 if (codec->dec_memory_mode || (node->sgprivate->tag==TAG_MPEG4_InputSensor)) {
233 CommandBufferItem *cbi = (CommandBufferItem *)gf_malloc(sizeof(CommandBufferItem));
234 cbi->node = node;
235 cbi->cb = sfcb;
236 gf_list_add(codec->command_buffers, cbi);
237 }
238 }
239 break;
240 case GF_SG_VRML_SFNODE:
241 //for nodes the field ptr is a ptr to the field, which is a node ptr ;)
242 new_node = gf_bifs_dec_node(codec, bs, field->NDTtype);
243 if (new_node) {
244 e = gf_node_register(new_node, is_mem_com ? NULL : node);
245 if (e) return e;
246 }
247 //it may happen that new_node is NULL (this is valid for a proto declaration)
248 *((GF_Node **) field->far_ptr) = new_node;
249 break;
250 case GF_SG_VRML_SFSCRIPT:
251 #ifdef GPAC_HAS_QJS
252 codec->LastError = SFScript_Parse(codec, (SFScript*)field->far_ptr, bs, node);
253 #else
254 return GF_NOT_SUPPORTED;
255 #endif
256 break;
257 case GF_SG_VRML_SFATTRREF:
258 {
259 SFAttrRef *ar = (SFAttrRef *)field->far_ptr;
260 u32 nodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
261 ar->node = gf_sg_find_node(codec->current_graph, nodeID);
262 if (!ar->node) {
263
264 } else {
265 u32 nbBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(ar->node, GF_SG_FIELD_CODING_DEF) - 1);
266 u32 field_ref = gf_bs_read_int(bs, nbBitsDEF);
267 codec->LastError = gf_bifs_get_field_index(ar->node, field_ref, GF_SG_FIELD_CODING_DEF, &ar->fieldIndex);
268 }
269 }
270 break;
271 default:
272 return GF_NON_COMPLIANT_BITSTREAM;
273 }
274 return codec->LastError;
275 }
276
BD_DecMFFieldList(GF_BifsDecoder * codec,GF_BitStream * bs,GF_Node * node,GF_FieldInfo * field,Bool is_mem_com)277 GF_Err BD_DecMFFieldList(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field, Bool is_mem_com)
278 {
279 GF_Node *new_node;
280 GF_Err e;
281 u8 endFlag, qp_local, qp_on, initial_qp;
282 GF_ChildNodeItem *last = NULL;
283 u32 nbF;
284
285 GF_FieldInfo sffield;
286
287 memset(&sffield, 0, sizeof(GF_FieldInfo));
288 sffield.fieldIndex = field->fieldIndex;
289 sffield.fieldType = gf_sg_vrml_get_sf_type(field->fieldType);
290 sffield.NDTtype = field->NDTtype;
291
292 nbF = 0;
293 qp_on = qp_local = 0;
294 initial_qp = codec->ActiveQP ? 1 : 0;
295
296 endFlag = gf_bs_read_int(bs, 1);
297 while (!endFlag && (codec->LastError>=0)) {
298 if (field->fieldType != GF_SG_VRML_MFNODE) {
299 e = gf_sg_vrml_mf_append(field->far_ptr, field->fieldType, & sffield.far_ptr);
300 if (e) return e;
301 e = gf_bifs_dec_sf_field(codec, bs, node, &sffield, GF_FALSE);
302 if (e) return e;
303 } else {
304 new_node = gf_bifs_dec_node(codec, bs, field->NDTtype);
305 //append
306 if (new_node) {
307 e = gf_node_register(new_node, is_mem_com ? NULL : node);
308 if (e) return e;
309
310 //regular coding
311 if (node) {
312 //special case for QP, register as the current QP
313 if (gf_node_get_tag(new_node) == TAG_MPEG4_QuantizationParameter) {
314 qp_local = ((M_QuantizationParameter *)new_node)->isLocal;
315 //we have a QP in the same scope, remove previous
316 if (qp_on) gf_bifs_dec_qp_remove(codec, GF_FALSE);
317 e = gf_bifs_dec_qp_set(codec, new_node);
318 if (e) return e;
319 qp_on = 1;
320 if (qp_local) qp_local = 2;
321 if (codec->force_keep_qp) {
322 e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);
323 } else {
324 gf_node_register(new_node, NULL);
325 gf_node_unregister(new_node, node);
326 }
327 } else
328 //this is generic MFNode container
329 e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);
330
331 }
332 //proto coding: directly add the child
333 else if (codec->pCurrentProto) {
334 //TO DO: what happens if this is a QP node on the interface ?
335 e = gf_node_list_add_child_last( (GF_ChildNodeItem **)field->far_ptr, new_node, &last);
336 }
337 } else {
338 return codec->LastError;
339 }
340 }
341 if (e) return e;
342
343 endFlag = gf_bs_read_int(bs, 1);
344
345 //according to the spec, the QP applies to the current node itself,
346 //not just children. If IsLocal is TRUE remove the node
347 if (qp_on && qp_local) {
348 if (qp_local == 2) {
349 qp_local = 1;
350 } else {
351 //ask to get rid of QP and reactivate if we had a QP when entering
352 gf_bifs_dec_qp_remove(codec, initial_qp);
353 qp_local = 0;
354 qp_on = 0;
355 }
356 }
357 nbF += 1;
358 }
359 /*finally delete the QP if any (local or not) as we get out of this node
360 and reactivate previous one*/
361 if (qp_on) gf_bifs_dec_qp_remove(codec, initial_qp);
362 /*this is for QP 14*/
363 gf_bifs_dec_qp14_set_length(codec, nbF);
364 return GF_OK;
365 }
366
BD_DecMFFieldVec(GF_BifsDecoder * codec,GF_BitStream * bs,GF_Node * node,GF_FieldInfo * field,Bool is_mem_com)367 GF_Err BD_DecMFFieldVec(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field, Bool is_mem_com)
368 {
369 GF_Err e;
370 u32 NbBits, nbFields;
371 u32 i;
372 GF_ChildNodeItem *last;
373 u8 qp_local, qp_on, initial_qp;
374 GF_FieldInfo sffield;
375
376 memset(&sffield, 0, sizeof(GF_FieldInfo));
377 sffield.fieldIndex = field->fieldIndex;
378 sffield.fieldType = gf_sg_vrml_get_sf_type(field->fieldType);
379 sffield.NDTtype = field->NDTtype;
380
381 initial_qp = qp_local = qp_on = 0;
382
383 //vector description - alloc the MF size before
384 NbBits = gf_bs_read_int(bs, 5);
385 nbFields = gf_bs_read_int(bs, NbBits);
386
387 if (codec->ActiveQP) {
388 initial_qp = 1;
389 /*this is for QP 14*/
390 gf_bifs_dec_qp14_set_length(codec, nbFields);
391 }
392
393 if (field->fieldType != GF_SG_VRML_MFNODE) {
394 e = gf_sg_vrml_mf_alloc(field->far_ptr, field->fieldType, nbFields);
395 if (e) return e;
396
397 for (i=0; i<nbFields; i++) {
398 e = gf_sg_vrml_mf_get_item(field->far_ptr, field->fieldType, & sffield.far_ptr, i);
399 if (e) return e;
400 e = gf_bifs_dec_sf_field(codec, bs, node, &sffield, GF_FALSE);
401 if (e) return e;
402 }
403 } else {
404 last = NULL;
405 for (i=0; i<nbFields; i++) {
406 GF_Node *new_node = gf_bifs_dec_node(codec, bs, field->NDTtype);
407 if (new_node) {
408 e = gf_node_register(new_node, is_mem_com ? NULL : node);
409 if (e) return e;
410
411 if (node) {
412 /*special case for QP, register as the current QP*/
413 if (gf_node_get_tag(new_node) == TAG_MPEG4_QuantizationParameter) {
414 qp_local = ((M_QuantizationParameter *)new_node)->isLocal;
415 /*we have a QP in the same scope, remove previous
416 NB: we assume this is the right behaviour, the spec doesn't say
417 whether QP is cumulative or not*/
418 if (qp_on) gf_bifs_dec_qp_remove(codec, GF_FALSE);
419
420 e = gf_bifs_dec_qp_set(codec, new_node);
421 if (e) return e;
422 qp_on = 1;
423 if (qp_local) qp_local = 2;
424 if (codec->force_keep_qp) {
425 e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);
426 if (e) return e;
427 } else {
428 gf_node_register(new_node, NULL);
429 gf_node_unregister(new_node, node);
430 }
431 } else {
432 e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);
433 if (e) return e;
434 }
435 }
436 /*proto coding*/
437 else if (codec->pCurrentProto) {
438 /*TO DO: what happens if this is a QP node on the interface ?*/
439 e = gf_node_list_add_child_last( (GF_ChildNodeItem **)field->far_ptr, new_node, &last);
440 if (e) return e;
441 }
442 } else {
443 return codec->LastError ? codec->LastError : GF_NON_COMPLIANT_BITSTREAM;
444 }
445 }
446 /*according to the spec, the QP applies to the current node itself, not just children.
447 If IsLocal is TRUE remove the node*/
448 if (qp_on && qp_local) {
449 if (qp_local == 2) {
450 // qp_local = 1;
451 } else {
452 //ask to get rid of QP and reactivate if we had a QP when entering the node
453 gf_bifs_dec_qp_remove(codec, initial_qp);
454 // qp_local = 0;
455 }
456 }
457 }
458 /*finally delete the QP if any (local or not) as we get out of this node*/
459 if (qp_on) gf_bifs_dec_qp_remove(codec, GF_TRUE);
460 return GF_OK;
461 }
462
463
gf_bifs_check_field_change(GF_Node * node,GF_FieldInfo * field)464 void gf_bifs_check_field_change(GF_Node *node, GF_FieldInfo *field)
465 {
466 if (field->fieldType==GF_SG_VRML_MFNODE) node->sgprivate->flags |= GF_SG_CHILD_DIRTY;
467 /*signal node modif*/
468 gf_node_changed(node, field);
469 /*Notify eventOut in all cases to handle protos*/
470 gf_node_event_out(node, field->fieldIndex);
471 /*and propagate eventIn if any*/
472 if (field->on_event_in) {
473 field->on_event_in(node, NULL);
474 } else if ((gf_node_get_tag(node) == TAG_MPEG4_Script) && (field->eventType==GF_SG_EVENT_IN)) {
475 gf_sg_script_event_in(node, field);
476 }
477
478 }
479
gf_bifs_dec_field(GF_BifsDecoder * codec,GF_BitStream * bs,GF_Node * node,GF_FieldInfo * field,Bool is_mem_com)480 GF_Err gf_bifs_dec_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field, Bool is_mem_com)
481 {
482 GF_Err e;
483 u8 flag;
484
485 // if (codec->LastError) return codec->LastError;
486
487 assert(node);
488 // if (field->fieldType == GF_SG_VRML_UNKNOWN) return GF_NON_COMPLIANT_BITSTREAM;
489
490 if (gf_sg_vrml_is_sf_field(field->fieldType)) {
491 e = gf_bifs_dec_sf_field(codec, bs, node, field, is_mem_com);
492 if (e) return e;
493 } else {
494 /*clean up the eventIn field if not done*/
495 if (field->eventType == GF_SG_EVENT_IN) {
496 if (field->fieldType == GF_SG_VRML_MFNODE) {
497 gf_node_unregister_children(node, * (GF_ChildNodeItem **)field->far_ptr);
498 * (GF_ChildNodeItem **)field->far_ptr = NULL;
499 } else {
500 //remove all items of the MFField
501 gf_sg_vrml_mf_reset(field->far_ptr, field->fieldType);
502 }
503 }
504
505 /*predictiveMFField*/
506 if (codec->info->config.UsePredictiveMFField) {
507 flag = gf_bs_read_int(bs, 1);
508 if (flag) {
509 #ifdef GPAC_ENABLE_BIFS_PMF
510 return gf_bifs_dec_pred_mf_field(codec, bs, node, field);
511 #else
512 GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[BIFS] Stream uses Predictive Field Coding, disabled in this build!\n"));
513 return GF_NOT_SUPPORTED;
514 #endif
515 }
516 }
517
518 /*reserved*/
519 flag = gf_bs_read_int(bs, 1);
520 if (!flag) {
521 /*destroy the field content...*/
522 if (field->fieldType != GF_SG_VRML_MFNODE) {
523 e = gf_sg_vrml_mf_reset(field->far_ptr, field->fieldType);
524 if (e) return e;
525 }
526 /*List description - alloc is dynamic*/
527 flag = gf_bs_read_int(bs, 1);
528 if (flag) {
529 e = BD_DecMFFieldList(codec, bs, node, field, is_mem_com);
530 } else {
531 e = BD_DecMFFieldVec(codec, bs, node, field, is_mem_com);
532 }
533 if (e) return e;
534 }
535 }
536 return GF_OK;
537 }
538
539
BD_SetProtoISed(GF_BifsDecoder * codec,u32 protofield,GF_Node * n,u32 nodefield)540 GF_Err BD_SetProtoISed(GF_BifsDecoder * codec, u32 protofield, GF_Node *n, u32 nodefield)
541 {
542 /*take care of conditional execution in proto*/
543 if (codec->current_graph->pOwningProto) {
544 return gf_sg_proto_instance_set_ised((GF_Node *) codec->current_graph->pOwningProto, protofield, n, nodefield);
545 }
546 /*regular ISed fields*/
547 else {
548 return gf_sg_proto_field_set_ised(codec->pCurrentProto, protofield, n, nodefield);
549 }
550 }
551
gf_bifs_dec_node_list(GF_BifsDecoder * codec,GF_BitStream * bs,GF_Node * node,Bool is_proto)552 GF_Err gf_bifs_dec_node_list(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, Bool is_proto)
553 {
554 u8 flag;
555 GF_Err e;
556 u32 numBitsALL, numBitsDEF, field_all, field_ref, numProtoBits;
557 GF_FieldInfo field;
558
559 numProtoBits = numBitsALL = 0;
560 if (codec->pCurrentProto) {
561 numProtoBits = gf_get_bit_size(gf_sg_proto_get_field_count(codec->pCurrentProto) - 1);
562 numBitsALL = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL)-1);
563 }
564 numBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF)-1);
565
566 flag = gf_bs_read_int(bs, 1);
567 while (!flag && (codec->LastError>=0)) {
568 if (codec->pCurrentProto) {
569 //IS'ed flag
570 flag = gf_bs_read_int(bs, 1);
571 if (flag) {
572 //get field index in ALL mode for node
573 field_ref = gf_bs_read_int(bs, numBitsALL);
574 //get field index in ALL mode for proto
575 field_all = gf_bs_read_int(bs, numProtoBits);
576 e = gf_node_get_field(node, field_ref, &field);
577 if (e) return e;
578 e = BD_SetProtoISed(codec, field_all, node, field_ref);
579 if (e) return e;
580 flag = gf_bs_read_int(bs, 1);
581 continue;
582 }
583 }
584
585 //fields are coded in DEF mode
586 field_ref = gf_bs_read_int(bs, numBitsDEF);
587 e = gf_bifs_get_field_index(node, field_ref, GF_SG_FIELD_CODING_DEF, &field_all);
588 if (e) return e;
589 e = gf_node_get_field(node, field_all, &field);
590 if (e) return e;
591 e = gf_bifs_dec_field(codec, bs, node, &field, GF_FALSE);
592 if (e) return e;
593 flag = gf_bs_read_int(bs, 1);
594
595 if (is_proto) gf_sg_proto_mark_field_loaded(node, &field);
596 }
597 return codec->LastError;
598 }
599
gf_bifs_dec_node_mask(GF_BifsDecoder * codec,GF_BitStream * bs,GF_Node * node,Bool is_proto)600 GF_Err gf_bifs_dec_node_mask(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, Bool is_proto)
601 {
602 u32 i, numFields, numProtoFields, index, flag, nbBits;
603 GF_Err e;
604 GF_FieldInfo field;
605
606 //proto coding
607 if (codec->pCurrentProto) {
608 numFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL);
609 numProtoFields = gf_sg_proto_get_field_count(codec->pCurrentProto);
610 nbBits = gf_get_bit_size(numProtoFields-1);
611
612 for (i=0; i<numFields; i++) {
613 flag = gf_bs_read_int(bs, 1);
614 if (!flag) continue;
615 flag = gf_bs_read_int(bs, 1);
616 //IS'ed field, create route for binding to Proto declaration
617 if (flag) {
618 //reference index of our IS'ed proto field
619 flag = gf_bs_read_int(bs, nbBits);
620 e = gf_node_get_field(node, i, &field);
621 if (e) return e;
622 e = BD_SetProtoISed(codec, flag, node, i);
623 }
624 //regular field, parse it (nb: no contextual coding for protos in maskNode,
625 //all node fields are coded
626 else {
627 e = gf_node_get_field(node, i, &field);
628 if (e) return e;
629 e = gf_bifs_dec_field(codec, bs, node, &field, GF_FALSE);
630 }
631 if (e) return e;
632 }
633 }
634 //regular coding
635 else {
636 numFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF);
637 for (i=0; i<numFields; i++) {
638 flag = gf_bs_read_int(bs, 1);
639 if (!flag) continue;
640 gf_bifs_get_field_index(node, i, GF_SG_FIELD_CODING_DEF, &index);
641 e = gf_node_get_field(node, index, &field);
642 if (e) return e;
643 e = gf_bifs_dec_field(codec, bs, node, &field, GF_FALSE);
644 if (e) return e;
645
646 if (is_proto) gf_sg_proto_mark_field_loaded(node, &field);
647 }
648 }
649 return GF_OK;
650 }
651
652
UpdateTimeNode(GF_BifsDecoder * codec,GF_Node * node)653 static void UpdateTimeNode(GF_BifsDecoder * codec, GF_Node *node)
654 {
655 switch (gf_node_get_tag(node)) {
656 case TAG_MPEG4_AnimationStream:
657 BD_OffsetSFTime(codec, & ((M_AnimationStream*)node)->startTime);
658 BD_OffsetSFTime(codec, & ((M_AnimationStream*)node)->stopTime);
659 break;
660 case TAG_MPEG4_AudioBuffer:
661 BD_OffsetSFTime(codec, & ((M_AudioBuffer*)node)->startTime);
662 BD_OffsetSFTime(codec, & ((M_AudioBuffer*)node)->stopTime);
663 break;
664 case TAG_MPEG4_AudioClip:
665 BD_OffsetSFTime(codec, & ((M_AudioClip*)node)->startTime);
666 BD_OffsetSFTime(codec, & ((M_AudioClip*)node)->stopTime);
667 break;
668 case TAG_MPEG4_AudioSource:
669 BD_OffsetSFTime(codec, & ((M_AudioSource*)node)->startTime);
670 BD_OffsetSFTime(codec, & ((M_AudioSource*)node)->stopTime);
671 break;
672 case TAG_MPEG4_MovieTexture:
673 BD_OffsetSFTime(codec, & ((M_MovieTexture*)node)->startTime);
674 BD_OffsetSFTime(codec, & ((M_MovieTexture*)node)->stopTime);
675 break;
676 case TAG_MPEG4_TimeSensor:
677 BD_OffsetSFTime(codec, & ((M_TimeSensor*)node)->startTime);
678 BD_OffsetSFTime(codec, & ((M_TimeSensor*)node)->stopTime);
679 break;
680 case TAG_ProtoNode:
681 {
682 u32 i, nbFields;
683 GF_FieldInfo inf;
684 nbFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL);
685 for (i=0; i<nbFields; i++) {
686 gf_node_get_field(node, i, &inf);
687 if (inf.fieldType != GF_SG_VRML_SFTIME) continue;
688 BD_CheckSFTimeOffset(codec, node, &inf);
689 }
690 }
691 break;
692 }
693 }
694
gf_bifs_dec_node(GF_BifsDecoder * codec,GF_BitStream * bs,u32 NDT_Tag)695 GF_Node *gf_bifs_dec_node(GF_BifsDecoder * codec, GF_BitStream *bs, u32 NDT_Tag)
696 {
697 u32 nodeID, NDTBits, node_type, node_tag, ProtoID, BVersion;
698 Bool skip_init, reset_qp14;
699 GF_Node *new_node;
700 GF_Err e;
701 GF_Proto *proto;
702 void SetupConditional(GF_BifsDecoder *codec, GF_Node *node);
703
704 //to store the UseName
705 char name[1000];
706
707 #if 0
708 /*should only happen with inputSensor, in which case this is BAAAAD*/
709 if (!codec->info) {
710 codec->LastError = GF_BAD_PARAM;
711 return NULL;
712 }
713 #endif
714
715
716 BVersion = GF_BIFS_V1;
717
718 /*this is a USE statement*/
719 if (gf_bs_read_int(bs, 1)) {
720 nodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
721 /*NULL node is encoded as USE with ID = all bits to 1*/
722 if (nodeID == (u32) (1<<codec->info->config.NodeIDBits))
723 return NULL;
724 //find node
725 new_node = gf_sg_find_node(codec->current_graph, nodeID);
726
727 //check node is allowed for the given NDT
728 if (new_node && !gf_node_in_table(new_node, NDT_Tag)) {
729 GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[BIFS] Node %s not allowed as field/child of NDT type %d\n", gf_node_get_class_name(new_node), NDT_Tag));
730 codec->LastError = GF_SG_UNKNOWN_NODE;
731 return NULL;
732 }
733
734 if (!new_node) {
735 codec->LastError = GF_SG_UNKNOWN_NODE;
736 } else {
737 /*restore QP14 length*/
738 switch (gf_node_get_tag(new_node)) {
739 case TAG_MPEG4_Coordinate:
740 {
741 u32 nbCoord = ((M_Coordinate *)new_node)->point.count;
742 gf_bifs_dec_qp14_enter(codec, GF_TRUE);
743 gf_bifs_dec_qp14_set_length(codec, nbCoord);
744 gf_bifs_dec_qp14_enter(codec, GF_FALSE);
745 }
746 break;
747 case TAG_MPEG4_Coordinate2D:
748 {
749 u32 nbCoord = ((M_Coordinate2D *)new_node)->point.count;
750 gf_bifs_dec_qp14_enter(codec, GF_TRUE);
751 gf_bifs_dec_qp14_set_length(codec, nbCoord);
752 gf_bifs_dec_qp14_enter(codec, GF_FALSE);
753 }
754 break;
755 }
756 }
757 return new_node;
758 }
759
760 //this is a new node
761 nodeID = 0;
762 name[0] = 0;
763 node_tag = 0;
764 proto = NULL;
765
766 //browse all node groups
767 while (1) {
768 NDTBits = gf_bifs_get_ndt_bits(NDT_Tag, BVersion);
769 /*this happens in replacescene where no top-level node is present (externProto)*/
770 if ((BVersion==1) && (NDTBits > 8 * gf_bs_available(bs)) ) {
771 codec->LastError = GF_OK;
772 return NULL;
773 }
774
775 node_type = gf_bs_read_int(bs, NDTBits);
776 if (node_type) break;
777
778 //increment BIFS version
779 BVersion += 1;
780 //not supported
781 if (BVersion > GF_BIFS_NUM_VERSION) {
782 codec->LastError = GF_BIFS_UNKNOWN_VERSION;
783 return NULL;
784 }
785 }
786 if (BVersion==2 && node_type==1) {
787 ProtoID = gf_bs_read_int(bs, codec->info->config.ProtoIDBits);
788 /*look in current graph for the proto - this may be a proto graph*/
789 proto = gf_sg_find_proto(codec->current_graph, ProtoID, NULL);
790 /*this was in proto so look in main scene*/
791 if (!proto && codec->current_graph != codec->scenegraph)
792 proto = gf_sg_find_proto(codec->scenegraph, ProtoID, NULL);
793
794 if (!proto) {
795 codec->LastError = GF_SG_UNKNOWN_NODE;
796 return NULL;
797 }
798 } else {
799 node_tag = gf_bifs_ndt_get_node_type(NDT_Tag, node_type, BVersion);
800 }
801
802 /*special handling of 3D mesh*/
803 if ((node_tag == TAG_MPEG4_IndexedFaceSet) && codec->info->config.Use3DMeshCoding) {
804 if (gf_bs_read_int(bs, 1)) {
805 /*nodeID = 1 + */gf_bs_read_int(bs, codec->info->config.NodeIDBits);
806 if (codec->UseName) gf_bifs_dec_name(bs, name);
807 }
808 /*parse the 3DMesh node*/
809 return NULL;
810 }
811 /*unknown node*/
812 if (!node_tag && !proto) {
813 codec->LastError = GF_SG_UNKNOWN_NODE;
814 return NULL;
815 }
816
817
818 /*DEF'd flag*/
819 if (gf_bs_read_int(bs, 1)) {
820 if (!codec->info->config.NodeIDBits) {
821 codec->LastError = GF_NON_COMPLIANT_BITSTREAM;
822 return NULL;
823 }
824 nodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
825 if (codec->UseName) gf_bifs_dec_name(bs, name);
826 }
827
828 new_node = NULL;
829 skip_init = GF_FALSE;
830
831 /*don't check node IDs duplicate since VRML may use them...*/
832 #if 0
833 /*if a node with same DEF is already in the scene, use it
834 we don't do that in memory mode because commands may force replacement
835 of a node with a new node with same ID, and we want to be able to dump it (otherwise we would
836 dump a USE)*/
837 if (nodeID && !codec->dec_memory_mode) {
838 new_node = gf_sg_find_node(codec->current_graph, nodeID);
839 if (new_node) {
840 if (proto) {
841 if ((gf_node_get_tag(new_node) != TAG_ProtoNode) || (gf_node_get_proto(new_node) != proto)) {
842 codec->LastError = GF_NON_COMPLIANT_BITSTREAM;
843 return NULL;
844 }
845 skip_init = 1;
846 } else {
847 if (gf_node_get_tag(new_node) != node_tag) {
848 codec->LastError = GF_NON_COMPLIANT_BITSTREAM;
849 return NULL;
850 }
851 skip_init = 1;
852 }
853 }
854 }
855 if (!new_node)
856 #endif
857
858 {
859 if (proto) {
860 /*create proto interface*/
861 new_node = gf_sg_proto_create_instance(codec->current_graph, proto);
862 //don't init protos unless externProto (in which case we want init for hardcoded protos)
863 if (! proto->ExternProto.count) skip_init = GF_TRUE;
864 } else {
865 new_node = gf_node_new(codec->current_graph, node_tag);
866 }
867 }
868 if (!new_node) {
869 codec->LastError = GF_NOT_SUPPORTED;
870 return NULL;
871 }
872
873 /*VRML: "The transformation hierarchy shall be a directed acyclic graph; results are undefined if a node
874 in the transformation hierarchy is its own ancestor"
875 that's good, because the scene graph can't handle cyclic graphs (destroy will never be called).
876 We therefore only register the node once parsed*/
877 if (nodeID) {
878 if (strlen(name)) {
879 gf_node_set_id(new_node, nodeID, name);
880 } else {
881 gf_node_set_id(new_node, nodeID, NULL);
882 }
883 }
884
885
886 /*update default time fields except in proto parsing*/
887 if (!codec->pCurrentProto) UpdateTimeNode(codec, new_node);
888 /*nodes are only init outside protos, nodes internal to protos are never intialized */
889 else skip_init = GF_TRUE;
890
891 /*if coords were not stored for QP14 before coding this node, reset QP14 it when leaving*/
892 reset_qp14 = !codec->coord_stored;
893
894 /*QP 14 is a special quant mode for IndexFace/Line(2D)Set to quantize the
895 coordonate(2D) child, based on the first field parsed
896 we must check the type of the node and notfy the QP*/
897 switch (node_tag) {
898 case TAG_MPEG4_Coordinate:
899 case TAG_MPEG4_Coordinate2D:
900 gf_bifs_dec_qp14_enter(codec, GF_TRUE);
901 }
902
903 if (gf_bs_read_int(bs, 1)) {
904 e = gf_bifs_dec_node_mask(codec, bs, new_node, proto ? GF_TRUE : GF_FALSE);
905 } else {
906 e = gf_bifs_dec_node_list(codec, bs, new_node, proto ? GF_TRUE : GF_FALSE);
907 }
908 if (codec->coord_stored && reset_qp14)
909 gf_bifs_dec_qp14_reset(codec);
910
911 if (e) {
912 codec->LastError = e;
913 /*register*/
914 gf_node_register(new_node, NULL);
915 /*unregister (deletes)*/
916 gf_node_unregister(new_node, NULL);
917 return NULL;
918 }
919
920 if (!skip_init)
921 gf_node_init(new_node);
922
923 switch (node_tag) {
924 case TAG_MPEG4_Coordinate:
925 case TAG_MPEG4_Coordinate2D:
926 gf_bifs_dec_qp14_enter(codec, GF_FALSE);
927 break;
928 case TAG_MPEG4_Script:
929 /*load script if in main graph (useless to load in proto declaration)*/
930 if (codec->scenegraph == codec->current_graph) {
931 gf_sg_script_load(new_node);
932 }
933 break;
934 /*conditionals must be init*/
935 case TAG_MPEG4_Conditional:
936 SetupConditional(codec, new_node);
937 break;
938 }
939
940 /*proto is initialized upon the first traversal to have the same behavior as wth BT/XMT loading*/
941 #if 0
942 /*if new node is a proto and we're in the top scene, load proto code*/
943 if (proto && (codec->scenegraph == codec->current_graph)) {
944 codec->LastError = gf_sg_proto_load_code(new_node);
945 }
946 #endif
947
948 return new_node;
949 }
950
951 #endif /*GPAC_DISABLE_BIFS*/
952