Coverage Report

Created: 2026-03-10 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gpac/src/bifs/bifs_codec.c
Line
Count
Source
1
/*
2
 *      GPAC - Multimedia Framework C SDK
3
 *
4
 *      Authors: Jean Le Feuvre
5
 *      Copyright (c) Telecom ParisTech 2000-2023
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 <gpac/mpeg4_odf.h>
29
#include <gpac/nodes_x3d.h>
30
31
#ifndef GPAC_DISABLE_BIFS
32
33
34
static GF_Err ParseConfig(GF_BitStream *bs, BIFSStreamInfo *info, u32 version)
35
0
{
36
0
  Bool hasSize, cmd_stream;
37
38
0
  if (info->config.elementaryMasks) gf_list_del(info->config.elementaryMasks);
39
0
  info->config.elementaryMasks = NULL  ;
40
41
0
  if (version==2) {
42
0
    info->config.Use3DMeshCoding = (Bool)gf_bs_read_int(bs, 1);
43
0
    info->config.UsePredictiveMFField = (Bool)gf_bs_read_int(bs, 1);
44
0
  }
45
0
  info->config.NodeIDBits = gf_bs_read_int(bs, 5);
46
0
  info->config.RouteIDBits = gf_bs_read_int(bs, 5);
47
0
  if (version==2) {
48
0
    info->config.ProtoIDBits = gf_bs_read_int(bs, 5);
49
0
  }
50
0
  cmd_stream = (Bool)gf_bs_read_int(bs, 1);
51
52
0
  if (cmd_stream) {
53
0
    info->config.PixelMetrics = (Bool)gf_bs_read_int(bs, 1);
54
0
    hasSize = (Bool)gf_bs_read_int(bs, 1);
55
0
    if (hasSize) {
56
0
      info->config.Width = gf_bs_read_int(bs, 16);
57
0
      info->config.Height = gf_bs_read_int(bs, 16);
58
0
    }
59
0
    gf_bs_align(bs);
60
61
0
    if (gf_bs_get_size(bs) != gf_bs_get_position(bs)) return GF_ODF_INVALID_DESCRIPTOR;
62
0
    return GF_OK;
63
0
  } else {
64
0
    info->config.BAnimRAP = (Bool)gf_bs_read_int(bs, 1);
65
0
    info->config.elementaryMasks = gf_list_new();
66
0
    while (1) {
67
0
      /*u32 node_id = */gf_bs_read_int(bs, info->config.NodeIDBits);
68
      /*this assumes only FDP, BDP and IFS2D (no elem mask)*/
69
0
      if (gf_bs_read_int(bs, 1) == 0) break;
70
0
    }
71
0
    gf_bs_align(bs);
72
0
    if (gf_bs_get_size(bs) != gf_bs_get_position(bs))  return GF_NOT_SUPPORTED;
73
0
    return GF_OK;
74
0
  }
75
0
}
76
77
static void bifs_info_del(BIFSStreamInfo *info)
78
0
{
79
0
  while (1) {
80
0
    BIFSElementaryMask *em = (BIFSElementaryMask *)gf_list_last(info->config.elementaryMasks);
81
0
    if (!em) break;
82
0
    gf_list_rem_last(info->config.elementaryMasks);
83
0
    gf_free(em);
84
0
  }
85
0
  gf_free(info);
86
0
}
87
88
GF_EXPORT
89
GF_BifsDecoder *gf_bifs_decoder_new(GF_SceneGraph *scenegraph, Bool command_dec)
90
0
{
91
0
  GF_BifsDecoder *tmp;
92
0
  GF_SAFEALLOC(tmp, GF_BifsDecoder);
93
0
  if (!tmp) return NULL;
94
  
95
0
  tmp->QPs = gf_list_new();
96
0
  tmp->streamInfo = gf_list_new();
97
0
  tmp->info = NULL;
98
99
0
  tmp->pCurrentProto = NULL;
100
0
  tmp->scenegraph = scenegraph;
101
0
  tmp->command_buffers = gf_list_new();
102
0
  if (command_dec) {
103
0
    tmp->dec_memory_mode = GF_TRUE;
104
0
    tmp->force_keep_qp = GF_TRUE;
105
0
  }
106
0
  tmp->current_graph = NULL;
107
0
  return tmp;
108
0
}
109
110
111
BIFSStreamInfo *gf_bifs_dec_get_stream(GF_BifsDecoder * codec, u16 ESID)
112
0
{
113
0
  u32 i;
114
0
  BIFSStreamInfo *ptr;
115
116
0
  i=0;
117
0
  if (!codec || !codec->streamInfo)
118
0
    return NULL;
119
0
  while ((ptr = (BIFSStreamInfo *) gf_list_enum(codec->streamInfo, &i))) {
120
0
    if(ptr->ESID==ESID) return ptr;
121
0
  }
122
0
  return NULL;
123
0
}
124
125
GF_EXPORT
126
GF_Err gf_bifs_decoder_configure_stream(GF_BifsDecoder * codec, u16 ESID, u8 *DecoderSpecificInfo, u32 DecoderSpecificInfoLength, u32 objectTypeIndication)
127
0
{
128
0
  GF_BitStream *bs;
129
0
  BIFSStreamInfo *pInfo;
130
0
  Bool new_cfg = GF_FALSE;
131
0
  GF_Err e;
132
133
0
  if (!codec) return GF_BAD_PARAM;
134
0
  if (!DecoderSpecificInfo) {
135
0
    if (!codec->streamInfo) return GF_BAD_PARAM;
136
    /* Hack for T-DMB non compliant streams */
137
0
    GF_SAFEALLOC(pInfo, BIFSStreamInfo);
138
0
    if (!pInfo) return GF_OUT_OF_MEM;
139
0
    pInfo->ESID = ESID;
140
0
    pInfo->config.PixelMetrics = GF_TRUE;
141
0
    pInfo->config.version = (objectTypeIndication==2) ? 1 : 2;
142
0
    return gf_list_add(codec->streamInfo, pInfo);
143
0
  }
144
145
0
  pInfo = gf_bifs_dec_get_stream(codec, ESID);
146
  //we allow reconfigure of the BIFS stream
147
0
  if (pInfo == NULL) {
148
0
    GF_SAFEALLOC(pInfo, BIFSStreamInfo);
149
0
    if (!pInfo) return GF_OUT_OF_MEM;
150
0
    new_cfg = GF_TRUE;
151
0
  }
152
0
  bs = gf_bs_new(DecoderSpecificInfo, DecoderSpecificInfoLength, GF_BITSTREAM_READ);
153
0
  pInfo->ESID = ESID;
154
155
0
  pInfo->config.version = objectTypeIndication;
156
  /*parse config with indicated oti*/
157
0
  e = ParseConfig(bs, pInfo, (u32) objectTypeIndication);
158
0
  if (e) {
159
0
    pInfo->ESID = ESID;
160
    /*some content indicates a wrong OTI, so try to parse with v1 or v2*/
161
0
    gf_bs_seek(bs, 0);
162
    /*try with reverse config*/
163
0
    e = ParseConfig(bs, pInfo, (objectTypeIndication==2) ? 1 : 2);
164
0
    pInfo->config.version = (objectTypeIndication==2) ? 1 : 2;
165
0
  }
166
167
0
  if (e && (e != GF_ODF_INVALID_DESCRIPTOR)) {
168
0
    gf_free(pInfo);
169
0
    gf_bs_del(bs);
170
0
    return GF_BIFS_UNKNOWN_VERSION;
171
0
  }
172
0
  gf_bs_del(bs);
173
174
0
  gf_assert( codec->streamInfo );
175
  //first stream, configure size
176
0
  if (!codec->ignore_size && !gf_list_count(codec->streamInfo)) {
177
0
    gf_sg_set_scene_size_info(codec->scenegraph, pInfo->config.Width, pInfo->config.Height, pInfo->config.PixelMetrics);
178
0
  }
179
180
0
  if (new_cfg)
181
0
    gf_list_add(codec->streamInfo, pInfo);
182
0
  return GF_OK;
183
0
}
184
185
186
187
#if 0 //deprecated
188
GF_EXPORT
189
void gf_bifs_decoder_ignore_size_info(GF_BifsDecoder *codec)
190
{
191
  if (codec) codec->ignore_size = GF_TRUE;
192
}
193
194
GF_EXPORT
195
GF_Err gf_bifs_decoder_remove_stream(GF_BifsDecoder *codec, u16 ESID)
196
{
197
  u32 i;
198
  BIFSStreamInfo *ptr;
199
200
  i=0;
201
  while ((ptr = (BIFSStreamInfo*)gf_list_enum(codec->streamInfo, &i))) {
202
    if(ptr->ESID==ESID) {
203
      gf_free(ptr);
204
      gf_list_rem(codec->streamInfo, i-1);
205
      return GF_OK;
206
    }
207
  }
208
  return GF_BAD_PARAM;
209
}
210
#endif
211
212
213
void command_buffers_del(GF_List *command_buffers)
214
0
{
215
0
  while (gf_list_count(command_buffers)) {
216
0
    CommandBufferItem *cbi = (CommandBufferItem *)gf_list_get(command_buffers, 0);
217
0
    gf_node_unregister(cbi->node, NULL);
218
0
    gf_free(cbi);
219
0
    gf_list_rem(command_buffers, 0);
220
0
  }
221
0
  gf_list_del(command_buffers);
222
0
}
223
224
GF_EXPORT
225
void gf_bifs_decoder_del(GF_BifsDecoder *codec)
226
0
{
227
0
  gf_assert(gf_list_count(codec->QPs)==0);
228
0
  gf_list_del(codec->QPs);
229
230
  /*destroy all config*/
231
0
  while (gf_list_count(codec->streamInfo)) {
232
0
    BIFSStreamInfo *p = (BIFSStreamInfo*)gf_list_get(codec->streamInfo, 0);
233
0
    bifs_info_del(p);
234
0
    gf_list_rem(codec->streamInfo, 0);
235
0
  }
236
0
  gf_list_del(codec->streamInfo);
237
238
0
  command_buffers_del(codec->command_buffers);
239
240
0
  gf_free(codec);
241
0
}
242
243
244
void BD_EndOfStream(void *co)
245
0
{
246
0
  ((GF_BifsDecoder *) co)->LastError = GF_NON_COMPLIANT_BITSTREAM;
247
0
}
248
249
void gf_bs_set_eos_callback(GF_BitStream *bs, void (*EndOfStream)(void *par), void *par);
250
251
GF_EXPORT
252
Bool gf_bifs_decode_has_conditionnals(GF_BifsDecoder *codec)
253
0
{
254
0
  return codec && codec->has_conditionnals ? GF_TRUE : GF_FALSE;
255
0
}
256
257
GF_EXPORT
258
GF_Err gf_bifs_decode_au(GF_BifsDecoder *codec, u16 ESID, const u8 *data, u32 data_length, Double ts_offset)
259
0
{
260
0
  GF_BitStream *bs;
261
0
  GF_Err e;
262
263
0
  if (!codec || !data || codec->dec_memory_mode) return GF_BAD_PARAM;
264
0
  if (!data_length) return GF_OK;
265
266
0
  codec->info = gf_bifs_dec_get_stream(codec, ESID);
267
0
  if (!codec->info) {
268
0
    return GF_BAD_PARAM;
269
0
  }
270
  /*setup current scene graph*/
271
0
  codec->current_graph = codec->scenegraph;
272
0
  codec->cts_offset = ts_offset;
273
274
0
  bs = gf_bs_new((u8 *)data, data_length, GF_BITSTREAM_READ);
275
0
  if (!bs) return GF_OUT_OF_MEM;
276
0
  gf_bs_set_eos_callback(bs, BD_EndOfStream, codec);
277
278
0
  if (codec->info->config.elementaryMasks) {
279
0
    e = GF_NOT_SUPPORTED;
280
0
  } else {
281
0
    e = gf_bifs_dec_command(codec, bs);
282
0
  }
283
0
  gf_bs_del(bs);
284
  /*reset current config*/
285
0
  codec->info = NULL;
286
0
  codec->current_graph = NULL;
287
0
  return e;
288
0
}
289
290
291
#ifndef GPAC_DISABLE_BIFS_ENC
292
293
GF_Node *gf_bifs_enc_find_node(GF_BifsEncoder *codec, u32 nodeID)
294
0
{
295
0
  if (codec->current_proto_graph)
296
0
    return gf_sg_find_node(codec->current_proto_graph, nodeID);
297
0
  if (codec->scene_graph)
298
0
    return gf_sg_find_node(codec->scene_graph, nodeID);
299
0
  return NULL;
300
0
}
301
302
303
GF_EXPORT
304
GF_BifsEncoder *gf_bifs_encoder_new(GF_SceneGraph *graph)
305
0
{
306
0
  GF_BifsEncoder * tmp;
307
0
  GF_SAFEALLOC(tmp, GF_BifsEncoder);
308
0
  if (!tmp) return NULL;
309
0
  tmp->QPs = gf_list_new();
310
0
  tmp->streamInfo = gf_list_new();
311
0
  tmp->info = NULL;
312
0
  tmp->encoded_nodes = gf_list_new();
313
0
  tmp->scene_graph = graph;
314
0
  return tmp;
315
0
}
316
317
static BIFSStreamInfo *BE_GetStream(GF_BifsEncoder * codec, u16 ESID)
318
0
{
319
0
  u32 i;
320
0
  BIFSStreamInfo *ptr;
321
322
0
  i=0;
323
0
  while ((ptr = (BIFSStreamInfo*)gf_list_enum(codec->streamInfo, &i))) {
324
0
    if(ptr->ESID==ESID) return ptr;
325
0
  }
326
0
  return NULL;
327
0
}
328
329
GF_EXPORT
330
void gf_bifs_encoder_del(GF_BifsEncoder *codec)
331
0
{
332
0
  gf_assert(gf_list_count(codec->QPs)==0);
333
0
  gf_list_del(codec->QPs);
334
  /*destroy all config*/
335
0
  while (gf_list_count(codec->streamInfo)) {
336
0
    BIFSStreamInfo *p = (BIFSStreamInfo*)gf_list_get(codec->streamInfo, 0);
337
0
    bifs_info_del(p);
338
0
    gf_list_rem(codec->streamInfo, 0);
339
0
  }
340
0
  gf_list_del(codec->streamInfo);
341
0
  gf_list_del(codec->encoded_nodes);
342
0
  if (codec->src_url) gf_free(codec->src_url);
343
//  gf_mx_del(codec->mx);
344
0
  gf_free(codec);
345
0
}
346
347
GF_EXPORT
348
GF_Err gf_bifs_encoder_new_stream(GF_BifsEncoder *codec, u16 ESID, GF_BIFSConfig *cfg, Bool encodeNames, Bool has_predictive)
349
0
{
350
0
  u32 i, count;
351
0
  BIFSStreamInfo *pInfo;
352
353
//  gf_mx_p(codec->mx);
354
0
  if (BE_GetStream(codec, ESID) != NULL) {
355
//    gf_mx_v(codec->mx);
356
0
    return GF_BAD_PARAM;
357
0
  }
358
359
0
  GF_SAFEALLOC(pInfo, BIFSStreamInfo);
360
0
  if (!pInfo) return GF_OUT_OF_MEM;
361
0
  pInfo->ESID = ESID;
362
0
  codec->UseName = encodeNames;
363
0
  pInfo->config.Height = cfg->pixelHeight;
364
0
  pInfo->config.Width = cfg->pixelWidth;
365
0
  pInfo->config.NodeIDBits = cfg->nodeIDbits;
366
0
  pInfo->config.RouteIDBits = cfg->routeIDbits;
367
0
  pInfo->config.ProtoIDBits = cfg->protoIDbits;
368
0
  pInfo->config.PixelMetrics = cfg->pixelMetrics;
369
0
  pInfo->config.version = (has_predictive || cfg->protoIDbits) ? 2 : 1;
370
0
  pInfo->config.UsePredictiveMFField = has_predictive;
371
372
0
  if (cfg->elementaryMasks) {
373
0
    pInfo->config.elementaryMasks = gf_list_new();
374
0
    count = gf_list_count(cfg->elementaryMasks);
375
0
    for (i=0; i<count; i++) {
376
0
      BIFSElementaryMask *bem;
377
0
      GF_ElementaryMask *em = (GF_ElementaryMask *)gf_list_get(cfg->elementaryMasks, i);
378
0
      GF_SAFEALLOC(bem, BIFSElementaryMask);
379
0
      if (!bem) {
380
0
        GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Fail to allocate elementary mask"));
381
0
        continue;
382
0
      }
383
0
      if (em->node_id) bem->node = gf_sg_find_node(codec->scene_graph, em->node_id);
384
0
      else if (em->node_name) bem->node = gf_sg_find_node_by_name(codec->scene_graph, em->node_name);
385
0
      bem->node_id = em->node_id;
386
0
      gf_list_add(pInfo->config.elementaryMasks, bem);
387
0
    }
388
0
  }
389
390
0
  gf_list_add(codec->streamInfo, pInfo);
391
//  gf_mx_v(codec->mx);
392
0
  return GF_OK;
393
0
}
394
395
GF_EXPORT
396
GF_Err gf_bifs_encode_au(GF_BifsEncoder *codec, u16 ESID, GF_List *command_list, u8 **out_data, u32 *out_data_length)
397
0
{
398
0
  GF_BitStream *bs;
399
0
  GF_Err e;
400
401
0
  if (!codec || !command_list || !out_data || !out_data_length) return GF_BAD_PARAM;
402
403
//  gf_mx_p(codec->mx);
404
0
  codec->info = BE_GetStream(codec, ESID);
405
0
  if (!codec->info) {
406
//    gf_mx_v(codec->mx);
407
0
    return GF_BAD_PARAM;
408
0
  }
409
410
0
  bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
411
412
0
  if (codec->info->config.elementaryMasks) {
413
0
    e = GF_NOT_SUPPORTED;
414
0
  } else {
415
0
    e = gf_bifs_enc_commands(codec, command_list, bs);
416
0
  }
417
0
  gf_bs_align(bs);
418
0
  gf_bs_get_content(bs, out_data, out_data_length);
419
0
  gf_bs_del(bs);
420
//  gf_mx_v(codec->mx);
421
0
  return e;
422
0
}
423
424
GF_EXPORT
425
GF_Err gf_bifs_encoder_get_config(GF_BifsEncoder *codec, u16 ESID, u8 **out_data, u32 *out_data_length)
426
0
{
427
0
  GF_BitStream *bs;
428
429
0
  if (!codec || !out_data || !out_data_length) return GF_BAD_PARAM;
430
431
//  gf_mx_p(codec->mx);
432
0
  codec->info = BE_GetStream(codec, ESID);
433
0
  if (!codec->info) {
434
//    gf_mx_v(codec->mx);
435
0
    return GF_BAD_PARAM;
436
0
  }
437
438
0
  bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
439
440
0
  if (codec->info->config.version==2) {
441
0
    gf_bs_write_int(bs, codec->info->config.Use3DMeshCoding ? 1 : 0, 1);
442
0
    gf_bs_write_int(bs, codec->info->config.UsePredictiveMFField ? 1 : 0, 1);
443
0
  }
444
0
  gf_bs_write_int(bs, codec->info->config.NodeIDBits, 5);
445
0
  gf_bs_write_int(bs, codec->info->config.RouteIDBits, 5);
446
0
  if (codec->info->config.version==2) {
447
0
    gf_bs_write_int(bs, codec->info->config.ProtoIDBits, 5);
448
0
  }
449
0
  if (codec->info->config.elementaryMasks) {
450
0
    u32 i, count;
451
0
    gf_bs_write_int(bs, 0, 1);
452
0
    gf_bs_write_int(bs, codec->info->config.BAnimRAP, 1);
453
0
    count = gf_list_count(codec->info->config.elementaryMasks);
454
0
    for (i=0; i<count; i++) {
455
0
      BIFSElementaryMask *em = (BIFSElementaryMask *)gf_list_get(codec->info->config.elementaryMasks, i);
456
0
      if (em->node) gf_bs_write_int(bs, gf_node_get_id((GF_Node*)em->node), codec->info->config.NodeIDBits);
457
0
      else  gf_bs_write_int(bs, em->node_id, codec->info->config.NodeIDBits);
458
0
      gf_bs_write_int(bs, (i+1==count) ? 0 : 1, 1);
459
0
    }
460
0
  } else {
461
0
    gf_bs_write_int(bs, 1, 1);
462
0
    gf_bs_write_int(bs, codec->info->config.PixelMetrics ? 1 : 0, 1);
463
0
    if (codec->info->config.Width || codec->info->config.Height) {
464
0
      gf_bs_write_int(bs, 1, 1);
465
0
      gf_bs_write_int(bs, codec->info->config.Width, 16);
466
0
      gf_bs_write_int(bs, codec->info->config.Height, 16);
467
0
    } else {
468
0
      gf_bs_write_int(bs, 0, 1);
469
0
    }
470
0
  }
471
472
0
  gf_bs_align(bs);
473
0
  gf_bs_get_content(bs, out_data, out_data_length);
474
0
  gf_bs_del(bs);
475
//  gf_mx_v(codec->mx);
476
0
  return GF_OK;
477
0
}
478
479
GF_EXPORT
480
u8 gf_bifs_encoder_get_version(GF_BifsEncoder *codec, u16 ESID)
481
0
{
482
0
  u8 ret = 0;
483
//  gf_mx_p(codec->mx);
484
0
  codec->info = BE_GetStream(codec, ESID);
485
0
  if (codec->info) ret = codec->info->config.version;
486
//  gf_mx_v(codec->mx);
487
0
  return ret;
488
0
}
489
490
GF_EXPORT
491
GF_Err gf_bifs_encoder_set_source_url(GF_BifsEncoder *codec, const char *src_url)
492
0
{
493
0
  if (!codec) return GF_BAD_PARAM;
494
0
  if (codec->src_url) gf_free(codec->src_url);
495
0
  codec->src_url = gf_strdup(src_url);
496
0
  return GF_OK;
497
0
}
498
499
500
#endif /*GPAC_DISABLE_BIFS_ENC*/
501
502
GF_EXPORT
503
u32 gf_bifs_get_child_table(GF_Node *Node)
504
0
{
505
0
  if (!Node) return 0;
506
0
  return gf_sg_mpeg4_node_get_child_ndt(Node);
507
0
}
508
509
510
GF_Err gf_bifs_get_field_index(GF_Node *Node, u32 inField, u8 IndexMode, u32 *allField)
511
0
{
512
0
  if (!Node) return GF_BAD_PARAM;
513
0
  switch (Node->sgprivate->tag) {
514
0
  case TAG_ProtoNode:
515
0
    return gf_sg_proto_get_field_ind_static(Node, inField, IndexMode, allField);
516
0
  case TAG_MPEG4_Script:
517
0
#ifndef GPAC_DISABLE_X3D
518
0
  case TAG_X3D_Script:
519
0
#endif
520
0
    return gf_sg_script_get_field_index(Node, inField, IndexMode, allField);
521
0
  default:
522
0
    if (inField >= gf_sg_mpeg4_node_get_field_count(Node, IndexMode))
523
0
      return GF_NON_COMPLIANT_BITSTREAM;
524
0
    return gf_sg_mpeg4_node_get_field_index(Node, inField, IndexMode, allField);
525
0
  }
526
0
}
527
528
529
/* QUANTIZATION AND BIFS_Anim Info */
530
GF_EXPORT
531
Bool gf_bifs_get_aq_info(GF_Node *Node, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits)
532
0
{
533
0
  *b_min = 0;
534
0
  *b_max = 0;
535
0
  *QT13_bits = 0;
536
0
  switch (Node->sgprivate->tag) {
537
0
  case TAG_ProtoNode:
538
0
    return gf_sg_proto_get_aq_info(Node, FieldIndex, QType, AType, b_min, b_max, QT13_bits);
539
0
  default:
540
0
    return gf_sg_mpeg4_node_get_aq_info(Node, FieldIndex, QType, AType, b_min, b_max, QT13_bits);
541
0
  }
542
0
}
543
544
#endif /*GPAC_DISABLE_BIFS*/
545