Coverage Report

Created: 2025-11-24 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gpac/src/bifs/field_encode.c
Line
Count
Source
1
/*
2
 *      GPAC - Multimedia Framework C SDK
3
 *
4
 *      Authors: Jean Le Feuvre
5
 *      Copyright (c) Telecom ParisTech 2000-2024
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
GF_Err gf_bifs_field_index_by_mode(GF_Node *node, u32 all_ind, u8 indexMode, u32 *outField)
37
0
{
38
0
  GF_Err e;
39
0
  u32 i, count, temp;
40
0
  count = gf_node_get_num_fields_in_mode(node, indexMode);
41
0
  for (i=0; i<count; i++) {
42
0
    e = gf_bifs_get_field_index(node, i, indexMode, &temp);
43
0
    if (e) return e;
44
0
    if (temp==all_ind) {
45
0
      *outField = i;
46
0
      return GF_OK;
47
0
    }
48
0
  }
49
0
  return GF_BAD_PARAM;
50
0
}
51
52
53
void BE_WriteSFFloat(GF_BifsEncoder *codec, Fixed val, GF_BitStream *bs, char *com)
54
0
{
55
0
  if (codec->ActiveQP && codec->ActiveQP->useEfficientCoding) {
56
0
    gf_bifs_enc_mantissa_float(codec, val, bs);
57
0
  } else {
58
0
    gf_bs_write_float(bs, FIX2FLT(val));
59
0
    GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] SFFloat\t\t32\t\t%g\t\t%s\n", FIX2FLT(val), com ? com : "") );
60
0
  }
61
0
}
62
63
64
GF_Err gf_bifs_enc_sf_field(GF_BifsEncoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field)
65
0
{
66
0
  GF_Err e;
67
68
0
  if (node) {
69
0
    e = gf_bifs_enc_quant_field(codec, bs, node, field);
70
0
    if (e != GF_EOS) return e;
71
0
  }
72
0
  switch (field->fieldType) {
73
0
  case GF_SG_VRML_SFBOOL:
74
0
    GF_BIFS_WRITE_INT(codec, bs, * ((SFBool *)field->far_ptr), 1, "SFBool", NULL);
75
0
    break;
76
0
  case GF_SG_VRML_SFCOLOR:
77
0
    BE_WriteSFFloat(codec, ((SFColor *)field->far_ptr)->red, bs, "color.red");
78
0
    BE_WriteSFFloat(codec, ((SFColor *)field->far_ptr)->green, bs, "color.green");
79
0
    BE_WriteSFFloat(codec, ((SFColor *)field->far_ptr)->blue, bs, "color.blue");
80
0
    break;
81
0
  case GF_SG_VRML_SFFLOAT:
82
0
    BE_WriteSFFloat(codec, * ((SFFloat *)field->far_ptr), bs, NULL);
83
0
    break;
84
0
  case GF_SG_VRML_SFINT32:
85
0
    GF_BIFS_WRITE_INT(codec, bs, * ((SFInt32 *)field->far_ptr), 32, "SFInt32", NULL);
86
0
    break;
87
0
  case GF_SG_VRML_SFROTATION:
88
0
    BE_WriteSFFloat(codec, ((SFRotation  *)field->far_ptr)->x, bs, "rot.x");
89
0
    BE_WriteSFFloat(codec, ((SFRotation  *)field->far_ptr)->y, bs, "rot.y");
90
0
    BE_WriteSFFloat(codec, ((SFRotation  *)field->far_ptr)->z, bs, "rot.z");
91
0
    BE_WriteSFFloat(codec, ((SFRotation  *)field->far_ptr)->q, bs, "rot.theta");
92
0
    break;
93
94
0
  case GF_SG_VRML_SFSTRING:
95
0
    if (node && (node->sgprivate->tag==TAG_MPEG4_CacheTexture) && (field->fieldIndex<=2)) {
96
0
      u32 size, val;
97
0
      char buf[2048];
98
0
      char *res_src = NULL;
99
0
      const char *src = ((SFString*)field->far_ptr)->buffer;
100
0
      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
0
      }
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
0
      }
119
0
      gf_fclose(f);
120
0
    } else {
121
0
      u32 i, val, len;
122
0
      char *dump_str = NULL;
123
0
      char *str = (char *) ((SFString*)field->far_ptr)->buffer;
124
0
      if (node && (node->sgprivate->tag==TAG_MPEG4_BitWrapper) ) {
125
0
        len = ((M_BitWrapper*)node)->buffer_len;
126
0
      } else {
127
0
        len = str ? (u32) strlen(str) : 0;
128
0
        dump_str = str;
129
0
      }
130
0
      val = gf_get_bit_size(len);
131
0
      GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL);
132
0
      GF_BIFS_WRITE_INT(codec, bs, len, val, "length", NULL);
133
0
      for (i=0; i<len; i++) gf_bs_write_int(bs, str[i], 8);
134
0
      if (dump_str) {
135
0
        GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] string\t\t%d\t\t%s\n", 8*len, str) );
136
0
      } else {
137
0
        GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] string\t\t%d\n", 8*len) );
138
0
      }
139
0
    }
140
0
    break;
141
142
0
  case GF_SG_VRML_SFTIME:
143
0
    gf_bs_write_double(bs, *((SFTime *)field->far_ptr));
144
0
    GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] SFTime\t\t%d\t\t%g\n", 64, *((SFTime *)field->far_ptr)));
145
0
    break;
146
147
0
  case GF_SG_VRML_SFVEC2F:
148
0
    BE_WriteSFFloat(codec, ((SFVec2f *)field->far_ptr)->x, bs, "vec2f.x");
149
0
    BE_WriteSFFloat(codec, ((SFVec2f *)field->far_ptr)->y, bs, "vec2f.y");
150
0
    break;
151
152
0
  case GF_SG_VRML_SFVEC3F:
153
0
    BE_WriteSFFloat(codec, ((SFVec3f *)field->far_ptr)->x, bs, "vec3f.x");
154
0
    BE_WriteSFFloat(codec, ((SFVec3f *)field->far_ptr)->y, bs, "vec3f.y");
155
0
    BE_WriteSFFloat(codec, ((SFVec3f *)field->far_ptr)->z, bs, "vec3f.z");
156
0
    break;
157
158
0
  case GF_SG_VRML_SFURL:
159
0
  {
160
0
    SFURL *url = (SFURL *) field->far_ptr;
161
0
    GF_BIFS_WRITE_INT(codec, bs, (url->OD_ID>0) ? 1 : 0, 1, "hasODID", "SFURL");
162
0
    if (url->OD_ID>0) {
163
0
      GF_BIFS_WRITE_INT(codec, bs, url->OD_ID, 10, "ODID", "SFURL");
164
0
    } else {
165
0
      u32 i, len = url->url ? (u32) strlen(url->url) : 0;
166
0
      u32 val = gf_get_bit_size(len);
167
0
      GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL);
168
0
      GF_BIFS_WRITE_INT(codec, bs, len, val, "length", NULL);
169
0
      for (i=0; i<len; i++) gf_bs_write_int(bs, url->url[i], 8);
170
0
      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
0
    }
172
0
  }
173
0
  break;
174
0
  case GF_SG_VRML_SFIMAGE:
175
0
  {
176
0
    u32 size, i;
177
0
    SFImage *img = (SFImage *)field->far_ptr;
178
0
    GF_BIFS_WRITE_INT(codec, bs, img->width, 12, "width", "SFImage");
179
0
    GF_BIFS_WRITE_INT(codec, bs, img->height, 12, "height", "SFImage");
180
0
    GF_BIFS_WRITE_INT(codec, bs, img->numComponents - 1, 2, "nbComp", "SFImage");
181
0
    size = img->width * img->height * img->numComponents;
182
0
    for (i=0; i<size; i++) gf_bs_write_int(bs, img->pixels[i], 8);
183
0
    GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] pixels\t\t%d\t\tnot dumped\t\t//SFImage\n", 8*size));
184
0
  }
185
0
  break;
186
187
0
  case GF_SG_VRML_SFCOMMANDBUFFER:
188
0
  {
189
0
    SFCommandBuffer *cb = (SFCommandBuffer *) field->far_ptr;
190
0
    if (cb->buffer) gf_free(cb->buffer);
191
0
    cb->buffer = NULL;
192
0
    cb->bufferSize = 0;
193
0
    if (gf_list_count(cb->commandList)) {
194
0
      u32 i, nbBits;
195
0
      GF_BitStream *bs_cond = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
196
0
      GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] /*SFCommandBuffer*/\n" ));
197
0
      e = gf_bifs_enc_commands(codec, cb->commandList, bs_cond);
198
0
      if (!e) gf_bs_get_content(bs_cond, &cb->buffer, &cb->bufferSize);
199
0
      gf_bs_del(bs_cond);
200
0
      if (e) return e;
201
0
      GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] /*End SFCommandBuffer*/\n"));
202
0
      nbBits = gf_get_bit_size(cb->bufferSize);
203
0
      GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "NbBits", NULL);
204
0
      GF_BIFS_WRITE_INT(codec, bs, cb->bufferSize, nbBits, "BufferSize", NULL);
205
0
      for (i=0; i<cb->bufferSize; i++) GF_BIFS_WRITE_INT(codec, bs, cb->buffer[i], 8, "buffer byte", NULL);
206
0
    }
207
    /*empty command buffer*/
208
0
    else {
209
0
      GF_BIFS_WRITE_INT(codec, bs, 0, 5, "NbBits", NULL);
210
0
    }
211
0
  }
212
0
  break;
213
214
0
  case GF_SG_VRML_SFNODE:
215
0
    return gf_bifs_enc_node(codec, *((GF_Node **)field->far_ptr), field->NDTtype, bs, node);
216
217
0
  case GF_SG_VRML_SFSCRIPT:
218
0
#ifdef GPAC_HAS_QJS
219
0
    codec->LastError = SFScript_Encode(codec, (SFScript *)field->far_ptr, bs, node);
220
#else
221
    return GF_NOT_SUPPORTED;
222
#endif
223
0
    break;
224
0
  case GF_SG_VRML_SFATTRREF:
225
0
  {
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
0
  }
234
0
  break;
235
0
  default:
236
0
    return GF_NOT_SUPPORTED;
237
0
  }
238
0
  return codec->LastError;
239
0
}
240
241
242
GF_Err gf_bifs_enc_mf_field(GF_BifsEncoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field)
243
0
{
244
0
  GF_ChildNodeItem *list = NULL;
245
0
  GF_Err e;
246
0
  u32 nbBits, qp_local;
247
0
  Bool use_list, qp_on, initial_qp;
248
0
  u32 nbF, i;
249
0
  GF_FieldInfo sffield;
250
251
0
  nbF = 0;
252
0
  if (field->fieldType != GF_SG_VRML_MFNODE) {
253
0
    nbF = field->far_ptr ? ((GenMFField *)field->far_ptr)->count : 0;
254
0
    if (!nbF && (field->fieldType == GF_SG_VRML_MFSCRIPT))
255
0
      nbF = 1;
256
0
  } else if (field->far_ptr) {
257
0
    list = *((GF_ChildNodeItem **)field->far_ptr);
258
0
    nbF = gf_node_list_get_count(list);
259
0
  }
260
  /*reserved*/
261
0
  GF_BIFS_WRITE_INT(codec, bs, 0, 1, "reserved", NULL);
262
0
  if (!nbF) {
263
    /*is list*/
264
0
    GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isList", NULL);
265
    /*end flag*/
266
0
    GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);
267
0
    return GF_OK;
268
0
  }
269
270
  /*do we work in list or vector*/
271
0
  use_list = GF_FALSE;
272
0
  nbBits = gf_get_bit_size(nbF);
273
0
  if (nbBits + 5 > nbF + 1) use_list = GF_TRUE;
274
275
0
  GF_BIFS_WRITE_INT(codec, bs, use_list, 1, "isList", NULL);
276
0
  if (!use_list) {
277
0
    GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "nbBits", NULL);
278
0
    GF_BIFS_WRITE_INT(codec, bs, nbF, nbBits, "length", NULL);
279
0
  }
280
281
0
  memset(&sffield, 0, sizeof(GF_FieldInfo));
282
0
  sffield.fieldIndex = field->fieldIndex;
283
0
  sffield.fieldType = gf_sg_vrml_get_sf_type(field->fieldType);
284
0
  sffield.NDTtype = field->NDTtype;
285
286
0
  qp_on = GF_FALSE;
287
0
  qp_local = 0;
288
0
  initial_qp = codec->ActiveQP ? GF_TRUE : GF_FALSE;
289
0
  for (i=0; i<nbF; i++) {
290
291
0
    if (use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL);
292
293
0
    if (field->fieldType != GF_SG_VRML_MFNODE) {
294
0
      gf_sg_vrml_mf_get_item(field->far_ptr, field->fieldType, &sffield.far_ptr, i);
295
0
      e = gf_bifs_enc_sf_field(codec, bs, node, &sffield);
296
0
    } else {
297
0
      if (!list) return GF_NON_COMPLIANT_BITSTREAM;
298
0
      e = gf_bifs_enc_node(codec, list->node, field->NDTtype, bs, node);
299
300
      /*activate QP*/
301
0
      if (list->node->sgprivate->tag == TAG_MPEG4_QuantizationParameter) {
302
0
        qp_local = ((M_QuantizationParameter *)list->node)->isLocal;
303
0
        if (qp_on) gf_bifs_enc_qp_remove(codec, GF_FALSE);
304
0
        e = gf_bifs_enc_qp_set(codec, list->node);
305
0
        if (e) return e;
306
0
        qp_on = GF_TRUE;
307
0
        if (qp_local) qp_local = 2;
308
0
      }
309
0
      list = list->next;
310
0
    }
311
312
0
    if (e) return e;
313
314
0
    if (qp_on && qp_local) {
315
0
      if (qp_local == 2) qp_local -= 1;
316
0
      else {
317
0
        gf_bifs_enc_qp_remove(codec, initial_qp);
318
0
        qp_local = qp_on = GF_FALSE;
319
0
      }
320
0
    }
321
0
  }
322
323
0
  if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);
324
0
  if (qp_on) gf_bifs_enc_qp_remove(codec, initial_qp);
325
  /*for QP14*/
326
0
  gf_bifs_enc_qp14_set_length(codec, nbF);
327
0
  return GF_OK;
328
0
}
329
330
331
GF_Err gf_bifs_enc_field(GF_BifsEncoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field)
332
0
{
333
0
  if (!node) return GF_BAD_PARAM;
334
0
  if (field->fieldType == GF_SG_VRML_UNKNOWN)
335
0
    return GF_NON_COMPLIANT_BITSTREAM;
336
337
0
  if (gf_sg_vrml_is_sf_field(field->fieldType)) {
338
0
    return gf_bifs_enc_sf_field(codec, bs, node, field);
339
0
  }
340
341
  /*TO DO : PMF support*/
342
343
0
  if (codec->info->config.UsePredictiveMFField) {
344
0
    GF_BIFS_WRITE_INT(codec, bs, 0, 1, "usePredictive", NULL);
345
0
  }
346
0
  return gf_bifs_enc_mf_field(codec, bs, node, field);
347
0
}
348
349
/*we assume a node field is not ISed several times (that's stated as "undefined behavior" in VRML*/
350
GF_Route *gf_bifs_enc_is_field_ised(GF_BifsEncoder *codec, GF_Node *node, u32 fieldIndex)
351
0
{
352
0
  GF_Route *r;
353
0
  u32 i;
354
0
  if (!codec->encoding_proto) return NULL;
355
356
0
  if (node->sgprivate->interact && node->sgprivate->interact->routes) {
357
0
    i=0;
358
0
    while ((r = (GF_Route*)gf_list_enum(node->sgprivate->interact->routes, &i))) {
359
0
      if (!r->IS_route) continue;
360
0
      if ((r->ToNode == node) && (r->ToField.fieldIndex==fieldIndex)) return r;
361
0
      else if ((r->FromNode == node) && (r->FromField.fieldIndex==fieldIndex)) return r;
362
0
    }
363
0
  }
364
365
0
  i=0;
366
0
  while ((r = (GF_Route*)gf_list_enum(codec->encoding_proto->sub_graph->Routes, &i))) {
367
0
    if (!r->IS_route) continue;
368
0
    if ((r->ToNode == node) && (r->ToField.fieldIndex==fieldIndex)) return r;
369
0
    else if ((r->FromNode == node) && (r->FromField.fieldIndex==fieldIndex)) return r;
370
0
  }
371
0
  return NULL;
372
0
}
373
374
/**/
375
GF_Err EncNodeFields(GF_BifsEncoder * codec, GF_BitStream *bs, GF_Node *node)
376
0
{
377
0
  u8 mode;
378
0
  GF_Route *isedField;
379
0
  GF_Node *clone;
380
0
  GF_Err e;
381
0
  s32 *enc_fields;
382
0
  u32 numBitsALL, numBitsDEF, allInd, count, i, nbBitsProto, nbFinal;
383
0
  Bool use_list, nodeIsFDP = GF_FALSE;
384
0
  GF_FieldInfo field, clone_field;
385
386
0
  e = GF_OK;
387
388
0
  if (codec->encoding_proto) {
389
0
    mode = GF_SG_FIELD_CODING_ALL;
390
0
    nbBitsProto = gf_get_bit_size(gf_sg_proto_get_field_count(codec->encoding_proto) - 1);
391
0
    numBitsALL = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL) - 1);
392
0
  } else {
393
0
    mode = GF_SG_FIELD_CODING_DEF;
394
0
    nbBitsProto = 0;
395
0
    numBitsALL = 0;
396
0
  }
397
0
  count = gf_node_get_num_fields_in_mode(node, mode);
398
0
  if (node->sgprivate->tag==TAG_MPEG4_Script) count = 3;
399
400
0
  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
0
    return GF_OK;
404
0
  }
405
406
0
  if (node->sgprivate->tag == TAG_ProtoNode) {
407
0
    clone = gf_sg_proto_create_instance(node->sgprivate->scenegraph, ((GF_ProtoInstance *)node)->proto_interface);
408
0
  } else {
409
0
    clone = gf_node_new(node->sgprivate->scenegraph, node->sgprivate->tag);
410
0
  }
411
0
  if (clone) gf_node_register(clone, NULL);
412
413
0
  numBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF) - 1);
414
415
0
  enc_fields = (s32*)gf_malloc(sizeof(s32) * count);
416
0
  nbFinal = 0;
417
0
  for (i=0; i<count; i++) {
418
0
    enc_fields[i] = -1;
419
    /*get field in ALL mode*/
420
0
    if (mode == GF_SG_FIELD_CODING_ALL) {
421
0
      allInd = i;
422
0
    } else {
423
0
      gf_bifs_get_field_index(node, i, GF_SG_FIELD_CODING_DEF, &allInd);
424
0
    }
425
426
    /*encode proto code*/
427
0
    if (codec->encoding_proto) {
428
0
      isedField = gf_bifs_enc_is_field_ised(codec, node, allInd);
429
0
      if (isedField) {
430
0
        enc_fields[i] = allInd;
431
0
        nbFinal ++;
432
0
        continue;
433
0
      }
434
0
    }
435
    /*common case*/
436
0
    gf_node_get_field(node, allInd, &field);
437
    /*if event don't encode (happens when encoding protos)*/
438
0
    if ((field.eventType == GF_SG_EVENT_IN) || (field.eventType == GF_SG_EVENT_OUT)) continue;
439
    /*if field is default skip*/
440
0
    switch (field.fieldType) {
441
0
    case GF_SG_VRML_SFNODE:
442
0
      if (* (GF_Node **) field.far_ptr) {
443
0
        enc_fields[i] = allInd;
444
0
        nbFinal++;
445
0
      }
446
0
      break;
447
0
    case GF_SG_VRML_MFNODE:
448
0
      if (* (GF_ChildNodeItem **) field.far_ptr) {
449
0
        enc_fields[i] = allInd;
450
0
        nbFinal++;
451
0
      }
452
0
      break;
453
0
    case GF_SG_VRML_SFCOMMANDBUFFER:
454
0
    {
455
0
      SFCommandBuffer *cb = (SFCommandBuffer *)field.far_ptr;
456
0
      if (gf_list_count(cb->commandList)) {
457
0
        enc_fields[i] = allInd;
458
0
        nbFinal++;
459
0
      }
460
0
    }
461
0
    break;
462
0
    case GF_SG_VRML_MFSCRIPT:
463
0
      enc_fields[i] = allInd;
464
0
      nbFinal++;
465
0
      break;
466
0
    default:
467
0
      gf_node_get_field(clone, allInd, &clone_field);
468
0
      if (!gf_sg_vrml_field_equal(clone_field.far_ptr, field.far_ptr, field.fieldType)) {
469
0
        enc_fields[i] = allInd;
470
0
        nbFinal++;
471
0
      }
472
0
      break;
473
0
    }
474
0
  }
475
0
  if (clone) gf_node_unregister(clone, NULL);
476
477
0
  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
0
  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
0
    nodeIsFDP = GF_TRUE;
485
0
    use_list = GF_TRUE;
486
0
  }
487
  /*number of bits in mask node is count*1, in list node is 1+nbFinal*(1+numBitsDEF) */
488
0
  else if (count < 1+nbFinal*(1+numBitsDEF))
489
0
    use_list = GF_FALSE;
490
491
0
  GF_BIFS_WRITE_INT(codec, bs, use_list ? 0 : 1, 1, "isMask", NULL);
492
493
0
  for (i=0; i<count; i++) {
494
0
    if (enc_fields[i] == -1) {
495
0
      if (!use_list) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "Mask", NULL);
496
0
      continue;
497
0
    }
498
0
    allInd = (u32) enc_fields[i];
499
500
    /*encode proto code*/
501
0
    if (codec->encoding_proto) {
502
0
      isedField = gf_bifs_enc_is_field_ised(codec, node, allInd);
503
0
      if (isedField) {
504
0
        if (use_list) {
505
0
          GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL);
506
0
        } else {
507
0
          GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL);
508
0
        }
509
0
        GF_BIFS_WRITE_INT(codec, bs, 1, 1, "isedField", NULL);
510
0
        if (use_list) GF_BIFS_WRITE_INT(codec, bs, allInd, numBitsALL, "nodeField", NULL);
511
512
0
        if (isedField->ToNode == node) {
513
0
          GF_BIFS_WRITE_INT(codec, bs, isedField->FromField.fieldIndex, nbBitsProto, "protoField", NULL);
514
0
        } else {
515
0
          GF_BIFS_WRITE_INT(codec, bs, isedField->ToField.fieldIndex, nbBitsProto, "protoField", NULL);
516
0
        }
517
0
        continue;
518
0
      }
519
0
    }
520
    /*common case*/
521
0
    gf_node_get_field(node, allInd, &field);
522
0
    if (use_list) {
523
      /*not end flag*/
524
0
      GF_BIFS_WRITE_INT(codec, bs, 0, 1, "end", NULL);
525
0
    } else {
526
      /*mask flag*/
527
0
      GF_BIFS_WRITE_INT(codec, bs, 1, 1, "Mask", NULL);
528
0
    }
529
    /*not ISed field*/
530
0
    if (codec->encoding_proto) GF_BIFS_WRITE_INT(codec, bs, 0, 1, "isedField", NULL);
531
0
    if (use_list) {
532
0
      if (codec->encoding_proto || nodeIsFDP) {
533
0
        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
0
        gf_bifs_field_index_by_mode(node, allInd, GF_SG_FIELD_CODING_DEF, &ind);
537
0
        GF_BIFS_WRITE_INT(codec, bs, ind, numBitsDEF, "field", (char*)field.name);
538
0
      } else {
539
0
        GF_BIFS_WRITE_INT(codec, bs, i, numBitsDEF, "field", (char*)field.name);
540
0
      }
541
0
    }
542
0
    e = gf_bifs_enc_field(codec, bs, node, &field);
543
0
    if (e) goto exit;
544
0
  }
545
  /*end flag*/
546
0
  if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL);
547
0
exit:
548
0
  gf_free(enc_fields);
549
0
  return e;
550
0
}
551
552
Bool BE_NodeIsUSE(GF_BifsEncoder * codec, GF_Node *node)
553
0
{
554
0
  u32 i, count;
555
0
  if (!node || !gf_node_get_id(node) ) return GF_FALSE;
556
0
  count = gf_list_count(codec->encoded_nodes);
557
0
  for (i=0; i<count; i++) {
558
0
    if (gf_list_get(codec->encoded_nodes, i) == node) return GF_TRUE;
559
0
  }
560
0
  gf_list_add(codec->encoded_nodes, node);
561
0
  return GF_FALSE;
562
0
}
563
564
GF_Err gf_bifs_enc_node(GF_BifsEncoder * codec, GF_Node *node, u32 NDT_Tag, GF_BitStream *bs, GF_Node *parent_node)
565
0
{
566
0
  u32 NDTBits, node_type, node_tag, BVersion, node_id;
567
0
  const char *node_name;
568
0
  Bool flag, reset_qp14;
569
0
  GF_Err e;
570
571
0
  if (!codec->info) return GF_BAD_PARAM;
572
0
  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
0
  if (!node) {
576
0
    GF_BIFS_WRITE_INT(codec, bs, 1, 1, "USE", NULL);
577
0
    GF_BIFS_WRITE_INT(codec, bs, (1<<codec->info->config.NodeIDBits) - 1 , codec->info->config.NodeIDBits, "NodeID", "NULL");
578
0
    return GF_OK;
579
0
  }
580
581
0
  flag = BE_NodeIsUSE(codec, node);
582
0
  GF_BIFS_WRITE_INT(codec, bs, flag ? 1 : 0, 1, "USE", (char*)gf_node_get_class_name(node));
583
584
0
  if (flag) {
585
0
    GF_Node *new_node;
586
0
    gf_bs_write_int(bs, gf_node_get_id(node) - 1, codec->info->config.NodeIDBits);
587
0
    new_node = gf_bifs_enc_find_node(codec, gf_node_get_id(node) );
588
0
    if (!new_node)
589
0
      return codec->LastError = GF_SG_UNKNOWN_NODE;
590
591
    /*restore QP14 length*/
592
0
    switch (gf_node_get_tag(new_node)) {
593
0
    case TAG_MPEG4_Coordinate:
594
0
    {
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
0
    }
600
0
    break;
601
0
    case TAG_MPEG4_Coordinate2D:
602
0
    {
603
0
      u32 nbCoord = ((M_Coordinate2D *)new_node)->point.count;
604
0
      gf_bifs_enc_qp14_enter(codec, GF_TRUE);
605
0
      gf_bifs_enc_qp14_set_length(codec, nbCoord);
606
0
      gf_bifs_enc_qp14_enter(codec, GF_FALSE);
607
0
    }
608
0
    break;
609
0
    }
610
0
    return GF_OK;
611
0
  }
612
613
0
  BVersion = GF_BIFS_V1;
614
0
  node_tag = node->sgprivate->tag;
615
0
  while (1) {
616
0
    node_type = gf_bifs_get_node_type(NDT_Tag, node_tag, BVersion);
617
0
    NDTBits = gf_bifs_get_ndt_bits(NDT_Tag, BVersion);
618
0
    if (BVersion==2 && (node_tag==TAG_ProtoNode)) node_type = 1;
619
0
    GF_BIFS_WRITE_INT(codec, bs, node_type, NDTBits, "ndt", NULL);
620
0
    if (node_type) break;
621
622
0
    BVersion += 1;
623
0
    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
0
      } 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
0
      }
629
0
      return codec->LastError = GF_BIFS_UNKNOWN_VERSION;
630
0
    }
631
0
  }
632
0
  if (BVersion==2 && node_type==1) {
633
0
    GF_Proto *proto = ((GF_ProtoInstance *)node)->proto_interface;
634
0
    GF_BIFS_WRITE_INT(codec, bs, proto->ID, codec->info->config.ProtoIDBits, "protoID", NULL);
635
0
  }
636
637
  /*special handling of 3D mesh*/
638
639
  /*DEF'd node*/
640
0
  node_name = gf_node_get_name_and_id(node, &node_id);
641
0
  GF_BIFS_WRITE_INT(codec, bs, node_id ? 1 : 0, 1, "DEF", NULL);
642
0
  if (node_id) {
643
0
    GF_BIFS_WRITE_INT(codec, bs, node_id - 1, codec->info->config.NodeIDBits, "NodeID", NULL);
644
0
    if (codec->UseName) gf_bifs_enc_name(codec, bs, (char*) node_name );
645
0
  }
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
0
  reset_qp14 = !codec->coord_stored;
651
652
  /*QP14 case*/
653
0
  switch (node_tag) {
654
0
  case TAG_MPEG4_Coordinate:
655
0
  case TAG_MPEG4_Coordinate2D:
656
0
    gf_bifs_enc_qp14_enter(codec, GF_TRUE);
657
0
  }
658
659
0
  e = EncNodeFields(codec, bs, node);
660
0
  if (e) return e;
661
662
0
  if (codec->coord_stored && reset_qp14)
663
0
    gf_bifs_enc_qp14_reset(codec);
664
665
0
  switch (node_tag) {
666
0
  case TAG_MPEG4_Coordinate:
667
0
  case TAG_MPEG4_Coordinate2D:
668
0
    gf_bifs_enc_qp14_enter(codec, GF_FALSE);
669
0
    break;
670
0
  }
671
0
  return GF_OK;
672
0
}
673
674
675
#endif /*GPAC_DISABLE_BIFS_ENC*/