Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2000-2019
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / MPEG-4 ObjectDescriptor 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 : #include <gpac/internal/odf_dev.h>
27 : #include <gpac/utf.h>
28 :
29 : #define DATE_CODING_LEN 5
30 :
31 : #ifndef GPAC_MINIMAL_ODF
32 :
33 : static GFINLINE GF_Err OD_ReadUTF8String(GF_BitStream *bs, char **string, Bool isUTF8, u32 *read)
34 : {
35 : u32 len;
36 : *read = 1;
37 : len = gf_bs_read_int(bs, 8) + 1;
38 : if (gf_bs_available(bs) < len) return GF_BAD_PARAM;
39 : if (!isUTF8) len *= 2;
40 : (*string) = (char *) gf_malloc(sizeof(char)*len);
41 : if (! (*string) ) return GF_OUT_OF_MEM;
42 : gf_bs_read_data(bs, (*string), len);
43 : *read += len;
44 : return GF_OK;
45 : }
46 :
47 : static GFINLINE u32 OD_SizeUTF8String(char *string, Bool isUTF8)
48 : {
49 : if (isUTF8) return 1 + (u32) strlen(string);
50 : return 1 + 2 * (u32) gf_utf8_wcslen((const unsigned short *)string);
51 : }
52 :
53 : static GFINLINE void OD_WriteUTF8String(GF_BitStream *bs, char *string, Bool isUTF8)
54 : {
55 : u32 len;
56 : if (isUTF8) {
57 : len = (u32) strlen(string);
58 : gf_bs_write_int(bs, len, 8);
59 : gf_bs_write_data(bs, string, len);
60 : } else {
61 : len = (u32) gf_utf8_wcslen((const unsigned short *)string);
62 : gf_bs_write_int(bs, len, 8);
63 : gf_bs_write_data(bs, string, len*2);
64 : }
65 : }
66 :
67 : #endif // GPAC_MINIMAL_ODF
68 :
69 : /*use to parse strings read the length as well - Warning : the alloc is done here !!*/
70 7 : GF_Err gf_odf_read_url_string(GF_BitStream *bs, char **string, u32 *readBytes)
71 : {
72 : u32 length;
73 7 : *readBytes = 0;
74 :
75 : /*if the string is not NULL, return an error...*/
76 7 : if (*string != NULL) return GF_BAD_PARAM;
77 :
78 : /*the len is always on 8 bits*/
79 7 : length = gf_bs_read_int(bs, 8);
80 7 : *readBytes = 1;
81 : /*JLF AMD to MPEG-4 systems :) - This is not conformant at all, just hoping MPEG will accept it soon
82 : since 255bytes URL is a real pain in the neck*/
83 7 : if (!length) {
84 0 : length = gf_bs_read_int(bs, 32);
85 0 : *readBytes += 4;
86 0 : if (length>0xFFFF) return GF_ODF_INVALID_DESCRIPTOR;
87 : }
88 : /*we want to use strlen to get rid of "stringLength" => we need an extra 0*/
89 7 : (*string) = (char *) gf_malloc(length + 1);
90 7 : if (! *string) return GF_OUT_OF_MEM;
91 7 : gf_bs_read_data(bs, (*string), length);
92 7 : *readBytes += length;
93 7 : (*string)[length] = 0;
94 7 : return GF_OK;
95 : }
96 :
97 : /*writes string*/
98 10 : GF_Err gf_odf_write_url_string(GF_BitStream *bs, char *string)
99 : {
100 : u32 len;
101 : /*we accept NULL strings now*/
102 10 : if (!string) {
103 0 : gf_bs_write_int(bs, 0, 8);
104 0 : return GF_OK;
105 : }
106 10 : len = (u32) strlen(string);
107 10 : if (len > 255) {
108 0 : gf_bs_write_int(bs, 0, 8);
109 0 : gf_bs_write_int(bs, len, 32);
110 : } else {
111 10 : gf_bs_write_int(bs, len, 8);
112 : }
113 10 : gf_bs_write_data(bs, string, len);
114 10 : return GF_OK;
115 : }
116 :
117 0 : u32 gf_odf_size_url_string(char *string)
118 : {
119 18 : u32 len = (u32) strlen(string);
120 18 : if (len>255) return len+5;
121 18 : return len+1;
122 : }
123 :
124 8059 : GF_Descriptor *gf_odf_new_esd()
125 : {
126 8059 : GF_ESD *newDesc = (GF_ESD *) gf_malloc(sizeof(GF_ESD));
127 8059 : if (!newDesc) return NULL;
128 : memset(newDesc, 0, sizeof(GF_ESD));
129 8059 : newDesc->IPIDataSet = gf_list_new();
130 8059 : newDesc->IPMPDescriptorPointers = gf_list_new();
131 8059 : newDesc->extensionDescriptors = gf_list_new();
132 8059 : newDesc->tag = GF_ODF_ESD_TAG;
133 8059 : return (GF_Descriptor *) newDesc;
134 : }
135 :
136 :
137 8059 : GF_Err gf_odf_del_esd(GF_ESD *esd)
138 : {
139 : GF_Err e;
140 8059 : if (!esd) return GF_BAD_PARAM;
141 8059 : if (esd->URLString) gf_free(esd->URLString);
142 :
143 8059 : if (esd->decoderConfig) {
144 7858 : e = gf_odf_delete_descriptor((GF_Descriptor *) esd->decoderConfig);
145 7858 : if (e) return e;
146 : }
147 8059 : if (esd->slConfig) {
148 7406 : e = gf_odf_delete_descriptor((GF_Descriptor *) esd->slConfig);
149 7406 : if (e) return e;
150 : }
151 8059 : if (esd->ipiPtr) {
152 0 : e = gf_odf_delete_descriptor((GF_Descriptor *) esd->ipiPtr);
153 0 : if (e) return e;
154 : }
155 8059 : if (esd->qos) {
156 0 : e = gf_odf_delete_descriptor((GF_Descriptor *) esd->qos);
157 0 : if (e) return e;
158 : }
159 8059 : if (esd->RegDescriptor) {
160 0 : e = gf_odf_delete_descriptor((GF_Descriptor *) esd->RegDescriptor);
161 0 : if (e) return e;
162 : }
163 8059 : if (esd->langDesc) {
164 30 : e = gf_odf_delete_descriptor((GF_Descriptor *) esd->langDesc);
165 30 : if (e) return e;
166 : }
167 :
168 8059 : e = gf_odf_delete_descriptor_list(esd->IPIDataSet);
169 8059 : if (e) return e;
170 8059 : e = gf_odf_delete_descriptor_list(esd->IPMPDescriptorPointers);
171 8059 : if (e) return e;
172 8059 : e = gf_odf_delete_descriptor_list(esd->extensionDescriptors);
173 8059 : if (e) return e;
174 8059 : gf_free(esd);
175 8059 : return GF_OK;
176 : }
177 :
178 :
179 8294 : GF_Err AddDescriptorToESD(GF_ESD *esd, GF_Descriptor *desc)
180 : {
181 8294 : if (!esd || !desc) return GF_BAD_PARAM;
182 :
183 8294 : switch (desc->tag) {
184 4311 : case GF_ODF_DCD_TAG:
185 4311 : if (esd->decoderConfig) return GF_ODF_INVALID_DESCRIPTOR;
186 4311 : esd->decoderConfig = (GF_DecoderConfig *) desc;
187 4311 : break;
188 :
189 3786 : case GF_ODF_SLC_TAG:
190 3786 : if (esd->slConfig) return GF_ODF_INVALID_DESCRIPTOR;
191 3786 : esd->slConfig = (GF_SLConfig *) desc;
192 3786 : break;
193 :
194 168 : case GF_ODF_MUXINFO_TAG:
195 168 : gf_list_add(esd->extensionDescriptors, desc);
196 168 : break;
197 :
198 9 : case GF_ODF_LANG_TAG:
199 9 : if (esd->langDesc) return GF_ODF_INVALID_DESCRIPTOR;
200 9 : esd->langDesc = (GF_Language *) desc;
201 9 : break;
202 :
203 : #ifndef GPAC_MINIMAL_ODF
204 : //the GF_ODF_ISOM_IPI_PTR_TAG is only used in the file format and replaces GF_ODF_IPI_PTR_TAG...
205 : case GF_ODF_ISOM_IPI_PTR_TAG:
206 : case GF_ODF_IPI_PTR_TAG:
207 : if (esd->ipiPtr) return GF_ODF_INVALID_DESCRIPTOR;
208 : esd->ipiPtr = (GF_IPIPtr *) desc;
209 : break;
210 :
211 : case GF_ODF_QOS_TAG:
212 : if (esd->qos) return GF_ODF_INVALID_DESCRIPTOR;
213 : esd->qos =(GF_QoS_Descriptor *) desc;
214 : break;
215 :
216 : case GF_ODF_CI_TAG:
217 : case GF_ODF_SCI_TAG:
218 : return gf_list_add(esd->IPIDataSet, desc);
219 :
220 : //we use the same struct for v1 and v2 IPMP DPs
221 : case GF_ODF_IPMP_PTR_TAG:
222 : return gf_list_add(esd->IPMPDescriptorPointers, desc);
223 :
224 : case GF_ODF_REG_TAG:
225 : if (esd->RegDescriptor) return GF_ODF_INVALID_DESCRIPTOR;
226 : esd->RegDescriptor =(GF_Registration *) desc;
227 : break;
228 : #endif
229 :
230 20 : default:
231 20 : if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) &&
232 : (desc->tag <= GF_ODF_EXT_END_TAG) ) {
233 20 : return gf_list_add(esd->extensionDescriptors, desc);
234 : }
235 0 : gf_odf_delete_descriptor(desc);
236 0 : return GF_OK;
237 : }
238 :
239 : return GF_OK;
240 : }
241 :
242 3754 : GF_Err gf_odf_read_esd(GF_BitStream *bs, GF_ESD *esd, u32 DescSize)
243 : {
244 : GF_Err e = GF_OK;
245 : u32 ocrflag, urlflag, streamdependflag, tmp_size, nbBytes, read;
246 :
247 3754 : if (! esd) return GF_BAD_PARAM;
248 :
249 : nbBytes = 0;
250 :
251 3754 : esd->ESID = gf_bs_read_int(bs, 16);
252 3754 : streamdependflag = gf_bs_read_int(bs, 1);
253 3754 : urlflag = gf_bs_read_int(bs, 1);
254 3754 : ocrflag = gf_bs_read_int(bs, 1);
255 3754 : esd->streamPriority = gf_bs_read_int(bs, 5);
256 : nbBytes += 3;
257 :
258 3754 : if (streamdependflag) {
259 59 : esd->dependsOnESID = gf_bs_read_int(bs, 16);
260 : nbBytes += 2;
261 : }
262 :
263 3754 : if (urlflag) {
264 0 : e = gf_odf_read_url_string(bs, & esd->URLString, &read);
265 0 : if (e) return e;
266 0 : nbBytes += read;
267 : }
268 3754 : if (ocrflag) {
269 221 : esd->OCRESID = gf_bs_read_int(bs, 16);
270 221 : nbBytes += 2;
271 : }
272 :
273 11268 : while (nbBytes < DescSize) {
274 7514 : GF_Descriptor *tmp = NULL;
275 7514 : e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size);
276 : /*fix for iPod files*/
277 7514 : if (e==GF_ODF_INVALID_DESCRIPTOR) {
278 0 : nbBytes += tmp_size;
279 0 : if (nbBytes>DescSize) return e;
280 0 : gf_bs_read_int(bs, DescSize-nbBytes);
281 0 : return GF_OK;
282 : }
283 7514 : if (e) return e;
284 7514 : if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
285 7514 : e = AddDescriptorToESD(esd, tmp);
286 7514 : if (e) {
287 0 : gf_odf_desc_del(tmp);
288 0 : return e;
289 : }
290 7514 : nbBytes += tmp_size + gf_odf_size_field_size(tmp_size);
291 :
292 : //apple fix
293 7514 : if (!tmp_size) nbBytes = DescSize;
294 :
295 : }
296 3754 : if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
297 3754 : return e;
298 :
299 : }
300 :
301 6121 : GF_Err gf_odf_size_esd(GF_ESD *esd, u32 *outSize)
302 : {
303 : GF_Err e;
304 : u32 tmpSize;
305 6121 : if (! esd) return GF_BAD_PARAM;
306 :
307 : *outSize = 0;
308 6121 : *outSize += 3;
309 :
310 6121 : if (esd->dependsOnESID) *outSize += 2;
311 6129 : if (esd->URLString) *outSize += gf_odf_size_url_string(esd->URLString);
312 6121 : if (esd->OCRESID) *outSize += 2;
313 :
314 6121 : if (esd->decoderConfig) {
315 6116 : e = gf_odf_size_descriptor((GF_Descriptor *) esd->decoderConfig, &tmpSize);
316 6116 : if (e) return e;
317 6116 : *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
318 : }
319 6121 : if (esd->slConfig) {
320 6116 : e = gf_odf_size_descriptor((GF_Descriptor *) esd->slConfig, &tmpSize);
321 6116 : if (e) return e;
322 6116 : *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
323 : }
324 6121 : if (esd->ipiPtr) {
325 0 : e = gf_odf_size_descriptor((GF_Descriptor *) esd->ipiPtr, &tmpSize);
326 0 : if (e) return e;
327 0 : *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
328 : }
329 6121 : if (esd->langDesc) {
330 7 : e = gf_odf_size_descriptor((GF_Descriptor *) esd->langDesc, &tmpSize);
331 7 : if (e) return e;
332 7 : *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
333 : }
334 :
335 6121 : e = gf_odf_size_descriptor_list(esd->IPIDataSet, outSize);
336 6121 : if (e) return e;
337 6121 : e = gf_odf_size_descriptor_list(esd->IPMPDescriptorPointers, outSize);
338 6121 : if (e) return e;
339 6121 : if (esd->qos) {
340 0 : e = gf_odf_size_descriptor((GF_Descriptor *) esd->qos, &tmpSize);
341 0 : if (e) return e;
342 0 : *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
343 : }
344 6121 : if (esd->RegDescriptor) {
345 0 : e = gf_odf_size_descriptor((GF_Descriptor *) esd->RegDescriptor, &tmpSize);
346 0 : if (e) return e;
347 0 : *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
348 : }
349 6121 : return gf_odf_size_descriptor_list(esd->extensionDescriptors, outSize);
350 : }
351 :
352 3639 : GF_Err gf_odf_write_esd(GF_BitStream *bs, GF_ESD *esd)
353 : {
354 : GF_Err e;
355 : u32 size;
356 3639 : if (! esd) return GF_BAD_PARAM;
357 :
358 3639 : e = gf_odf_size_descriptor((GF_Descriptor *)esd, &size);
359 3639 : if (e) return e;
360 3639 : e = gf_odf_write_base_descriptor(bs, esd->tag, size);
361 3639 : if (e) return e;
362 :
363 3639 : gf_bs_write_int(bs, esd->ESID, 16);
364 3639 : gf_bs_write_int(bs, esd->dependsOnESID ? 1 : 0, 1);
365 3639 : gf_bs_write_int(bs, esd->URLString != NULL ? 1 : 0, 1);
366 3639 : gf_bs_write_int(bs, esd->OCRESID ? 1 : 0, 1);
367 3639 : gf_bs_write_int(bs, esd->streamPriority, 5);
368 :
369 3639 : if (esd->dependsOnESID) {
370 59 : gf_bs_write_int(bs, esd->dependsOnESID, 16);
371 : }
372 3639 : if (esd->URLString) {
373 4 : e = gf_odf_write_url_string(bs, esd->URLString);
374 4 : if (e) return e;
375 : }
376 :
377 :
378 3639 : if (esd->OCRESID) {
379 240 : gf_bs_write_int(bs, esd->OCRESID, 16);
380 : }
381 3639 : if (esd->decoderConfig) {
382 3637 : e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->decoderConfig);
383 3637 : if (e) return e;
384 : }
385 3639 : if (esd->slConfig) {
386 3637 : e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->slConfig);
387 3637 : if (e) return e;
388 : }
389 3639 : if (esd->ipiPtr) {
390 0 : e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->ipiPtr);
391 0 : if (e) return e;
392 : }
393 3639 : if (esd->langDesc) {
394 4 : e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->langDesc);
395 4 : if (e) return e;
396 : }
397 :
398 3639 : e = gf_odf_write_descriptor_list(bs, esd->IPIDataSet);
399 3639 : if (e) return e;
400 3639 : e = gf_odf_write_descriptor_list(bs, esd->IPMPDescriptorPointers);
401 3639 : if (e) return e;
402 3639 : if (esd->qos) {
403 0 : e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->qos);
404 0 : if (e) return e;
405 : }
406 3639 : if (esd->RegDescriptor) {
407 0 : e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->RegDescriptor);
408 0 : if (e) return e;
409 : }
410 3639 : return gf_odf_write_descriptor_list(bs, esd->extensionDescriptors);
411 : }
412 :
413 390 : GF_Descriptor *gf_odf_new_iod()
414 : {
415 390 : GF_InitialObjectDescriptor *newDesc = (GF_InitialObjectDescriptor *) gf_malloc(sizeof(GF_InitialObjectDescriptor));
416 390 : if (!newDesc) return NULL;
417 : memset(newDesc, 0, sizeof(GF_InitialObjectDescriptor));
418 :
419 390 : newDesc->ESDescriptors = gf_list_new();
420 390 : newDesc->OCIDescriptors = gf_list_new();
421 390 : newDesc->IPMP_Descriptors = gf_list_new();
422 :
423 390 : newDesc->extensionDescriptors = gf_list_new();
424 390 : newDesc->tag = GF_ODF_IOD_TAG;
425 390 : return (GF_Descriptor *) newDesc;
426 : }
427 :
428 963 : GF_Err gf_odf_del_iod(GF_InitialObjectDescriptor *iod)
429 : {
430 : GF_Err e;
431 963 : if (!iod) return GF_BAD_PARAM;
432 963 : if (iod->URLString) gf_free(iod->URLString);
433 963 : e = gf_odf_delete_descriptor_list(iod->ESDescriptors);
434 963 : if (e) return e;
435 963 : e = gf_odf_delete_descriptor_list(iod->OCIDescriptors);
436 963 : if (e) return e;
437 963 : e = gf_odf_delete_descriptor_list(iod->IPMP_Descriptors);
438 963 : if (e) return e;
439 963 : e = gf_odf_delete_descriptor_list(iod->extensionDescriptors);
440 963 : if (e) return e;
441 963 : if (iod->IPMPToolList) gf_odf_delete_descriptor((GF_Descriptor *) iod->IPMPToolList);
442 963 : gf_free(iod);
443 963 : return GF_OK;
444 : }
445 :
446 528 : GF_Err AddDescriptorToIOD(GF_InitialObjectDescriptor *iod, GF_Descriptor *desc)
447 : {
448 528 : if (!iod || !desc) return GF_BAD_PARAM;
449 :
450 528 : switch (desc->tag) {
451 522 : case GF_ODF_ESD_TAG:
452 522 : return gf_list_add(iod->ESDescriptors, desc);
453 :
454 : //we use the same struct for v1 and v2 IPMP DPs
455 0 : case GF_ODF_IPMP_PTR_TAG:
456 : /*IPMPX*/
457 : case GF_ODF_IPMP_TAG:
458 0 : return gf_list_add(iod->IPMP_Descriptors, desc);
459 :
460 : /*IPMPX*/
461 0 : case GF_ODF_IPMP_TL_TAG:
462 0 : if (iod->IPMPToolList) gf_odf_desc_del((GF_Descriptor *)iod->IPMPToolList);
463 0 : iod->IPMPToolList = (GF_IPMP_ToolList *)desc;
464 0 : return GF_OK;
465 :
466 : default:
467 : break;
468 : }
469 6 : if ( (desc->tag >= GF_ODF_OCI_BEGIN_TAG) && (desc->tag <= GF_ODF_OCI_END_TAG) ) return gf_list_add(iod->OCIDescriptors, desc);
470 0 : if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) && (desc->tag <= GF_ODF_EXT_END_TAG) ) return gf_list_add(iod->extensionDescriptors, desc);
471 : return GF_BAD_PARAM;
472 : }
473 :
474 4 : GF_Err gf_odf_read_iod(GF_BitStream *bs, GF_InitialObjectDescriptor *iod, u32 DescSize)
475 : {
476 : GF_Err e;
477 : u32 urlflag, read;
478 : u32 tmp_size, nbBytes = 0;
479 4 : if (! iod) return GF_BAD_PARAM;
480 :
481 4 : iod->objectDescriptorID = gf_bs_read_int(bs, 10);
482 4 : urlflag = gf_bs_read_int(bs, 1);
483 4 : iod->inlineProfileFlag = gf_bs_read_int(bs, 1);
484 4 : /*reserved = */gf_bs_read_int(bs, 4);
485 : nbBytes += 2;
486 :
487 4 : if (urlflag) {
488 0 : e = gf_odf_read_url_string(bs, & iod->URLString, &read);
489 0 : if (e) return e;
490 0 : nbBytes += read;
491 : } else {
492 4 : iod->OD_profileAndLevel = gf_bs_read_int(bs, 8);
493 4 : iod->scene_profileAndLevel = gf_bs_read_int(bs, 8);
494 4 : iod->audio_profileAndLevel = gf_bs_read_int(bs, 8);
495 4 : iod->visual_profileAndLevel = gf_bs_read_int(bs, 8);
496 4 : iod->graphics_profileAndLevel = gf_bs_read_int(bs, 8);
497 : nbBytes += 5;
498 : }
499 :
500 11 : while (nbBytes < DescSize) {
501 7 : GF_Descriptor *tmp = NULL;
502 7 : e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size);
503 7 : if (e) return e;
504 7 : if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
505 7 : e = AddDescriptorToIOD(iod, tmp);
506 7 : if (e) {
507 0 : gf_odf_delete_descriptor(tmp);
508 0 : return e;
509 : }
510 7 : nbBytes += tmp_size + gf_odf_size_field_size(tmp_size);
511 : }
512 4 : if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
513 4 : return GF_OK;
514 : }
515 :
516 83 : GF_Err gf_odf_size_iod(GF_InitialObjectDescriptor *iod, u32 *outSize)
517 : {
518 : GF_Err e;
519 83 : if (! iod) return GF_BAD_PARAM;
520 :
521 : *outSize = 0;
522 83 : *outSize += 2;
523 83 : if (iod->URLString) {
524 0 : *outSize += gf_odf_size_url_string(iod->URLString);
525 : } else {
526 83 : *outSize += 5;
527 83 : e = gf_odf_size_descriptor_list(iod->ESDescriptors, outSize);
528 83 : if (e) return e;
529 83 : e = gf_odf_size_descriptor_list(iod->OCIDescriptors, outSize);
530 83 : if (e) return e;
531 83 : e = gf_odf_size_descriptor_list(iod->IPMP_Descriptors, outSize);
532 83 : if (e) return e;
533 :
534 : }
535 83 : e = gf_odf_size_descriptor_list(iod->extensionDescriptors, outSize);
536 83 : if (e) return e;
537 83 : if (iod->IPMPToolList) {
538 : u32 tmpSize;
539 0 : e = gf_odf_size_descriptor((GF_Descriptor *) iod->IPMPToolList, &tmpSize);
540 0 : if (e) return e;
541 0 : *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
542 : }
543 : return GF_OK;
544 : }
545 :
546 9 : GF_Err gf_odf_write_iod(GF_BitStream *bs, GF_InitialObjectDescriptor *iod)
547 : {
548 : GF_Err e;
549 : u32 size;
550 9 : if (! iod) return GF_BAD_PARAM;
551 :
552 9 : e = gf_odf_size_descriptor((GF_Descriptor *)iod, &size);
553 9 : if (e) return e;
554 9 : e = gf_odf_write_base_descriptor(bs, iod->tag, size);
555 9 : if (e) return e;
556 :
557 9 : gf_bs_write_int(bs, iod->objectDescriptorID, 10);
558 9 : gf_bs_write_int(bs, iod->URLString != NULL ? 1 : 0, 1);
559 9 : gf_bs_write_int(bs, iod->inlineProfileFlag, 1);
560 9 : gf_bs_write_int(bs, 15, 4); //reserved: 0b1111 == 15
561 :
562 9 : if (iod->URLString) {
563 0 : gf_odf_write_url_string(bs, iod->URLString);
564 : } else {
565 9 : gf_bs_write_int(bs, iod->OD_profileAndLevel, 8);
566 9 : gf_bs_write_int(bs, iod->scene_profileAndLevel, 8);
567 9 : gf_bs_write_int(bs, iod->audio_profileAndLevel, 8);
568 9 : gf_bs_write_int(bs, iod->visual_profileAndLevel, 8);
569 9 : gf_bs_write_int(bs, iod->graphics_profileAndLevel, 8);
570 9 : e = gf_odf_write_descriptor_list(bs, iod->ESDescriptors);
571 9 : if (e) return e;
572 9 : e = gf_odf_write_descriptor_list(bs, iod->OCIDescriptors);
573 9 : if (e) return e;
574 9 : e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
575 9 : if (e) return e;
576 9 : e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_TAG);
577 9 : if (e) return e;
578 9 : if (iod->IPMPToolList) {
579 0 : e = gf_odf_write_descriptor(bs, (GF_Descriptor *) iod->IPMPToolList);
580 0 : if (e) return e;
581 : }
582 : }
583 9 : return gf_odf_write_descriptor_list(bs, iod->extensionDescriptors);
584 : }
585 :
586 :
587 :
588 701 : GF_Descriptor *gf_odf_new_od()
589 : {
590 : GF_ObjectDescriptor *newDesc;
591 701 : GF_SAFEALLOC(newDesc, GF_ObjectDescriptor);
592 701 : if (!newDesc) return NULL;
593 :
594 701 : newDesc->URLString = NULL;
595 701 : newDesc->ESDescriptors = gf_list_new();
596 701 : newDesc->OCIDescriptors = gf_list_new();
597 701 : newDesc->IPMP_Descriptors = gf_list_new();
598 701 : newDesc->extensionDescriptors = gf_list_new();
599 701 : newDesc->objectDescriptorID = 0;
600 701 : newDesc->tag = GF_ODF_OD_TAG;
601 701 : return (GF_Descriptor *) newDesc;
602 : }
603 :
604 797 : GF_Err gf_odf_del_od(GF_ObjectDescriptor *od)
605 : {
606 : GF_Err e;
607 797 : if (!od) return GF_BAD_PARAM;
608 797 : if (od->URLString) gf_free(od->URLString);
609 797 : e = gf_odf_delete_descriptor_list(od->ESDescriptors);
610 797 : if (e) return e;
611 797 : e = gf_odf_delete_descriptor_list(od->OCIDescriptors);
612 797 : if (e) return e;
613 797 : e = gf_odf_delete_descriptor_list(od->IPMP_Descriptors);
614 797 : if (e) return e;
615 797 : e = gf_odf_delete_descriptor_list(od->extensionDescriptors);
616 797 : if (e) return e;
617 797 : gf_free(od);
618 797 : return GF_OK;
619 : }
620 :
621 628 : GF_Err AddDescriptorToOD(GF_ObjectDescriptor *od, GF_Descriptor *desc)
622 : {
623 628 : if (!od || !desc) return GF_BAD_PARAM;
624 :
625 : //check if we can handle ContentClassif tags
626 628 : if ( (desc->tag >= GF_ODF_OCI_BEGIN_TAG) &&
627 : (desc->tag <= GF_ODF_OCI_END_TAG) ) {
628 9 : return gf_list_add(od->OCIDescriptors, desc);
629 : }
630 :
631 : //or extensions
632 619 : if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) &&
633 : (desc->tag <= GF_ODF_EXT_END_TAG) ) {
634 0 : return gf_list_add(od->extensionDescriptors, desc);
635 : }
636 :
637 : //to cope with envivio
638 619 : switch (desc->tag) {
639 619 : case GF_ODF_ESD_TAG:
640 : case GF_ODF_ESD_REF_TAG:
641 619 : return gf_list_add(od->ESDescriptors, desc);
642 :
643 : //we use the same struct for v1 and v2 IPMP DPs
644 0 : case GF_ODF_IPMP_PTR_TAG:
645 : case GF_ODF_IPMP_TAG:
646 0 : return gf_list_add(od->IPMP_Descriptors, desc);
647 :
648 : default:
649 : return GF_BAD_PARAM;
650 : }
651 : }
652 :
653 323 : GF_Err gf_odf_read_od(GF_BitStream *bs, GF_ObjectDescriptor *od, u32 DescSize)
654 : {
655 : GF_Err e;
656 : u32 urlflag;
657 : u32 tmpSize, nbBytes = 0;
658 323 : if (! od) return GF_BAD_PARAM;
659 :
660 323 : od->objectDescriptorID = gf_bs_read_int(bs, 10);
661 323 : urlflag = gf_bs_read_int(bs, 1);
662 323 : /*reserved = */gf_bs_read_int(bs, 5);
663 : nbBytes += 2;
664 :
665 323 : if (urlflag) {
666 : u32 read;
667 4 : e = gf_odf_read_url_string(bs, & od->URLString, &read);
668 4 : if (e) return e;
669 4 : nbBytes += read;
670 : }
671 :
672 636 : while (nbBytes < DescSize) {
673 313 : GF_Descriptor *tmp = NULL;
674 313 : e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
675 313 : if (e) return e;
676 313 : if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
677 313 : e = AddDescriptorToOD(od, tmp);
678 313 : if (e) {
679 0 : gf_odf_desc_del(tmp);
680 0 : return e;
681 : }
682 313 : nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
683 : }
684 323 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
685 323 : return GF_OK;
686 : }
687 :
688 535 : GF_Err gf_odf_size_od(GF_ObjectDescriptor *od, u32 *outSize)
689 : {
690 : GF_Err e;
691 535 : if (! od) return GF_BAD_PARAM;
692 :
693 535 : *outSize = 2;
694 535 : if (od->URLString) {
695 6 : *outSize += gf_odf_size_url_string(od->URLString);
696 : } else {
697 529 : e = gf_odf_size_descriptor_list(od->ESDescriptors, outSize);
698 529 : if (e) return e;
699 529 : e = gf_odf_size_descriptor_list(od->OCIDescriptors, outSize);
700 529 : if (e) return e;
701 529 : e = gf_odf_size_descriptor_list(od->IPMP_Descriptors, outSize);
702 529 : if (e) return e;
703 : }
704 535 : return gf_odf_size_descriptor_list(od->extensionDescriptors, outSize);
705 : }
706 :
707 335 : GF_Err gf_odf_write_od(GF_BitStream *bs, GF_ObjectDescriptor *od)
708 : {
709 : GF_Err e;
710 : u32 size;
711 335 : if (! od) return GF_BAD_PARAM;
712 :
713 335 : e = gf_odf_size_descriptor((GF_Descriptor *)od, &size);
714 335 : if (e) return e;
715 335 : e = gf_odf_write_base_descriptor(bs, od->tag, size);
716 335 : if (e) return e;
717 :
718 335 : gf_bs_write_int(bs, od->objectDescriptorID, 10);
719 335 : gf_bs_write_int(bs, od->URLString != NULL ? 1 : 0, 1);
720 335 : gf_bs_write_int(bs, 31, 5); //reserved: 0b1111.1 == 31
721 :
722 335 : if (od->URLString) {
723 4 : gf_odf_write_url_string(bs, od->URLString);
724 : } else {
725 331 : e = gf_odf_write_descriptor_list(bs, od->ESDescriptors);
726 331 : if (e) return e;
727 331 : e = gf_odf_write_descriptor_list(bs, od->OCIDescriptors);
728 331 : if (e) return e;
729 331 : e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
730 331 : if (e) return e;
731 331 : e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_TAG);
732 331 : if (e) return e;
733 : }
734 335 : return gf_odf_write_descriptor_list(bs, od->extensionDescriptors);
735 : }
736 :
737 1857 : GF_Descriptor *gf_odf_new_isom_iod()
738 : {
739 1857 : GF_IsomInitialObjectDescriptor *newDesc = (GF_IsomInitialObjectDescriptor *) gf_malloc(sizeof(GF_IsomInitialObjectDescriptor));
740 1857 : if (!newDesc) return NULL;
741 : memset(newDesc, 0, sizeof(GF_IsomInitialObjectDescriptor));
742 :
743 1857 : newDesc->ES_ID_IncDescriptors = gf_list_new();
744 1857 : newDesc->ES_ID_RefDescriptors = gf_list_new();
745 1857 : newDesc->OCIDescriptors = gf_list_new();
746 1857 : newDesc->IPMP_Descriptors = gf_list_new();
747 1857 : newDesc->extensionDescriptors = gf_list_new();
748 1857 : newDesc->tag = GF_ODF_ISOM_IOD_TAG;
749 :
750 : //by default create an IOD with no inline and no capabilities
751 1857 : newDesc->audio_profileAndLevel = 0xFF;
752 1857 : newDesc->graphics_profileAndLevel = 0xFF;
753 1857 : newDesc->scene_profileAndLevel = 0xFF;
754 1857 : newDesc->OD_profileAndLevel = 0xFF;
755 1857 : newDesc->visual_profileAndLevel = 0xFF;
756 1857 : return (GF_Descriptor *) newDesc;
757 : }
758 :
759 1893 : GF_Err gf_odf_del_isom_iod(GF_IsomInitialObjectDescriptor *iod)
760 : {
761 : GF_Err e;
762 1893 : if (!iod) return GF_BAD_PARAM;
763 1893 : if (iod->URLString) gf_free(iod->URLString);
764 1893 : e = gf_odf_delete_descriptor_list(iod->ES_ID_IncDescriptors);
765 1893 : if (e) return e;
766 1893 : e = gf_odf_delete_descriptor_list(iod->ES_ID_RefDescriptors);
767 1893 : if (e) return e;
768 1893 : e = gf_odf_delete_descriptor_list(iod->OCIDescriptors);
769 1893 : if (e) return e;
770 1893 : e = gf_odf_delete_descriptor_list(iod->IPMP_Descriptors);
771 1893 : if (e) return e;
772 1893 : e = gf_odf_delete_descriptor_list(iod->extensionDescriptors);
773 1893 : if (e) return e;
774 1893 : if (iod->IPMPToolList) gf_odf_delete_descriptor((GF_Descriptor *) iod->IPMPToolList);
775 1893 : gf_free(iod);
776 1893 : return GF_OK;
777 : }
778 :
779 279 : GF_Err AddDescriptorToIsomIOD(GF_IsomInitialObjectDescriptor *iod, GF_Descriptor *desc)
780 : {
781 279 : if (!iod || !desc) return GF_BAD_PARAM;
782 :
783 279 : switch (desc->tag) {
784 : case GF_ODF_ESD_TAG:
785 : return GF_ODF_FORBIDDEN_DESCRIPTOR;
786 :
787 261 : case GF_ODF_ESD_INC_TAG:
788 : //there shouldn't be ref if inc
789 261 : if (gf_list_count(iod->ES_ID_RefDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
790 261 : return gf_list_add(iod->ES_ID_IncDescriptors, desc);
791 :
792 0 : case GF_ODF_ESD_REF_TAG:
793 : //there shouldn't be inc if ref
794 0 : if (gf_list_count(iod->ES_ID_IncDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
795 0 : return gf_list_add(iod->ES_ID_RefDescriptors, desc);
796 :
797 : //we use the same struct for v1 and v2 IPMP DPs
798 0 : case GF_ODF_IPMP_PTR_TAG:
799 : case GF_ODF_IPMP_TAG:
800 0 : return gf_list_add(iod->IPMP_Descriptors, desc);
801 :
802 : /*IPMPX*/
803 0 : case GF_ODF_IPMP_TL_TAG:
804 0 : if (iod->IPMPToolList) gf_odf_desc_del((GF_Descriptor *)iod->IPMPToolList);
805 0 : iod->IPMPToolList = (GF_IPMP_ToolList *)desc;
806 0 : return GF_OK;
807 :
808 : default:
809 : break;
810 : }
811 : //check if we can handle ContentClassif tags
812 18 : if ( (desc->tag >= GF_ODF_OCI_BEGIN_TAG) && (desc->tag <= GF_ODF_OCI_END_TAG) ) return gf_list_add(iod->OCIDescriptors, desc);
813 : //or extensions
814 0 : if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) && (desc->tag <= GF_ODF_EXT_END_TAG) ) return gf_list_add(iod->extensionDescriptors, desc);
815 : return GF_BAD_PARAM;
816 : }
817 :
818 1383 : GF_Err gf_odf_read_isom_iod(GF_BitStream *bs, GF_IsomInitialObjectDescriptor *iod, u32 DescSize)
819 : {
820 : u32 nbBytes = 0, tmpSize;
821 : u32 urlflag;
822 : GF_Err e;
823 1383 : if (! iod) return GF_BAD_PARAM;
824 :
825 1383 : iod->objectDescriptorID = gf_bs_read_int(bs, 10);
826 1383 : urlflag = gf_bs_read_int(bs, 1);
827 1383 : iod->inlineProfileFlag = gf_bs_read_int(bs, 1);
828 1383 : /*reserved = */gf_bs_read_int(bs, 4);
829 : nbBytes += 2;
830 :
831 1383 : if (urlflag) {
832 : u32 read;
833 0 : e = gf_odf_read_url_string(bs, & iod->URLString, &read);
834 0 : if (e) return e;
835 0 : nbBytes += read;
836 : } else {
837 1383 : iod->OD_profileAndLevel = gf_bs_read_int(bs, 8);
838 1383 : iod->scene_profileAndLevel = gf_bs_read_int(bs, 8);
839 1383 : iod->audio_profileAndLevel = gf_bs_read_int(bs, 8);
840 1383 : iod->visual_profileAndLevel = gf_bs_read_int(bs, 8);
841 1383 : iod->graphics_profileAndLevel = gf_bs_read_int(bs, 8);
842 : nbBytes += 5;
843 : }
844 :
845 1598 : while (nbBytes < DescSize) {
846 215 : GF_Descriptor *tmp = NULL;
847 215 : e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
848 215 : if (e) {
849 0 : if (tmp) gf_odf_desc_del((GF_Descriptor *) tmp);
850 0 : return e;
851 : }
852 215 : if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
853 215 : e = AddDescriptorToIsomIOD(iod, tmp);
854 215 : if (e) {
855 0 : gf_odf_desc_del(tmp);
856 0 : return e;
857 : }
858 215 : nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
859 : }
860 1383 : if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
861 1383 : return GF_OK;
862 : }
863 :
864 2999 : GF_Err gf_odf_size_isom_iod(GF_IsomInitialObjectDescriptor *iod, u32 *outSize)
865 : {
866 : GF_Err e;
867 2999 : if (! iod) return GF_BAD_PARAM;
868 :
869 2999 : *outSize = 2;
870 2999 : if (iod->URLString) {
871 0 : *outSize += gf_odf_size_url_string(iod->URLString);
872 : } else {
873 2999 : *outSize += 5;
874 2999 : e = gf_odf_size_descriptor_list(iod->ES_ID_IncDescriptors, outSize);
875 2999 : if (e) return e;
876 2999 : e = gf_odf_size_descriptor_list(iod->ES_ID_RefDescriptors, outSize);
877 2999 : if (e) return e;
878 2999 : e = gf_odf_size_descriptor_list(iod->OCIDescriptors, outSize);
879 2999 : if (e) return e;
880 2999 : e = gf_odf_size_descriptor_list(iod->IPMP_Descriptors, outSize);
881 2999 : if (e) return e;
882 : }
883 2999 : if (iod->IPMPToolList) {
884 : u32 tmpSize;
885 0 : e = gf_odf_size_descriptor((GF_Descriptor *) iod->IPMPToolList, &tmpSize);
886 0 : if (e) return e;
887 0 : *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
888 : }
889 2999 : return gf_odf_size_descriptor_list(iod->extensionDescriptors, outSize);
890 : }
891 :
892 1204 : GF_Err gf_odf_write_isom_iod(GF_BitStream *bs, GF_IsomInitialObjectDescriptor *iod)
893 : {
894 : GF_Err e;
895 : u32 size;
896 1204 : if (! iod) return GF_BAD_PARAM;
897 :
898 1204 : e = gf_odf_size_descriptor((GF_Descriptor *)iod, &size);
899 1204 : if (e) return e;
900 1204 : e = gf_odf_write_base_descriptor(bs, iod->tag, size);
901 1204 : if (e) return e;
902 :
903 1204 : gf_bs_write_int(bs, iod->objectDescriptorID, 10);
904 1204 : gf_bs_write_int(bs, iod->URLString != NULL ? 1 : 0, 1);
905 1204 : gf_bs_write_int(bs, iod->inlineProfileFlag, 1);
906 1204 : gf_bs_write_int(bs, 15, 4); //reserved: 0b1111 == 15
907 :
908 1204 : if (iod->URLString) {
909 0 : gf_odf_write_url_string(bs, iod->URLString);
910 : } else {
911 1204 : gf_bs_write_int(bs, iod->OD_profileAndLevel, 8);
912 1204 : gf_bs_write_int(bs, iod->scene_profileAndLevel, 8);
913 1204 : gf_bs_write_int(bs, iod->audio_profileAndLevel, 8);
914 1204 : gf_bs_write_int(bs, iod->visual_profileAndLevel, 8);
915 1204 : gf_bs_write_int(bs, iod->graphics_profileAndLevel, 8);
916 1204 : e = gf_odf_write_descriptor_list(bs, iod->ES_ID_IncDescriptors);
917 1204 : if (e) return e;
918 1204 : e = gf_odf_write_descriptor_list(bs, iod->ES_ID_RefDescriptors);
919 1204 : if (e) return e;
920 1204 : e = gf_odf_write_descriptor_list(bs, iod->OCIDescriptors);
921 1204 : if (e) return e;
922 1204 : e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
923 1204 : if (e) return e;
924 1204 : e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_TAG);
925 1204 : if (e) return e;
926 1204 : if (iod->IPMPToolList) {
927 0 : e = gf_odf_write_descriptor(bs, (GF_Descriptor *) iod->IPMPToolList);
928 0 : if (e) return e;
929 : }
930 : }
931 1204 : e = gf_odf_write_descriptor_list(bs, iod->extensionDescriptors);
932 1204 : if (e) return e;
933 1204 : return GF_OK;
934 : }
935 :
936 :
937 232 : GF_Descriptor *gf_odf_new_isom_od()
938 : {
939 232 : GF_IsomObjectDescriptor *newDesc = (GF_IsomObjectDescriptor *) gf_malloc(sizeof(GF_IsomObjectDescriptor));
940 232 : if (!newDesc) return NULL;
941 :
942 232 : newDesc->URLString = NULL;
943 232 : newDesc->ES_ID_IncDescriptors = gf_list_new();
944 232 : newDesc->ES_ID_RefDescriptors = gf_list_new();
945 232 : newDesc->OCIDescriptors = gf_list_new();
946 232 : newDesc->IPMP_Descriptors = gf_list_new();
947 232 : newDesc->extensionDescriptors = gf_list_new();
948 232 : newDesc->objectDescriptorID = 0;
949 232 : newDesc->tag = GF_ODF_ISOM_OD_TAG;
950 232 : return (GF_Descriptor *) newDesc;
951 : }
952 :
953 349 : GF_Err gf_odf_del_isom_od(GF_IsomObjectDescriptor *od)
954 : {
955 : GF_Err e;
956 349 : if (!od) return GF_BAD_PARAM;
957 349 : if (od->URLString) gf_free(od->URLString);
958 349 : e = gf_odf_delete_descriptor_list(od->ES_ID_IncDescriptors);
959 349 : if (e) return e;
960 349 : e = gf_odf_delete_descriptor_list(od->ES_ID_RefDescriptors);
961 349 : if (e) return e;
962 349 : e = gf_odf_delete_descriptor_list(od->OCIDescriptors);
963 349 : if (e) return e;
964 349 : e = gf_odf_delete_descriptor_list(od->IPMP_Descriptors);
965 349 : if (e) return e;
966 349 : e = gf_odf_delete_descriptor_list(od->extensionDescriptors);
967 349 : if (e) return e;
968 349 : gf_free(od);
969 349 : return GF_OK;
970 : }
971 :
972 341 : GF_Err AddDescriptorToIsomOD(GF_IsomObjectDescriptor *od, GF_Descriptor *desc)
973 : {
974 341 : if (!od || !desc) return GF_BAD_PARAM;
975 :
976 : //check if we can handle ContentClassif tags
977 341 : if ( (desc->tag >= GF_ODF_OCI_BEGIN_TAG) &&
978 : (desc->tag <= GF_ODF_OCI_END_TAG) ) {
979 0 : return gf_list_add(od->OCIDescriptors, desc);
980 : }
981 :
982 : //or extension ...
983 341 : if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) &&
984 : (desc->tag <= GF_ODF_EXT_END_TAG) ) {
985 0 : return gf_list_add(od->extensionDescriptors, desc);
986 : }
987 :
988 341 : switch (desc->tag) {
989 : case GF_ODF_ESD_TAG:
990 : return GF_ODF_FORBIDDEN_DESCRIPTOR;
991 :
992 36 : case GF_ODF_ESD_INC_TAG:
993 : //there shouldn't be ref if inc
994 36 : if (gf_list_count(od->ES_ID_RefDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
995 36 : return gf_list_add(od->ES_ID_IncDescriptors, desc);
996 :
997 305 : case GF_ODF_ESD_REF_TAG:
998 : //there shouldn't be inc if ref
999 305 : if (gf_list_count(od->ES_ID_IncDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
1000 305 : return gf_list_add(od->ES_ID_RefDescriptors, desc);
1001 :
1002 : //we use the same struct for v1 and v2 IPMP DPs
1003 0 : case GF_ODF_IPMP_PTR_TAG:
1004 : case GF_ODF_IPMP_TAG:
1005 0 : return gf_list_add(od->IPMP_Descriptors, desc);
1006 :
1007 0 : default:
1008 0 : return GF_BAD_PARAM;
1009 : }
1010 : }
1011 :
1012 196 : GF_Err gf_odf_read_isom_od(GF_BitStream *bs, GF_IsomObjectDescriptor *od, u32 DescSize)
1013 : {
1014 : GF_Err e;
1015 : u32 urlflag;
1016 : u32 tmpSize, nbBytes = 0;
1017 196 : if (! od) return GF_BAD_PARAM;
1018 :
1019 196 : od->objectDescriptorID = gf_bs_read_int(bs, 10);
1020 196 : urlflag = gf_bs_read_int(bs, 1);
1021 196 : /*reserved = */gf_bs_read_int(bs, 5);
1022 : nbBytes += 2;
1023 :
1024 196 : if (urlflag) {
1025 : u32 read;
1026 3 : e = gf_odf_read_url_string(bs, & od->URLString, &read);
1027 3 : if (e) return e;
1028 3 : nbBytes += read;
1029 : }
1030 :
1031 389 : while (nbBytes < DescSize) {
1032 193 : GF_Descriptor *tmp = NULL;
1033 193 : e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
1034 193 : if (e) return e;
1035 193 : if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
1036 193 : e = AddDescriptorToIsomOD(od, tmp);
1037 193 : if (e) {
1038 0 : gf_odf_delete_descriptor(tmp);
1039 0 : return e;
1040 : }
1041 193 : nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
1042 : }
1043 196 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1044 196 : return GF_OK;
1045 : }
1046 :
1047 330 : GF_Err gf_odf_size_isom_od(GF_IsomObjectDescriptor *od, u32 *outSize)
1048 : {
1049 : GF_Err e;
1050 330 : if (! od) return GF_BAD_PARAM;
1051 :
1052 330 : *outSize = 2;
1053 330 : if (od->URLString) {
1054 4 : *outSize += gf_odf_size_url_string(od->URLString);
1055 : } else {
1056 326 : e = gf_odf_size_descriptor_list(od->ES_ID_IncDescriptors, outSize);
1057 326 : if (e) return e;
1058 326 : e = gf_odf_size_descriptor_list(od->ES_ID_RefDescriptors, outSize);
1059 326 : if (e) return e;
1060 326 : e = gf_odf_size_descriptor_list(od->OCIDescriptors, outSize);
1061 326 : if (e) return e;
1062 326 : e = gf_odf_size_descriptor_list(od->IPMP_Descriptors, outSize);
1063 326 : if (e) return e;
1064 : }
1065 330 : return gf_odf_size_descriptor_list(od->extensionDescriptors, outSize);
1066 : }
1067 :
1068 213 : GF_Err gf_odf_write_isom_od(GF_BitStream *bs, GF_IsomObjectDescriptor *od)
1069 : {
1070 : GF_Err e;
1071 : u32 size;
1072 213 : if (! od) return GF_BAD_PARAM;
1073 :
1074 213 : e = gf_odf_size_descriptor((GF_Descriptor *)od, &size);
1075 213 : if (e) return e;
1076 213 : e = gf_odf_write_base_descriptor(bs, od->tag, size);
1077 213 : if (e) return e;
1078 :
1079 213 : gf_bs_write_int(bs, od->objectDescriptorID, 10);
1080 213 : gf_bs_write_int(bs, od->URLString != NULL ? 1 : 0, 1);
1081 213 : gf_bs_write_int(bs, 31, 5); //reserved: 0b1111.1 == 31
1082 :
1083 213 : if (od->URLString) {
1084 2 : gf_odf_write_url_string(bs, od->URLString);
1085 : } else {
1086 211 : e = gf_odf_write_descriptor_list(bs, od->ES_ID_IncDescriptors);
1087 211 : if (e) return e;
1088 211 : e = gf_odf_write_descriptor_list(bs, od->ES_ID_RefDescriptors);
1089 211 : if (e) return e;
1090 211 : e = gf_odf_write_descriptor_list(bs, od->OCIDescriptors);
1091 211 : if (e) return e;
1092 211 : e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
1093 211 : if (e) return e;
1094 211 : e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_TAG);
1095 211 : if (e) return e;
1096 : }
1097 213 : e = gf_odf_write_descriptor_list(bs, od->extensionDescriptors);
1098 213 : if (e) return e;
1099 213 : return GF_OK;
1100 : }
1101 :
1102 :
1103 :
1104 7893 : GF_Descriptor *gf_odf_new_dcd()
1105 : {
1106 : GF_DecoderConfig *newDesc;
1107 7893 : GF_SAFEALLOC(newDesc, GF_DecoderConfig);
1108 7893 : if (!newDesc) return NULL;
1109 :
1110 7893 : newDesc->profileLevelIndicationIndexDescriptor = gf_list_new();
1111 7893 : newDesc->tag = GF_ODF_DCD_TAG;
1112 7893 : return (GF_Descriptor *) newDesc;
1113 : }
1114 :
1115 7893 : GF_Err gf_odf_del_dcd(GF_DecoderConfig *dcd)
1116 : {
1117 : GF_Err e;
1118 7893 : if (!dcd) return GF_BAD_PARAM;
1119 7893 : if (dcd->decoderSpecificInfo) {
1120 7594 : e = gf_odf_delete_descriptor((GF_Descriptor *) dcd->decoderSpecificInfo);
1121 7594 : if (e) return e;
1122 : }
1123 7893 : if (dcd->rvc_config) {
1124 0 : e = gf_odf_delete_descriptor((GF_Descriptor *) dcd->rvc_config);
1125 0 : if (e) return e;
1126 : }
1127 7893 : e = gf_odf_delete_descriptor_list(dcd->profileLevelIndicationIndexDescriptor);
1128 7893 : if (e) return e;
1129 7893 : gf_free(dcd);
1130 7893 : return GF_OK;
1131 : }
1132 :
1133 3752 : GF_Err gf_odf_read_dcd(GF_BitStream *bs, GF_DecoderConfig *dcd, u32 DescSize)
1134 : {
1135 : GF_Err e;
1136 : u32 /*reserved, */tmp_size, nbBytes = 0;
1137 3752 : if (! dcd) return GF_BAD_PARAM;
1138 :
1139 3752 : dcd->objectTypeIndication = gf_bs_read_int(bs, 8);
1140 3752 : dcd->streamType = gf_bs_read_int(bs, 6);
1141 3752 : dcd->upstream = gf_bs_read_int(bs, 1);
1142 3752 : /*reserved = */gf_bs_read_int(bs, 1);
1143 3752 : dcd->bufferSizeDB = gf_bs_read_int(bs, 24);
1144 3752 : dcd->maxBitrate = gf_bs_read_int(bs, 32);
1145 3752 : dcd->avgBitrate = gf_bs_read_int(bs, 32);
1146 : nbBytes += 13;
1147 :
1148 11108 : while (nbBytes < DescSize) {
1149 3604 : GF_Descriptor *tmp = NULL;
1150 3604 : e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size);
1151 3604 : if (e) return e;
1152 3604 : if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
1153 3604 : switch (tmp->tag) {
1154 3604 : case GF_ODF_DSI_TAG:
1155 3604 : if (dcd->decoderSpecificInfo) {
1156 0 : gf_odf_delete_descriptor(tmp);
1157 0 : return GF_ODF_INVALID_DESCRIPTOR;
1158 : }
1159 3604 : dcd->decoderSpecificInfo = (GF_DefaultDescriptor *) tmp;
1160 3604 : break;
1161 :
1162 0 : case GF_ODF_EXT_PL_TAG:
1163 0 : e = gf_list_add(dcd->profileLevelIndicationIndexDescriptor, tmp);
1164 0 : if (e < GF_OK) {
1165 0 : gf_odf_delete_descriptor(tmp);
1166 0 : return e;
1167 : }
1168 : break;
1169 :
1170 : /*iPod fix: delete and aborts, this will create an InvalidDescriptor at the ESD level with a loaded DSI,
1171 : loading will abort with a partially valid ESD which is all the matters*/
1172 0 : case GF_ODF_SLC_TAG:
1173 0 : gf_odf_delete_descriptor(tmp);
1174 0 : return GF_OK;
1175 :
1176 : //what the hell is this descriptor ?? Don't know, so delete it !
1177 0 : default:
1178 0 : gf_odf_delete_descriptor(tmp);
1179 0 : break;
1180 : }
1181 3604 : nbBytes += tmp_size + gf_odf_size_field_size(tmp_size);
1182 : }
1183 3752 : if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
1184 3752 : return GF_OK;
1185 : }
1186 :
1187 : #include <gpac/constants.h>
1188 :
1189 9753 : GF_Err gf_odf_size_dcd(GF_DecoderConfig *dcd, u32 *outSize)
1190 : {
1191 : GF_Err e;
1192 : u32 tmpSize;
1193 : u32 oti;
1194 9753 : if (! dcd) return GF_BAD_PARAM;
1195 :
1196 9753 : oti = dcd->objectTypeIndication;
1197 9753 : if (oti > 0xFF) {
1198 0 : oti = gf_codecid_oti(oti);
1199 : }
1200 9753 : if (oti > 0xFF) {
1201 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[ODF] Attempt to write an internal ESD with codec ID %s (%s) , not mappable to 8 bits MPEG-4 Systems OTI", gf_4cc_to_str(dcd->objectTypeIndication), gf_codecid_name(dcd->objectTypeIndication) ));
1202 : return GF_BAD_PARAM;
1203 : }
1204 :
1205 : *outSize = 0;
1206 9753 : *outSize += 13;
1207 9753 : if (dcd->decoderSpecificInfo) {
1208 : //warning: we don't know anything about the structure of a generic DecSpecInfo
1209 : //we check the tag and size of the descriptor, but we most ofthe time can't parse it
1210 : //the decSpecInfo is handle as a defaultDescriptor (opaque data, but same structure....)
1211 9401 : e = gf_odf_size_descriptor((GF_Descriptor *) dcd->decoderSpecificInfo , &tmpSize);
1212 9401 : if (e) return e;
1213 9401 : *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
1214 : }
1215 9753 : e = gf_odf_size_descriptor_list(dcd->profileLevelIndicationIndexDescriptor, outSize);
1216 9753 : if (e) return e;
1217 9753 : return GF_OK;
1218 : }
1219 :
1220 3637 : GF_Err gf_odf_write_dcd(GF_BitStream *bs, GF_DecoderConfig *dcd)
1221 : {
1222 : GF_Err e;
1223 : u32 size, oti;
1224 3637 : if (! dcd) return GF_BAD_PARAM;
1225 :
1226 3637 : oti = dcd->objectTypeIndication;
1227 3637 : if (oti > 0xFF) {
1228 0 : oti = gf_codecid_oti(oti);
1229 : }
1230 3637 : if (oti > 0xFF) {
1231 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[ODF] Attempt to write an internal ESD with codec ID %s (%s) , not mappable to 8 bits MPEG-4 Systems OTI", gf_4cc_to_str(dcd->objectTypeIndication), gf_codecid_name(dcd->objectTypeIndication) ));
1232 : return GF_BAD_PARAM;
1233 : }
1234 :
1235 3637 : e = gf_odf_size_descriptor((GF_Descriptor *)dcd, &size);
1236 3637 : if (e) return e;
1237 3637 : e = gf_odf_write_base_descriptor(bs, dcd->tag, size);
1238 3637 : if (e) return e;
1239 :
1240 3637 : gf_bs_write_int(bs, oti, 8);
1241 3637 : gf_bs_write_int(bs, dcd->streamType, 6);
1242 3637 : gf_bs_write_int(bs, dcd->upstream, 1);
1243 3637 : gf_bs_write_int(bs, 1, 1); //reserved field...
1244 3637 : gf_bs_write_int(bs, dcd->bufferSizeDB, 24);
1245 3637 : gf_bs_write_int(bs, dcd->maxBitrate, 32);
1246 3637 : gf_bs_write_int(bs, dcd->avgBitrate, 32);
1247 :
1248 3637 : if (dcd->decoderSpecificInfo) {
1249 3499 : e = gf_odf_write_descriptor(bs, (GF_Descriptor *) dcd->decoderSpecificInfo);
1250 3499 : if (e) return e;
1251 : }
1252 3637 : e = gf_odf_write_descriptor_list(bs, dcd->profileLevelIndicationIndexDescriptor);
1253 3637 : return e;
1254 : }
1255 :
1256 :
1257 7264 : GF_Descriptor *gf_odf_new_default()
1258 : {
1259 7264 : GF_DefaultDescriptor *newDesc = (GF_DefaultDescriptor *) gf_malloc(sizeof(GF_DefaultDescriptor));
1260 7264 : if (!newDesc) return NULL;
1261 :
1262 7264 : newDesc->dataLength = 0;
1263 7264 : newDesc->data = NULL;
1264 : //set it to the Max allowed
1265 7264 : newDesc->tag = GF_ODF_USER_END_TAG;
1266 7264 : return (GF_Descriptor *) newDesc;
1267 : }
1268 :
1269 7264 : GF_Err gf_odf_del_default(GF_DefaultDescriptor *dd)
1270 : {
1271 7264 : if (!dd) return GF_BAD_PARAM;
1272 :
1273 7264 : if (dd->data) gf_free(dd->data);
1274 7264 : gf_free(dd);
1275 7264 : return GF_OK;
1276 : }
1277 :
1278 3604 : GF_Err gf_odf_read_default(GF_BitStream *bs, GF_DefaultDescriptor *dd, u32 DescSize)
1279 : {
1280 : u32 nbBytes = 0;
1281 3604 : if (! dd) return GF_BAD_PARAM;
1282 :
1283 3604 : dd->dataLength = DescSize;
1284 3604 : dd->data = NULL;
1285 3604 : if (DescSize) {
1286 3213 : dd->data = (char*)gf_malloc(dd->dataLength);
1287 3213 : if (! dd->data) return GF_OUT_OF_MEM;
1288 3213 : gf_bs_read_data(bs, dd->data, dd->dataLength);
1289 3213 : nbBytes += dd->dataLength;
1290 : /* internal tags are read as default but deleted as their own types
1291 : so dd->data would leak here */
1292 3213 : if ((dd->tag>=GF_ODF_MUXINFO_TAG) && (dd->tag<=GF_ODF_LASER_CFG_TAG)) {
1293 0 : gf_free(dd->data);
1294 0 : dd->data = NULL;
1295 : }
1296 : }
1297 3604 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1298 3604 : return GF_OK;
1299 : }
1300 :
1301 12900 : GF_Err gf_odf_size_default(GF_DefaultDescriptor *dd, u32 *outSize)
1302 : {
1303 12900 : if (! dd) return GF_BAD_PARAM;
1304 12900 : *outSize = dd->dataLength;
1305 12900 : return GF_OK;
1306 : }
1307 :
1308 3499 : GF_Err gf_odf_write_default(GF_BitStream *bs, GF_DefaultDescriptor *dd)
1309 : {
1310 : GF_Err e;
1311 : u32 size;
1312 3499 : if (! dd) return GF_BAD_PARAM;
1313 :
1314 3499 : e = gf_odf_size_descriptor((GF_Descriptor *)dd, &size);
1315 3499 : if (e) return e;
1316 3499 : e = gf_odf_write_base_descriptor(bs, dd->tag, size);
1317 3499 : if (e) return e;
1318 :
1319 3499 : if (dd->data) {
1320 3101 : gf_bs_write_data(bs, dd->data, dd->dataLength);
1321 : }
1322 : return GF_OK;
1323 : }
1324 :
1325 391 : GF_Descriptor *gf_odf_new_esd_inc()
1326 : {
1327 391 : GF_ES_ID_Inc *newDesc = (GF_ES_ID_Inc *) gf_malloc(sizeof(GF_ES_ID_Inc));
1328 391 : if (!newDesc) return NULL;
1329 391 : newDesc->tag = GF_ODF_ESD_INC_TAG;
1330 391 : newDesc->trackID = 0;
1331 391 : return (GF_Descriptor *) newDesc;
1332 : }
1333 :
1334 391 : GF_Err gf_odf_del_esd_inc(GF_ES_ID_Inc *esd_inc)
1335 : {
1336 391 : if (!esd_inc) return GF_BAD_PARAM;
1337 391 : gf_free(esd_inc);
1338 391 : return GF_OK;
1339 : }
1340 297 : GF_Err gf_odf_read_esd_inc(GF_BitStream *bs, GF_ES_ID_Inc *esd_inc, u32 DescSize)
1341 : {
1342 : u32 nbBytes = 0;
1343 297 : if (! esd_inc) return GF_BAD_PARAM;
1344 :
1345 297 : esd_inc->trackID = gf_bs_read_int(bs, 32);
1346 : nbBytes += 4;
1347 297 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1348 297 : return GF_OK;
1349 : }
1350 775 : GF_Err gf_odf_size_esd_inc(GF_ES_ID_Inc *esd_inc, u32 *outSize)
1351 : {
1352 775 : if (! esd_inc) return GF_BAD_PARAM;
1353 775 : *outSize = 4;
1354 775 : return GF_OK;
1355 : }
1356 284 : GF_Err gf_odf_write_esd_inc(GF_BitStream *bs, GF_ES_ID_Inc *esd_inc)
1357 : {
1358 : GF_Err e;
1359 : u32 size;
1360 284 : if (! esd_inc) return GF_BAD_PARAM;
1361 :
1362 284 : e = gf_odf_size_descriptor((GF_Descriptor *)esd_inc, &size);
1363 284 : if (e) return e;
1364 284 : e = gf_odf_write_base_descriptor(bs, esd_inc->tag, size);
1365 284 : if (e) return e;
1366 284 : gf_bs_write_int(bs, esd_inc->trackID, 32);
1367 284 : return GF_OK;
1368 : }
1369 :
1370 314 : GF_Descriptor *gf_odf_new_esd_ref()
1371 : {
1372 314 : GF_ES_ID_Ref *newDesc = (GF_ES_ID_Ref *) gf_malloc(sizeof(GF_ES_ID_Ref));
1373 314 : if (!newDesc) return NULL;
1374 314 : newDesc->tag = GF_ODF_ESD_REF_TAG;
1375 314 : newDesc->trackRef = 0;
1376 314 : return (GF_Descriptor *) newDesc;
1377 : }
1378 :
1379 314 : GF_Err gf_odf_del_esd_ref(GF_ES_ID_Ref *esd_ref)
1380 : {
1381 314 : if (!esd_ref) return GF_BAD_PARAM;
1382 314 : gf_free(esd_ref);
1383 314 : return GF_OK;
1384 : }
1385 199 : GF_Err gf_odf_read_esd_ref(GF_BitStream *bs, GF_ES_ID_Ref *esd_ref, u32 DescSize)
1386 : {
1387 : u32 nbBytes = 0;
1388 199 : if (! esd_ref) return GF_BAD_PARAM;
1389 :
1390 199 : esd_ref->trackRef = gf_bs_read_int(bs, 16);
1391 : nbBytes += 2;
1392 199 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1393 199 : return GF_OK;
1394 : }
1395 :
1396 534 : GF_Err gf_odf_size_esd_ref(GF_ES_ID_Ref *esd_ref, u32 *outSize)
1397 : {
1398 534 : if (! esd_ref) return GF_BAD_PARAM;
1399 534 : *outSize = 2;
1400 534 : return GF_OK;
1401 : }
1402 211 : GF_Err gf_odf_write_esd_ref(GF_BitStream *bs, GF_ES_ID_Ref *esd_ref)
1403 : {
1404 : GF_Err e;
1405 : u32 size;
1406 211 : if (! esd_ref) return GF_BAD_PARAM;
1407 :
1408 211 : e = gf_odf_size_descriptor((GF_Descriptor *)esd_ref, &size);
1409 211 : if (e) return e;
1410 211 : e = gf_odf_write_base_descriptor(bs, esd_ref->tag, size);
1411 211 : if (e) return e;
1412 :
1413 211 : gf_bs_write_int(bs, esd_ref->trackRef, 16);
1414 211 : return GF_OK;
1415 : }
1416 :
1417 :
1418 :
1419 33 : GF_Descriptor *gf_odf_new_segment()
1420 : {
1421 33 : GF_Segment *newDesc = (GF_Segment *) gf_malloc(sizeof(GF_Segment));
1422 33 : if (!newDesc) return NULL;
1423 :
1424 : memset(newDesc, 0, sizeof(GF_Segment));
1425 33 : newDesc->tag = GF_ODF_SEGMENT_TAG;
1426 33 : return (GF_Descriptor *) newDesc;
1427 : }
1428 :
1429 33 : GF_Err gf_odf_del_segment(GF_Segment *sd)
1430 : {
1431 33 : if (!sd) return GF_BAD_PARAM;
1432 :
1433 33 : if (sd->SegmentName) gf_free(sd->SegmentName);
1434 33 : gf_free(sd);
1435 33 : return GF_OK;
1436 : }
1437 :
1438 18 : GF_Err gf_odf_read_segment(GF_BitStream *bs, GF_Segment *sd, u32 DescSize)
1439 : {
1440 : u32 size, nbBytes = 0;
1441 18 : if (!sd) return GF_BAD_PARAM;
1442 :
1443 18 : sd->startTime = gf_bs_read_double(bs);
1444 18 : sd->Duration = gf_bs_read_double(bs);
1445 : nbBytes += 16;
1446 18 : size = gf_bs_read_int(bs, 8);
1447 : nbBytes += 1;
1448 18 : if (size) {
1449 18 : sd->SegmentName = (char*) gf_malloc(sizeof(char)*(size+1));
1450 18 : if (!sd->SegmentName) return GF_OUT_OF_MEM;
1451 18 : gf_bs_read_data(bs, sd->SegmentName, size);
1452 18 : sd->SegmentName[size] = 0;
1453 18 : nbBytes += size;
1454 : }
1455 18 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1456 18 : return GF_OK;
1457 : }
1458 :
1459 48 : GF_Err gf_odf_size_segment(GF_Segment *sd, u32 *outSize)
1460 : {
1461 48 : if (!sd) return GF_BAD_PARAM;
1462 48 : *outSize = 17;
1463 48 : if (sd->SegmentName) *outSize += (u32) strlen(sd->SegmentName);
1464 : return GF_OK;
1465 : }
1466 :
1467 18 : GF_Err gf_odf_write_segment(GF_BitStream *bs, GF_Segment *sd)
1468 : {
1469 : GF_Err e;
1470 : u32 size;
1471 18 : if (!sd) return GF_BAD_PARAM;
1472 18 : e = gf_odf_size_descriptor((GF_Descriptor *)sd, &size);
1473 18 : if (e) return e;
1474 18 : e = gf_odf_write_base_descriptor(bs, sd->tag, size);
1475 18 : if (e) return e;
1476 18 : gf_bs_write_double(bs, sd->startTime);
1477 18 : gf_bs_write_double(bs, sd->Duration);
1478 18 : if (sd->SegmentName) {
1479 18 : gf_bs_write_int(bs, (u32) strlen(sd->SegmentName), 8);
1480 18 : gf_bs_write_data(bs, sd->SegmentName, (u32) strlen(sd->SegmentName));
1481 : } else {
1482 0 : gf_bs_write_int(bs, 0, 8);
1483 : }
1484 : return GF_OK;
1485 : }
1486 :
1487 :
1488 :
1489 329 : GF_Descriptor *gf_odf_new_lang()
1490 : {
1491 : GF_Language *newDesc;
1492 329 : GF_SAFEALLOC(newDesc, GF_Language);
1493 329 : if (!newDesc) return NULL;
1494 329 : newDesc->tag = GF_ODF_LANG_TAG;
1495 329 : return (GF_Descriptor *) newDesc;
1496 : }
1497 :
1498 329 : GF_Err gf_odf_del_lang(GF_Language *ld)
1499 : {
1500 329 : if (!ld) return GF_BAD_PARAM;
1501 329 : if (ld->full_lang_code) gf_free(ld->full_lang_code);
1502 329 : gf_free(ld);
1503 329 : return GF_OK;
1504 : }
1505 :
1506 19 : GF_Err gf_odf_read_lang(GF_BitStream *bs, GF_Language *ld, u32 DescSize)
1507 : {
1508 : u32 nbBytes = 0;
1509 19 : if (!ld) return GF_BAD_PARAM;
1510 :
1511 19 : ld->langCode = gf_bs_read_int(bs, 24);
1512 : nbBytes += 3;
1513 19 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1514 19 : return GF_OK;
1515 : }
1516 :
1517 33 : GF_Err gf_odf_size_lang(GF_Language *ld, u32 *outSize)
1518 : {
1519 33 : if (!ld) return GF_BAD_PARAM;
1520 33 : *outSize = 3;
1521 33 : return GF_OK;
1522 : }
1523 :
1524 15 : GF_Err gf_odf_write_lang(GF_BitStream *bs, GF_Language *ld)
1525 : {
1526 : GF_Err e;
1527 : u32 size;
1528 15 : if (!ld) return GF_BAD_PARAM;
1529 :
1530 15 : e = gf_odf_size_descriptor((GF_Descriptor *)ld, &size);
1531 15 : if (e) return e;
1532 15 : e = gf_odf_write_base_descriptor(bs, ld->tag, size);
1533 15 : if (e) return e;
1534 15 : gf_bs_write_int(bs, ld->langCode, 24);
1535 15 : return GF_OK;
1536 : }
1537 :
1538 :
1539 :
1540 10 : GF_Descriptor *gf_odf_new_auxvid()
1541 : {
1542 : GF_AuxVideoDescriptor *newDesc;
1543 10 : GF_SAFEALLOC(newDesc, GF_AuxVideoDescriptor);
1544 10 : if (!newDesc) return NULL;
1545 10 : newDesc->tag = GF_ODF_AUX_VIDEO_DATA;
1546 10 : return (GF_Descriptor *) newDesc;
1547 : }
1548 :
1549 10 : GF_Err gf_odf_del_auxvid(GF_AuxVideoDescriptor *ld)
1550 : {
1551 10 : if (!ld) return GF_BAD_PARAM;
1552 10 : gf_free(ld);
1553 10 : return GF_OK;
1554 : }
1555 :
1556 2 : GF_Err gf_odf_read_auxvid(GF_BitStream *bs, GF_AuxVideoDescriptor *ld, u32 DescSize)
1557 : {
1558 : u32 nbBytes = 0;
1559 2 : if (!ld) return GF_BAD_PARAM;
1560 :
1561 2 : ld->aux_video_type = gf_bs_read_int(bs, 8);
1562 2 : ld->position_offset_h = gf_bs_read_int(bs, 8);
1563 2 : ld->position_offset_v = gf_bs_read_int(bs, 8);
1564 : nbBytes += 3;
1565 2 : switch (ld->aux_video_type) {
1566 0 : case 0x10:
1567 0 : ld->kfar = gf_bs_read_int(bs, 8);
1568 0 : ld->knear = gf_bs_read_int(bs, 8);
1569 : nbBytes += 2;
1570 0 : break;
1571 0 : case 0x11:
1572 0 : ld->parallax_zero = gf_bs_read_int(bs, 16);
1573 0 : ld->parallax_scale = gf_bs_read_int(bs, 16);
1574 0 : ld->dref = gf_bs_read_int(bs, 16);
1575 0 : ld->wref = gf_bs_read_int(bs, 16);
1576 : nbBytes += 8;
1577 0 : break;
1578 : }
1579 2 : while (nbBytes < DescSize) {
1580 0 : gf_bs_read_int(bs, 8);
1581 0 : nbBytes ++;
1582 : }
1583 : return GF_OK;
1584 : }
1585 :
1586 8 : GF_Err gf_odf_size_auxvid(GF_AuxVideoDescriptor *ld, u32 *outSize)
1587 : {
1588 8 : if (!ld) return GF_BAD_PARAM;
1589 8 : switch (ld->aux_video_type) {
1590 0 : case 0x10:
1591 0 : *outSize = 5;
1592 0 : break;
1593 0 : case 0x11:
1594 0 : *outSize = 11;
1595 0 : break;
1596 8 : default:
1597 8 : *outSize = 3;
1598 8 : break;
1599 : }
1600 : return GF_OK;
1601 : }
1602 :
1603 2 : GF_Err gf_odf_write_auxvid(GF_BitStream *bs, GF_AuxVideoDescriptor *ld)
1604 : {
1605 : GF_Err e;
1606 : u32 size;
1607 2 : if (!ld) return GF_BAD_PARAM;
1608 2 : e = gf_odf_size_descriptor((GF_Descriptor *)ld, &size);
1609 2 : if (e) return e;
1610 2 : e = gf_odf_write_base_descriptor(bs, ld->tag, size);
1611 2 : if (e) return e;
1612 :
1613 2 : gf_bs_write_int(bs, ld->aux_video_type, 8);
1614 2 : gf_bs_write_int(bs, ld->position_offset_h, 8);
1615 2 : gf_bs_write_int(bs, ld->position_offset_v, 8);
1616 2 : switch (ld->aux_video_type) {
1617 0 : case 0x10:
1618 0 : gf_bs_write_int(bs, ld->kfar, 8);
1619 0 : gf_bs_write_int(bs, ld->knear, 8);
1620 0 : break;
1621 0 : case 0x11:
1622 0 : gf_bs_write_int(bs, ld->parallax_zero, 16);
1623 0 : gf_bs_write_int(bs, ld->parallax_scale, 16);
1624 0 : gf_bs_write_int(bs, ld->dref, 16);
1625 0 : gf_bs_write_int(bs, ld->wref, 16);
1626 0 : break;
1627 : }
1628 : return GF_OK;
1629 : }
1630 :
1631 :
1632 :
1633 245 : GF_Descriptor *gf_odf_new_muxinfo()
1634 : {
1635 245 : GF_MuxInfo *newDesc = (GF_MuxInfo *) gf_malloc(sizeof(GF_MuxInfo));
1636 245 : if (!newDesc) return NULL;
1637 : memset(newDesc, 0, sizeof(GF_MuxInfo));
1638 245 : newDesc->tag = GF_ODF_MUXINFO_TAG;
1639 245 : return (GF_Descriptor *) newDesc;
1640 : }
1641 :
1642 245 : GF_Err gf_odf_del_muxinfo(GF_MuxInfo *mi)
1643 : {
1644 245 : if (!mi) return GF_BAD_PARAM;
1645 245 : if (mi->file_name) gf_free(mi->file_name);
1646 245 : if (mi->src_url) gf_free(mi->src_url);
1647 245 : if (mi->streamFormat) gf_free(mi->streamFormat);
1648 245 : if (mi->textNode) gf_free(mi->textNode);
1649 245 : if (mi->fontNode) gf_free(mi->fontNode);
1650 245 : gf_free(mi);
1651 245 : return GF_OK;
1652 : }
1653 :
1654 156 : GF_Err gf_odf_size_muxinfo(GF_MuxInfo *mi, u32 *outSize)
1655 : {
1656 156 : *outSize = 0;
1657 156 : return GF_OK;
1658 : }
1659 55 : GF_Err gf_odf_write_muxinfo(GF_BitStream *bs, GF_MuxInfo *mi)
1660 : {
1661 55 : return GF_OK;
1662 : }
1663 :
1664 1 : GF_Descriptor *gf_odf_New_ElemMask()
1665 : {
1666 1 : GF_ElementaryMask *newDesc = (GF_ElementaryMask*) gf_malloc (sizeof(GF_ElementaryMask));
1667 1 : if (!newDesc) return NULL;
1668 : memset(newDesc, 0, sizeof(GF_ElementaryMask));
1669 1 : newDesc->tag = GF_ODF_ELEM_MASK_TAG;
1670 1 : return (GF_Descriptor *) newDesc;
1671 : }
1672 :
1673 1 : GF_Err gf_odf_del_ElemMask(GF_ElementaryMask *desc)
1674 : {
1675 1 : if (desc->node_name) gf_free(desc->node_name);
1676 1 : gf_free(desc);
1677 1 : return GF_OK;
1678 : }
1679 :
1680 421 : GF_Descriptor *gf_odf_new_bifs_cfg()
1681 : {
1682 421 : GF_BIFSConfig *newDesc = (GF_BIFSConfig *) gf_malloc(sizeof(GF_BIFSConfig));
1683 421 : if (!newDesc) return NULL;
1684 : memset(newDesc, 0, sizeof(GF_BIFSConfig));
1685 421 : newDesc->tag = GF_ODF_BIFS_CFG_TAG;
1686 421 : return (GF_Descriptor *) newDesc;
1687 : }
1688 :
1689 421 : GF_Err gf_odf_del_bifs_cfg(GF_BIFSConfig *desc)
1690 : {
1691 421 : if (desc->elementaryMasks) {
1692 0 : u32 i, count = gf_list_count(desc->elementaryMasks);
1693 0 : for (i=0; i<count; i++) {
1694 0 : GF_ElementaryMask *tmp = (GF_ElementaryMask *)gf_list_get(desc->elementaryMasks, i);
1695 0 : if (tmp->node_name) gf_free(tmp->node_name);
1696 0 : gf_free(tmp);
1697 : }
1698 0 : gf_list_del(desc->elementaryMasks);
1699 : }
1700 421 : gf_free(desc);
1701 421 : return GF_OK;
1702 : }
1703 :
1704 2 : GF_Descriptor *gf_odf_new_laser_cfg()
1705 : {
1706 2 : GF_LASERConfig *newDesc = (GF_LASERConfig *) gf_malloc(sizeof(GF_LASERConfig));
1707 2 : if (!newDesc) return NULL;
1708 : memset(newDesc, 0, sizeof(GF_LASERConfig));
1709 2 : newDesc->tag = GF_ODF_LASER_CFG_TAG;
1710 2 : return (GF_Descriptor *) newDesc;
1711 : }
1712 :
1713 2 : GF_Err gf_odf_del_laser_cfg(GF_LASERConfig *desc)
1714 : {
1715 2 : gf_free(desc);
1716 2 : return GF_OK;
1717 : }
1718 :
1719 33 : GF_Descriptor *gf_odf_new_ui_cfg()
1720 : {
1721 33 : GF_UIConfig *newDesc = (GF_UIConfig *) gf_malloc(sizeof(GF_UIConfig));
1722 33 : if (!newDesc) return NULL;
1723 : memset(newDesc, 0, sizeof(GF_UIConfig));
1724 33 : newDesc->tag = GF_ODF_UI_CFG_TAG;
1725 33 : return (GF_Descriptor *) newDesc;
1726 : }
1727 :
1728 33 : GF_Err gf_odf_del_ui_cfg(GF_UIConfig *desc)
1729 : {
1730 33 : if (desc->deviceName) gf_free(desc->deviceName);
1731 33 : if (desc->ui_data) gf_free(desc->ui_data);
1732 33 : gf_free(desc);
1733 33 : return GF_OK;
1734 : }
1735 :
1736 : #ifndef GPAC_MINIMAL_ODF
1737 :
1738 : GF_Descriptor *gf_odf_new_mediatime()
1739 : {
1740 : GF_MediaTime *newDesc = (GF_MediaTime *) gf_malloc(sizeof(GF_MediaTime));
1741 : if (!newDesc) return NULL;
1742 :
1743 : memset(newDesc, 0, sizeof(GF_MediaTime));
1744 : newDesc->tag = GF_ODF_MEDIATIME_TAG;
1745 : return (GF_Descriptor *) newDesc;
1746 : }
1747 : GF_Err gf_odf_del_mediatime(GF_MediaTime *mt)
1748 : {
1749 : if (!mt) return GF_BAD_PARAM;
1750 : gf_free(mt);
1751 : return GF_OK;
1752 : }
1753 : GF_Err gf_odf_read_mediatime(GF_BitStream *bs, GF_MediaTime *mt, u32 DescSize)
1754 : {
1755 : if (!mt) return GF_BAD_PARAM;
1756 : mt->mediaTimeStamp = gf_bs_read_double(bs);
1757 : return GF_OK;
1758 : }
1759 : GF_Err gf_odf_size_mediatime(GF_MediaTime *mt, u32 *outSize)
1760 : {
1761 : if (!mt) return GF_BAD_PARAM;
1762 : *outSize = 8;
1763 : return GF_OK;
1764 : }
1765 : GF_Err gf_odf_write_mediatime(GF_BitStream *bs, GF_MediaTime *mt)
1766 : {
1767 : GF_Err e;
1768 : u32 size;
1769 : if (!mt) return GF_BAD_PARAM;
1770 : e = gf_odf_size_descriptor((GF_Descriptor *)mt, &size);
1771 : if (e) return e;
1772 : e = gf_odf_write_base_descriptor(bs, mt->tag, size);
1773 : if (e) return e;
1774 : gf_bs_write_double(bs, mt->mediaTimeStamp);
1775 : return GF_OK;
1776 : }
1777 :
1778 : GF_Descriptor *gf_odf_new_cc()
1779 : {
1780 : GF_CCDescriptor *newDesc = (GF_CCDescriptor *) gf_malloc(sizeof(GF_CCDescriptor));
1781 : if (!newDesc) return NULL;
1782 :
1783 : newDesc->contentClassificationData = NULL;
1784 : newDesc->dataLength = 0;
1785 : newDesc->classificationEntity = 0;
1786 : newDesc->classificationTable = 0;
1787 : newDesc->tag = GF_ODF_CC_TAG;
1788 : return (GF_Descriptor *) newDesc;
1789 : }
1790 :
1791 : GF_Err gf_odf_del_cc(GF_CCDescriptor *ccd)
1792 : {
1793 : if (!ccd) return GF_BAD_PARAM;
1794 : if (ccd->contentClassificationData) gf_free(ccd->contentClassificationData);
1795 : gf_free(ccd);
1796 : return GF_OK;
1797 : }
1798 :
1799 : GF_Err gf_odf_read_cc(GF_BitStream *bs, GF_CCDescriptor *ccd, u32 DescSize)
1800 : {
1801 : u32 nbBytes = 0;
1802 : if (!ccd) return GF_BAD_PARAM;
1803 :
1804 : ccd->classificationEntity = gf_bs_read_int(bs, 32);
1805 : ccd->classificationTable = gf_bs_read_int(bs, 16);
1806 : nbBytes += 6;
1807 : if (DescSize < 6) return GF_ODF_INVALID_DESCRIPTOR;
1808 :
1809 : ccd->dataLength = DescSize - 6;
1810 : ccd->contentClassificationData = (char*)gf_malloc(sizeof(char) * ccd->dataLength);
1811 : if (!ccd->contentClassificationData) return GF_OUT_OF_MEM;
1812 : gf_bs_read_data(bs, ccd->contentClassificationData, ccd->dataLength);
1813 : nbBytes += ccd->dataLength;
1814 :
1815 : if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
1816 : return GF_OK;
1817 : }
1818 :
1819 : GF_Err gf_odf_size_cc(GF_CCDescriptor *ccd, u32 *outSize)
1820 : {
1821 : if (!ccd) return GF_BAD_PARAM;
1822 : *outSize = 6 + ccd->dataLength;
1823 : return GF_OK;
1824 : }
1825 :
1826 : GF_Err gf_odf_write_cc(GF_BitStream *bs, GF_CCDescriptor *ccd)
1827 : {
1828 : u32 size;
1829 : GF_Err e;
1830 : if (!ccd) return GF_BAD_PARAM;
1831 :
1832 : e = gf_odf_size_descriptor((GF_Descriptor *)ccd, &size);
1833 : if (e) return e;
1834 : e = gf_odf_write_base_descriptor(bs, ccd->tag, size);
1835 : if (e) return e;
1836 : gf_bs_write_int(bs, ccd->classificationEntity, 32);
1837 : gf_bs_write_int(bs, ccd->classificationTable, 16);
1838 : gf_bs_write_data(bs, ccd->contentClassificationData, ccd->dataLength);
1839 : return GF_OK;
1840 : }
1841 :
1842 : GF_Descriptor *gf_odf_new_cc_date()
1843 : {
1844 : GF_CC_Date *newDesc = (GF_CC_Date *) gf_malloc(sizeof(GF_CC_Date));
1845 : if (!newDesc) return NULL;
1846 : memset(newDesc->contentCreationDate, 0, 5);
1847 : newDesc->tag = GF_ODF_CC_DATE_TAG;
1848 : return (GF_Descriptor *) newDesc;
1849 : }
1850 :
1851 :
1852 : GF_Err gf_odf_del_cc_date(GF_CC_Date *cdd)
1853 : {
1854 : if (!cdd) return GF_BAD_PARAM;
1855 : gf_free(cdd);
1856 : return GF_OK;
1857 : }
1858 :
1859 : GF_Err gf_odf_read_cc_date(GF_BitStream *bs, GF_CC_Date *cdd, u32 DescSize)
1860 : {
1861 : u32 nbBytes = 0;
1862 : if (!cdd) return GF_BAD_PARAM;
1863 :
1864 : gf_bs_read_data(bs, cdd->contentCreationDate, DATE_CODING_LEN);
1865 : nbBytes += DATE_CODING_LEN;
1866 : if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
1867 : return GF_OK;
1868 : }
1869 :
1870 : GF_Err gf_odf_size_cc_date(GF_CC_Date *cdd, u32 *outSize)
1871 : {
1872 : if (!cdd) return GF_BAD_PARAM;
1873 : *outSize = DATE_CODING_LEN;
1874 : return GF_OK;
1875 : }
1876 :
1877 : GF_Err gf_odf_write_cc_date(GF_BitStream *bs, GF_CC_Date *cdd)
1878 : {
1879 : u32 size;
1880 : GF_Err e;
1881 : if (!cdd) return GF_BAD_PARAM;
1882 :
1883 : e = gf_odf_size_descriptor((GF_Descriptor *)cdd, &size);
1884 : if (e) return e;
1885 : e = gf_odf_write_base_descriptor(bs, cdd->tag, size);
1886 : if (e) return e;
1887 :
1888 : gf_bs_write_data(bs, cdd->contentCreationDate, DATE_CODING_LEN);
1889 : return GF_OK;
1890 : }
1891 :
1892 : GF_Descriptor *gf_odf_new_cc_name()
1893 : {
1894 : GF_CC_Name *newDesc = (GF_CC_Name *) gf_malloc(sizeof(GF_CC_Name));
1895 : if (!newDesc) return NULL;
1896 :
1897 : newDesc->ContentCreators = gf_list_new();
1898 : if (! newDesc->ContentCreators) {
1899 : gf_free(newDesc);
1900 : return NULL;
1901 : }
1902 : newDesc->tag = GF_ODF_CC_NAME_TAG;
1903 : return (GF_Descriptor *) newDesc;
1904 : }
1905 :
1906 : GF_Err gf_odf_del_cc_name(GF_CC_Name *cnd)
1907 : {
1908 : u32 i;
1909 : GF_ContentCreatorInfo *tmp;
1910 : if (!cnd) return GF_BAD_PARAM;
1911 :
1912 : i=0;
1913 : while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) {
1914 : if (tmp->contentCreatorName) gf_free(tmp->contentCreatorName);
1915 : gf_free(tmp);
1916 : }
1917 : gf_list_del(cnd->ContentCreators);
1918 : gf_free(cnd);
1919 : return GF_OK;
1920 : }
1921 :
1922 : GF_Err gf_odf_read_cc_name(GF_BitStream *bs, GF_CC_Name *cnd, u32 DescSize)
1923 : {
1924 : GF_Err e;
1925 : u32 i, count, len, nbBytes = 0;
1926 : if (!cnd) return GF_BAD_PARAM;
1927 :
1928 : count = gf_bs_read_int(bs, 8);
1929 : nbBytes += 1;
1930 : for (i = 0; i< count; i++) {
1931 : GF_ContentCreatorInfo *tmp = (GF_ContentCreatorInfo*)gf_malloc(sizeof(GF_ContentCreatorInfo));
1932 : if (! tmp) return GF_OUT_OF_MEM;
1933 : memset(tmp , 0, sizeof(GF_ContentCreatorInfo));
1934 : tmp->langCode = gf_bs_read_int(bs, 24);
1935 : tmp->isUTF8 = gf_bs_read_int(bs, 1);
1936 : /*aligned = */gf_bs_read_int(bs, 7);
1937 : nbBytes += 4;
1938 :
1939 : e = OD_ReadUTF8String(bs, & tmp->contentCreatorName, tmp->isUTF8, &len);
1940 : if (e) {
1941 : gf_free(tmp);
1942 : return e;
1943 : }
1944 : nbBytes += len;
1945 : e = gf_list_add(cnd->ContentCreators, tmp);
1946 : if (e) return e;
1947 : }
1948 : if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
1949 : return GF_OK;
1950 : }
1951 :
1952 : GF_Err gf_odf_size_cc_name(GF_CC_Name *cnd, u32 *outSize)
1953 : {
1954 : u32 i;
1955 : GF_ContentCreatorInfo *tmp;
1956 : if (!cnd) return GF_BAD_PARAM;
1957 :
1958 : *outSize = 1;
1959 : i=0;
1960 : while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) {
1961 : *outSize += 4 + OD_SizeUTF8String(tmp->contentCreatorName, tmp->isUTF8);
1962 : }
1963 : return GF_OK;
1964 : }
1965 :
1966 : GF_Err gf_odf_write_cc_name(GF_BitStream *bs, GF_CC_Name *cnd)
1967 : {
1968 : GF_Err e;
1969 : GF_ContentCreatorInfo *tmp;
1970 : u32 i, size;
1971 : if (!cnd) return GF_BAD_PARAM;
1972 :
1973 : e = gf_odf_size_descriptor((GF_Descriptor *)cnd, &size);
1974 : if (e) return e;
1975 : e = gf_odf_write_base_descriptor(bs, cnd->tag, size);
1976 : if (e) return e;
1977 : gf_bs_write_int(bs, gf_list_count(cnd->ContentCreators), 8);
1978 :
1979 : i=0;
1980 : while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) {
1981 : gf_bs_write_int(bs, tmp->langCode, 24);
1982 : gf_bs_write_int(bs, tmp->isUTF8, 1);
1983 : gf_bs_write_int(bs, 0, 7); //aligned
1984 : OD_WriteUTF8String(bs, tmp->contentCreatorName, tmp->isUTF8);
1985 : }
1986 : return GF_OK;
1987 : }
1988 :
1989 :
1990 : GF_Descriptor *gf_odf_new_ci()
1991 : {
1992 : GF_CIDesc *newDesc = (GF_CIDesc *) gf_malloc(sizeof(GF_CIDesc));
1993 : if (!newDesc) return NULL;
1994 :
1995 : newDesc->compatibility = 0;
1996 : newDesc->contentIdentifier = NULL;
1997 : newDesc->tag = GF_ODF_CI_TAG;
1998 : newDesc->contentIdentifierFlag = 0;
1999 : newDesc->contentIdentifierType = 0;
2000 : newDesc->contentType = 0;
2001 : newDesc->contentTypeFlag = 0;
2002 : newDesc->protectedContent = 0;
2003 : return (GF_Descriptor *) newDesc;
2004 : }
2005 :
2006 :
2007 : GF_Err gf_odf_del_ci(GF_CIDesc *cid)
2008 : {
2009 : if (!cid) return GF_BAD_PARAM;
2010 :
2011 : if (cid->contentIdentifier) gf_free(cid->contentIdentifier);
2012 : gf_free(cid);
2013 : return GF_OK;
2014 : }
2015 :
2016 :
2017 : GF_Err gf_odf_read_ci(GF_BitStream *bs, GF_CIDesc *cid, u32 DescSize)
2018 : {
2019 : u32 nbBytes = 0;
2020 : if (! cid) return GF_BAD_PARAM;
2021 :
2022 : cid->compatibility = gf_bs_read_int(bs, 2); //MUST BE NULL
2023 : if (cid->compatibility) return GF_ODF_INVALID_DESCRIPTOR;
2024 :
2025 : cid->contentTypeFlag = gf_bs_read_int(bs, 1);
2026 : cid->contentIdentifierFlag = gf_bs_read_int(bs, 1);
2027 : cid->protectedContent = gf_bs_read_int(bs, 1);
2028 : /*reserved = */gf_bs_read_int(bs, 3);
2029 : nbBytes += 1;
2030 :
2031 : if (cid->contentTypeFlag) {
2032 : cid->contentType = gf_bs_read_int(bs, 8);
2033 : nbBytes += 1;
2034 : }
2035 : if (cid->contentIdentifierFlag) {
2036 : cid->contentIdentifierType = gf_bs_read_int(bs, 8);
2037 : if (DescSize < (u32) 2 + cid->contentTypeFlag) return GF_ODF_INVALID_DESCRIPTOR;
2038 : cid->contentIdentifier = (char*)gf_malloc(DescSize - 2 - cid->contentTypeFlag);
2039 : if (! cid->contentIdentifier) return GF_OUT_OF_MEM;
2040 :
2041 : gf_bs_read_data(bs, cid->contentIdentifier, DescSize - 2 - cid->contentTypeFlag);
2042 : nbBytes += DescSize - 1 - cid->contentTypeFlag;
2043 : }
2044 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2045 : return GF_OK;
2046 : }
2047 :
2048 : GF_Err gf_odf_size_ci(GF_CIDesc *cid, u32 *outSize)
2049 : {
2050 : if (! cid) return GF_BAD_PARAM;
2051 :
2052 : *outSize = 1;
2053 : if (cid->contentTypeFlag) *outSize += 1;
2054 :
2055 : if (cid->contentIdentifierFlag)
2056 : *outSize += (u32) strlen((const char*)cid->contentIdentifier) - 1 - cid->contentTypeFlag;
2057 : return GF_OK;
2058 : }
2059 :
2060 : GF_Err gf_odf_write_ci(GF_BitStream *bs, GF_CIDesc *cid)
2061 : {
2062 : GF_Err e;
2063 : u32 size;
2064 : if (! cid) return GF_BAD_PARAM;
2065 :
2066 : e = gf_odf_size_descriptor((GF_Descriptor *)cid, &size);
2067 : if (e) return e;
2068 : e = gf_odf_write_base_descriptor(bs, cid->tag, size);
2069 : if (e) return e;
2070 :
2071 : gf_bs_write_int(bs, cid->compatibility, 2);
2072 : gf_bs_write_int(bs, cid->contentTypeFlag, 1);
2073 : gf_bs_write_int(bs, cid->contentIdentifierFlag, 1);
2074 : gf_bs_write_int(bs, cid->protectedContent, 1);
2075 : gf_bs_write_int(bs, 7, 3); //reserved 0b111 = 7
2076 :
2077 : if (cid->contentTypeFlag) {
2078 : gf_bs_write_int(bs, cid->contentType, 8);
2079 : }
2080 :
2081 : if (cid->contentIdentifierFlag) {
2082 : gf_bs_write_int(bs, cid->contentIdentifierType, 8);
2083 : gf_bs_write_data(bs, cid->contentIdentifier, size - 2 - cid->contentTypeFlag);
2084 : }
2085 : return GF_OK;
2086 : }
2087 :
2088 : GF_Descriptor *gf_odf_new_exp_text()
2089 : {
2090 : GF_ExpandedTextual *newDesc = (GF_ExpandedTextual *) gf_malloc(sizeof(GF_ExpandedTextual));
2091 : if (!newDesc) return NULL;
2092 :
2093 : newDesc->itemDescriptionList = gf_list_new();
2094 : if (! newDesc->itemDescriptionList) {
2095 : gf_free(newDesc);
2096 : return NULL;
2097 : }
2098 : newDesc->itemTextList = gf_list_new();
2099 : if (! newDesc->itemTextList) {
2100 : gf_free(newDesc->itemDescriptionList);
2101 : gf_free(newDesc);
2102 : return NULL;
2103 : }
2104 : newDesc->isUTF8 = 0;
2105 : newDesc->langCode = 0;
2106 : newDesc->NonItemText = NULL;
2107 : newDesc->tag = GF_ODF_TEXT_TAG;
2108 : return (GF_Descriptor *) newDesc;
2109 : }
2110 :
2111 : GF_Err gf_odf_del_exp_text(GF_ExpandedTextual *etd)
2112 : {
2113 : if (!etd) return GF_BAD_PARAM;
2114 :
2115 : while (gf_list_count(etd->itemDescriptionList)) {
2116 : GF_ETD_ItemText *tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemDescriptionList, 0);
2117 : if (tmp) {
2118 : if (tmp->text) gf_free(tmp->text);
2119 : gf_free(tmp);
2120 : }
2121 : gf_list_rem(etd->itemDescriptionList, 0);
2122 : }
2123 : gf_list_del(etd->itemDescriptionList);
2124 :
2125 : while (gf_list_count(etd->itemTextList)) {
2126 : GF_ETD_ItemText *tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemTextList, 0);
2127 : if (tmp) {
2128 : if (tmp->text) gf_free(tmp->text);
2129 : gf_free(tmp);
2130 : }
2131 : gf_list_rem(etd->itemTextList, 0);
2132 : }
2133 : gf_list_del(etd->itemTextList);
2134 :
2135 : if (etd->NonItemText) gf_free(etd->NonItemText);
2136 : gf_free(etd);
2137 : return GF_OK;
2138 : }
2139 :
2140 : GF_Err gf_odf_read_exp_text(GF_BitStream *bs, GF_ExpandedTextual *etd, u32 DescSize)
2141 : {
2142 : GF_Err e;
2143 : u32 nbBytes = 0;
2144 : u32 i, len, nonLen, count;
2145 : if (!etd) return GF_BAD_PARAM;
2146 :
2147 : etd->langCode = gf_bs_read_int(bs, 24);
2148 : etd->isUTF8 = gf_bs_read_int(bs, 1);
2149 : /*aligned = */gf_bs_read_int(bs, 7);
2150 : count = gf_bs_read_int(bs, 8);
2151 : nbBytes += 5;
2152 :
2153 : for (i = 0; i< count; i++) {
2154 : //description
2155 : GF_ETD_ItemText *description, *Text;
2156 : description = (GF_ETD_ItemText*)gf_malloc(sizeof(GF_ETD_ItemText));
2157 : if (! description) return GF_OUT_OF_MEM;
2158 : description->text = NULL;
2159 : e = OD_ReadUTF8String(bs, & description->text, etd->isUTF8, &len);
2160 : if (e) {
2161 : gf_free(description);
2162 : return e;
2163 : }
2164 : e = gf_list_add(etd->itemDescriptionList, description);
2165 : if (e) return e;
2166 : nbBytes += len;
2167 :
2168 : //text
2169 : Text = (GF_ETD_ItemText*)gf_malloc(sizeof(GF_ETD_ItemText));
2170 : if (! Text) return GF_OUT_OF_MEM;
2171 : Text->text = NULL;
2172 : e = OD_ReadUTF8String(bs, & Text->text, etd->isUTF8, &len);
2173 : if (e) return e;
2174 : e = gf_list_add(etd->itemTextList, Text);
2175 : if (e) return e;
2176 : nbBytes += len;
2177 : }
2178 : len = gf_bs_read_int(bs, 8);
2179 : nbBytes += 1;
2180 : nonLen = 0;
2181 : while (len == 255) {
2182 : nonLen += len;
2183 : len = gf_bs_read_int(bs, 8);
2184 : nbBytes += 1;
2185 : }
2186 : nonLen += len;
2187 : if (nonLen) {
2188 : //here we have no choice but do the job ourselves
2189 : //because the length is not encoded on 8 bits
2190 : etd->NonItemText = (char *) gf_malloc(sizeof(char) * (1+nonLen) * (etd->isUTF8 ? 1 : 2));
2191 : if (! etd->NonItemText) return GF_OUT_OF_MEM;
2192 : gf_bs_read_data(bs, etd->NonItemText, nonLen * (etd->isUTF8 ? 1 : 2));
2193 : nbBytes += nonLen * (etd->isUTF8 ? 1 : 2);
2194 : }
2195 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2196 : return GF_OK;
2197 : }
2198 :
2199 :
2200 : GF_Err gf_odf_size_exp_text(GF_ExpandedTextual *etd, u32 *outSize)
2201 : {
2202 : u32 i, len, nonLen, lentmp, count;
2203 : if (!etd) return GF_BAD_PARAM;
2204 :
2205 : *outSize = 5;
2206 : if (gf_list_count(etd->itemDescriptionList) != gf_list_count(etd->itemTextList)) return GF_ODF_INVALID_DESCRIPTOR;
2207 :
2208 : count = gf_list_count(etd->itemDescriptionList);
2209 : for (i=0; i<count; i++) {
2210 : GF_ETD_ItemText *tmp = (GF_ETD_ItemText *)gf_list_get(etd->itemDescriptionList, i);
2211 : *outSize += OD_SizeUTF8String(tmp->text, etd->isUTF8);
2212 : tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemTextList, i);
2213 : *outSize += OD_SizeUTF8String(tmp->text, etd->isUTF8);
2214 : }
2215 : *outSize += 1;
2216 : if (etd->NonItemText) {
2217 : if (etd->isUTF8) {
2218 : nonLen = (u32) strlen((const char*)etd->NonItemText);
2219 : } else {
2220 : nonLen = (u32) gf_utf8_wcslen((const unsigned short*)etd->NonItemText);
2221 : }
2222 : } else {
2223 : nonLen = 0;
2224 : }
2225 : len = 255;
2226 : lentmp = nonLen;
2227 : if (lentmp < 255) {
2228 : len = lentmp;
2229 : }
2230 : while (len == 255) {
2231 : *outSize += 1;
2232 : lentmp -= 255;
2233 : if (lentmp < 255) {
2234 : len = lentmp;
2235 : }
2236 : }
2237 : *outSize += nonLen * (etd->isUTF8 ? 1 : 2);
2238 : return GF_OK;
2239 : }
2240 :
2241 : GF_Err gf_odf_write_exp_text(GF_BitStream *bs, GF_ExpandedTextual *etd)
2242 : {
2243 : GF_Err e;
2244 : u32 size, i, len, nonLen, lentmp, count;
2245 : if (!etd) return GF_BAD_PARAM;
2246 :
2247 : if (gf_list_count(etd->itemDescriptionList) != gf_list_count(etd->itemTextList)) return GF_ODF_INVALID_DESCRIPTOR;
2248 :
2249 : e = gf_odf_size_descriptor((GF_Descriptor *)etd, &size);
2250 : if (e) return e;
2251 : e = gf_odf_write_base_descriptor(bs, etd->tag, size);
2252 : if (e) return e;
2253 :
2254 : gf_bs_write_int(bs, etd->langCode, 24);
2255 : gf_bs_write_int(bs, etd->isUTF8, 1);
2256 : gf_bs_write_int(bs, 0, 7); //aligned
2257 : gf_bs_write_int(bs, gf_list_count(etd->itemDescriptionList), 8);
2258 :
2259 : count = gf_list_count(etd->itemDescriptionList);
2260 : for (i=0; i<count; i++) {
2261 : GF_ETD_ItemText *tmp = (GF_ETD_ItemText *)gf_list_get(etd->itemDescriptionList, i);
2262 : OD_WriteUTF8String(bs, tmp->text, etd->isUTF8);
2263 : tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemTextList, i);
2264 : OD_WriteUTF8String(bs, tmp->text, etd->isUTF8);
2265 : }
2266 : if (etd->NonItemText) {
2267 : if (etd->isUTF8) {
2268 : nonLen = (u32) strlen((const char*)etd->NonItemText);
2269 : } else {
2270 : nonLen = (u32) gf_utf8_wcslen((const unsigned short*)etd->NonItemText);
2271 : }
2272 : } else {
2273 : nonLen = 0;
2274 : }
2275 : lentmp = nonLen;
2276 : len = lentmp < 255 ? lentmp : 255;
2277 : while (len == 255) {
2278 : gf_bs_write_int(bs, len, 8);
2279 : lentmp -= len;
2280 : len = lentmp < 255 ? lentmp : 255;
2281 : }
2282 : gf_bs_write_int(bs, len, 8);
2283 : gf_bs_write_data(bs, etd->NonItemText, nonLen * (etd->isUTF8 ? 1 : 2));
2284 : return GF_OK;
2285 : }
2286 :
2287 : GF_Descriptor *gf_odf_new_pl_ext()
2288 : {
2289 : GF_PLExt *newDesc = (GF_PLExt *) gf_malloc(sizeof(GF_PLExt));
2290 : if (!newDesc) return NULL;
2291 : newDesc->AudioProfileLevelIndication = 0;
2292 : newDesc->GraphicsProfileLevelIndication = 0;
2293 : newDesc->MPEGJProfileLevelIndication = 0;
2294 : newDesc->ODProfileLevelIndication = 0;
2295 : newDesc->profileLevelIndicationIndex = 0;
2296 : newDesc->SceneProfileLevelIndication = 0;
2297 : newDesc->VisualProfileLevelIndication = 0;
2298 : newDesc->tag = GF_ODF_EXT_PL_TAG;
2299 : return (GF_Descriptor *) newDesc;
2300 : }
2301 :
2302 : GF_Err gf_odf_del_pl_ext(GF_PLExt *pld)
2303 : {
2304 : if (!pld) return GF_BAD_PARAM;
2305 :
2306 : gf_free(pld);
2307 : return GF_OK;
2308 : }
2309 :
2310 : GF_Err gf_odf_read_pl_ext(GF_BitStream *bs, GF_PLExt *pld, u32 DescSize)
2311 : {
2312 : u32 nbBytes = 0;
2313 : if (!pld) return GF_BAD_PARAM;
2314 :
2315 : pld->profileLevelIndicationIndex = gf_bs_read_int(bs, 8);
2316 : pld->ODProfileLevelIndication = gf_bs_read_int(bs, 8);
2317 : pld->SceneProfileLevelIndication = gf_bs_read_int(bs, 8);
2318 : pld->AudioProfileLevelIndication = gf_bs_read_int(bs, 8);
2319 : pld->VisualProfileLevelIndication = gf_bs_read_int(bs, 8);
2320 : pld->GraphicsProfileLevelIndication = gf_bs_read_int(bs, 8);
2321 : pld->MPEGJProfileLevelIndication = gf_bs_read_int(bs, 8);
2322 :
2323 : nbBytes += 7;
2324 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2325 : return GF_OK;
2326 : }
2327 :
2328 : GF_Err gf_odf_size_pl_ext(GF_PLExt *pld, u32 *outSize)
2329 : {
2330 : if (!pld) return GF_BAD_PARAM;
2331 :
2332 : *outSize = 7;
2333 : return GF_OK;
2334 : }
2335 :
2336 : GF_Err gf_odf_write_pl_ext(GF_BitStream *bs, GF_PLExt *pld)
2337 : {
2338 : GF_Err e;
2339 : u32 size;
2340 : if (!pld) return GF_BAD_PARAM;
2341 :
2342 : e = gf_odf_size_descriptor((GF_Descriptor *)pld, &size);
2343 : if (e) return e;
2344 : e = gf_odf_write_base_descriptor(bs, pld->tag, size);
2345 : if (e) return e;
2346 :
2347 : gf_bs_write_int(bs, pld->profileLevelIndicationIndex, 8);
2348 : gf_bs_write_int(bs, pld->ODProfileLevelIndication, 8);
2349 : gf_bs_write_int(bs, pld->SceneProfileLevelIndication, 8);
2350 : gf_bs_write_int(bs, pld->AudioProfileLevelIndication, 8);
2351 : gf_bs_write_int(bs, pld->VisualProfileLevelIndication, 8);
2352 : gf_bs_write_int(bs, pld->GraphicsProfileLevelIndication, 8);
2353 : gf_bs_write_int(bs, pld->MPEGJProfileLevelIndication, 8);
2354 : return GF_OK;
2355 : }
2356 :
2357 : GF_Descriptor *gf_odf_new_ipi_ptr()
2358 : {
2359 : GF_IPIPtr *newDesc = (GF_IPIPtr *) gf_malloc(sizeof(GF_IPIPtr));
2360 : if (!newDesc) return NULL;
2361 : newDesc->IPI_ES_Id = 0;
2362 : newDesc->tag = GF_ODF_IPI_PTR_TAG;
2363 : return (GF_Descriptor *) newDesc;
2364 : }
2365 :
2366 : GF_Err gf_odf_del_ipi_ptr(GF_IPIPtr *ipid)
2367 : {
2368 : if (!ipid) return GF_BAD_PARAM;
2369 : gf_free(ipid);
2370 : return GF_OK;
2371 : }
2372 :
2373 : GF_Err gf_odf_read_ipi_ptr(GF_BitStream *bs, GF_IPIPtr *ipid, u32 DescSize)
2374 : {
2375 : u32 nbBytes = 0;
2376 : if (! ipid) return GF_BAD_PARAM;
2377 :
2378 : ipid->IPI_ES_Id = gf_bs_read_int(bs, 16);
2379 : nbBytes += 2;
2380 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2381 : return GF_OK;
2382 : }
2383 :
2384 : GF_Err gf_odf_size_ipi_ptr(GF_IPIPtr *ipid, u32 *outSize)
2385 : {
2386 : if (! ipid) return GF_BAD_PARAM;
2387 : *outSize = 2;
2388 : return GF_OK;
2389 : }
2390 :
2391 : GF_Err gf_odf_write_ipi_ptr(GF_BitStream *bs, GF_IPIPtr *ipid)
2392 : {
2393 : GF_Err e;
2394 : u32 size;
2395 : if (! ipid) return GF_BAD_PARAM;
2396 : e = gf_odf_size_descriptor((GF_Descriptor *)ipid, &size);
2397 : if (e) return e;
2398 : e = gf_odf_write_base_descriptor(bs, ipid->tag, size);
2399 : if (e) return e;
2400 : gf_bs_write_int(bs, ipid->IPI_ES_Id, 16);
2401 : return GF_OK;
2402 : }
2403 :
2404 : GF_Descriptor *gf_odf_new_ipmp()
2405 : {
2406 : GF_IPMP_Descriptor *newDesc;
2407 : GF_SAFEALLOC(newDesc, GF_IPMP_Descriptor);
2408 : if (!newDesc) return NULL;
2409 :
2410 : newDesc->ipmpx_data = gf_list_new();
2411 : newDesc->tag = GF_ODF_IPMP_TAG;
2412 : return (GF_Descriptor *) newDesc;
2413 : }
2414 : GF_Err gf_odf_del_ipmp(GF_IPMP_Descriptor *ipmp)
2415 : {
2416 : if (!ipmp) return GF_BAD_PARAM;
2417 : if (ipmp->opaque_data) gf_free(ipmp->opaque_data);
2418 : #ifndef GPAC_MINIMAL_ODF
2419 : /*TODO DELETE IPMPX*/
2420 : while (gf_list_count(ipmp->ipmpx_data)) {
2421 : GF_IPMPX_Data *p = (GF_IPMPX_Data *)gf_list_get(ipmp->ipmpx_data, 0);
2422 : gf_list_rem(ipmp->ipmpx_data, 0);
2423 : gf_ipmpx_data_del(p);
2424 : }
2425 : #endif
2426 : gf_list_del(ipmp->ipmpx_data);
2427 : gf_free(ipmp);
2428 : return GF_OK;
2429 : }
2430 :
2431 : GF_Err gf_odf_read_ipmp(GF_BitStream *bs, GF_IPMP_Descriptor *ipmp, u32 DescSize)
2432 : {
2433 : u32 size;
2434 : u64 nbBytes = 0;
2435 : if (!ipmp) return GF_BAD_PARAM;
2436 :
2437 : ipmp->IPMP_DescriptorID = gf_bs_read_int(bs, 8);
2438 : ipmp->IPMPS_Type = gf_bs_read_int(bs, 16);
2439 : nbBytes += 3;
2440 : if (DescSize<3) return GF_ODF_INVALID_DESCRIPTOR;
2441 :
2442 : size = DescSize - 3;
2443 :
2444 : /*IPMPX escape*/
2445 : if ((ipmp->IPMP_DescriptorID==0xFF) && (ipmp->IPMPS_Type==0xFFFF)) {
2446 : ipmp->IPMP_DescriptorIDEx = gf_bs_read_int(bs, 16);
2447 : if (gf_bs_available(bs) < 16) return GF_ODF_INVALID_DESCRIPTOR;
2448 : gf_bs_read_data(bs, (char*)ipmp->IPMP_ToolID, 16);
2449 : ipmp->control_point = gf_bs_read_int(bs, 8);
2450 : nbBytes += 19;
2451 : if (ipmp->control_point) {
2452 : ipmp->cp_sequence_code = gf_bs_read_int(bs, 8);
2453 : nbBytes += 1;
2454 : }
2455 : while (nbBytes<DescSize) {
2456 : u64 pos;
2457 : GF_Err e;
2458 : GF_IPMPX_Data *p;
2459 : pos = gf_bs_get_position(bs);
2460 : e = gf_ipmpx_data_parse(bs, &p);
2461 : if (e) return e;
2462 : gf_list_add(ipmp->ipmpx_data, p);
2463 : nbBytes += gf_bs_get_position(bs) - pos;
2464 : }
2465 : }
2466 : /*URL*/
2467 : else if (! ipmp->IPMPS_Type) {
2468 : ipmp->opaque_data = (char*)gf_malloc(size + 1);
2469 : if (! ipmp->opaque_data) return GF_OUT_OF_MEM;
2470 : gf_bs_read_data(bs, ipmp->opaque_data, size);
2471 : nbBytes += size;
2472 : ipmp->opaque_data[size] = 0;
2473 : ipmp->opaque_data_size = size;
2474 :
2475 : }
2476 : /*data*/
2477 : else {
2478 : ipmp->opaque_data_size = size;
2479 : ipmp->opaque_data = (char*)gf_malloc(size);
2480 : if (! ipmp->opaque_data) return GF_OUT_OF_MEM;
2481 : gf_bs_read_data(bs, ipmp->opaque_data, size);
2482 : nbBytes += size;
2483 : }
2484 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2485 : return GF_OK;
2486 : }
2487 :
2488 : GF_Err gf_odf_size_ipmp(GF_IPMP_Descriptor *ipmp, u32 *outSize)
2489 : {
2490 : u32 i, s;
2491 : if (!ipmp) return GF_BAD_PARAM;
2492 :
2493 : *outSize = 3;
2494 : /*IPMPX escape*/
2495 : if ((ipmp->IPMP_DescriptorID==0xFF) && (ipmp->IPMPS_Type==0xFFFF)) {
2496 : GF_IPMPX_Data *p;
2497 : *outSize += 19;
2498 : if (ipmp->control_point) *outSize += 1;
2499 : s = 0;
2500 : i=0;
2501 : while ((p = (GF_IPMPX_Data *)gf_list_enum(ipmp->ipmpx_data, &i))) {
2502 : s += gf_ipmpx_data_full_size(p);
2503 : }
2504 : (*outSize) += s;
2505 : }
2506 : else if (! ipmp->IPMPS_Type) {
2507 : if (!ipmp->opaque_data) return GF_ODF_INVALID_DESCRIPTOR;
2508 : *outSize += (u32) strlen(ipmp->opaque_data);
2509 : } else {
2510 : *outSize += ipmp->opaque_data_size;
2511 : }
2512 : return GF_OK;
2513 : }
2514 :
2515 : GF_Err gf_odf_write_ipmp(GF_BitStream *bs, GF_IPMP_Descriptor *ipmp)
2516 : {
2517 : GF_Err e;
2518 : u32 size, i;
2519 : if (!ipmp) return GF_BAD_PARAM;
2520 :
2521 : e = gf_odf_size_descriptor((GF_Descriptor *)ipmp, &size);
2522 : if (e) return e;
2523 : e = gf_odf_write_base_descriptor(bs, ipmp->tag, size);
2524 : if (e) return e;
2525 : gf_bs_write_int(bs, ipmp->IPMP_DescriptorID, 8);
2526 : gf_bs_write_int(bs, ipmp->IPMPS_Type, 16);
2527 :
2528 : if ((ipmp->IPMP_DescriptorID==0xFF) && (ipmp->IPMPS_Type==0xFFFF)) {
2529 : GF_IPMPX_Data *p;
2530 : gf_bs_write_int(bs, ipmp->IPMP_DescriptorIDEx, 16);
2531 : gf_bs_write_data(bs, (char*)ipmp->IPMP_ToolID, 16);
2532 : gf_bs_write_int(bs, ipmp->control_point, 8);
2533 : if (ipmp->control_point) gf_bs_write_int(bs, ipmp->cp_sequence_code, 8);
2534 :
2535 : i=0;
2536 : while ((p = (GF_IPMPX_Data *) gf_list_enum(ipmp->ipmpx_data, &i))) {
2537 : gf_ipmpx_data_write(bs, p);
2538 : }
2539 : }
2540 : else if (!ipmp->IPMPS_Type) {
2541 : if (!ipmp->opaque_data) return GF_ODF_INVALID_DESCRIPTOR;
2542 : gf_bs_write_data(bs, ipmp->opaque_data, (u32) strlen(ipmp->opaque_data));
2543 : } else {
2544 : gf_bs_write_data(bs, ipmp->opaque_data, ipmp->opaque_data_size);
2545 : }
2546 : return GF_OK;
2547 : }
2548 :
2549 : GF_Descriptor *gf_odf_new_ipmp_ptr()
2550 : {
2551 : GF_IPMPPtr *newDesc;
2552 : GF_SAFEALLOC(newDesc, GF_IPMPPtr);
2553 : if (!newDesc) return NULL;
2554 : newDesc->tag = GF_ODF_IPMP_PTR_TAG;
2555 : return (GF_Descriptor *) newDesc;
2556 : }
2557 : GF_Err gf_odf_del_ipmp_ptr(GF_IPMPPtr *ipmpd)
2558 : {
2559 : if (!ipmpd) return GF_BAD_PARAM;
2560 : gf_free(ipmpd);
2561 : return GF_OK;
2562 : }
2563 :
2564 : GF_Err gf_odf_read_ipmp_ptr(GF_BitStream *bs, GF_IPMPPtr *ipmpd, u32 DescSize)
2565 : {
2566 : u32 nbBytes = 0;
2567 : if (! ipmpd) return GF_BAD_PARAM;
2568 : ipmpd->IPMP_DescriptorID = gf_bs_read_int(bs, 8);
2569 : nbBytes += 1;
2570 : if (ipmpd->IPMP_DescriptorID == 0xFF) {
2571 : ipmpd->IPMP_DescriptorIDEx = gf_bs_read_int(bs, 16);
2572 : ipmpd->IPMP_ES_ID = gf_bs_read_int(bs, 16);
2573 : nbBytes += 4;
2574 : }
2575 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2576 : return GF_OK;
2577 : }
2578 : GF_Err gf_odf_size_ipmp_ptr(GF_IPMPPtr *ipmpd, u32 *outSize)
2579 : {
2580 : if (! ipmpd) return GF_BAD_PARAM;
2581 : *outSize = 1;
2582 : if (ipmpd->IPMP_DescriptorID == 0xFF) *outSize += 4;
2583 : return GF_OK;
2584 : }
2585 : GF_Err gf_odf_write_ipmp_ptr(GF_BitStream *bs, GF_IPMPPtr *ipmpd)
2586 : {
2587 : GF_Err e;
2588 : u32 size;
2589 : if (! ipmpd) return GF_BAD_PARAM;
2590 :
2591 : e = gf_odf_size_descriptor((GF_Descriptor *)ipmpd, &size);
2592 : if (e) return e;
2593 : e = gf_odf_write_base_descriptor(bs, ipmpd->tag, size);
2594 : if (e) return e;
2595 : gf_bs_write_int(bs, ipmpd->IPMP_DescriptorID, 8);
2596 : if (ipmpd->IPMP_DescriptorID == 0xFF) {
2597 : gf_bs_write_int(bs, ipmpd->IPMP_DescriptorIDEx, 16);
2598 : gf_bs_write_int(bs, ipmpd->IPMP_ES_ID, 16);
2599 : }
2600 : return GF_OK;
2601 : }
2602 :
2603 : GF_Descriptor *gf_odf_new_kw()
2604 : {
2605 : GF_KeyWord *newDesc = (GF_KeyWord *) gf_malloc(sizeof(GF_KeyWord));
2606 : if (!newDesc) return NULL;
2607 :
2608 : newDesc->keyWordsList = gf_list_new();
2609 : if (! newDesc->keyWordsList) {
2610 : gf_free(newDesc);
2611 : return NULL;
2612 : }
2613 : newDesc->isUTF8 = 0;
2614 : newDesc->languageCode = 0;
2615 : newDesc->tag = GF_ODF_KW_TAG;
2616 : return (GF_Descriptor *) newDesc;
2617 : }
2618 :
2619 : GF_Err gf_odf_del_kw(GF_KeyWord *kwd)
2620 : {
2621 : if (!kwd) return GF_BAD_PARAM;
2622 :
2623 : while (gf_list_count(kwd->keyWordsList)) {
2624 : GF_KeyWordItem *tmp = (GF_KeyWordItem*)gf_list_get(kwd->keyWordsList, 0);
2625 : if (tmp) {
2626 : if (tmp->keyWord) gf_free(tmp->keyWord);
2627 : tmp->keyWord = NULL;
2628 : gf_list_rem(kwd->keyWordsList, 0);
2629 : gf_free(tmp);
2630 : }
2631 : }
2632 : gf_list_del(kwd->keyWordsList);
2633 : gf_free(kwd);
2634 : return GF_OK;
2635 : }
2636 :
2637 : GF_Err gf_odf_read_kw(GF_BitStream *bs, GF_KeyWord *kwd, u32 DescSize)
2638 : {
2639 : GF_Err e;
2640 : u32 nbBytes = 0, i, kwcount, len;
2641 : if (!kwd) return GF_BAD_PARAM;
2642 :
2643 : kwd->languageCode = gf_bs_read_int(bs, 24);
2644 : kwd->isUTF8 = gf_bs_read_int(bs, 1);
2645 : /*aligned = */gf_bs_read_int(bs, 7);
2646 : kwcount = gf_bs_read_int(bs, 8);
2647 : nbBytes += 5;
2648 :
2649 : for (i = 0 ; i < kwcount; i++) {
2650 : GF_KeyWordItem *tmp = (GF_KeyWordItem*)gf_malloc(sizeof(GF_KeyWordItem));
2651 : if (! tmp) return GF_OUT_OF_MEM;
2652 : e = OD_ReadUTF8String(bs, & tmp->keyWord, kwd->isUTF8, &len);
2653 : if (e) {
2654 : if (tmp->keyWord) gf_free(tmp->keyWord);
2655 : gf_free(tmp);
2656 : return e;
2657 : }
2658 : nbBytes += len;
2659 : if (nbBytes > DescSize) {
2660 : gf_free(tmp->keyWord);
2661 : gf_free(tmp);
2662 : return GF_ODF_INVALID_DESCRIPTOR;
2663 : }
2664 : e = gf_list_add(kwd->keyWordsList, tmp);
2665 : if (e) {
2666 : if (tmp) gf_free(tmp);
2667 : return e;
2668 : }
2669 : }
2670 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2671 : return GF_OK;
2672 : }
2673 :
2674 :
2675 : GF_Err gf_odf_size_kw(GF_KeyWord *kwd, u32 *outSize)
2676 : {
2677 : u32 i;
2678 : GF_KeyWordItem *tmp;
2679 : if (!kwd) return GF_BAD_PARAM;
2680 :
2681 : *outSize = 5;
2682 : i=0;
2683 : while ((tmp = (GF_KeyWordItem *)gf_list_enum(kwd->keyWordsList, &i))) {
2684 : *outSize += OD_SizeUTF8String(tmp->keyWord, kwd->isUTF8);
2685 : }
2686 : return GF_OK;
2687 : }
2688 : GF_Err gf_odf_write_kw(GF_BitStream *bs, GF_KeyWord *kwd)
2689 : {
2690 : GF_Err e;
2691 : u32 size, i;
2692 : GF_KeyWordItem *tmp;
2693 : if (!kwd) return GF_BAD_PARAM;
2694 :
2695 : e = gf_odf_size_descriptor((GF_Descriptor *)kwd, &size);
2696 : if (e) return e;
2697 : e = gf_odf_write_base_descriptor(bs, kwd->tag, size);
2698 : if (e) return e;
2699 :
2700 : gf_bs_write_int(bs, kwd->languageCode, 24);
2701 : gf_bs_write_int(bs, kwd->isUTF8, 1);
2702 : gf_bs_write_int(bs, 0, 7); //aligned(8)
2703 : gf_bs_write_int(bs, gf_list_count(kwd->keyWordsList), 8);
2704 :
2705 : i=0;
2706 : while ((tmp = (GF_KeyWordItem *)gf_list_enum(kwd->keyWordsList, &i))) {
2707 : OD_WriteUTF8String(bs, tmp->keyWord, kwd->isUTF8);
2708 : }
2709 : return GF_OK;
2710 : }
2711 :
2712 : GF_Descriptor *gf_odf_new_oci_date()
2713 : {
2714 : GF_OCI_Data *newDesc = (GF_OCI_Data *) gf_malloc(sizeof(GF_OCI_Data));
2715 : if (!newDesc) return NULL;
2716 : memset(newDesc->OCICreationDate, 0, 5);
2717 : newDesc->tag = GF_ODF_OCI_DATE_TAG;
2718 : return (GF_Descriptor *) newDesc;
2719 : }
2720 :
2721 : GF_Err gf_odf_del_oci_date(GF_OCI_Data *ocd)
2722 : {
2723 : if (!ocd) return GF_BAD_PARAM;
2724 : gf_free(ocd);
2725 : return GF_OK;
2726 : }
2727 :
2728 : GF_Err gf_odf_read_oci_date(GF_BitStream *bs, GF_OCI_Data *ocd, u32 DescSize)
2729 : {
2730 : u32 nbBytes = 0;
2731 : if (!ocd) return GF_BAD_PARAM;
2732 :
2733 : gf_bs_read_data(bs, ocd->OCICreationDate, DATE_CODING_LEN);
2734 : nbBytes += DATE_CODING_LEN;
2735 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2736 : return GF_OK;
2737 : }
2738 :
2739 : GF_Err gf_odf_size_oci_date(GF_OCI_Data *ocd, u32 *outSize)
2740 : {
2741 : if (!ocd) return GF_BAD_PARAM;
2742 : *outSize = DATE_CODING_LEN;
2743 : return GF_OK;
2744 : }
2745 :
2746 : GF_Err gf_odf_write_oci_date(GF_BitStream *bs, GF_OCI_Data *ocd)
2747 : {
2748 : GF_Err e;
2749 : u32 size;
2750 : if (!ocd) return GF_BAD_PARAM;
2751 :
2752 : e = gf_odf_size_descriptor((GF_Descriptor *)ocd, &size);
2753 : if (e) return e;
2754 : e = gf_odf_write_base_descriptor(bs, ocd->tag, size);
2755 : if (e) return e;
2756 : gf_bs_write_data(bs, ocd->OCICreationDate, DATE_CODING_LEN);
2757 : return GF_OK;
2758 : }
2759 :
2760 : GF_Descriptor *gf_odf_new_oci_name()
2761 : {
2762 : GF_OCICreators *newDesc = (GF_OCICreators *) gf_malloc(sizeof(GF_OCICreators));
2763 : if (!newDesc) return NULL;
2764 :
2765 : newDesc->OCICreators = gf_list_new();
2766 : if (! newDesc->OCICreators) {
2767 : gf_free(newDesc);
2768 : return NULL;
2769 : }
2770 : newDesc->tag = GF_ODF_OCI_NAME_TAG;
2771 : return (GF_Descriptor *) newDesc;
2772 : }
2773 : GF_Err gf_odf_del_oci_name(GF_OCICreators *ocn)
2774 : {
2775 : u32 i;
2776 : GF_OCICreator_item *tmp;
2777 : if (!ocn) return GF_BAD_PARAM;
2778 :
2779 : i=0;
2780 : while ((tmp = (GF_OCICreator_item *)gf_list_enum(ocn->OCICreators, &i))) {
2781 : if (tmp->OCICreatorName) gf_free(tmp->OCICreatorName);
2782 : gf_free(tmp);
2783 : }
2784 : gf_list_del(ocn->OCICreators);
2785 : gf_free(ocn);
2786 : return GF_OK;
2787 : }
2788 :
2789 : GF_Err gf_odf_read_oci_name(GF_BitStream *bs, GF_OCICreators *ocn, u32 DescSize)
2790 : {
2791 : GF_Err e;
2792 : u32 nbBytes = 0;
2793 : u32 i, count, len;
2794 : if (!ocn) return GF_BAD_PARAM;
2795 :
2796 : count = gf_bs_read_int(bs, 8);
2797 : nbBytes += 1;
2798 : for (i = 0; i< count; i++) {
2799 : GF_OCICreator_item *tmp = (GF_OCICreator_item*)gf_malloc(sizeof(GF_OCICreator_item));
2800 : if (! tmp) return GF_OUT_OF_MEM;
2801 : tmp->langCode = gf_bs_read_int(bs, 24);
2802 : tmp->isUTF8 = gf_bs_read_int(bs, 1);
2803 : /*aligned = */gf_bs_read_int(bs, 7);
2804 : nbBytes += 4;
2805 : e = OD_ReadUTF8String(bs, & tmp->OCICreatorName, tmp->isUTF8, &len);
2806 : if (e) {
2807 : gf_free(tmp);
2808 : return e;
2809 : }
2810 : nbBytes += len;
2811 : e = gf_list_add(ocn->OCICreators, tmp);
2812 : if (e) return e;
2813 : }
2814 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2815 : return GF_OK;
2816 : }
2817 :
2818 : GF_Err gf_odf_size_oci_name(GF_OCICreators *ocn, u32 *outSize)
2819 : {
2820 : u32 i;
2821 : GF_OCICreator_item *tmp;
2822 : if (!ocn) return GF_BAD_PARAM;
2823 :
2824 : *outSize = 1;
2825 : i=0;
2826 : while ((tmp = (GF_OCICreator_item *)gf_list_enum(ocn->OCICreators, &i))) {
2827 : *outSize += 4 + OD_SizeUTF8String(tmp->OCICreatorName, tmp->isUTF8);
2828 : }
2829 : return GF_OK;
2830 : }
2831 :
2832 : GF_Err gf_odf_write_oci_name(GF_BitStream *bs, GF_OCICreators *ocn)
2833 : {
2834 : GF_Err e;
2835 : u32 size;
2836 : u32 i;
2837 : GF_OCICreator_item *tmp;
2838 : if (!ocn) return GF_BAD_PARAM;
2839 :
2840 : e = gf_odf_size_descriptor((GF_Descriptor *)ocn, &size);
2841 : if (e) return e;
2842 : e = gf_odf_write_base_descriptor(bs, ocn->tag, size);
2843 : if (e) return e;
2844 : gf_bs_write_int(bs, gf_list_count(ocn->OCICreators), 8);
2845 :
2846 : i=0;
2847 : while ((tmp = (GF_OCICreator_item *)gf_list_enum(ocn->OCICreators, &i))) {
2848 : gf_bs_write_int(bs, tmp->langCode, 24);
2849 : gf_bs_write_int(bs, tmp->isUTF8, 1);
2850 : gf_bs_write_int(bs, 0, 7); //aligned
2851 : gf_bs_write_int(bs, (u32) strlen(tmp->OCICreatorName) , 8);
2852 : OD_WriteUTF8String(bs, tmp->OCICreatorName, tmp->isUTF8);
2853 : }
2854 : return GF_OK;
2855 : }
2856 :
2857 :
2858 : GF_Descriptor *gf_odf_new_pl_idx()
2859 : {
2860 : GF_PL_IDX *newDesc = (GF_PL_IDX *) gf_malloc(sizeof(GF_PL_IDX));
2861 : if (!newDesc) return NULL;
2862 : newDesc->profileLevelIndicationIndex = 0;
2863 : newDesc->tag = GF_ODF_PL_IDX_TAG;
2864 : return (GF_Descriptor *) newDesc;
2865 : }
2866 :
2867 : GF_Err gf_odf_del_pl_idx(GF_PL_IDX *plid)
2868 : {
2869 : if (!plid) return GF_BAD_PARAM;
2870 : gf_free(plid);
2871 : return GF_OK;
2872 : }
2873 :
2874 : GF_Err gf_odf_read_pl_idx(GF_BitStream *bs, GF_PL_IDX *plid, u32 DescSize)
2875 : {
2876 : u32 nbBytes = 0;
2877 : if (!plid) return GF_BAD_PARAM;
2878 :
2879 : plid->profileLevelIndicationIndex = gf_bs_read_int(bs, 8);
2880 : nbBytes += 1;
2881 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2882 : return GF_OK;
2883 : }
2884 : GF_Err gf_odf_size_pl_idx(GF_PL_IDX *plid, u32 *outSize)
2885 : {
2886 : if (!plid) return GF_BAD_PARAM;
2887 : *outSize = 1;
2888 : return GF_OK;
2889 : }
2890 : GF_Err gf_odf_write_pl_idx(GF_BitStream *bs, GF_PL_IDX *plid)
2891 : {
2892 : GF_Err e;
2893 : u32 size;
2894 : if (!plid) return GF_BAD_PARAM;
2895 : e = gf_odf_size_descriptor((GF_Descriptor *)plid, &size);
2896 : if (e) return e;
2897 : e = gf_odf_write_base_descriptor(bs, plid->tag, size);
2898 : if (e) return e;
2899 : gf_bs_write_int(bs, plid->profileLevelIndicationIndex, 8);
2900 : return GF_OK;
2901 : }
2902 :
2903 :
2904 : GF_Descriptor *gf_odf_new_rating()
2905 : {
2906 : GF_Rating *newDesc = (GF_Rating *) gf_malloc(sizeof(GF_Rating));
2907 : if (!newDesc) return NULL;
2908 :
2909 : newDesc->infoLength = 0;
2910 : newDesc->ratingInfo = NULL;
2911 : newDesc->ratingCriteria = 0;
2912 : newDesc->ratingEntity = 0;
2913 : newDesc->tag = GF_ODF_RATING_TAG;
2914 : return (GF_Descriptor *) newDesc;
2915 : }
2916 :
2917 : GF_Err gf_odf_del_rating(GF_Rating *rd)
2918 : {
2919 : if (!rd) return GF_BAD_PARAM;
2920 :
2921 : if (rd->ratingInfo) gf_free(rd->ratingInfo);
2922 : gf_free(rd);
2923 : return GF_OK;
2924 : }
2925 :
2926 : GF_Err gf_odf_read_rating(GF_BitStream *bs, GF_Rating *rd, u32 DescSize)
2927 : {
2928 : u32 nbBytes = 0;
2929 : if (!rd) return GF_BAD_PARAM;
2930 :
2931 : rd->ratingEntity = gf_bs_read_int(bs, 32);
2932 : rd->ratingCriteria = gf_bs_read_int(bs, 16);
2933 : if (DescSize<6) return GF_ODF_INVALID_DESCRIPTOR;
2934 : rd->infoLength = DescSize - 6;
2935 : nbBytes += 6;
2936 :
2937 : rd->ratingInfo = (char*)gf_malloc(rd->infoLength);
2938 : if (! rd->ratingInfo) return GF_OUT_OF_MEM;
2939 : gf_bs_read_data(bs, rd->ratingInfo, rd->infoLength);
2940 : nbBytes += rd->infoLength;
2941 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2942 : return GF_OK;
2943 : }
2944 :
2945 : GF_Err gf_odf_size_rating(GF_Rating *rd, u32 *outSize)
2946 : {
2947 : if (!rd) return GF_BAD_PARAM;
2948 :
2949 : *outSize = 6 + rd->infoLength;
2950 : return GF_OK;
2951 : }
2952 :
2953 : GF_Err gf_odf_write_rating(GF_BitStream *bs, GF_Rating *rd)
2954 : {
2955 : GF_Err e;
2956 : u32 size;
2957 : if (!rd) return GF_BAD_PARAM;
2958 : e = gf_odf_size_descriptor((GF_Descriptor *)rd, &size);
2959 : if (e) return e;
2960 : e = gf_odf_write_base_descriptor(bs, rd->tag, size);
2961 : if (e) return e;
2962 : gf_bs_write_int(bs, rd->ratingEntity, 32);
2963 : gf_bs_write_int(bs, rd->ratingCriteria, 16);
2964 : gf_bs_write_data(bs, rd->ratingInfo, rd->infoLength);
2965 : return GF_OK;
2966 : }
2967 :
2968 :
2969 : GF_Descriptor *gf_odf_new_reg()
2970 : {
2971 : GF_Registration *newDesc = (GF_Registration *) gf_malloc(sizeof(GF_Registration));
2972 : if (!newDesc) return NULL;
2973 : newDesc->additionalIdentificationInfo = NULL;
2974 : newDesc->dataLength = 0;
2975 : newDesc->formatIdentifier = 0;
2976 : newDesc->tag = GF_ODF_REG_TAG;
2977 : return (GF_Descriptor *) newDesc;
2978 : }
2979 :
2980 : GF_Err gf_odf_del_reg(GF_Registration *reg)
2981 : {
2982 : if (!reg) return GF_BAD_PARAM;
2983 :
2984 : if (reg->additionalIdentificationInfo) gf_free(reg->additionalIdentificationInfo);
2985 : gf_free(reg);
2986 : return GF_OK;
2987 : }
2988 :
2989 : GF_Err gf_odf_read_reg(GF_BitStream *bs, GF_Registration *reg, u32 DescSize)
2990 : {
2991 : u32 nbBytes = 0;
2992 : if (!reg) return GF_BAD_PARAM;
2993 :
2994 : reg->formatIdentifier = gf_bs_read_int(bs, 32);
2995 : if (DescSize<4) return GF_ODF_INVALID_DESCRIPTOR;
2996 : reg->dataLength = DescSize - 4;
2997 : reg->additionalIdentificationInfo = (char*)gf_malloc(reg->dataLength);
2998 : if (! reg->additionalIdentificationInfo) return GF_OUT_OF_MEM;
2999 : gf_bs_read_data(bs, reg->additionalIdentificationInfo, reg->dataLength);
3000 : nbBytes += reg->dataLength + 4;
3001 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
3002 : return GF_OK;
3003 : }
3004 :
3005 :
3006 : GF_Err gf_odf_size_reg(GF_Registration *reg, u32 *outSize)
3007 : {
3008 : if (!reg) return GF_BAD_PARAM;
3009 :
3010 : *outSize = 4 + reg->dataLength;
3011 : return GF_OK;
3012 : }
3013 :
3014 : GF_Err gf_odf_write_reg(GF_BitStream *bs, GF_Registration *reg)
3015 : {
3016 : GF_Err e;
3017 : u32 size;
3018 : if (!reg) return GF_BAD_PARAM;
3019 :
3020 : e = gf_odf_size_descriptor((GF_Descriptor *)reg, &size);
3021 : if (e) return e;
3022 : e = gf_odf_write_base_descriptor(bs, reg->tag, size);
3023 : if (e) return e;
3024 :
3025 : gf_bs_write_int(bs, reg->formatIdentifier, 32);
3026 : gf_bs_write_data(bs, reg->additionalIdentificationInfo, reg->dataLength);
3027 : return GF_OK;
3028 : }
3029 :
3030 : GF_Descriptor *gf_odf_new_short_text()
3031 : {
3032 : GF_ShortTextual *newDesc = (GF_ShortTextual *) gf_malloc(sizeof(GF_ShortTextual));
3033 : if (!newDesc) return NULL;
3034 :
3035 : newDesc->eventName = NULL;
3036 : newDesc->eventText = NULL;
3037 : newDesc->isUTF8 = 0;
3038 : newDesc->langCode = 0;
3039 : newDesc->tag = GF_ODF_SHORT_TEXT_TAG;
3040 : return (GF_Descriptor *) newDesc;
3041 : }
3042 :
3043 : GF_Err gf_odf_del_short_text(GF_ShortTextual *std)
3044 : {
3045 : if (!std) return GF_BAD_PARAM;
3046 :
3047 : if (std->eventName) gf_free(std->eventName);
3048 : if (std->eventText) gf_free(std->eventText);
3049 : gf_free(std);
3050 : return GF_OK;
3051 : }
3052 :
3053 : GF_Err gf_odf_read_short_text(GF_BitStream *bs, GF_ShortTextual *std, u32 DescSize)
3054 : {
3055 : GF_Err e;
3056 : u32 nbBytes = 0, len;
3057 : if (!std) return GF_BAD_PARAM;
3058 :
3059 : std->langCode = gf_bs_read_int(bs, 24);
3060 : std->isUTF8 = gf_bs_read_int(bs, 1);
3061 : /*aligned = */gf_bs_read_int(bs, 7);
3062 : nbBytes += 4;
3063 :
3064 : e = OD_ReadUTF8String(bs, & std->eventName, std->isUTF8, &len);
3065 : if (e) return e;
3066 : nbBytes += len;
3067 : e = OD_ReadUTF8String(bs, & std->eventText, std->isUTF8, &len);
3068 : if (e) return e;
3069 : nbBytes += len;
3070 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
3071 : return GF_OK;
3072 : }
3073 :
3074 : GF_Err gf_odf_size_short_text(GF_ShortTextual *std, u32 *outSize)
3075 : {
3076 : if (!std) return GF_BAD_PARAM;
3077 : *outSize = 4;
3078 : *outSize += OD_SizeUTF8String(std->eventName, std->isUTF8) + OD_SizeUTF8String(std->eventText, std->isUTF8);
3079 : return GF_OK;
3080 : }
3081 :
3082 : GF_Err gf_odf_write_short_text(GF_BitStream *bs, GF_ShortTextual *std)
3083 : {
3084 : GF_Err e;
3085 : u32 size;
3086 : if (!std) return GF_BAD_PARAM;
3087 :
3088 : e = gf_odf_size_descriptor((GF_Descriptor *)std, &size);
3089 : if (e) return e;
3090 : e = gf_odf_write_base_descriptor(bs, std->tag, size);
3091 : if (e) return e;
3092 : gf_bs_write_int(bs, std->langCode, 24);
3093 : gf_bs_write_int(bs, std->isUTF8, 1);
3094 : gf_bs_write_int(bs, 0, 7);
3095 : OD_WriteUTF8String(bs, std->eventName, std->isUTF8);
3096 : OD_WriteUTF8String(bs, std->eventText, std->isUTF8);
3097 : return GF_OK;
3098 : }
3099 :
3100 : GF_Descriptor *gf_odf_new_smpte_camera()
3101 : {
3102 : GF_SMPTECamera *newDesc = (GF_SMPTECamera *) gf_malloc(sizeof(GF_SMPTECamera));
3103 : if (!newDesc) return NULL;
3104 :
3105 : newDesc->ParamList = gf_list_new();
3106 : if (! newDesc->ParamList) {
3107 : gf_free(newDesc);
3108 : return NULL;
3109 : }
3110 : newDesc->cameraID = 0;
3111 : newDesc->tag = GF_ODF_SMPTE_TAG;
3112 : return (GF_Descriptor *) newDesc;
3113 : }
3114 :
3115 : GF_Err gf_odf_del_smpte_camera(GF_SMPTECamera *cpd)
3116 : {
3117 : u32 i;
3118 : GF_SmpteParam *tmp;
3119 : if (!cpd) return GF_BAD_PARAM;
3120 :
3121 : i=0;
3122 : while ((tmp = (GF_SmpteParam *)gf_list_enum(cpd->ParamList, &i))) {
3123 : gf_free(tmp);
3124 : }
3125 : gf_list_del(cpd->ParamList);
3126 : gf_free(cpd);
3127 : return GF_OK;
3128 : }
3129 : GF_Err gf_odf_read_smpte_camera(GF_BitStream *bs, GF_SMPTECamera *cpd, u32 DescSize)
3130 : {
3131 : GF_Err e;
3132 : u32 nbBytes = 0, i, count;
3133 : if (!cpd) return GF_BAD_PARAM;
3134 :
3135 : cpd->cameraID = gf_bs_read_int(bs, 8);
3136 : count = gf_bs_read_int(bs, 8);
3137 : nbBytes += 2;
3138 :
3139 : for (i=0; i< count ; i++) {
3140 : GF_SmpteParam *tmp = (GF_SmpteParam*)gf_malloc(sizeof(GF_SmpteParam));
3141 : if (! tmp) return GF_OUT_OF_MEM;
3142 : tmp->paramID = gf_bs_read_int(bs, 8);
3143 : tmp->param = gf_bs_read_int(bs, 32);
3144 : nbBytes += 5;
3145 : e = gf_list_add(cpd->ParamList, tmp);
3146 : if (e) return e;
3147 : }
3148 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
3149 : return GF_OK;
3150 : }
3151 :
3152 : GF_Err gf_odf_size_smpte_camera(GF_SMPTECamera *cpd, u32 *outSize)
3153 : {
3154 : if (!cpd) return GF_BAD_PARAM;
3155 : *outSize = 2 + 5 * gf_list_count(cpd->ParamList);
3156 : return GF_OK;
3157 : }
3158 :
3159 : GF_Err gf_odf_write_smpte_camera(GF_BitStream *bs, GF_SMPTECamera *cpd)
3160 : {
3161 : GF_Err e;
3162 : GF_SmpteParam *tmp;
3163 : u32 size, i;
3164 : if (!cpd) return GF_BAD_PARAM;
3165 :
3166 : e = gf_odf_size_descriptor((GF_Descriptor *)cpd, &size);
3167 : if (e) return e;
3168 : e = gf_odf_write_base_descriptor(bs, cpd->tag, size);
3169 : if (e) return e;
3170 : gf_bs_write_int(bs, cpd->cameraID, 8);
3171 : gf_bs_write_int(bs, gf_list_count(cpd->ParamList), 8);
3172 :
3173 : i=0;
3174 : while ((tmp = (GF_SmpteParam *)gf_list_enum(cpd->ParamList, &i))) {
3175 : gf_bs_write_int(bs, tmp->paramID, 8);
3176 : gf_bs_write_int(bs, tmp->param, 32);
3177 : }
3178 : return GF_OK;
3179 : }
3180 :
3181 : GF_Descriptor *gf_odf_new_sup_cid()
3182 : {
3183 : GF_SCIDesc *newDesc = (GF_SCIDesc *) gf_malloc(sizeof(GF_SCIDesc));
3184 : if (!newDesc) return NULL;
3185 : newDesc->supplContentIdentifierTitle = NULL;
3186 : newDesc->supplContentIdentifierValue =NULL;
3187 : newDesc->languageCode = 0;
3188 : newDesc->tag = GF_ODF_SCI_TAG;
3189 : return (GF_Descriptor *) newDesc;
3190 : }
3191 :
3192 : GF_Err gf_odf_del_sup_cid(GF_SCIDesc *scid)
3193 : {
3194 : if (!scid) return GF_BAD_PARAM;
3195 :
3196 : if (scid->supplContentIdentifierTitle) gf_free(scid->supplContentIdentifierTitle);
3197 : if (scid->supplContentIdentifierValue) gf_free(scid->supplContentIdentifierValue);
3198 : gf_free(scid);
3199 : return GF_OK;
3200 : }
3201 :
3202 : GF_Err gf_odf_read_sup_cid(GF_BitStream *bs, GF_SCIDesc *scid, u32 DescSize)
3203 : {
3204 : GF_Err e;
3205 : u32 nbBytes = 0, len;
3206 : if (! scid) return GF_BAD_PARAM;
3207 :
3208 : scid->languageCode = gf_bs_read_int(bs, 24);
3209 : nbBytes += 3;
3210 : e = OD_ReadUTF8String(bs, & scid->supplContentIdentifierTitle, GF_TRUE, &len);
3211 : if (e) return e;
3212 : nbBytes += len;
3213 : e = OD_ReadUTF8String(bs, & scid->supplContentIdentifierValue, GF_TRUE, &len);
3214 : if (e) return e;
3215 : nbBytes += len;
3216 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
3217 : return GF_OK;
3218 : }
3219 :
3220 :
3221 : GF_Err gf_odf_size_sup_cid(GF_SCIDesc *scid, u32 *outSize)
3222 : {
3223 : if (! scid) return GF_BAD_PARAM;
3224 : *outSize = 3 + OD_SizeUTF8String(scid->supplContentIdentifierTitle, GF_TRUE) + OD_SizeUTF8String(scid->supplContentIdentifierValue, GF_TRUE);
3225 : return GF_OK;
3226 : }
3227 : GF_Err gf_odf_write_sup_cid(GF_BitStream *bs, GF_SCIDesc *scid)
3228 : {
3229 : GF_Err e;
3230 : u32 size;
3231 : if (! scid) return GF_BAD_PARAM;
3232 : e = gf_odf_size_descriptor((GF_Descriptor *)scid, &size);
3233 : if (e) return e;
3234 : e = gf_odf_write_base_descriptor(bs, scid->tag, size);
3235 : if (e) return e;
3236 : gf_bs_write_int(bs, scid->languageCode, 24);
3237 : OD_WriteUTF8String(bs, scid->supplContentIdentifierTitle, GF_TRUE);
3238 : OD_WriteUTF8String(bs, scid->supplContentIdentifierValue, GF_TRUE);
3239 : return GF_OK;
3240 : }
3241 :
3242 :
3243 : /*IPMPX stuff*/
3244 : GF_Descriptor *gf_odf_new_ipmp_tool_list()
3245 : {
3246 : GF_IPMP_ToolList*newDesc = (GF_IPMP_ToolList*) gf_malloc(sizeof(GF_IPMP_ToolList));
3247 : if (!newDesc) return NULL;
3248 : newDesc->ipmp_tools = gf_list_new();
3249 : newDesc->tag = GF_ODF_IPMP_TL_TAG;
3250 : return (GF_Descriptor *) newDesc;
3251 : }
3252 :
3253 : GF_Err gf_odf_del_ipmp_tool_list(GF_IPMP_ToolList *ipmptl)
3254 : {
3255 : if (!ipmptl) return GF_BAD_PARAM;
3256 :
3257 : while (gf_list_count(ipmptl->ipmp_tools)) {
3258 : GF_Descriptor *t = (GF_Descriptor *) gf_list_get(ipmptl->ipmp_tools, 0);
3259 : gf_list_rem(ipmptl->ipmp_tools, 0);
3260 : gf_odf_delete_descriptor(t);
3261 : }
3262 : gf_list_del(ipmptl->ipmp_tools);
3263 : gf_free(ipmptl);
3264 : return GF_OK;
3265 : }
3266 :
3267 : GF_Err gf_odf_read_ipmp_tool_list(GF_BitStream *bs, GF_IPMP_ToolList *ipmptl, u32 DescSize)
3268 : {
3269 : GF_Err e;
3270 : u32 tmpSize;
3271 : u32 nbBytes = 0;
3272 : if (! ipmptl) return GF_BAD_PARAM;
3273 :
3274 : while (nbBytes < DescSize) {
3275 : GF_Descriptor *tmp = NULL;
3276 : e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
3277 : if (e) return e;
3278 : if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
3279 : e = gf_list_add(ipmptl->ipmp_tools, tmp);
3280 : if (e) return e;
3281 : nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
3282 : }
3283 : if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
3284 : return GF_OK;
3285 : }
3286 :
3287 :
3288 : GF_Err gf_odf_size_ipmp_tool_list(GF_IPMP_ToolList *ipmptl, u32 *outSize)
3289 : {
3290 : if (!ipmptl) return GF_BAD_PARAM;
3291 : *outSize = 0;
3292 : return gf_odf_size_descriptor_list(ipmptl->ipmp_tools, outSize);
3293 : }
3294 :
3295 : GF_Err gf_odf_write_ipmp_tool_list(GF_BitStream *bs, GF_IPMP_ToolList *ipmptl)
3296 : {
3297 : GF_Err e;
3298 : u32 size;
3299 : if (!ipmptl) return GF_BAD_PARAM;
3300 : e = gf_odf_size_descriptor((GF_Descriptor *)ipmptl, &size);
3301 : if (e) return e;
3302 : e = gf_odf_write_base_descriptor(bs, ipmptl->tag, size);
3303 : if (e) return e;
3304 : return gf_odf_write_descriptor_list(bs, ipmptl->ipmp_tools);
3305 : }
3306 :
3307 : GF_Descriptor *gf_odf_new_ipmp_tool()
3308 : {
3309 : GF_IPMP_Tool *newDesc = (GF_IPMP_Tool*) gf_malloc(sizeof(GF_IPMP_Tool));
3310 : if (!newDesc) return NULL;
3311 : memset(newDesc, 0, sizeof(GF_IPMP_Tool));
3312 : newDesc->tag = GF_ODF_IPMP_TL_TAG;
3313 : return (GF_Descriptor *) newDesc;
3314 : }
3315 :
3316 : GF_Err gf_odf_del_ipmp_tool(GF_IPMP_Tool *ipmpt)
3317 : {
3318 : if (!ipmpt) return GF_BAD_PARAM;
3319 : if (ipmpt->tool_url) gf_free(ipmpt->tool_url);
3320 : gf_free(ipmpt);
3321 : return GF_OK;
3322 : }
3323 :
3324 : GF_Err gf_odf_read_ipmp_tool(GF_BitStream *bs, GF_IPMP_Tool *ipmpt, u32 DescSize)
3325 : {
3326 : Bool is_alt, is_param;
3327 : u32 nbBytes = 0;
3328 : if (! ipmpt) return GF_BAD_PARAM;
3329 : gf_bs_read_data(bs, (char*) ipmpt->IPMP_ToolID, 16);
3330 : is_alt = (Bool)gf_bs_read_int(bs, 1);
3331 : is_param = (Bool)gf_bs_read_int(bs, 1);
3332 : gf_bs_read_int(bs, 6);
3333 : nbBytes = 17;
3334 :
3335 : if (is_alt) {
3336 : u32 i;
3337 : ipmpt->num_alternate = gf_bs_read_int(bs, 8);
3338 : nbBytes += 1;
3339 : for (i=0; i<ipmpt->num_alternate; i++) {
3340 : if (nbBytes + 16 > DescSize) return GF_ODF_INVALID_DESCRIPTOR;
3341 : gf_bs_read_data(bs, (char*)ipmpt->specificToolID[i], 16);
3342 : nbBytes += 16;
3343 : }
3344 : }
3345 : if (nbBytes>DescSize) return GF_ODF_INVALID_DESCRIPTOR;
3346 :
3347 : if (is_param) { }
3348 :
3349 : if (nbBytes<DescSize) {
3350 : u32 s;
3351 : nbBytes += gf_ipmpx_array_size(bs, &s);
3352 : if (s>0xFFFFFF) return GF_ODF_INVALID_DESCRIPTOR;
3353 :
3354 : if (s) {
3355 : ipmpt->tool_url = (char*)gf_malloc(sizeof(char)*(s+1));
3356 : gf_bs_read_data(bs, ipmpt->tool_url, s);
3357 : ipmpt->tool_url[s] = 0;
3358 : nbBytes += s;
3359 : }
3360 : }
3361 :
3362 : if (nbBytes!=DescSize) return GF_NON_COMPLIANT_BITSTREAM;
3363 : return GF_OK;
3364 : }
3365 :
3366 :
3367 : GF_Err gf_odf_size_ipmp_tool(GF_IPMP_Tool *ipmpt, u32 *outSize)
3368 : {
3369 : if (!ipmpt) return GF_BAD_PARAM;
3370 : *outSize = 17;
3371 : if (ipmpt->num_alternate) *outSize += 1 + 16*ipmpt->num_alternate;
3372 :
3373 : if (ipmpt->tool_url) {
3374 : u32 s = (u32) strlen(ipmpt->tool_url);
3375 : *outSize += gf_odf_size_field_size(s) - 1 + s;
3376 : }
3377 : return GF_OK;
3378 : }
3379 :
3380 : GF_Err gf_odf_write_ipmp_tool(GF_BitStream *bs, GF_IPMP_Tool *ipmpt)
3381 : {
3382 : GF_Err e;
3383 : u32 size;
3384 : if (!ipmpt) return GF_BAD_PARAM;
3385 : e = gf_odf_size_descriptor((GF_Descriptor *)ipmpt, &size);
3386 : if (e) return e;
3387 : e = gf_odf_write_base_descriptor(bs, ipmpt->tag, size);
3388 : if (e) return e;
3389 :
3390 : gf_bs_write_data(bs, (char*)ipmpt->IPMP_ToolID, 16);
3391 : gf_bs_write_int(bs, ipmpt->num_alternate ? 1 : 0, 1);
3392 : gf_bs_write_int(bs, 0, 1);
3393 : gf_bs_write_int(bs, 0, 6);
3394 :
3395 : if (ipmpt->num_alternate) {
3396 : u32 i;
3397 : gf_bs_write_int(bs, ipmpt->num_alternate, 8);
3398 : for (i=0; i<ipmpt->num_alternate; i++) gf_bs_write_data(bs, (char*)ipmpt->specificToolID[i], 16);
3399 : }
3400 : if (ipmpt->tool_url) gf_ipmpx_write_array(bs, ipmpt->tool_url, (u32) strlen(ipmpt->tool_url));
3401 : return GF_OK;
3402 : }
3403 :
3404 : #endif /*GPAC_MINIMAL_ODF*/
|