Line data Source code
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 :
35 95 : void SFCommandBufferChanged(GF_BifsDecoder * codec, GF_Node *node)
36 : {
37 : void Conditional_BufferReplaced(GF_BifsDecoder * codec, GF_Node *node);
38 :
39 95 : switch (gf_node_get_tag(node)) {
40 65 : case TAG_MPEG4_Conditional:
41 65 : Conditional_BufferReplaced(codec, node);
42 65 : break;
43 : }
44 95 : }
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
49 0 : void BD_OffsetSFTime(GF_BifsDecoder * codec, Double *time)
50 : {
51 164 : if ((!codec->is_com_dec && codec->pCurrentProto) || codec->dec_memory_mode) return;
52 42 : *time += codec->cts_offset;
53 : }
54 :
55 18 : void BD_CheckSFTimeOffset(GF_BifsDecoder *codec, GF_Node *node, GF_FieldInfo *inf)
56 : {
57 18 : if (gf_node_get_tag(node) != TAG_ProtoNode) {
58 18 : if (!stricmp(inf->name, "startTime") || !stricmp(inf->name, "stopTime"))
59 18 : BD_OffsetSFTime(codec, (Double *)inf->far_ptr);
60 0 : } else if (gf_sg_proto_field_is_sftime_offset(node, inf)) {
61 0 : BD_OffsetSFTime(codec, (Double *)inf->far_ptr);
62 : }
63 18 : }
64 :
65 :
66 34876 : Fixed BD_ReadSFFloat(GF_BifsDecoder * codec, GF_BitStream *bs)
67 : {
68 34876 : if (codec->ActiveQP && codec->ActiveQP->useEfficientCoding)
69 90 : return gf_bifs_dec_mantissa_float(codec, bs);
70 :
71 34786 : return FLT2FIX(gf_bs_read_float(bs));
72 : }
73 :
74 :
75 45751 : 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 45751 : if (codec->ActiveQP && node) {
84 1065 : e = gf_bifs_dec_unquant_field(codec, bs, node, field);
85 1065 : if (e != GF_EOS) return e;
86 : }
87 : //not quantized, use normal scheme
88 45166 : switch (field->fieldType) {
89 455 : case GF_SG_VRML_SFBOOL:
90 455 : * ((SFBool *) field->far_ptr) = (SFBool) gf_bs_read_int(bs, 1);
91 455 : break;
92 700 : case GF_SG_VRML_SFCOLOR:
93 700 : ((SFColor *)field->far_ptr)->red = BD_ReadSFFloat(codec, bs);
94 700 : ((SFColor *)field->far_ptr)->green = BD_ReadSFFloat(codec, bs);
95 700 : ((SFColor *)field->far_ptr)->blue = BD_ReadSFFloat(codec, bs);
96 700 : break;
97 7082 : case GF_SG_VRML_SFFLOAT:
98 7082 : *((SFFloat *)field->far_ptr) = BD_ReadSFFloat(codec, bs);
99 7082 : break;
100 20424 : case GF_SG_VRML_SFINT32:
101 20424 : *((SFInt32 *)field->far_ptr) = (s32) gf_bs_read_int(bs, 32);
102 20424 : break;
103 20 : case GF_SG_VRML_SFTIME:
104 20 : *((SFTime *)field->far_ptr) = gf_bs_read_double(bs);
105 20 : if (node) BD_CheckSFTimeOffset(codec, node, field);
106 : break;
107 11917 : case GF_SG_VRML_SFVEC2F:
108 11917 : ((SFVec2f *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs);
109 11917 : ((SFVec2f *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs);
110 11917 : break;
111 600 : case GF_SG_VRML_SFVEC3F:
112 600 : ((SFVec3f *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs);
113 600 : ((SFVec3f *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs);
114 600 : ((SFVec3f *)field->far_ptr)->z = BD_ReadSFFloat(codec, bs);
115 600 : break;
116 15 : case GF_SG_VRML_SFROTATION:
117 15 : ((SFRotation *)field->far_ptr)->x = BD_ReadSFFloat(codec, bs);
118 15 : ((SFRotation *)field->far_ptr)->y = BD_ReadSFFloat(codec, bs);
119 15 : ((SFRotation *)field->far_ptr)->z = BD_ReadSFFloat(codec, bs);
120 15 : ((SFRotation *)field->far_ptr)->q = BD_ReadSFFloat(codec, bs);
121 15 : break;
122 424 : case GF_SG_VRML_SFSTRING:
123 424 : size = gf_bs_read_int(bs, 5);
124 424 : length = gf_bs_read_int(bs, size);
125 424 : if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM;
126 :
127 424 : if (node && (node->sgprivate->tag==TAG_MPEG4_CacheTexture) && (field->fieldIndex<=2)) {
128 : M_CacheTexture *ct = (M_CacheTexture *) node;
129 0 : ct->data_len = length;
130 0 : if (ct->data) gf_free(ct->data);
131 0 : ct->data = (u8*)gf_malloc(sizeof(char)*length);
132 0 : gf_bs_read_data(bs, (char*)ct->data, length);
133 439 : } else if (node && (node->sgprivate->tag==TAG_MPEG4_BitWrapper) ) {
134 : M_BitWrapper *bw = (M_BitWrapper*) node;
135 15 : if (bw->buffer.buffer) gf_free(bw->buffer.buffer);
136 15 : bw->buffer_len = length;
137 15 : bw->buffer.buffer = (char*)gf_malloc(sizeof(char)*length);
138 15 : gf_bs_read_data(bs, (char*)bw->buffer.buffer, length);
139 : } else {
140 409 : if ( ((SFString *)field->far_ptr)->buffer ) gf_free( ((SFString *)field->far_ptr)->buffer);
141 409 : ((SFString *)field->far_ptr)->buffer = (char *)gf_malloc(sizeof(char)*(length+1));
142 409 : memset(((SFString *)field->far_ptr)->buffer , 0, length+1);
143 8614 : for (i=0; i<length; i++) {
144 8205 : ((SFString *)field->far_ptr)->buffer[i] = gf_bs_read_int(bs, 8);
145 : }
146 : }
147 : break;
148 101 : case GF_SG_VRML_SFURL:
149 : {
150 101 : SFURL *url = (SFURL *) field->far_ptr;
151 101 : size = gf_bs_read_int(bs, 1);
152 101 : if (size) {
153 70 : if (url->url) gf_free(url->url );
154 70 : url->url = NULL;
155 70 : length = gf_bs_read_int(bs, 10);
156 70 : url->OD_ID = length;
157 : } else {
158 31 : if ( url->OD_ID ) url->OD_ID = (u32) -1;
159 31 : size = gf_bs_read_int(bs, 5);
160 31 : length = gf_bs_read_int(bs, size);
161 31 : if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM;
162 : buffer = NULL;
163 31 : if (length) {
164 31 : buffer = (char *)gf_malloc(sizeof(char)*(length+1));
165 : memset(buffer, 0, length+1);
166 31 : for (i=0; i<length; i++) buffer[i] = gf_bs_read_int(bs, 8);
167 : }
168 31 : if (url->url) gf_free( url->url);
169 : /*if URL is empty set it to NULL*/
170 31 : if (buffer && strlen(buffer)) {
171 31 : url->url = buffer;
172 : } else {
173 0 : gf_free(buffer);
174 0 : url->url = NULL;
175 : }
176 : }
177 : }
178 : break;
179 15 : case GF_SG_VRML_SFIMAGE:
180 15 : if (((SFImage *)field->far_ptr)->pixels) gf_free(((SFImage *)field->far_ptr)->pixels);
181 15 : w = gf_bs_read_int(bs, 12);
182 15 : h = gf_bs_read_int(bs, 12);
183 15 : length = gf_bs_read_int(bs, 2);
184 :
185 15 : if (length > 3) length = 3;
186 15 : length += 1;
187 15 : size = w * h * length;
188 15 : if (gf_bs_available(bs) < size) return GF_NON_COMPLIANT_BITSTREAM;
189 15 : ((SFImage *)field->far_ptr)->width = w;
190 15 : ((SFImage *)field->far_ptr)->height = h;
191 15 : ((SFImage *)field->far_ptr)->numComponents = length;
192 15 : ((SFImage *)field->far_ptr)->pixels = (unsigned char *)gf_malloc(sizeof(char)*size);
193 : //WARNING: Buffers are NOT ALIGNED IN THE BITSTREAM
194 255 : for (i=0; i<size; i++) {
195 240 : ((SFImage *)field->far_ptr)->pixels[i] = gf_bs_read_int(bs, 8);
196 : }
197 : break;
198 95 : case GF_SG_VRML_SFCOMMANDBUFFER:
199 : {
200 95 : SFCommandBuffer *sfcb = (SFCommandBuffer *)field->far_ptr;
201 95 : if (!node) return GF_BAD_PARAM;
202 95 : if (sfcb->buffer) {
203 0 : gf_free(sfcb->buffer);
204 0 : sfcb->buffer = NULL;
205 : }
206 95 : while (gf_list_count(sfcb->commandList)) {
207 0 : GF_Command *com = (GF_Command*)gf_list_get(sfcb->commandList, 0);
208 0 : gf_list_rem(sfcb->commandList, 0);
209 0 : gf_sg_command_del(com);
210 : }
211 :
212 95 : size = gf_bs_read_int(bs, 5);
213 95 : length = gf_bs_read_int(bs, size);
214 95 : if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM;
215 :
216 95 : sfcb->bufferSize = length;
217 95 : if (length) {
218 95 : sfcb->buffer = (unsigned char *)gf_malloc(sizeof(char)*(length));
219 : //WARNING Buffers are NOT ALIGNED IN THE BITSTREAM
220 1090 : for (i=0; i<length; i++) {
221 995 : 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 95 : 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 95 : if (codec->dec_memory_mode || (node->sgprivate->tag==TAG_MPEG4_InputSensor)) {
233 82 : CommandBufferItem *cbi = (CommandBufferItem *)gf_malloc(sizeof(CommandBufferItem));
234 82 : cbi->node = node;
235 82 : cbi->cb = sfcb;
236 82 : gf_list_add(codec->command_buffers, cbi);
237 : }
238 : }
239 : break;
240 3303 : case GF_SG_VRML_SFNODE:
241 : //for nodes the field ptr is a ptr to the field, which is a node ptr ;)
242 3303 : new_node = gf_bifs_dec_node(codec, bs, field->NDTtype);
243 3303 : if (new_node) {
244 3261 : e = gf_node_register(new_node, is_mem_com ? NULL : node);
245 3261 : if (e) return e;
246 : }
247 : //it may happen that new_node is NULL (this is valid for a proto declaration)
248 3303 : *((GF_Node **) field->far_ptr) = new_node;
249 3303 : break;
250 15 : case GF_SG_VRML_SFSCRIPT:
251 : #ifdef GPAC_HAS_QJS
252 15 : codec->LastError = SFScript_Parse(codec, (SFScript*)field->far_ptr, bs, node);
253 : #else
254 : return GF_NOT_SUPPORTED;
255 : #endif
256 15 : break;
257 0 : case GF_SG_VRML_SFATTRREF:
258 : {
259 0 : SFAttrRef *ar = (SFAttrRef *)field->far_ptr;
260 0 : u32 nodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
261 0 : ar->node = gf_sg_find_node(codec->current_graph, nodeID);
262 0 : if (!ar->node) {
263 :
264 : } else {
265 0 : u32 nbBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(ar->node, GF_SG_FIELD_CODING_DEF) - 1);
266 0 : u32 field_ref = gf_bs_read_int(bs, nbBitsDEF);
267 0 : 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 45166 : return codec->LastError;
275 : }
276 :
277 2294 : 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 2294 : GF_ChildNodeItem *last = NULL;
283 : u32 nbF;
284 :
285 : GF_FieldInfo sffield;
286 :
287 : memset(&sffield, 0, sizeof(GF_FieldInfo));
288 2294 : sffield.fieldIndex = field->fieldIndex;
289 2294 : sffield.fieldType = gf_sg_vrml_get_sf_type(field->fieldType);
290 2294 : sffield.NDTtype = field->NDTtype;
291 :
292 : nbF = 0;
293 : qp_on = qp_local = 0;
294 2294 : initial_qp = codec->ActiveQP ? 1 : 0;
295 :
296 2294 : endFlag = gf_bs_read_int(bs, 1);
297 9130 : while (!endFlag && (codec->LastError>=0)) {
298 4542 : if (field->fieldType != GF_SG_VRML_MFNODE) {
299 2625 : e = gf_sg_vrml_mf_append(field->far_ptr, field->fieldType, & sffield.far_ptr);
300 2625 : if (e) return e;
301 2625 : e = gf_bifs_dec_sf_field(codec, bs, node, &sffield, GF_FALSE);
302 2625 : if (e) return e;
303 : } else {
304 1917 : new_node = gf_bifs_dec_node(codec, bs, field->NDTtype);
305 : //append
306 1917 : if (new_node) {
307 1917 : e = gf_node_register(new_node, is_mem_com ? NULL : node);
308 1917 : if (e) return e;
309 :
310 : //regular coding
311 1917 : if (node) {
312 : //special case for QP, register as the current QP
313 1917 : if (gf_node_get_tag(new_node) == TAG_MPEG4_QuantizationParameter) {
314 45 : qp_local = ((M_QuantizationParameter *)new_node)->isLocal;
315 : //we have a QP in the same scope, remove previous
316 45 : if (qp_on) gf_bifs_dec_qp_remove(codec, GF_FALSE);
317 45 : e = gf_bifs_dec_qp_set(codec, new_node);
318 45 : if (e) return e;
319 : qp_on = 1;
320 45 : if (qp_local) qp_local = 2;
321 45 : if (codec->force_keep_qp) {
322 36 : e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);
323 : } else {
324 9 : gf_node_register(new_node, NULL);
325 9 : gf_node_unregister(new_node, node);
326 : }
327 : } else
328 : //this is generic MFNode container
329 1872 : e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);
330 :
331 : }
332 : //proto coding: directly add the child
333 0 : else if (codec->pCurrentProto) {
334 : //TO DO: what happens if this is a QP node on the interface ?
335 0 : e = gf_node_list_add_child_last( (GF_ChildNodeItem **)field->far_ptr, new_node, &last);
336 : }
337 : } else {
338 0 : return codec->LastError;
339 : }
340 : }
341 4542 : if (e) return e;
342 :
343 4542 : 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 4542 : if (qp_on && qp_local) {
348 30 : 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 15 : gf_bifs_dec_qp_remove(codec, initial_qp);
353 : qp_local = 0;
354 : qp_on = 0;
355 : }
356 : }
357 4542 : 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 2294 : if (qp_on) gf_bifs_dec_qp_remove(codec, initial_qp);
362 : /*this is for QP 14*/
363 2294 : gf_bifs_dec_qp14_set_length(codec, nbF);
364 2294 : return GF_OK;
365 : }
366 :
367 1031 : 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 1031 : sffield.fieldIndex = field->fieldIndex;
378 1031 : sffield.fieldType = gf_sg_vrml_get_sf_type(field->fieldType);
379 1031 : sffield.NDTtype = field->NDTtype;
380 :
381 : initial_qp = qp_local = qp_on = 0;
382 :
383 : //vector description - alloc the MF size before
384 1031 : NbBits = gf_bs_read_int(bs, 5);
385 1031 : nbFields = gf_bs_read_int(bs, NbBits);
386 :
387 1031 : if (codec->ActiveQP) {
388 : initial_qp = 1;
389 : /*this is for QP 14*/
390 0 : gf_bifs_dec_qp14_set_length(codec, nbFields);
391 : }
392 :
393 1031 : if (field->fieldType != GF_SG_VRML_MFNODE) {
394 1000 : e = gf_sg_vrml_mf_alloc(field->far_ptr, field->fieldType, nbFields);
395 1000 : if (e) return e;
396 :
397 32737 : for (i=0; i<nbFields; i++) {
398 32737 : e = gf_sg_vrml_mf_get_item(field->far_ptr, field->fieldType, & sffield.far_ptr, i);
399 32737 : if (e) return e;
400 32737 : e = gf_bifs_dec_sf_field(codec, bs, node, &sffield, GF_FALSE);
401 32737 : if (e) return e;
402 : }
403 : } else {
404 31 : last = NULL;
405 1517 : for (i=0; i<nbFields; i++) {
406 1486 : GF_Node *new_node = gf_bifs_dec_node(codec, bs, field->NDTtype);
407 1486 : if (new_node) {
408 1486 : e = gf_node_register(new_node, is_mem_com ? NULL : node);
409 1486 : if (e) return e;
410 :
411 1486 : if (node) {
412 : /*special case for QP, register as the current QP*/
413 1486 : if (gf_node_get_tag(new_node) == TAG_MPEG4_QuantizationParameter) {
414 0 : 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 behavior, the spec doesn't say
417 : whether QP is cumulative or not*/
418 0 : if (qp_on) gf_bifs_dec_qp_remove(codec, GF_FALSE);
419 :
420 0 : e = gf_bifs_dec_qp_set(codec, new_node);
421 0 : if (e) return e;
422 : qp_on = 1;
423 0 : if (qp_local) qp_local = 2;
424 0 : if (codec->force_keep_qp) {
425 0 : e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);
426 0 : if (e) return e;
427 : } else {
428 0 : gf_node_register(new_node, NULL);
429 0 : gf_node_unregister(new_node, node);
430 : }
431 : } else {
432 1486 : e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);
433 1486 : if (e) return e;
434 : }
435 : }
436 : /*proto coding*/
437 0 : else if (codec->pCurrentProto) {
438 : /*TO DO: what happens if this is a QP node on the interface ?*/
439 0 : e = gf_node_list_add_child_last( (GF_ChildNodeItem **)field->far_ptr, new_node, &last);
440 0 : if (e) return e;
441 : }
442 : } else {
443 0 : 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 31 : if (qp_on && qp_local) {
449 0 : 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 0 : 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 1031 : if (qp_on) gf_bifs_dec_qp_remove(codec, GF_TRUE);
460 : return GF_OK;
461 : }
462 :
463 :
464 994 : void gf_bifs_check_field_change(GF_Node *node, GF_FieldInfo *field)
465 : {
466 994 : if (field->fieldType==GF_SG_VRML_MFNODE) node->sgprivate->flags |= GF_SG_CHILD_DIRTY;
467 : /*signal node modif*/
468 994 : gf_node_changed(node, field);
469 : /*Notify eventOut in all cases to handle protos*/
470 994 : gf_node_event_out(node, field->fieldIndex);
471 : /*and propagate eventIn if any*/
472 994 : if (field->on_event_in) {
473 3 : field->on_event_in(node, NULL);
474 991 : } else if ((gf_node_get_tag(node) == TAG_MPEG4_Script) && (field->eventType==GF_SG_EVENT_IN)) {
475 0 : gf_sg_script_event_in(node, field);
476 : }
477 :
478 994 : }
479 :
480 13315 : 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 13315 : if (gf_sg_vrml_is_sf_field(field->fieldType)) {
491 10009 : e = gf_bifs_dec_sf_field(codec, bs, node, field, is_mem_com);
492 10009 : if (e) return e;
493 : } else {
494 : /*clean up the eventIn field if not done*/
495 3306 : if (field->eventType == GF_SG_EVENT_IN) {
496 0 : if (field->fieldType == GF_SG_VRML_MFNODE) {
497 0 : gf_node_unregister_children(node, * (GF_ChildNodeItem **)field->far_ptr);
498 0 : * (GF_ChildNodeItem **)field->far_ptr = NULL;
499 : } else {
500 : //remove all items of the MFField
501 0 : gf_sg_vrml_mf_reset(field->far_ptr, field->fieldType);
502 : }
503 : }
504 :
505 : /*predictiveMFField*/
506 3306 : if (codec->info->config.UsePredictiveMFField) {
507 0 : flag = gf_bs_read_int(bs, 1);
508 0 : if (flag) {
509 : #ifdef GPAC_ENABLE_BIFS_PMF
510 : return gf_bifs_dec_pred_mf_field(codec, bs, node, field);
511 : #else
512 0 : 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 3306 : flag = gf_bs_read_int(bs, 1);
520 3306 : if (!flag) {
521 : /*destroy the field content...*/
522 3306 : if (field->fieldType != GF_SG_VRML_MFNODE) {
523 1796 : e = gf_sg_vrml_mf_reset(field->far_ptr, field->fieldType);
524 1796 : if (e) return e;
525 : }
526 : /*List description - alloc is dynamic*/
527 3306 : flag = gf_bs_read_int(bs, 1);
528 3306 : if (flag) {
529 2275 : e = BD_DecMFFieldList(codec, bs, node, field, is_mem_com);
530 : } else {
531 1031 : e = BD_DecMFFieldVec(codec, bs, node, field, is_mem_com);
532 : }
533 3306 : if (e) return e;
534 : }
535 : }
536 : return GF_OK;
537 : }
538 :
539 :
540 181 : GF_Err BD_SetProtoISed(GF_BifsDecoder * codec, u32 protofield, GF_Node *n, u32 nodefield)
541 : {
542 : /*take care of conditional execution in proto*/
543 181 : if (codec->current_graph->pOwningProto) {
544 0 : return gf_sg_proto_instance_set_ised((GF_Node *) codec->current_graph->pOwningProto, protofield, n, nodefield);
545 : }
546 : /*regular ISed fields*/
547 : else {
548 181 : return gf_sg_proto_field_set_ised(codec->pCurrentProto, protofield, n, nodefield);
549 : }
550 : }
551 :
552 1041 : 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 1041 : if (codec->pCurrentProto) {
561 42 : numProtoBits = gf_get_bit_size(gf_sg_proto_get_field_count(codec->pCurrentProto) - 1);
562 42 : numBitsALL = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL)-1);
563 : }
564 1041 : numBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF)-1);
565 :
566 1041 : flag = gf_bs_read_int(bs, 1);
567 2983 : while (!flag && (codec->LastError>=0)) {
568 901 : if (codec->pCurrentProto) {
569 : //IS'ed flag
570 71 : flag = gf_bs_read_int(bs, 1);
571 71 : if (flag) {
572 : //get field index in ALL mode for node
573 30 : field_ref = gf_bs_read_int(bs, numBitsALL);
574 : //get field index in ALL mode for proto
575 30 : field_all = gf_bs_read_int(bs, numProtoBits);
576 30 : e = gf_node_get_field(node, field_ref, &field);
577 30 : if (e) return e;
578 30 : e = BD_SetProtoISed(codec, field_all, node, field_ref);
579 30 : if (e) return e;
580 30 : flag = gf_bs_read_int(bs, 1);
581 30 : continue;
582 : }
583 : }
584 :
585 : //fields are coded in DEF mode
586 871 : field_ref = gf_bs_read_int(bs, numBitsDEF);
587 871 : e = gf_bifs_get_field_index(node, field_ref, GF_SG_FIELD_CODING_DEF, &field_all);
588 871 : if (e) return e;
589 871 : e = gf_node_get_field(node, field_all, &field);
590 871 : if (e) return e;
591 871 : e = gf_bifs_dec_field(codec, bs, node, &field, GF_FALSE);
592 871 : if (e) return e;
593 871 : flag = gf_bs_read_int(bs, 1);
594 :
595 871 : if (is_proto) gf_sg_proto_mark_field_loaded(node, &field);
596 : }
597 1041 : return codec->LastError;
598 : }
599 :
600 4781 : 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 4781 : if (codec->pCurrentProto) {
608 268 : numFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL);
609 268 : numProtoFields = gf_sg_proto_get_field_count(codec->pCurrentProto);
610 268 : nbBits = gf_get_bit_size(numProtoFields-1);
611 :
612 1155 : for (i=0; i<numFields; i++) {
613 887 : flag = gf_bs_read_int(bs, 1);
614 887 : if (!flag) continue;
615 528 : flag = gf_bs_read_int(bs, 1);
616 : //IS'ed field, create route for binding to Proto declaration
617 528 : if (flag) {
618 : //reference index of our IS'ed proto field
619 151 : flag = gf_bs_read_int(bs, nbBits);
620 151 : e = gf_node_get_field(node, i, &field);
621 151 : if (e) return e;
622 151 : 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 377 : e = gf_node_get_field(node, i, &field);
628 377 : if (e) return e;
629 377 : e = gf_bifs_dec_field(codec, bs, node, &field, GF_FALSE);
630 : }
631 528 : if (e) return e;
632 : }
633 : }
634 : //regular coding
635 : else {
636 4513 : numFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF);
637 21648 : for (i=0; i<numFields; i++) {
638 17135 : flag = gf_bs_read_int(bs, 1);
639 17135 : if (!flag) continue;
640 11791 : gf_bifs_get_field_index(node, i, GF_SG_FIELD_CODING_DEF, &index);
641 11791 : e = gf_node_get_field(node, index, &field);
642 11791 : if (e) return e;
643 11791 : e = gf_bifs_dec_field(codec, bs, node, &field, GF_FALSE);
644 11791 : if (e) return e;
645 :
646 11791 : if (is_proto) gf_sg_proto_mark_field_loaded(node, &field);
647 : }
648 : }
649 : return GF_OK;
650 : }
651 :
652 :
653 5508 : static void UpdateTimeNode(GF_BifsDecoder * codec, GF_Node *node)
654 : {
655 5508 : switch (gf_node_get_tag(node)) {
656 11 : case TAG_MPEG4_AnimationStream:
657 : BD_OffsetSFTime(codec, & ((M_AnimationStream*)node)->startTime);
658 : BD_OffsetSFTime(codec, & ((M_AnimationStream*)node)->stopTime);
659 : break;
660 10 : case TAG_MPEG4_AudioBuffer:
661 : BD_OffsetSFTime(codec, & ((M_AudioBuffer*)node)->startTime);
662 : BD_OffsetSFTime(codec, & ((M_AudioBuffer*)node)->stopTime);
663 : break;
664 10 : case TAG_MPEG4_AudioClip:
665 : BD_OffsetSFTime(codec, & ((M_AudioClip*)node)->startTime);
666 : BD_OffsetSFTime(codec, & ((M_AudioClip*)node)->stopTime);
667 : break;
668 12 : case TAG_MPEG4_AudioSource:
669 : BD_OffsetSFTime(codec, & ((M_AudioSource*)node)->startTime);
670 : BD_OffsetSFTime(codec, & ((M_AudioSource*)node)->stopTime);
671 : break;
672 20 : case TAG_MPEG4_MovieTexture:
673 : BD_OffsetSFTime(codec, & ((M_MovieTexture*)node)->startTime);
674 : BD_OffsetSFTime(codec, & ((M_MovieTexture*)node)->stopTime);
675 : break;
676 10 : case TAG_MPEG4_TimeSensor:
677 : BD_OffsetSFTime(codec, & ((M_TimeSensor*)node)->startTime);
678 : BD_OffsetSFTime(codec, & ((M_TimeSensor*)node)->stopTime);
679 : break;
680 323 : case TAG_ProtoNode:
681 : {
682 : u32 i, nbFields;
683 : GF_FieldInfo inf;
684 323 : nbFields = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL);
685 1825 : for (i=0; i<nbFields; i++) {
686 1502 : gf_node_get_field(node, i, &inf);
687 1502 : if (inf.fieldType != GF_SG_VRML_SFTIME) continue;
688 0 : BD_CheckSFTimeOffset(codec, node, &inf);
689 : }
690 : }
691 323 : break;
692 : }
693 5508 : }
694 :
695 7970 : 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 7970 : if (gf_bs_read_int(bs, 1)) {
720 2142 : 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 2142 : if (nodeID == (u32) (1<<codec->info->config.NodeIDBits))
723 : return NULL;
724 : //find node
725 2030 : new_node = gf_sg_find_node(codec->current_graph, nodeID);
726 :
727 : //check node is allowed for the given NDT
728 2030 : if (new_node && !gf_node_in_table(new_node, NDT_Tag)) {
729 0 : 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 0 : codec->LastError = GF_SG_UNKNOWN_NODE;
731 0 : return NULL;
732 : }
733 :
734 2030 : if (!new_node) {
735 0 : codec->LastError = GF_SG_UNKNOWN_NODE;
736 : } else {
737 : /*restore QP14 length*/
738 2030 : switch (gf_node_get_tag(new_node)) {
739 0 : case TAG_MPEG4_Coordinate:
740 : {
741 0 : u32 nbCoord = ((M_Coordinate *)new_node)->point.count;
742 0 : gf_bifs_dec_qp14_enter(codec, GF_TRUE);
743 0 : gf_bifs_dec_qp14_set_length(codec, nbCoord);
744 0 : gf_bifs_dec_qp14_enter(codec, GF_FALSE);
745 : }
746 0 : break;
747 96 : case TAG_MPEG4_Coordinate2D:
748 : {
749 96 : u32 nbCoord = ((M_Coordinate2D *)new_node)->point.count;
750 96 : gf_bifs_dec_qp14_enter(codec, GF_TRUE);
751 96 : gf_bifs_dec_qp14_set_length(codec, nbCoord);
752 96 : gf_bifs_dec_qp14_enter(codec, GF_FALSE);
753 : }
754 96 : break;
755 : }
756 : }
757 : return new_node;
758 : }
759 :
760 : //this is a new node
761 : nodeID = 0;
762 5828 : name[0] = 0;
763 : node_tag = 0;
764 : proto = NULL;
765 :
766 : //browse all node groups
767 : while (1) {
768 11696 : NDTBits = gf_bifs_get_ndt_bits(NDT_Tag, BVersion);
769 : /*this happens in replacescene where no top-level node is present (externProto)*/
770 11696 : if ((BVersion==1) && (NDTBits > 8 * gf_bs_available(bs)) ) {
771 10 : codec->LastError = GF_OK;
772 10 : return NULL;
773 : }
774 :
775 11686 : node_type = gf_bs_read_int(bs, NDTBits);
776 11686 : if (node_type) break;
777 :
778 : //increment BIFS version
779 5868 : BVersion += 1;
780 : //not supported
781 5868 : if (BVersion > GF_BIFS_NUM_VERSION) {
782 0 : codec->LastError = GF_BIFS_UNKNOWN_VERSION;
783 0 : return NULL;
784 : }
785 : }
786 5818 : if (BVersion==2 && node_type==1) {
787 323 : 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 323 : proto = gf_sg_find_proto(codec->current_graph, ProtoID, NULL);
790 : /*this was in proto so look in main scene*/
791 323 : if (!proto && codec->current_graph != codec->scenegraph)
792 0 : proto = gf_sg_find_proto(codec->scenegraph, ProtoID, NULL);
793 :
794 323 : if (!proto) {
795 0 : codec->LastError = GF_SG_UNKNOWN_NODE;
796 0 : return NULL;
797 : }
798 : } else {
799 5495 : node_tag = gf_bifs_ndt_get_node_type(NDT_Tag, node_type, BVersion);
800 : }
801 :
802 : /*special handling of 3D mesh*/
803 5495 : if ((node_tag == TAG_MPEG4_IndexedFaceSet) && codec->info->config.Use3DMeshCoding) {
804 0 : if (gf_bs_read_int(bs, 1)) {
805 0 : /*nodeID = 1 + */gf_bs_read_int(bs, codec->info->config.NodeIDBits);
806 0 : if (codec->UseName) gf_bifs_dec_name(bs, name);
807 : }
808 : /*parse the 3DMesh node*/
809 : return NULL;
810 : }
811 : /*unknown node*/
812 5818 : if (!node_tag && !proto) {
813 0 : codec->LastError = GF_SG_UNKNOWN_NODE;
814 0 : return NULL;
815 : }
816 :
817 :
818 : /*DEF'd flag*/
819 5818 : if (gf_bs_read_int(bs, 1)) {
820 1241 : if (!codec->info->config.NodeIDBits) {
821 0 : codec->LastError = GF_NON_COMPLIANT_BITSTREAM;
822 0 : return NULL;
823 : }
824 1241 : nodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits);
825 1241 : 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 5818 : if (proto) {
860 : /*create proto interface*/
861 323 : 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 323 : if (! proto->ExternProto.count) skip_init = GF_TRUE;
864 : } else {
865 5495 : new_node = gf_node_new(codec->current_graph, node_tag);
866 : }
867 : }
868 5818 : if (!new_node) {
869 0 : codec->LastError = GF_NOT_SUPPORTED;
870 0 : 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 5818 : if (nodeID) {
878 1241 : if (strlen(name)) {
879 0 : gf_node_set_id(new_node, nodeID, name);
880 : } else {
881 1241 : gf_node_set_id(new_node, nodeID, NULL);
882 : }
883 : }
884 :
885 :
886 : /*update default time fields except in proto parsing*/
887 5818 : 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 5818 : 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 5818 : switch (node_tag) {
898 521 : case TAG_MPEG4_Coordinate:
899 : case TAG_MPEG4_Coordinate2D:
900 521 : gf_bifs_dec_qp14_enter(codec, GF_TRUE);
901 : }
902 :
903 5818 : if (gf_bs_read_int(bs, 1)) {
904 4777 : e = gf_bifs_dec_node_mask(codec, bs, new_node, proto ? GF_TRUE : GF_FALSE);
905 : } else {
906 1041 : e = gf_bifs_dec_node_list(codec, bs, new_node, proto ? GF_TRUE : GF_FALSE);
907 : }
908 5818 : if (codec->coord_stored && reset_qp14)
909 60 : gf_bifs_dec_qp14_reset(codec);
910 :
911 5818 : if (e) {
912 0 : codec->LastError = e;
913 : /*register*/
914 0 : gf_node_register(new_node, NULL);
915 : /*unregister (deletes)*/
916 0 : gf_node_unregister(new_node, NULL);
917 0 : return NULL;
918 : }
919 :
920 5818 : if (!skip_init)
921 5463 : gf_node_init(new_node);
922 :
923 5818 : switch (node_tag) {
924 521 : case TAG_MPEG4_Coordinate:
925 : case TAG_MPEG4_Coordinate2D:
926 521 : gf_bifs_dec_qp14_enter(codec, GF_FALSE);
927 521 : break;
928 15 : case TAG_MPEG4_Script:
929 : /*load script if in main graph (useless to load in proto declaration)*/
930 15 : if (codec->scenegraph == codec->current_graph) {
931 15 : gf_sg_script_load(new_node);
932 : }
933 : break;
934 : /*conditionals must be init*/
935 90 : case TAG_MPEG4_Conditional:
936 90 : SetupConditional(codec, new_node);
937 90 : 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*/
|