LCOV - code coverage report
Current view: top level - bifs - field_decode.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 361 442 81.7 %
Date: 2021-04-29 23:48:07 Functions: 13 14 92.9 %

          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*/

Generated by: LCOV version 1.13