LCOV - code coverage report
Current view: top level - bifs - com_enc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 493 557 88.5 %
Date: 2021-04-29 23:48:07 Functions: 20 20 100.0 %

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

Generated by: LCOV version 1.13