Coverage Report

Created: 2026-06-15 07:02

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