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