/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 | | |