Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Author: Romain Bouqueau, Jean Le Feuvre
5 : * Copyright (c) Romain Bouqueau 2012- Telecom Paris 2019-
6 : * All rights reserved
7 : *
8 : * Note: this development was kindly sponsorized by Vizion'R (http://vizionr.com)
9 : *
10 : * This file is part of GPAC / ISO Media File Format sub-project
11 : *
12 : * GPAC is free software; you can redistribute it and/or modify
13 : * it under the terms of the GNU Lesser General Public License as published by
14 : * the Free Software Foundation either version 2, or (at your option)
15 : * any later version.
16 : *
17 : * GPAC is distributed in the hope that it will be useful,
18 : * but WITHOUT ANY WARRANTY without even the implied warranty of
19 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 : * GNU Lesser General Public License for more details.
21 : *
22 : * You should have received a copy of the GNU Lesser General Public
23 : * License along with this library see the file COPYING. If not, write to
24 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25 : *
26 : */
27 :
28 : #include <gpac/internal/isomedia_dev.h>
29 :
30 : #ifndef GPAC_DISABLE_ISOM_ADOBE
31 :
32 : #ifndef GPAC_DISABLE_ISOM
33 :
34 : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
35 :
36 3 : void abst_box_del(GF_Box *s)
37 : {
38 : GF_AdobeBootstrapInfoBox *ptr = (GF_AdobeBootstrapInfoBox *)s;
39 3 : if (ptr == NULL) return;
40 :
41 3 : if (ptr->movie_identifier)
42 0 : gf_free(ptr->movie_identifier);
43 3 : if (ptr->drm_data)
44 0 : gf_free(ptr->drm_data);
45 3 : if (ptr->meta_data)
46 0 : gf_free(ptr->meta_data);
47 :
48 3 : while (gf_list_count(ptr->server_entry_table)) {
49 0 : gf_free(gf_list_get(ptr->server_entry_table, 0));
50 0 : gf_list_rem(ptr->server_entry_table, 0);
51 : }
52 3 : gf_list_del(ptr->server_entry_table);
53 :
54 6 : while (gf_list_count(ptr->quality_entry_table)) {
55 0 : gf_free(gf_list_get(ptr->quality_entry_table, 0));
56 0 : gf_list_rem(ptr->quality_entry_table, 0);
57 : }
58 3 : gf_list_del(ptr->quality_entry_table);
59 :
60 :
61 6 : while (gf_list_count(ptr->segment_run_table_entries)) {
62 0 : gf_isom_box_del((GF_Box *)gf_list_get(ptr->segment_run_table_entries, 0));
63 0 : gf_list_rem(ptr->segment_run_table_entries, 0);
64 : }
65 3 : gf_list_del(ptr->segment_run_table_entries);
66 :
67 6 : while (gf_list_count(ptr->fragment_run_table_entries)) {
68 0 : gf_isom_box_del((GF_Box *)gf_list_get(ptr->fragment_run_table_entries, 0));
69 0 : gf_list_rem(ptr->fragment_run_table_entries, 0);
70 : }
71 3 : gf_list_del(ptr->fragment_run_table_entries);
72 :
73 3 : gf_free(ptr);
74 : }
75 :
76 1 : GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs)
77 : {
78 : GF_AdobeBootstrapInfoBox *ptr = (GF_AdobeBootstrapInfoBox *)s;
79 : int i;
80 : u32 tmp_strsize;
81 : char *tmp_str;
82 : Bool zfound=GF_FALSE;
83 : GF_Err e = GF_OK;
84 :
85 1 : ISOM_DECREASE_SIZE(ptr, 25)
86 1 : ptr->bootstrapinfo_version = gf_bs_read_u32(bs);
87 1 : ptr->profile = gf_bs_read_int(bs, 2);
88 1 : ptr->live = gf_bs_read_int(bs, 1);
89 1 : ptr->update = gf_bs_read_int(bs, 1);
90 1 : ptr->reserved = gf_bs_read_int(bs, 4);
91 1 : ptr->time_scale = gf_bs_read_u32(bs);
92 1 : ptr->current_media_time = gf_bs_read_u64(bs);
93 1 : ptr->smpte_time_code_offset = gf_bs_read_u64(bs);
94 :
95 : i=0;
96 1 : if (ptr->size<8) return GF_ISOM_INVALID_FILE;
97 0 : tmp_strsize =(u32)ptr->size;
98 0 : tmp_str = gf_malloc(sizeof(char)*tmp_strsize);
99 0 : if (!tmp_str) return GF_OUT_OF_MEM;
100 : memset(tmp_str, 0, sizeof(char)*tmp_strsize);
101 :
102 0 : while (tmp_strsize) {
103 0 : ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, 1)
104 0 : tmp_str[i] = gf_bs_read_u8(bs);
105 0 : tmp_strsize--;
106 0 : if (!tmp_str[i]) {
107 : zfound = GF_TRUE;
108 : break;
109 : }
110 0 : i++;
111 : }
112 0 : if (!zfound) {
113 : e = GF_ISOM_INVALID_FILE;
114 : goto exit;
115 : }
116 0 : if (i) {
117 0 : ptr->movie_identifier = gf_strdup(tmp_str);
118 : }
119 :
120 0 : ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, 1)
121 0 : ptr->server_entry_count = gf_bs_read_u8(bs);
122 0 : for (i=0; i<ptr->server_entry_count; i++) {
123 : int j=0;
124 : zfound = GF_FALSE;
125 0 : tmp_strsize=(u32)ptr->size;
126 0 : while (tmp_strsize) {
127 0 : ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, 1)
128 0 : tmp_str[j] = gf_bs_read_u8(bs);
129 0 : tmp_strsize--;
130 0 : if (!tmp_str[j]) {
131 : zfound = GF_TRUE;
132 : break;
133 : }
134 0 : j++;
135 : }
136 0 : if (!zfound) {
137 : e = GF_ISOM_INVALID_FILE;
138 : goto exit;
139 : }
140 0 : if (j) {
141 0 : gf_list_insert(ptr->server_entry_table, gf_strdup(tmp_str), i);
142 : }
143 : }
144 0 : if (ptr->server_entry_count != gf_list_count(ptr->server_entry_table)) {
145 : e = GF_ISOM_INVALID_FILE;
146 : goto exit;
147 : }
148 :
149 0 : ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, 1)
150 0 : ptr->quality_entry_count = gf_bs_read_u8(bs);
151 0 : for (i=0; i<ptr->quality_entry_count; i++) {
152 : int j=0;
153 : zfound = GF_FALSE;
154 0 : tmp_strsize=(u32)ptr->size;
155 0 : while (tmp_strsize) {
156 0 : ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, 1)
157 0 : tmp_str[j] = gf_bs_read_u8(bs);
158 0 : tmp_strsize--;
159 0 : if (!tmp_str[j]) {
160 : zfound = GF_TRUE;
161 : break;
162 : }
163 0 : j++;
164 : }
165 :
166 0 : if (!zfound) {
167 : e = GF_ISOM_INVALID_FILE;
168 : goto exit;
169 : }
170 0 : if (j) {
171 0 : gf_list_insert(ptr->quality_entry_table, gf_strdup(tmp_str), i);
172 : }
173 : }
174 0 : if (ptr->quality_entry_count != gf_list_count(ptr->quality_entry_table)) {
175 : e = GF_ISOM_INVALID_FILE;
176 : goto exit;
177 : }
178 :
179 : i=0;
180 0 : tmp_strsize=(u32)ptr->size;
181 : zfound = GF_FALSE;
182 0 : while (tmp_strsize) {
183 0 : ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, 1)
184 0 : tmp_str[i] = gf_bs_read_u8(bs);
185 0 : tmp_strsize--;
186 0 : if (!tmp_str[i]) {
187 : zfound = GF_TRUE;
188 : break;
189 : }
190 0 : i++;
191 : }
192 0 : if (!zfound) {
193 : e = GF_ISOM_INVALID_FILE;
194 : goto exit;
195 : }
196 :
197 0 : if (i) {
198 0 : ptr->drm_data = gf_strdup(tmp_str);
199 : }
200 :
201 : i=0;
202 0 : tmp_strsize=(u32)ptr->size;
203 : zfound = GF_FALSE;
204 0 : while (tmp_strsize) {
205 0 : ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, 1)
206 0 : tmp_str[i] = gf_bs_read_u8(bs);
207 0 : tmp_strsize--;
208 0 : if (!tmp_str[i]) {
209 : zfound = GF_TRUE;
210 : break;
211 : }
212 0 : i++;
213 : }
214 0 : if (!zfound) {
215 : e = GF_ISOM_INVALID_FILE;
216 : goto exit;
217 : }
218 :
219 0 : if (i) {
220 0 : ptr->meta_data = gf_strdup(tmp_str);
221 : }
222 :
223 0 : ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, 1)
224 0 : ptr->segment_run_table_count = gf_bs_read_u8(bs);
225 0 : for (i=0; i<ptr->segment_run_table_count; i++) {
226 0 : GF_AdobeSegmentRunTableBox *asrt = NULL;
227 0 : e = gf_isom_box_parse((GF_Box **)&asrt, bs);
228 0 : if (e) {
229 0 : if (asrt) gf_isom_box_del((GF_Box*)asrt);
230 0 : goto exit;
231 : }
232 0 : gf_list_add(ptr->segment_run_table_entries, asrt);
233 : }
234 0 : if (ptr->segment_run_table_count != gf_list_count(ptr->segment_run_table_entries)) {
235 : e = GF_ISOM_INVALID_FILE;
236 : goto exit;
237 : }
238 :
239 0 : ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, 1)
240 0 : ptr->fragment_run_table_count = gf_bs_read_u8(bs);
241 0 : for (i=0; i<ptr->fragment_run_table_count; i++) {
242 0 : GF_AdobeFragmentRunTableBox *afrt = NULL;
243 0 : e = gf_isom_box_parse((GF_Box **)&afrt, bs);
244 0 : if (e) {
245 0 : if (afrt) gf_isom_box_del((GF_Box*)afrt);
246 0 : goto exit;
247 : }
248 0 : gf_list_add(ptr->fragment_run_table_entries, afrt);
249 : }
250 0 : if (ptr->fragment_run_table_count != gf_list_count(ptr->fragment_run_table_entries)) {
251 : e = GF_ISOM_INVALID_FILE;
252 0 : goto exit;
253 : }
254 :
255 0 : exit:
256 0 : gf_free(tmp_str);
257 0 : return e;
258 : }
259 :
260 3 : GF_Box *abst_box_new()
261 : {
262 6 : ISOM_DECL_BOX_ALLOC(GF_AdobeBootstrapInfoBox, GF_ISOM_BOX_TYPE_ABST);
263 3 : tmp->server_entry_table = gf_list_new();
264 3 : tmp->quality_entry_table = gf_list_new();
265 3 : tmp->segment_run_table_entries = gf_list_new();
266 3 : tmp->fragment_run_table_entries = gf_list_new();
267 3 : return (GF_Box *)tmp;
268 : }
269 :
270 : #ifndef GPAC_DISABLE_ISOM_WRITE
271 :
272 1 : GF_Err abst_box_write(GF_Box *s, GF_BitStream *bs)
273 : {
274 : GF_Err e;
275 : unsigned int i;
276 : GF_AdobeBootstrapInfoBox *ptr = (GF_AdobeBootstrapInfoBox *)s;
277 :
278 1 : e = gf_isom_full_box_write(s, bs);
279 1 : if (e) return e;
280 :
281 1 : gf_bs_write_u32(bs, ptr->bootstrapinfo_version);
282 1 : gf_bs_write_int(bs, ptr->profile, 2);
283 1 : gf_bs_write_int(bs, ptr->live, 1);
284 1 : gf_bs_write_int(bs, ptr->update, 1);
285 1 : gf_bs_write_int(bs, ptr->reserved, 4);
286 1 : gf_bs_write_u32(bs, ptr->time_scale);
287 1 : gf_bs_write_u64(bs, ptr->current_media_time);
288 1 : gf_bs_write_u64(bs, ptr->smpte_time_code_offset);
289 1 : if (ptr->movie_identifier)
290 0 : gf_bs_write_data(bs, ptr->movie_identifier, (u32)strlen(ptr->movie_identifier) + 1);
291 : else
292 1 : gf_bs_write_u8(bs, 0);
293 :
294 1 : gf_bs_write_u8(bs, ptr->server_entry_count);
295 1 : for (i=0; i<ptr->server_entry_count; i++) {
296 0 : char *str = (char*)gf_list_get(ptr->server_entry_table, i);
297 0 : gf_bs_write_data(bs, str, (u32)strlen(str) + 1);
298 : }
299 :
300 1 : gf_bs_write_u8(bs, ptr->quality_entry_count);
301 1 : for (i=0; i<ptr->quality_entry_count; i++) {
302 0 : char *str = (char*)gf_list_get(ptr->quality_entry_table, i);
303 0 : gf_bs_write_data(bs, str, (u32)strlen(str) + 1);
304 : }
305 :
306 1 : if (ptr->drm_data)
307 0 : gf_bs_write_data(bs, ptr->drm_data, (u32)strlen(ptr->drm_data) + 1);
308 : else
309 1 : gf_bs_write_u8(bs, 0);
310 :
311 1 : if (ptr->meta_data)
312 0 : gf_bs_write_data(bs, ptr->meta_data, (u32)strlen(ptr->meta_data) + 1);
313 : else
314 1 : gf_bs_write_u8(bs, 0);
315 :
316 1 : gf_bs_write_u8(bs, ptr->segment_run_table_count);
317 1 : for (i=0; i<ptr->segment_run_table_count; i++) {
318 0 : e = gf_isom_box_write((GF_Box *)gf_list_get(ptr->segment_run_table_entries, i), bs);
319 0 : if (e) return e;
320 : }
321 :
322 1 : gf_bs_write_u8(bs, ptr->fragment_run_table_count);
323 1 : for (i=0; i<ptr->fragment_run_table_count; i++) {
324 0 : e = gf_isom_box_write((GF_Box *)gf_list_get(ptr->fragment_run_table_entries, i), bs);
325 0 : if (e) return e;
326 : }
327 :
328 : return GF_OK;
329 : }
330 :
331 1 : GF_Err abst_box_size(GF_Box *s)
332 : {
333 : GF_Err e;
334 : u32 i;
335 : GF_AdobeBootstrapInfoBox *ptr = (GF_AdobeBootstrapInfoBox *)s;
336 :
337 2 : s->size += 25
338 1 : + (ptr->movie_identifier ? (strlen(ptr->movie_identifier) + 1) : 1)
339 1 : + 1;
340 :
341 1 : for (i=0; i<ptr->server_entry_count; i++)
342 0 : s->size += strlen(gf_list_get(ptr->server_entry_table, i)) + 1;
343 :
344 1 : s->size += 1;
345 :
346 1 : for (i=0; i<ptr->quality_entry_count; i++)
347 0 : s->size += strlen(gf_list_get(ptr->quality_entry_table, i)) + 1;
348 :
349 2 : s->size += (ptr->drm_data ? (strlen(ptr->drm_data) + 1) : 1)
350 1 : + (ptr->meta_data ? (strlen(ptr->meta_data) + 1) : 1)
351 : + 1;
352 :
353 1 : for (i=0; i<ptr->segment_run_table_count; i++) {
354 0 : GF_Box *box = (GF_Box *)gf_list_get(ptr->segment_run_table_entries, i);
355 0 : e = gf_isom_box_size(box);
356 0 : if (e) return e;
357 0 : s->size += box->size;
358 : }
359 :
360 1 : s->size += 1;
361 1 : for (i=0; i<ptr->fragment_run_table_count; i++) {
362 0 : GF_Box *box = (GF_Box *)gf_list_get(ptr->fragment_run_table_entries, i);
363 0 : e = gf_isom_box_size(box);
364 0 : if (e) return e;
365 0 : s->size += box->size;
366 : }
367 : return GF_OK;
368 : }
369 :
370 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
371 :
372 3 : void afra_box_del(GF_Box *s)
373 : {
374 : GF_AdobeFragRandomAccessBox *ptr = (GF_AdobeFragRandomAccessBox *)s;
375 3 : if (ptr == NULL) return;
376 :
377 3 : while (gf_list_count(ptr->local_access_entries)) {
378 0 : gf_free(gf_list_get(ptr->local_access_entries, 0));
379 0 : gf_list_rem(ptr->local_access_entries, 0);
380 : }
381 3 : gf_list_del(ptr->local_access_entries);
382 :
383 6 : while (gf_list_count(ptr->global_access_entries)) {
384 0 : gf_free(gf_list_get(ptr->global_access_entries, 0));
385 0 : gf_list_rem(ptr->global_access_entries, 0);
386 : }
387 3 : gf_list_del(ptr->global_access_entries);
388 :
389 3 : gf_free(ptr);
390 : }
391 :
392 1 : GF_Err afra_box_read(GF_Box *s, GF_BitStream *bs)
393 : {
394 : unsigned int i;
395 : GF_AdobeFragRandomAccessBox *ptr = (GF_AdobeFragRandomAccessBox *)s;
396 :
397 1 : ISOM_DECREASE_SIZE(ptr, 9)
398 1 : ptr->long_ids = gf_bs_read_int(bs, 1);
399 1 : ptr->long_offsets = gf_bs_read_int(bs, 1);
400 1 : ptr->global_entries = gf_bs_read_int(bs, 1);
401 1 : ptr->reserved = gf_bs_read_int(bs, 5);
402 1 : ptr->time_scale = gf_bs_read_u32(bs);
403 :
404 1 : ptr->entry_count = gf_bs_read_u32(bs);
405 1 : if (ptr->size / ( (ptr->long_offsets ? 16 : 12) ) < ptr->entry_count)
406 : return GF_ISOM_INVALID_FILE;
407 :
408 0 : for (i=0; i<ptr->entry_count; i++) {
409 0 : GF_AfraEntry *ae = gf_malloc(sizeof(GF_AfraEntry));
410 0 : if (!ae) return GF_OUT_OF_MEM;
411 :
412 0 : ISOM_DECREASE_SIZE(ptr, 8)
413 0 : ae->time = gf_bs_read_u64(bs);
414 0 : if (ptr->long_offsets) {
415 0 : ISOM_DECREASE_SIZE(ptr, 8)
416 0 : ae->offset = gf_bs_read_u64(bs);
417 : } else {
418 0 : ISOM_DECREASE_SIZE(ptr, 4)
419 0 : ae->offset = gf_bs_read_u32(bs);
420 : }
421 :
422 0 : gf_list_insert(ptr->local_access_entries, ae, i);
423 : }
424 :
425 1 : if (ptr->global_entries) {
426 0 : ISOM_DECREASE_SIZE(ptr, 4)
427 0 : ptr->global_entry_count = gf_bs_read_u32(bs);
428 0 : for (i=0; i<ptr->global_entry_count; i++) {
429 0 : GF_GlobalAfraEntry *ae = gf_malloc(sizeof(GF_GlobalAfraEntry));
430 0 : if (!ae) return GF_OUT_OF_MEM;
431 0 : ISOM_DECREASE_SIZE(ptr, 8)
432 0 : ae->time = gf_bs_read_u64(bs);
433 0 : if (ptr->long_ids) {
434 0 : ISOM_DECREASE_SIZE(ptr, 8)
435 0 : ae->segment = gf_bs_read_u32(bs);
436 0 : ae->fragment = gf_bs_read_u32(bs);
437 : } else {
438 0 : ISOM_DECREASE_SIZE(ptr, 4)
439 0 : ae->segment = gf_bs_read_u16(bs);
440 0 : ae->fragment = gf_bs_read_u16(bs);
441 : }
442 0 : if (ptr->long_offsets) {
443 0 : ISOM_DECREASE_SIZE(ptr, 16)
444 0 : ae->afra_offset = gf_bs_read_u64(bs);
445 0 : ae->offset_from_afra = gf_bs_read_u64(bs);
446 : } else {
447 0 : ISOM_DECREASE_SIZE(ptr, 8)
448 0 : ae->afra_offset = gf_bs_read_u32(bs);
449 0 : ae->offset_from_afra = gf_bs_read_u32(bs);
450 : }
451 :
452 0 : gf_list_insert(ptr->global_access_entries, ae, i);
453 : }
454 : }
455 :
456 : return GF_OK;
457 : }
458 :
459 3 : GF_Box *afra_box_new()
460 : {
461 6 : ISOM_DECL_BOX_ALLOC(GF_AdobeFragRandomAccessBox, GF_ISOM_BOX_TYPE_AFRA);
462 3 : tmp->local_access_entries = gf_list_new();
463 3 : tmp->global_access_entries = gf_list_new();
464 3 : return (GF_Box *)tmp;
465 : }
466 :
467 : #ifndef GPAC_DISABLE_ISOM_WRITE
468 :
469 1 : GF_Err afra_box_write(GF_Box *s, GF_BitStream *bs)
470 : {
471 : GF_Err e;
472 : unsigned int i;
473 : GF_AdobeFragRandomAccessBox *ptr = (GF_AdobeFragRandomAccessBox *)s;
474 :
475 1 : e = gf_isom_full_box_write(s, bs);
476 1 : if (e) return e;
477 :
478 1 : gf_bs_write_int(bs, ptr->long_ids, 1);
479 1 : gf_bs_write_int(bs, ptr->long_offsets, 1);
480 1 : gf_bs_write_int(bs, ptr->global_entries, 1);
481 1 : gf_bs_write_int(bs, 0, 5);
482 1 : gf_bs_write_u32(bs, ptr->time_scale);
483 :
484 1 : gf_bs_write_u32(bs, ptr->entry_count);
485 1 : for (i=0; i<ptr->entry_count; i++) {
486 0 : GF_AfraEntry *ae = (GF_AfraEntry *)gf_list_get(ptr->local_access_entries, i);
487 0 : gf_bs_write_u64(bs, ae->time);
488 0 : if (ptr->long_offsets)
489 0 : gf_bs_write_u64(bs, ae->offset);
490 : else
491 0 : gf_bs_write_u32(bs, (u32)ae->offset);
492 : }
493 :
494 1 : if (ptr->global_entries) {
495 0 : gf_bs_write_u32(bs, ptr->global_entry_count);
496 0 : for (i=0; i<ptr->global_entry_count; i++) {
497 0 : GF_GlobalAfraEntry *gae = (GF_GlobalAfraEntry *)gf_list_get(ptr->global_access_entries, i);
498 0 : gf_bs_write_u64(bs, gae->time);
499 0 : if (ptr->long_ids) {
500 0 : gf_bs_write_u32(bs, gae->segment);
501 0 : gf_bs_write_u32(bs, gae->fragment);
502 : } else {
503 0 : gf_bs_write_u16(bs, (u16)gae->segment);
504 0 : gf_bs_write_u16(bs, (u16)gae->fragment);
505 : }
506 0 : if (ptr->long_offsets) {
507 0 : gf_bs_write_u64(bs, gae->afra_offset);
508 0 : gf_bs_write_u64(bs, gae->offset_from_afra);
509 : } else {
510 0 : gf_bs_write_u32(bs, (u32)gae->afra_offset);
511 0 : gf_bs_write_u32(bs, (u32)gae->offset_from_afra);
512 : }
513 : }
514 : }
515 :
516 : return GF_OK;
517 : }
518 :
519 :
520 1 : GF_Err afra_box_size(GF_Box *s)
521 : {
522 : GF_AdobeFragRandomAccessBox *ptr = (GF_AdobeFragRandomAccessBox *)s;
523 :
524 2 : s->size += 9
525 1 : + ptr->entry_count * (ptr->long_offsets ? 16 : 12)
526 1 : + (ptr->global_entries ? 4 + ptr->global_entry_count * (4 + (ptr->long_offsets ? 16 : 8) + (ptr->long_ids ? 8 : 4)) : 0);
527 :
528 1 : return GF_OK;
529 : }
530 :
531 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
532 :
533 3 : void asrt_box_del(GF_Box *s)
534 : {
535 : GF_AdobeSegmentRunTableBox *ptr = (GF_AdobeSegmentRunTableBox *)s;
536 3 : if (ptr == NULL) return;
537 :
538 3 : while (gf_list_count(ptr->quality_segment_url_modifiers)) {
539 0 : gf_free(gf_list_get(ptr->quality_segment_url_modifiers, 0));
540 0 : gf_list_rem(ptr->quality_segment_url_modifiers, 0);
541 : }
542 3 : gf_list_del(ptr->quality_segment_url_modifiers);
543 :
544 6 : while (gf_list_count(ptr->segment_run_entry_table)) {
545 0 : gf_free(gf_list_get(ptr->segment_run_entry_table, 0));
546 0 : gf_list_rem(ptr->segment_run_entry_table, 0);
547 : }
548 3 : gf_list_del(ptr->segment_run_entry_table);
549 :
550 3 : gf_free(ptr);
551 : }
552 :
553 1 : GF_Err asrt_box_read(GF_Box *s, GF_BitStream *bs)
554 : {
555 : unsigned int i;
556 : GF_AdobeSegmentRunTableBox *ptr = (GF_AdobeSegmentRunTableBox *)s;
557 :
558 1 : ISOM_DECREASE_SIZE(ptr, 1)
559 1 : ptr->quality_entry_count = gf_bs_read_u8(bs);
560 1 : if (ptr->size < ptr->quality_entry_count)
561 : return GF_ISOM_INVALID_FILE;
562 :
563 0 : for (i=0; i<ptr->quality_entry_count; i++) {
564 : int j=0;
565 0 : u32 tmp_strsize=(u32)ptr->size;
566 0 : char *tmp_str = (char*) gf_malloc(tmp_strsize);
567 0 : if (!tmp_str) return GF_OUT_OF_MEM;
568 0 : while (tmp_strsize) {
569 0 : tmp_str[j] = gf_bs_read_u8(bs);
570 0 : tmp_strsize--;
571 0 : if (!tmp_str[j])
572 : break;
573 0 : j++;
574 : }
575 0 : ISOM_DECREASE_SIZE(ptr, j)
576 0 : gf_list_insert(ptr->quality_segment_url_modifiers, tmp_str, i);
577 : }
578 :
579 1 : ISOM_DECREASE_SIZE(ptr, 4)
580 1 : ptr->segment_run_entry_count = gf_bs_read_u32(bs);
581 1 : if (ptr->size / 8 < ptr->segment_run_entry_count)
582 : return GF_ISOM_INVALID_FILE;
583 :
584 0 : for (i=0; i<ptr->segment_run_entry_count; i++) {
585 0 : GF_AdobeSegmentRunEntry *sre = gf_malloc(sizeof(GF_AdobeSegmentRunEntry));
586 0 : if (!sre) return GF_OUT_OF_MEM;
587 0 : ISOM_DECREASE_SIZE(ptr, 8)
588 0 : sre->first_segment = gf_bs_read_u32(bs);
589 0 : sre->fragment_per_segment = gf_bs_read_u32(bs);
590 0 : gf_list_insert(ptr->segment_run_entry_table, sre, i);
591 : }
592 :
593 : return GF_OK;
594 : }
595 :
596 3 : GF_Box *asrt_box_new()
597 : {
598 6 : ISOM_DECL_BOX_ALLOC(GF_AdobeSegmentRunTableBox, GF_ISOM_BOX_TYPE_ASRT);
599 3 : tmp->quality_segment_url_modifiers = gf_list_new();
600 3 : tmp->segment_run_entry_table = gf_list_new();
601 3 : return (GF_Box *)tmp;
602 : }
603 :
604 : #ifndef GPAC_DISABLE_ISOM_WRITE
605 :
606 1 : GF_Err asrt_box_write(GF_Box *s, GF_BitStream *bs)
607 : {
608 : GF_Err e;
609 : unsigned int i;
610 : GF_AdobeSegmentRunTableBox *ptr = (GF_AdobeSegmentRunTableBox *)s;
611 :
612 1 : e = gf_isom_full_box_write(s, bs);
613 1 : if (e) return e;
614 :
615 1 : gf_bs_write_u8(bs, ptr->quality_entry_count);
616 1 : for (i=0; i<ptr->quality_entry_count; i++) {
617 0 : char *str = (char*)gf_list_get(ptr->quality_segment_url_modifiers, i);
618 0 : gf_bs_write_data(bs, str, (u32)strlen(str) + 1);
619 : }
620 :
621 1 : gf_bs_write_u32(bs, ptr->segment_run_entry_count);
622 1 : for (i=0; i<ptr->segment_run_entry_count; i++) {
623 0 : GF_AdobeSegmentRunEntry *sre = (GF_AdobeSegmentRunEntry *)gf_list_get(ptr->segment_run_entry_table, i);
624 0 : gf_bs_write_u32(bs, sre->first_segment);
625 0 : gf_bs_write_u32(bs, sre->fragment_per_segment);
626 : }
627 :
628 : return GF_OK;
629 : }
630 :
631 :
632 1 : GF_Err asrt_box_size(GF_Box *s)
633 : {
634 : int i;
635 : GF_AdobeSegmentRunTableBox *ptr = (GF_AdobeSegmentRunTableBox *)s;
636 :
637 1 : s->size += 5;
638 :
639 1 : for (i=0; i<ptr->quality_entry_count; i++)
640 0 : s->size += strlen(gf_list_get(ptr->quality_segment_url_modifiers, i)) + 1;
641 :
642 1 : s->size += ptr->segment_run_entry_count * sizeof(GF_AdobeSegmentRunEntry);
643 :
644 1 : return GF_OK;
645 : }
646 :
647 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
648 :
649 3 : void afrt_box_del(GF_Box *s)
650 : {
651 : GF_AdobeFragmentRunTableBox *ptr = (GF_AdobeFragmentRunTableBox *)s;
652 3 : if (ptr == NULL) return;
653 :
654 3 : while (gf_list_count(ptr->quality_segment_url_modifiers)) {
655 0 : gf_free(gf_list_get(ptr->quality_segment_url_modifiers, 0));
656 0 : gf_list_rem(ptr->quality_segment_url_modifiers, 0);
657 : }
658 3 : gf_list_del(ptr->quality_segment_url_modifiers);
659 :
660 6 : while (gf_list_count(ptr->fragment_run_entry_table)) {
661 0 : gf_free(gf_list_get(ptr->fragment_run_entry_table, 0));
662 0 : gf_list_rem(ptr->fragment_run_entry_table, 0);
663 : }
664 3 : gf_list_del(ptr->fragment_run_entry_table);
665 :
666 3 : gf_free(ptr);
667 : }
668 :
669 1 : GF_Err afrt_box_read(GF_Box *s, GF_BitStream *bs)
670 : {
671 : unsigned int i;
672 : GF_AdobeFragmentRunTableBox *ptr = (GF_AdobeFragmentRunTableBox *)s;
673 :
674 1 : ISOM_DECREASE_SIZE(ptr, 5)
675 1 : ptr->timescale = gf_bs_read_u32(bs);
676 :
677 1 : ptr->quality_entry_count = gf_bs_read_u8(bs);
678 1 : if (ptr->size < ptr->quality_entry_count)
679 : return GF_ISOM_INVALID_FILE;
680 :
681 0 : for (i=0; i<ptr->quality_entry_count; i++) {
682 : int j=0;
683 0 : u32 tmp_strsize=(u32)ptr->size-8;
684 0 : char *tmp_str = (char*) gf_malloc(tmp_strsize);
685 0 : if (!tmp_str) return GF_OUT_OF_MEM;
686 0 : while (tmp_strsize) {
687 0 : tmp_str[j] = gf_bs_read_u8(bs);
688 0 : tmp_strsize--;
689 0 : if (!tmp_str[j])
690 : break;
691 0 : j++;
692 : }
693 0 : ISOM_DECREASE_SIZE(ptr, j)
694 0 : gf_list_insert(ptr->quality_segment_url_modifiers, tmp_str, i);
695 : }
696 :
697 1 : ptr->fragment_run_entry_count = gf_bs_read_u32(bs);
698 1 : if (ptr->size / 16 < ptr->fragment_run_entry_count)
699 : return GF_ISOM_INVALID_FILE;
700 0 : for (i=0; i<ptr->fragment_run_entry_count; i++) {
701 0 : GF_AdobeFragmentRunEntry *fre = gf_malloc(sizeof(GF_AdobeFragmentRunEntry));
702 0 : if (!fre) return GF_OUT_OF_MEM;
703 0 : ISOM_DECREASE_SIZE(ptr, 16)
704 0 : fre->first_fragment = gf_bs_read_u32(bs);
705 0 : fre->first_fragment_timestamp = gf_bs_read_u64(bs);
706 0 : fre->fragment_duration = gf_bs_read_u32(bs);
707 0 : if (!fre->fragment_duration) {
708 0 : ISOM_DECREASE_SIZE(ptr, 1)
709 0 : fre->discontinuity_indicator = gf_bs_read_u8(bs);
710 : }
711 0 : gf_list_insert(ptr->fragment_run_entry_table, fre, i);
712 : }
713 :
714 : return GF_OK;
715 : }
716 :
717 3 : GF_Box *afrt_box_new()
718 : {
719 6 : ISOM_DECL_BOX_ALLOC(GF_AdobeFragmentRunTableBox, GF_ISOM_BOX_TYPE_AFRT);
720 3 : tmp->quality_segment_url_modifiers = gf_list_new();
721 3 : tmp->fragment_run_entry_table = gf_list_new();
722 3 : return (GF_Box *)tmp;
723 : }
724 :
725 : #ifndef GPAC_DISABLE_ISOM_WRITE
726 :
727 1 : GF_Err afrt_box_write(GF_Box *s, GF_BitStream *bs)
728 : {
729 : GF_Err e;
730 : unsigned int i;
731 : GF_AdobeFragmentRunTableBox *ptr = (GF_AdobeFragmentRunTableBox *)s;
732 :
733 1 : e = gf_isom_full_box_write(s, bs);
734 1 : if (e) return e;
735 :
736 1 : gf_bs_write_u32(bs, ptr->timescale);
737 1 : gf_bs_write_u8(bs, ptr->quality_entry_count);
738 1 : for (i=0; i<ptr->quality_entry_count; i++) {
739 0 : char *str = (char*)gf_list_get(ptr->quality_segment_url_modifiers, i);
740 0 : gf_bs_write_data(bs, str, (u32)strlen(str) + 1);
741 : }
742 :
743 1 : gf_bs_write_u32(bs, ptr->fragment_run_entry_count);
744 1 : for (i=0; i<ptr->fragment_run_entry_count; i++) {
745 0 : GF_AdobeFragmentRunEntry *fre = (GF_AdobeFragmentRunEntry *)gf_list_get(ptr->fragment_run_entry_table, i);
746 0 : gf_bs_write_u32(bs, fre->first_fragment);
747 0 : gf_bs_write_u64(bs, fre->first_fragment_timestamp);
748 0 : gf_bs_write_u32(bs, fre->fragment_duration);
749 0 : if (!fre->fragment_duration)
750 0 : gf_bs_write_u8(bs, fre->discontinuity_indicator);
751 : }
752 :
753 : return GF_OK;
754 : }
755 :
756 :
757 1 : GF_Err afrt_box_size(GF_Box *s)
758 : {
759 : u32 i;
760 : GF_AdobeFragmentRunTableBox *ptr = (GF_AdobeFragmentRunTableBox *)s;
761 :
762 1 : s->size += 5;
763 :
764 1 : for (i=0; i<ptr->quality_entry_count; i++)
765 0 : s->size += strlen(gf_list_get(ptr->quality_segment_url_modifiers, i)) + 1;
766 :
767 1 : s->size += 4;
768 :
769 1 : for (i=0; i<ptr->fragment_run_entry_count; i++) {
770 0 : GF_AdobeFragmentRunEntry *fre = (GF_AdobeFragmentRunEntry *)gf_list_get(ptr->fragment_run_entry_table, i);
771 0 : if (fre->fragment_duration)
772 0 : s->size += 16;
773 : else
774 0 : s->size += 17;
775 : }
776 :
777 1 : return GF_OK;
778 : }
779 :
780 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
781 :
782 : #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
783 :
784 : #endif /*GPAC_DISABLE_ISOM*/
785 :
786 : #endif /*GPAC_DISABLE_ISOM_ADOBE*/
|