LCOV - code coverage report
Current view: top level - bifs - field_encode.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 305 347 87.9 %
Date: 2021-04-29 23:48:07 Functions: 9 9 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-2020
       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/internal/bifs_tables.h>
      30             : #include <gpac/network.h>
      31             : #include "quant.h"
      32             : #include "script.h"
      33             : 
      34             : #ifndef GPAC_DISABLE_BIFS_ENC
      35             : 
      36        4791 : GF_Err gf_bifs_field_index_by_mode(GF_Node *node, u32 all_ind, u8 indexMode, u32 *outField)
      37             : {
      38             :         GF_Err e;
      39             :         u32 i, count, temp;
      40        4791 :         count = gf_node_get_num_fields_in_mode(node, indexMode);
      41       13523 :         for (i=0; i<count; i++) {
      42       13523 :                 e = gf_bifs_get_field_index(node, i, indexMode, &temp);
      43       13523 :                 if (e) return e;
      44       13523 :                 if (temp==all_ind) {
      45        4791 :                         *outField = i;
      46        4791 :                         return GF_OK;
      47             :                 }
      48             :         }
      49             :         return GF_BAD_PARAM;
      50             : }
      51             : 
      52             : 
      53      148196 : void BE_WriteSFFloat(GF_BifsEncoder *codec, Fixed val, GF_BitStream *bs, char *com)
      54             : {
      55      148196 :         if (codec->ActiveQP && codec->ActiveQP->useEfficientCoding) {
      56         120 :                 gf_bifs_enc_mantissa_float(codec, val, bs);
      57             :         } else {
      58      148076 :                 gf_bs_write_float(bs, FIX2FLT(val));
      59      148076 :                 GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] SFFloat\t\t32\t\t%g\t\t%s\n", FIX2FLT(val), com ? com : "") );
      60             :         }
      61      148196 : }
      62             : 
      63             : 
      64      151921 : GF_Err gf_bifs_enc_sf_field(GF_BifsEncoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field)
      65             : {
      66             :         GF_Err e;
      67             : 
      68      151921 :         if (node) {
      69      151511 :                 e = gf_bifs_enc_quant_field(codec, bs, node, field);
      70      151511 :                 if (e != GF_EOS) return e;
      71             :         }
      72      149799 :         switch (field->fieldType) {
      73        1552 :         case GF_SG_VRML_SFBOOL:
      74        1552 :                 GF_BIFS_WRITE_INT(codec, bs, * ((SFBool *)field->far_ptr), 1, "SFBool", NULL);
      75             :                 break;
      76        1980 :         case GF_SG_VRML_SFCOLOR:
      77        1980 :                 BE_WriteSFFloat(codec, ((SFColor *)field->far_ptr)->red, bs, "color.red");
      78        1980 :                 BE_WriteSFFloat(codec, ((SFColor *)field->far_ptr)->green, bs, "color.green");
      79        1980 :                 BE_WriteSFFloat(codec, ((SFColor *)field->far_ptr)->blue, bs, "color.blue");
      80        1980 :                 break;
      81       19534 :         case GF_SG_VRML_SFFLOAT:
      82       19534 :                 BE_WriteSFFloat(codec, * ((SFFloat *)field->far_ptr), bs, NULL);
      83       19534 :                 break;
      84       54909 :         case GF_SG_VRML_SFINT32:
      85       54909 :                 GF_BIFS_WRITE_INT(codec, bs, * ((SFInt32 *)field->far_ptr), 32, "SFInt32", NULL);
      86             :                 break;
      87          12 :         case GF_SG_VRML_SFROTATION:
      88          12 :                 BE_WriteSFFloat(codec, ((SFRotation  *)field->far_ptr)->x, bs, "rot.x");
      89          12 :                 BE_WriteSFFloat(codec, ((SFRotation  *)field->far_ptr)->y, bs, "rot.y");
      90          12 :                 BE_WriteSFFloat(codec, ((SFRotation  *)field->far_ptr)->z, bs, "rot.z");
      91          12 :                 BE_WriteSFFloat(codec, ((SFRotation  *)field->far_ptr)->q, bs, "rot.theta");
      92          12 :                 break;
      93             : 
      94         534 :         case GF_SG_VRML_SFSTRING:
      95         534 :                 if (node && (node->sgprivate->tag==TAG_MPEG4_CacheTexture) && (field->fieldIndex<=2)) {
      96             :                         u32 size, val;
      97             :                         char buf[4096];
      98             :                         char *res_src = NULL;
      99           0 :                         const char *src = ((SFString*)field->far_ptr)->buffer;
     100             :                         FILE *f;
     101           0 :                         if (codec->src_url) res_src = gf_url_concatenate(codec->src_url, src);
     102             : 
     103           0 :                         f = gf_fopen(res_src ? res_src : src, "rb");
     104           0 :                         if (!f) {
     105           0 :                                 GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot open source file %s for encoding CacheTexture\n", res_src ? res_src : src));
     106           0 :                                 return GF_URL_ERROR;
     107             :                         }
     108           0 :                         if (res_src) gf_free(res_src);
     109           0 :                         size = (u32) gf_fsize(f);
     110           0 :                         val = gf_get_bit_size(size);
     111           0 :                         GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL);
     112           0 :                         GF_BIFS_WRITE_INT(codec, bs, size, val, "length", NULL);
     113             : 
     114           0 :                         while (size) {
     115           0 :                                 u32 read = (u32) gf_fread(buf, 4096, f);
     116           0 :                                 gf_bs_write_data(bs, buf, read);
     117           0 :                                 size -= read;
     118             :                         }
     119           0 :                         gf_fclose(f);
     120             :                 } else {
     121             :                         u32 i, val, len;
     122             :                         char *dump_str = NULL;
     123         534 :                         char *str = (char *) ((SFString*)field->far_ptr)->buffer;
     124         534 :                         if (node && (node->sgprivate->tag==TAG_MPEG4_BitWrapper) ) {
     125          21 :                                 len = ((M_BitWrapper*)node)->buffer_len;
     126             :                         } else {
     127         513 :                                 len = str ? (u32) strlen(str) : 0;
     128             :                                 dump_str = str;
     129             :                         }
     130         534 :                         val = gf_get_bit_size(len);
     131         534 :                         GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL);
     132         534 :                         GF_BIFS_WRITE_INT(codec, bs, len, val, "length", NULL);
     133      107164 :                         for (i=0; i<len; i++) gf_bs_write_int(bs, str[i], 8);
     134         534 :                         if (dump_str) {
     135         481 :                                 GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] string\t\t%d\t\t%s\n", 8*len, str) );
     136             :                         } else {
     137          53 :                                 GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] string\t\t%d\n", 8*len) );
     138             :                         }
     139             :                 }
     140             :                 break;
     141             : 
     142          56 :         case GF_SG_VRML_SFTIME:
     143          56 :                 gf_bs_write_double(bs, *((SFTime *)field->far_ptr));
     144          56 :                 GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] SFTime\t\t%d\t\t%g\n", 64, *((SFTime *)field->far_ptr)));
     145             :                 break;
     146             : 
     147       60137 :         case GF_SG_VRML_SFVEC2F:
     148       60137 :                 BE_WriteSFFloat(codec, ((SFVec2f *)field->far_ptr)->x, bs, "vec2f.x");
     149       60137 :                 BE_WriteSFFloat(codec, ((SFVec2f *)field->far_ptr)->y, bs, "vec2f.y");
     150       60137 :                 break;
     151             : 
     152         800 :         case GF_SG_VRML_SFVEC3F:
     153         800 :                 BE_WriteSFFloat(codec, ((SFVec3f *)field->far_ptr)->x, bs, "vec3f.x");
     154         800 :                 BE_WriteSFFloat(codec, ((SFVec3f *)field->far_ptr)->y, bs, "vec3f.y");
     155         800 :                 BE_WriteSFFloat(codec, ((SFVec3f *)field->far_ptr)->z, bs, "vec3f.z");
     156         800 :                 break;
     157             : 
     158         175 :         case GF_SG_VRML_SFURL:
     159             :         {
     160         175 :                 SFURL *url = (SFURL *) field->far_ptr;
     161         175 :                 GF_BIFS_WRITE_INT(codec, bs, (url->OD_ID>0) ? 1 : 0, 1, "hasODID", "SFURL");
     162         175 :                 if (url->OD_ID>0) {
     163         133 :                         GF_BIFS_WRITE_INT(codec, bs, url->OD_ID, 10, "ODID", "SFURL");
     164             :                 } else {
     165          42 :                         u32 i, len = url->url ? (u32) strlen(url->url) : 0;
     166          42 :                         u32 val = gf_get_bit_size(len);
     167          42 :                         GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL);
     168          42 :                         GF_BIFS_WRITE_INT(codec, bs, len, val, "length", NULL);
     169        1460 :                         for (i=0; i<len; i++) gf_bs_write_int(bs, url->url[i], 8);
     170          42 :                         GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] string\t\t%d\t\t%s\t\t//SFURL\n", 8*len, url->url));
     171             :                 }
     172             :         }
     173             :         break;
     174          20 :         case GF_SG_VRML_SFIMAGE:
     175             :         {
     176             :                 u32 size, i;
     177          20 :                 SFImage *img = (SFImage *)field->far_ptr;
     178          20 :                 GF_BIFS_WRITE_INT(codec, bs, img->width, 12, "width", "SFImage");
     179          20 :                 GF_BIFS_WRITE_INT(codec, bs, img->height, 12, "height", "SFImage");
     180          20 :                 GF_BIFS_WRITE_INT(codec, bs, img->numComponents - 1, 2, "nbComp", "SFImage");
     181          20 :                 size = img->width * img->height * img->numComponents;
     182          20 :                 for (i=0; i<size; i++) gf_bs_write_int(bs, img->pixels[i], 8);
     183          20 :                 GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] pixels\t\t%d\t\tnot dumped\t\t//SFImage\n", 8*size));
     184             :         }
     185             :         break;
     186             : 
     187         141 :         case GF_SG_VRML_SFCOMMANDBUFFER:
     188             :         {
     189         141 :                 SFCommandBuffer *cb = (SFCommandBuffer *) field->far_ptr;
     190         141 :                 if (cb->buffer) gf_free(cb->buffer);
     191         141 :                 cb->buffer = NULL;
     192         141 :                 cb->bufferSize = 0;
     193         141 :                 if (gf_list_count(cb->commandList)) {
     194             :                         u32 i, nbBits;
     195         141 :                         GF_BitStream *bs_cond = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
     196         141 :                         GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] /*SFCommandBuffer*/\n" ));
     197         141 :                         e = gf_bifs_enc_commands(codec, cb->commandList, bs_cond);
     198         141 :                         if (!e) gf_bs_get_content(bs_cond, &cb->buffer, &cb->bufferSize);
     199         141 :                         gf_bs_del(bs_cond);
     200         141 :                         if (e) return e;
     201         141 :                         GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] /*End SFCommandBuffer*/\n"));
     202         141 :                         nbBits = gf_get_bit_size(cb->bufferSize);
     203         141 :                         GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "NbBits", NULL);
     204         141 :                         GF_BIFS_WRITE_INT(codec, bs, cb->bufferSize, nbBits, "BufferSize", NULL);
     205        1824 :                         for (i=0; i<cb->bufferSize; i++) GF_BIFS_WRITE_INT(codec, bs, cb->buffer[i], 8, "buffer byte", NULL);
     206             :                 }
     207             :                 /*empty command buffer*/
     208             :                 else {
     209           0 :                         GF_BIFS_WRITE_INT(codec, bs, 0, 5, "NbBits", NULL);
     210             :                 }
     211             :         }
     212             :         break;
     213             : 
     214        9929 :         case GF_SG_VRML_SFNODE:
     215        9929 :                 return gf_bifs_enc_node(codec, *((GF_Node **)field->far_ptr), field->NDTtype, bs, node);
     216             : 
     217          20 :         case GF_SG_VRML_SFSCRIPT:
     218             : #ifdef GPAC_HAS_QJS
     219          20 :                 codec->LastError = SFScript_Encode(codec, (SFScript *)field->far_ptr, bs, node);
     220             : #else
     221             :                 return GF_NOT_SUPPORTED;
     222             : #endif
     223          20 :                 break;
     224           0 :         case GF_SG_VRML_SFATTRREF:
     225             :         {
     226           0 :                 u32 idx=0;
     227           0 :                 SFAttrRef *ar = (SFAttrRef *)field->far_ptr;
     228           0 :                 u32 nbBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(ar->node, GF_SG_FIELD_CODING_DEF) - 1);
     229           0 :                 GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(ar->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL);
     230             : 
     231           0 :                 gf_bifs_field_index_by_mode(ar->node, ar->fieldIndex, GF_SG_FIELD_CODING_DEF, &idx);
     232           0 :                 GF_BIFS_WRITE_INT(codec, bs, idx, nbBitsDEF, "field", NULL);
     233             :         }
     234           0 :         break;
     235             :         default:
     236             :                 return GF_NOT_SUPPORTED;
     237             :         }
     238      139870 :         return codec->LastError;
     239             : }
     240             : 
     241             : 
     242        9384 : GF_Err gf_bifs_enc_mf_field(GF_BifsEncoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field)
     243             : {
     244             :         GF_ChildNodeItem *list = NULL;
     245             :         GF_Err e;
     246             :         u32 nbBits, qp_local;
     247             :         Bool use_list, qp_on, initial_qp;
     248             :         u32 nbF, i;
     249             :         GF_FieldInfo sffield;
     250             : 
     251             :         nbF = 0;
     252        9384 :         if (field->fieldType != GF_SG_VRML_MFNODE) {
     253        4540 :                 nbF = field->far_ptr ? ((GenMFField *)field->far_ptr)->count : 0;
     254        4540 :                 if (!nbF && (field->fieldType == GF_SG_VRML_MFSCRIPT))
     255             :                         nbF = 1;
     256        4844 :         } else if (field->far_ptr) {
     257        4844 :                 list = *((GF_ChildNodeItem **)field->far_ptr);
     258        4844 :                 nbF = gf_node_list_get_count(list);
     259             :         }
     260             :         /*reserved*/
     261        9384 :         GF_BIFS_WRITE_INT(codec, bs, 0, 1, "reserved", NULL);
     262        9384 :         if (!nbF) {
     263             :                 /*is list*/
     264           2 :                 GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL);
     265             :                 /*end flag*/
     266           2 :                 GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);
     267             :                 return GF_OK;
     268             :         }
     269             : 
     270             :         /*do we work in list or vector*/
     271             :         use_list = GF_FALSE;
     272        9382 :         nbBits = gf_get_bit_size(nbF);
     273        9382 :         if (nbBits + 5 > nbF + 1) use_list = GF_TRUE;
     274             : 
     275        9382 :         GF_BIFS_WRITE_INT(codec, bs, use_list, 1, "isList", NULL);
     276        9382 :         if (!use_list) {
     277        2900 :                 GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL);
     278        2900 :                 GF_BIFS_WRITE_INT(codec, bs, nbF, nbBits, "length", NULL);
     279             :         }
     280             : 
     281             :         memset(&sffield, 0, sizeof(GF_FieldInfo));
     282        9382 :         sffield.fieldIndex = field->fieldIndex;
     283        9382 :         sffield.fieldType = gf_sg_vrml_get_sf_type(field->fieldType);
     284        9382 :         sffield.NDTtype = field->NDTtype;
     285             : 
     286             :         qp_on = GF_FALSE;
     287             :         qp_local = 0;
     288        9382 :         initial_qp = codec->ActiveQP ? GF_TRUE : GF_FALSE;
     289      138393 :         for (i=0; i<nbF; i++) {
     290             : 
     291      129011 :                 if (use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL);
     292             : 
     293      129011 :                 if (field->fieldType != GF_SG_VRML_MFNODE) {
     294      120199 :                         gf_sg_vrml_mf_get_item(field->far_ptr, field->fieldType, &sffield.far_ptr, i);
     295      120199 :                         e = gf_bifs_enc_sf_field(codec, bs, node, &sffield);
     296             :                 } else {
     297             :                         assert(list);
     298        8812 :                         e = gf_bifs_enc_node(codec, list->node, field->NDTtype, bs, node);
     299             : 
     300             :                         /*activate QP*/
     301        8812 :                         if (list->node->sgprivate->tag == TAG_MPEG4_QuantizationParameter) {
     302          49 :                                 qp_local = ((M_QuantizationParameter *)list->node)->isLocal;
     303          49 :                                 if (qp_on) gf_bifs_enc_qp_remove(codec, GF_FALSE);
     304          49 :                                 e = gf_bifs_enc_qp_set(codec, list->node);
     305          49 :                                 if (e) return e;
     306             :                                 qp_on = GF_TRUE;
     307          49 :                                 if (qp_local) qp_local = 2;
     308             :                         }
     309        8812 :                         list = list->next;
     310             :                 }
     311             : 
     312      129011 :                 if (e) return e;
     313             : 
     314      129011 :                 if (qp_on && qp_local) {
     315          40 :                         if (qp_local == 2) qp_local -= 1;
     316             :                         else {
     317          20 :                                 gf_bifs_enc_qp_remove(codec, initial_qp);
     318             :                                 qp_local = qp_on = GF_FALSE;
     319             :                         }
     320             :                 }
     321             :         }
     322             : 
     323        9382 :         if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);
     324        9382 :         if (qp_on) gf_bifs_enc_qp_remove(codec, initial_qp);
     325             :         /*for QP14*/
     326        9382 :         gf_bifs_enc_qp14_set_length(codec, nbF);
     327        9382 :         return GF_OK;
     328             : }
     329             : 
     330             : 
     331       40676 : GF_Err gf_bifs_enc_field(GF_BifsEncoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field)
     332             : {
     333             :         assert(node);
     334       40676 :         if (field->fieldType == GF_SG_VRML_UNKNOWN)
     335             :                 return GF_NON_COMPLIANT_BITSTREAM;
     336             : 
     337       40676 :         if (gf_sg_vrml_is_sf_field(field->fieldType)) {
     338       31316 :                 return gf_bifs_enc_sf_field(codec, bs, node, field);
     339             :         }
     340             : 
     341             :         /*TO DO : PMF support*/
     342             : 
     343        9360 :         if (codec->info->config.UsePredictiveMFField) {
     344           0 :                 GF_BIFS_WRITE_INT(codec, bs, 0, 1, "usePredictive", NULL);
     345             :         }
     346        9360 :         return gf_bifs_enc_mf_field(codec, bs, node, field);
     347             : }
     348             : 
     349             : /*we assume a node field is not ISed several times (that's stated as "undefined behavior" in VRML*/
     350        1988 : GF_Route *gf_bifs_enc_is_field_ised(GF_BifsEncoder *codec, GF_Node *node, u32 fieldIndex)
     351             : {
     352             :         GF_Route *r;
     353             :         u32 i;
     354        1988 :         if (!codec->encoding_proto) return NULL;
     355             : 
     356        1988 :         if (node->sgprivate->interact && node->sgprivate->interact->routes) {
     357         863 :                 i=0;
     358        2722 :                 while ((r = (GF_Route*)gf_list_enum(node->sgprivate->interact->routes, &i))) {
     359        1394 :                         if (!r->IS_route) continue;
     360        1346 :                         if ((r->ToNode == node) && (r->ToField.fieldIndex==fieldIndex)) return r;
     361        1346 :                         else if ((r->FromNode == node) && (r->FromField.fieldIndex==fieldIndex)) return r;
     362             :                 }
     363             :         }
     364             : 
     365        1590 :         i=0;
     366       25488 :         while ((r = (GF_Route*)gf_list_enum(codec->encoding_proto->sub_graph->Routes, &i))) {
     367       22388 :                 if (!r->IS_route) continue;
     368       21228 :                 if ((r->ToNode == node) && (r->ToField.fieldIndex==fieldIndex)) return r;
     369       21148 :                 else if ((r->FromNode == node) && (r->FromField.fieldIndex==fieldIndex)) return r;
     370             :         }
     371             :         return NULL;
     372             : }
     373             : 
     374             : /**/
     375       16737 : GF_Err EncNodeFields(GF_BifsEncoder * codec, GF_BitStream *bs, GF_Node *node)
     376             : {
     377             :         u8 mode;
     378             :         GF_Route *isedField;
     379             :         GF_Node *clone;
     380             :         GF_Err e;
     381             :         s32 *enc_fields;
     382             :         u32 numBitsALL, numBitsDEF, allInd, count, i, nbBitsProto, nbFinal;
     383             :         Bool use_list, nodeIsFDP = GF_FALSE;
     384             :         GF_FieldInfo field, clone_field;
     385             : 
     386             :         e = GF_OK;
     387             : 
     388       16737 :         if (codec->encoding_proto) {
     389             :                 mode = GF_SG_FIELD_CODING_ALL;
     390         350 :                 nbBitsProto = gf_get_bit_size(gf_sg_proto_get_field_count(codec->encoding_proto) - 1);
     391         350 :                 numBitsALL = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL) - 1);
     392             :         } else {
     393             :                 mode = GF_SG_FIELD_CODING_DEF;
     394             :                 nbBitsProto = 0;
     395             :                 numBitsALL = 0;
     396             :         }
     397       16737 :         count = gf_node_get_num_fields_in_mode(node, mode);
     398       16737 :         if (node->sgprivate->tag==TAG_MPEG4_Script) count = 3;
     399             : 
     400       16717 :         if (!count) {
     401           0 :                 GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isMask", NULL);
     402           0 :                 GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);
     403             :                 return GF_OK;
     404             :         }
     405             : 
     406       16737 :         if (node->sgprivate->tag == TAG_ProtoNode) {
     407         333 :                 clone = gf_sg_proto_create_instance(node->sgprivate->scenegraph, ((GF_ProtoInstance *)node)->proto_interface);
     408             :         } else {
     409       16404 :                 clone = gf_node_new(node->sgprivate->scenegraph, node->sgprivate->tag);
     410             :         }
     411       16737 :         if (clone) gf_node_register(clone, NULL);
     412             : 
     413       16737 :         numBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF) - 1);
     414             : 
     415       16737 :         enc_fields = (s32*)gf_malloc(sizeof(s32) * count);
     416             :         nbFinal = 0;
     417       87026 :         for (i=0; i<count; i++) {
     418       70289 :                 enc_fields[i] = -1;
     419             :                 /*get field in ALL mode*/
     420       70289 :                 if (mode == GF_SG_FIELD_CODING_ALL) {
     421        1292 :                         allInd = i;
     422             :                 } else {
     423       68997 :                         gf_bifs_get_field_index(node, i, GF_SG_FIELD_CODING_DEF, &allInd);
     424             :                 }
     425             : 
     426             :                 /*encode proto code*/
     427       70289 :                 if (codec->encoding_proto) {
     428        1292 :                         isedField = gf_bifs_enc_is_field_ised(codec, node, allInd);
     429        1292 :                         if (isedField) {
     430         239 :                                 enc_fields[i] = allInd;
     431         239 :                                 nbFinal ++;
     432         239 :                                 continue;
     433             :                         }
     434             :                 }
     435             :                 /*common case*/
     436       70050 :                 gf_node_get_field(node, allInd, &field);
     437             :                 /*if event don't encode (happens when encoding protos)*/
     438       70050 :                 if ((field.eventType == GF_SG_EVENT_IN) || (field.eventType == GF_SG_EVENT_OUT)) continue;
     439             :                 /*if field is default skip*/
     440       69820 :                 switch (field.fieldType) {
     441       14991 :                 case GF_SG_VRML_SFNODE:
     442       14991 :                         if (* (GF_Node **) field.far_ptr) {
     443        9849 :                                 enc_fields[i] = allInd;
     444        9849 :                                 nbFinal++;
     445             :                         }
     446             :                         break;
     447        5221 :                 case GF_SG_VRML_MFNODE:
     448        5221 :                         if (* (GF_ChildNodeItem **) field.far_ptr) {
     449        4838 :                                 enc_fields[i] = allInd;
     450        4838 :                                 nbFinal++;
     451             :                         }
     452             :                         break;
     453         165 :                 case GF_SG_VRML_SFCOMMANDBUFFER:
     454             :                 {
     455         165 :                         SFCommandBuffer *cb = (SFCommandBuffer *)field.far_ptr;
     456         165 :                         if (gf_list_count(cb->commandList)) {
     457         141 :                                 enc_fields[i] = allInd;
     458         141 :                                 nbFinal++;
     459             :                         }
     460             :                 }
     461             :                 break;
     462          20 :                 case GF_SG_VRML_MFSCRIPT:
     463          20 :                         enc_fields[i] = allInd;
     464          20 :                         nbFinal++;
     465          20 :                         break;
     466       49423 :                 default:
     467       49423 :                         gf_node_get_field(clone, allInd, &clone_field);
     468       49423 :                         if (!gf_sg_vrml_field_equal(clone_field.far_ptr, field.far_ptr, field.fieldType)) {
     469       25322 :                                 enc_fields[i] = allInd;
     470       25322 :                                 nbFinal++;
     471             :                         }
     472             :                         break;
     473             :                 }
     474             :         }
     475       16737 :         if (clone) gf_node_unregister(clone, NULL);
     476             : 
     477             :         use_list = GF_TRUE;
     478             :         /* patch for FDP node : */
     479             :         /* cannot use default field sorting due to spec "mistake", so use list to imply inversion between field 2 and field 3 of FDP*/
     480       16737 :         if (node->sgprivate->tag == TAG_MPEG4_FDP) {
     481           0 :                 s32 s4SwapValue = enc_fields[2];
     482           0 :                 enc_fields[2] = enc_fields[3];
     483           0 :                 enc_fields[3] = s4SwapValue;
     484             :                 nodeIsFDP = GF_TRUE;
     485             :                 use_list = GF_TRUE;
     486             :         }
     487             :         /*number of bits in mask node is count*1, in list node is 1+nbFinal*(1+numBitsDEF) */
     488       16737 :         else if (count < 1+nbFinal*(1+numBitsDEF))
     489             :                 use_list = GF_FALSE;
     490             : 
     491       16737 :         GF_BIFS_WRITE_INT(codec, bs, use_list ? 0 : 1, 1, "isMask", NULL);
     492             : 
     493       70289 :         for (i=0; i<count; i++) {
     494       70289 :                 if (enc_fields[i] == -1) {
     495       29880 :                         if (!use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "Mask", NULL);
     496       29880 :                         continue;
     497             :                 }
     498       40409 :                 allInd = (u32) enc_fields[i];
     499             : 
     500             :                 /*encode proto code*/
     501       40409 :                 if (codec->encoding_proto) {
     502         696 :                         isedField = gf_bifs_enc_is_field_ised(codec, node, allInd);
     503         696 :                         if (isedField) {
     504         239 :                                 if (use_list) {
     505          40 :                                         GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL);
     506             :                                 } else {
     507         199 :                                         GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL);
     508             :                                 }
     509         239 :                                 GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isedField", NULL);
     510         239 :                                 if (use_list) GF_BIFS_WRITE_INT(codec, bs, allInd, numBitsALL, "nodeField", NULL);
     511             : 
     512         239 :                                 if (isedField->ToNode == node) {
     513          40 :                                         GF_BIFS_WRITE_INT(codec, bs, isedField->FromField.fieldIndex, nbBitsProto, "protoField", NULL);
     514             :                                 } else {
     515         199 :                                         GF_BIFS_WRITE_INT(codec, bs, isedField->ToField.fieldIndex, nbBitsProto, "protoField", NULL);
     516             :                                 }
     517         239 :                                 continue;
     518             :                         }
     519             :                 }
     520             :                 /*common case*/
     521       40170 :                 gf_node_get_field(node, allInd, &field);
     522       40170 :                 if (use_list) {
     523             :                         /*not end flag*/
     524        1541 :                         GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL);
     525             :                 } else {
     526             :                         /*mask flag*/
     527       38629 :                         GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL);
     528             :                 }
     529             :                 /*not ISed field*/
     530       40170 :                 if (codec->encoding_proto) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isedField", NULL);
     531       40170 :                 if (use_list) {
     532        1592 :                         if (codec->encoding_proto || nodeIsFDP) {
     533          51 :                                 u32 ind=0;
     534             :                                 /*for proto, we're in ALL mode and we need DEF mode*/
     535             :                                 /*for FDP, encoding requires to get def id from all id as fields 2 and 3 are reversed*/
     536          51 :                                 gf_bifs_field_index_by_mode(node, allInd, GF_SG_FIELD_CODING_DEF, &ind);
     537          51 :                                 GF_BIFS_WRITE_INT(codec, bs, ind, numBitsDEF, "field", (char*)field.name);
     538             :                         } else {
     539        1490 :                                 GF_BIFS_WRITE_INT(codec, bs, i, numBitsDEF, "field", (char*)field.name);
     540             :                         }
     541             :                 }
     542       40170 :                 e = gf_bifs_enc_field(codec, bs, node, &field);
     543       40170 :                 if (e) goto exit;
     544             :         }
     545             :         /*end flag*/
     546       18741 :         if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);
     547       33278 : exit:
     548       16737 :         gf_free(enc_fields);
     549       16737 :         return e;
     550             : }
     551             : 
     552       22810 : Bool BE_NodeIsUSE(GF_BifsEncoder * codec, GF_Node *node)
     553             : {
     554             :         u32 i, count;
     555       22810 :         if (!node || !gf_node_get_id(node) ) return GF_FALSE;
     556        8310 :         count = gf_list_count(codec->encoded_nodes);
     557      739478 :         for (i=0; i<count; i++) {
     558      737241 :                 if (gf_list_get(codec->encoded_nodes, i) == node) return GF_TRUE;
     559             :         }
     560        2237 :         gf_list_add(codec->encoded_nodes, node);
     561        2237 :         return GF_FALSE;
     562             : }
     563             : 
     564       22905 : GF_Err gf_bifs_enc_node(GF_BifsEncoder * codec, GF_Node *node, u32 NDT_Tag, GF_BitStream *bs, GF_Node *parent_node)
     565             : {
     566             :         u32 NDTBits, node_type, node_tag, BVersion, node_id;
     567             :         const char *node_name;
     568             :         Bool flag, reset_qp14;
     569             :         GF_Err e;
     570             : 
     571             :         assert(codec->info);
     572       22905 :         GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[BIFS] Encode node %s\n", gf_node_get_class_name(node) ));
     573             : 
     574             :         /*NULL node is a USE of maxID*/
     575       22905 :         if (!node) {
     576          95 :                 GF_BIFS_WRITE_INT(codec, bs, 1, 1, "USE", NULL);
     577          95 :                 GF_BIFS_WRITE_INT(codec, bs, (1<<codec->info->config.NodeIDBits) - 1 , codec->info->config.NodeIDBits, "NodeID", "NULL");
     578             :                 return GF_OK;
     579             :         }
     580             : 
     581       22810 :         flag = BE_NodeIsUSE(codec, node);
     582       22810 :         GF_BIFS_WRITE_INT(codec, bs, flag ? 1 : 0, 1, "USE", (char*)gf_node_get_class_name(node));
     583             : 
     584       22810 :         if (flag) {
     585             :                 GF_Node *new_node;
     586        6073 :                 gf_bs_write_int(bs, gf_node_get_id(node) - 1, codec->info->config.NodeIDBits);
     587        6073 :                 new_node = gf_bifs_enc_find_node(codec, gf_node_get_id(node) );
     588        6073 :                 if (!new_node)
     589           0 :                         return codec->LastError = GF_SG_UNKNOWN_NODE;
     590             : 
     591             :                 /*restore QP14 length*/
     592        6073 :                 switch (gf_node_get_tag(new_node)) {
     593           0 :                 case TAG_MPEG4_Coordinate:
     594             :                 {
     595           0 :                         u32 nbCoord = ((M_Coordinate *)new_node)->point.count;
     596           0 :                         gf_bifs_enc_qp14_enter(codec, GF_TRUE);
     597           0 :                         gf_bifs_enc_qp14_set_length(codec, nbCoord);
     598           0 :                         gf_bifs_enc_qp14_enter(codec, GF_FALSE);
     599             :                 }
     600           0 :                 break;
     601          96 :                 case TAG_MPEG4_Coordinate2D:
     602             :                 {
     603          96 :                         u32 nbCoord = ((M_Coordinate2D *)new_node)->point.count;
     604          96 :                         gf_bifs_enc_qp14_enter(codec, GF_TRUE);
     605          96 :                         gf_bifs_enc_qp14_set_length(codec, nbCoord);
     606          96 :                         gf_bifs_enc_qp14_enter(codec, GF_FALSE);
     607             :                 }
     608          96 :                 break;
     609             :                 }
     610             :                 return GF_OK;
     611             :         }
     612             : 
     613             :         BVersion = GF_BIFS_V1;
     614       16737 :         node_tag = node->sgprivate->tag;
     615             :         while (1) {
     616       37479 :                 node_type = gf_bifs_get_node_type(NDT_Tag, node_tag, BVersion);
     617       37479 :                 NDTBits = gf_bifs_get_ndt_bits(NDT_Tag, BVersion);
     618       37479 :                 if (BVersion==2 && (node_tag==TAG_ProtoNode)) node_type = 1;
     619       37479 :                 GF_BIFS_WRITE_INT(codec, bs, node_type, NDTBits, "ndt", NULL);
     620       37479 :                 if (node_type) break;
     621             : 
     622       20742 :                 BVersion += 1;
     623       20742 :                 if (BVersion > GF_BIFS_NUM_VERSION) {
     624           0 :                         if (parent_node) {
     625           0 :                                 GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot encode node %s as a child of %s\n", gf_node_get_class_name(node), gf_node_get_class_name(parent_node) ));
     626             :                         } else {
     627           0 :                                 GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot encode node %s in the SFWorldNode context\n", gf_node_get_class_name(node) ));
     628             :                         }
     629           0 :                         return codec->LastError = GF_BIFS_UNKNOWN_VERSION;
     630             :                 }
     631             :         }
     632       16737 :         if (BVersion==2 && node_type==1) {
     633         333 :                 GF_Proto *proto = ((GF_ProtoInstance *)node)->proto_interface;
     634         333 :                 GF_BIFS_WRITE_INT(codec, bs, proto->ID, codec->info->config.ProtoIDBits, "protoID", NULL);
     635             :         }
     636             : 
     637             :         /*special handling of 3D mesh*/
     638             : 
     639             :         /*DEF'd node*/
     640       16737 :         node_name = gf_node_get_name_and_id(node, &node_id);
     641       16737 :         GF_BIFS_WRITE_INT(codec, bs, node_id ? 1 : 0, 1, "DEF", NULL);
     642       16737 :         if (node_id) {
     643        2237 :                 GF_BIFS_WRITE_INT(codec, bs, node_id - 1, codec->info->config.NodeIDBits, "NodeID", NULL);
     644        2237 :                 if (codec->UseName) gf_bifs_enc_name(codec, bs, (char*) node_name );
     645             :         }
     646             : 
     647             :         /*no updates of time fields for now - NEEDED FOR A LIVE ENCODER*/
     648             : 
     649             :         /*if coords were not stored for QP14 before coding this node, reset QP14 it when leaving*/
     650       16737 :         reset_qp14 = !codec->coord_stored;
     651             : 
     652             :         /*QP14 case*/
     653       16737 :         switch (node_tag) {
     654        1677 :         case TAG_MPEG4_Coordinate:
     655             :         case TAG_MPEG4_Coordinate2D:
     656        1677 :                 gf_bifs_enc_qp14_enter(codec, GF_TRUE);
     657             :         }
     658             : 
     659       16737 :         e = EncNodeFields(codec, bs, node);
     660       16737 :         if (e) return e;
     661             : 
     662       16737 :         if (codec->coord_stored && reset_qp14)
     663         116 :                 gf_bifs_enc_qp14_reset(codec);
     664             : 
     665       16737 :         switch (node_tag) {
     666        1677 :         case TAG_MPEG4_Coordinate:
     667             :         case TAG_MPEG4_Coordinate2D:
     668        1677 :                 gf_bifs_enc_qp14_enter(codec, GF_FALSE);
     669        1677 :                 break;
     670             :         }
     671             :         return GF_OK;
     672             : }
     673             : 
     674             : 
     675             : #endif /*GPAC_DISABLE_BIFS_ENC*/

Generated by: LCOV version 1.13