Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre, Cyril Concolato
5 : * Copyright (c) Telecom ParisTech 2005-2021
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / ISO Media File Format 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/isomedia_dev.h>
27 :
28 : #ifndef GPAC_DISABLE_ISOM
29 :
30 : /* ProtectionInfo Box */
31 1137 : GF_Box *sinf_box_new()
32 : {
33 2274 : ISOM_DECL_BOX_ALLOC(GF_ProtectionSchemeInfoBox, GF_ISOM_BOX_TYPE_SINF);
34 1137 : return (GF_Box *)tmp;
35 : }
36 :
37 1137 : void sinf_box_del(GF_Box *s)
38 : {
39 1137 : gf_free(s);
40 1137 : }
41 :
42 2591 : GF_Err sinf_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
43 : {
44 : GF_ProtectionSchemeInfoBox *ptr = (GF_ProtectionSchemeInfoBox *)s;
45 2591 : switch (a->type) {
46 856 : case GF_ISOM_BOX_TYPE_FRMA:
47 856 : BOX_FIELD_ASSIGN(original_format, GF_OriginalFormatBox)
48 856 : break;
49 879 : case GF_ISOM_BOX_TYPE_SCHM:
50 879 : BOX_FIELD_ASSIGN(scheme_type, GF_SchemeTypeBox)
51 879 : break;
52 856 : case GF_ISOM_BOX_TYPE_SCHI:
53 856 : BOX_FIELD_ASSIGN(info, GF_SchemeInformationBox)
54 856 : break;
55 : }
56 : return GF_OK;
57 : }
58 :
59 881 : GF_Err sinf_box_read(GF_Box *s, GF_BitStream *bs)
60 : {
61 881 : return gf_isom_box_array_read(s, bs);
62 : }
63 :
64 : #ifndef GPAC_DISABLE_ISOM_WRITE
65 486 : GF_Err sinf_box_write(GF_Box *s, GF_BitStream *bs)
66 : {
67 486 : return gf_isom_box_write_header(s, bs);
68 : }
69 :
70 770 : GF_Err sinf_box_size(GF_Box *s)
71 : {
72 770 : u32 pos=0;
73 : GF_ProtectionSchemeInfoBox *ptr = (GF_ProtectionSchemeInfoBox *)s;
74 770 : gf_isom_check_position(s, (GF_Box *)ptr->original_format, &pos);
75 770 : gf_isom_check_position(s, (GF_Box *)ptr->scheme_type, &pos);
76 770 : gf_isom_check_position(s, (GF_Box *)ptr->info, &pos);
77 770 : return GF_OK;
78 : }
79 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
80 :
81 : /* OriginalFormat Box */
82 1181 : GF_Box *frma_box_new()
83 : {
84 2362 : ISOM_DECL_BOX_ALLOC(GF_OriginalFormatBox, GF_ISOM_BOX_TYPE_FRMA);
85 1181 : return (GF_Box *)tmp;
86 : }
87 :
88 1181 : void frma_box_del(GF_Box *s)
89 : {
90 : GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
91 1181 : if (ptr == NULL) return;
92 1181 : gf_free(ptr);
93 : }
94 :
95 947 : GF_Err frma_box_read(GF_Box *s, GF_BitStream *bs)
96 : {
97 : GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
98 947 : ISOM_DECREASE_SIZE(ptr, 4);
99 947 : ptr->data_format = gf_bs_read_u32(bs);
100 947 : return GF_OK;
101 : }
102 :
103 : #ifndef GPAC_DISABLE_ISOM_WRITE
104 528 : GF_Err frma_box_write(GF_Box *s, GF_BitStream *bs)
105 : {
106 : GF_Err e;
107 : GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
108 528 : if (!s) return GF_BAD_PARAM;
109 528 : e = gf_isom_box_write_header(s, bs);
110 528 : if (e) return e;
111 528 : gf_bs_write_u32(bs, ptr->data_format);
112 528 : return GF_OK;
113 : }
114 :
115 816 : GF_Err frma_box_size(GF_Box *s)
116 : {
117 : GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
118 816 : ptr->size += 4;
119 816 : return GF_OK;
120 : }
121 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
122 :
123 : /* SchemeType Box */
124 1134 : GF_Box *schm_box_new()
125 : {
126 2268 : ISOM_DECL_BOX_ALLOC(GF_SchemeTypeBox, GF_ISOM_BOX_TYPE_SCHM);
127 1134 : return (GF_Box *)tmp;
128 : }
129 :
130 1134 : void schm_box_del(GF_Box *s)
131 : {
132 : GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *)s;
133 1134 : if (ptr == NULL) return;
134 1134 : if (ptr->URI) gf_free(ptr->URI);
135 1134 : gf_free(ptr);
136 : }
137 :
138 880 : GF_Err schm_box_read(GF_Box *s, GF_BitStream *bs)
139 : {
140 : GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *)s;
141 :
142 880 : ISOM_DECREASE_SIZE(ptr, 8);
143 880 : ptr->scheme_type = gf_bs_read_u32(bs);
144 880 : ptr->scheme_version = gf_bs_read_u32(bs);
145 :
146 880 : if (ptr->size && (ptr->flags & 0x000001)) {
147 42 : u32 len = (u32) (ptr->size);
148 42 : ptr->URI = (char*)gf_malloc(sizeof(char)*len);
149 42 : if (!ptr->URI) return GF_OUT_OF_MEM;
150 42 : gf_bs_read_data(bs, ptr->URI, len);
151 : }
152 : return GF_OK;
153 : }
154 :
155 : #ifndef GPAC_DISABLE_ISOM_WRITE
156 485 : GF_Err schm_box_write(GF_Box *s, GF_BitStream *bs)
157 : {
158 : GF_Err e;
159 : GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *) s;
160 485 : if (!s) return GF_BAD_PARAM;
161 485 : e = gf_isom_full_box_write(s, bs);
162 485 : if (e) return e;
163 485 : gf_bs_write_u32(bs, ptr->scheme_type);
164 485 : gf_bs_write_u32(bs, ptr->scheme_version);
165 485 : if (ptr->flags & 0x000001) {
166 33 : if (ptr->URI)
167 33 : gf_bs_write_data(bs, ptr->URI, (u32) strlen(ptr->URI)+1);
168 : else
169 0 : gf_bs_write_u8(bs, 0);
170 : }
171 : return GF_OK;
172 : }
173 :
174 769 : GF_Err schm_box_size(GF_Box *s)
175 : {
176 : GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *) s;
177 769 : if (!s) return GF_BAD_PARAM;
178 769 : ptr->size += 8;
179 769 : if (ptr->flags & 0x000001) ptr->size += 1 + (ptr->URI ? strlen(ptr->URI) : 0);
180 : return GF_OK;
181 : }
182 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
183 :
184 : /* SchemeInformation Box */
185 1088 : GF_Box *schi_box_new()
186 : {
187 2176 : ISOM_DECL_BOX_ALLOC(GF_SchemeInformationBox, GF_ISOM_BOX_TYPE_SCHI);
188 1088 : return (GF_Box *)tmp;
189 : }
190 :
191 1088 : void schi_box_del(GF_Box *s)
192 : {
193 1088 : gf_free(s);
194 1088 : }
195 :
196 889 : GF_Err schi_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
197 : {
198 : GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s;
199 889 : switch (a->type) {
200 42 : case GF_ISOM_BOX_TYPE_IKMS:
201 42 : BOX_FIELD_ASSIGN(ikms, GF_ISMAKMSBox)
202 42 : return GF_OK;
203 42 : case GF_ISOM_BOX_TYPE_ISFM:
204 42 : BOX_FIELD_ASSIGN(isfm, GF_ISMASampleFormatBox)
205 42 : return GF_OK;
206 0 : case GF_ISOM_BOX_TYPE_ISLT:
207 0 : BOX_FIELD_ASSIGN(islt, GF_ISMACrypSaltBox)
208 0 : return GF_OK;
209 0 : case GF_ISOM_BOX_TYPE_ODKM:
210 0 : BOX_FIELD_ASSIGN(odkm, GF_OMADRMKMSBox)
211 0 : return GF_OK;
212 777 : case GF_ISOM_BOX_TYPE_TENC:
213 777 : BOX_FIELD_ASSIGN(tenc, GF_TrackEncryptionBox)
214 777 : return GF_OK;
215 25 : case GF_ISOM_BOX_TYPE_ADKM:
216 25 : BOX_FIELD_ASSIGN(adkm, GF_AdobeDRMKeyManagementSystemBox)
217 25 : return GF_OK;
218 3 : case GF_ISOM_BOX_TYPE_UUID:
219 3 : if (((GF_UUIDBox*)a)->internal_4cc==GF_ISOM_BOX_UUID_TENC) {
220 3 : BOX_FIELD_ASSIGN(piff_tenc, GF_PIFFTrackEncryptionBox)
221 3 : return GF_OK;
222 : } else {
223 : return GF_OK;
224 : }
225 : }
226 : return GF_OK;
227 : }
228 :
229 857 : GF_Err schi_box_read(GF_Box *s, GF_BitStream *bs)
230 : {
231 857 : return gf_isom_box_array_read(s, bs);
232 : }
233 :
234 : #ifndef GPAC_DISABLE_ISOM_WRITE
235 462 : GF_Err schi_box_write(GF_Box *s, GF_BitStream *bs)
236 : {
237 462 : return gf_isom_box_write_header(s, bs);
238 : }
239 :
240 700 : GF_Err schi_box_size(GF_Box *s)
241 : {
242 700 : u32 pos=0;
243 : GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s;
244 :
245 700 : gf_isom_check_position(s, (GF_Box *)ptr->ikms, &pos);
246 700 : gf_isom_check_position(s, (GF_Box *)ptr->isfm, &pos);
247 700 : gf_isom_check_position(s, (GF_Box *)ptr->islt, &pos);
248 700 : gf_isom_check_position(s, (GF_Box *)ptr->odkm, &pos);
249 700 : gf_isom_check_position(s, (GF_Box *)ptr->tenc, &pos);
250 700 : gf_isom_check_position(s, (GF_Box *)ptr->adkm, &pos);
251 700 : gf_isom_check_position(s, (GF_Box *)ptr->piff_tenc, &pos);
252 700 : return GF_OK;
253 : }
254 :
255 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
256 :
257 : /* ISMAKMS Box */
258 56 : GF_Box *iKMS_box_new()
259 : {
260 112 : ISOM_DECL_BOX_ALLOC(GF_ISMAKMSBox, GF_ISOM_BOX_TYPE_IKMS);
261 56 : return (GF_Box *)tmp;
262 : }
263 :
264 56 : void iKMS_box_del(GF_Box *s)
265 : {
266 : GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
267 56 : if (ptr == NULL) return;
268 56 : if (ptr->URI) gf_free(ptr->URI);
269 56 : gf_free(ptr);
270 : }
271 :
272 43 : GF_Err iKMS_box_read(GF_Box *s, GF_BitStream *bs)
273 : {
274 : u32 len;
275 : GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
276 :
277 43 : len = (u32) (ptr->size);
278 43 : ptr->URI = (char*) gf_malloc(sizeof(char)*len);
279 43 : if (!ptr->URI) return GF_OUT_OF_MEM;
280 43 : gf_bs_read_data(bs, ptr->URI, len);
281 43 : return GF_OK;
282 : }
283 :
284 : #ifndef GPAC_DISABLE_ISOM_WRITE
285 34 : GF_Err iKMS_box_write(GF_Box *s, GF_BitStream *bs)
286 : {
287 : GF_Err e;
288 : GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
289 34 : if (!s) return GF_BAD_PARAM;
290 34 : e = gf_isom_full_box_write(s, bs);
291 34 : if (e) return e;
292 34 : if (ptr->URI)
293 33 : gf_bs_write_data(bs, ptr->URI, (u32) strlen(ptr->URI));
294 34 : gf_bs_write_u8(bs, 0);
295 34 : return GF_OK;
296 : }
297 :
298 66 : GF_Err iKMS_box_size(GF_Box *s)
299 : {
300 : GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
301 66 : ptr->size += (ptr->URI ? strlen(ptr->URI) : 0) + 1;
302 66 : return GF_OK;
303 : }
304 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
305 :
306 : /* ISMASampleFormat Box */
307 59 : GF_Box *iSFM_box_new()
308 : {
309 118 : ISOM_DECL_BOX_ALLOC(GF_ISMASampleFormatBox, GF_ISOM_BOX_TYPE_ISFM);
310 59 : return (GF_Box *)tmp;
311 : }
312 :
313 59 : void iSFM_box_del(GF_Box *s)
314 : {
315 : GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
316 59 : if (ptr == NULL) return;
317 59 : gf_free(ptr);
318 : }
319 :
320 :
321 44 : GF_Err iSFM_box_read(GF_Box *s, GF_BitStream *bs)
322 : {
323 : GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
324 :
325 44 : ISOM_DECREASE_SIZE(ptr, 3);
326 44 : ptr->selective_encryption = gf_bs_read_int(bs, 1);
327 44 : gf_bs_read_int(bs, 7);
328 44 : ptr->key_indicator_length = gf_bs_read_u8(bs);
329 44 : ptr->IV_length = gf_bs_read_u8(bs);
330 44 : return GF_OK;
331 : }
332 :
333 : #ifndef GPAC_DISABLE_ISOM_WRITE
334 35 : GF_Err iSFM_box_write(GF_Box *s, GF_BitStream *bs)
335 : {
336 : GF_Err e;
337 : GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
338 35 : if (!s) return GF_BAD_PARAM;
339 35 : e = gf_isom_full_box_write(s, bs);
340 35 : if (e) return e;
341 35 : gf_bs_write_int(bs, ptr->selective_encryption, 1);
342 35 : gf_bs_write_int(bs, 0, 7);
343 35 : gf_bs_write_u8(bs, ptr->key_indicator_length);
344 35 : gf_bs_write_u8(bs, ptr->IV_length);
345 35 : return GF_OK;
346 : }
347 :
348 67 : GF_Err iSFM_box_size(GF_Box *s)
349 : {
350 : GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
351 67 : ptr->size += 3;
352 67 : return GF_OK;
353 : }
354 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
355 :
356 : /* ISMASampleFormat Box */
357 3 : GF_Box *iSLT_box_new()
358 : {
359 6 : ISOM_DECL_BOX_ALLOC(GF_ISMACrypSaltBox, GF_ISOM_BOX_TYPE_ISLT);
360 3 : return (GF_Box *)tmp;
361 : }
362 :
363 3 : void iSLT_box_del(GF_Box *s)
364 : {
365 : GF_ISMACrypSaltBox *ptr = (GF_ISMACrypSaltBox *)s;
366 3 : if (ptr == NULL) return;
367 3 : gf_free(ptr);
368 : }
369 :
370 :
371 1 : GF_Err iSLT_box_read(GF_Box *s, GF_BitStream *bs)
372 : {
373 : GF_ISMACrypSaltBox *ptr = (GF_ISMACrypSaltBox *)s;
374 1 : if (ptr == NULL) return GF_BAD_PARAM;
375 1 : ISOM_DECREASE_SIZE(ptr, 8);
376 1 : ptr->salt = gf_bs_read_u64(bs);
377 1 : return GF_OK;
378 : }
379 :
380 : #ifndef GPAC_DISABLE_ISOM_WRITE
381 1 : GF_Err iSLT_box_write(GF_Box *s, GF_BitStream *bs)
382 : {
383 : GF_Err e;
384 : GF_ISMACrypSaltBox *ptr = (GF_ISMACrypSaltBox *)s;
385 1 : if (!s) return GF_BAD_PARAM;
386 1 : e = gf_isom_full_box_write(s, bs);
387 1 : if (e) return e;
388 :
389 1 : gf_bs_write_u64(bs, ptr->salt);
390 1 : return GF_OK;
391 : }
392 :
393 1 : GF_Err iSLT_box_size(GF_Box *s)
394 : {
395 1 : s->size += 8;
396 1 : return GF_OK;
397 : }
398 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
399 :
400 :
401 :
402 : /* OMADRMCommonHeader Box */
403 3 : GF_Box *ohdr_box_new()
404 : {
405 6 : ISOM_DECL_BOX_ALLOC(GF_OMADRMCommonHeaderBox, GF_ISOM_BOX_TYPE_OHDR);
406 3 : tmp->child_boxes = gf_list_new();
407 3 : return (GF_Box *)tmp;
408 : }
409 :
410 3 : void ohdr_box_del(GF_Box *s)
411 : {
412 : GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox*)s;
413 3 : if (ptr == NULL) return;
414 3 : if (ptr->ContentID) gf_free(ptr->ContentID);
415 3 : if (ptr->RightsIssuerURL) gf_free(ptr->RightsIssuerURL);
416 3 : if (ptr->TextualHeaders) gf_free(ptr->TextualHeaders);
417 3 : gf_free(ptr);
418 : }
419 :
420 1 : GF_Err ohdr_box_read(GF_Box *s, GF_BitStream *bs)
421 : {
422 : u16 cid_len, ri_len;
423 : GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox*)s;
424 :
425 1 : ISOM_DECREASE_SIZE(ptr, (1+1+8+2+2+2) );
426 1 : ptr->EncryptionMethod = gf_bs_read_u8(bs);
427 1 : ptr->PaddingScheme = gf_bs_read_u8(bs);
428 1 : ptr->PlaintextLength = gf_bs_read_u64(bs);
429 1 : cid_len = gf_bs_read_u16(bs);
430 1 : ri_len = gf_bs_read_u16(bs);
431 1 : ptr->TextualHeadersLen = gf_bs_read_u16(bs);
432 :
433 1 : if (ptr->size<cid_len+ri_len+ptr->TextualHeadersLen) return GF_ISOM_INVALID_FILE;
434 :
435 1 : if (cid_len) {
436 0 : ptr->ContentID = (char *)gf_malloc(sizeof(char)*(cid_len+1));
437 0 : if (!ptr->ContentID) return GF_OUT_OF_MEM;
438 0 : gf_bs_read_data(bs, ptr->ContentID, cid_len);
439 0 : ptr->ContentID[cid_len]=0;
440 : }
441 :
442 1 : if (ri_len) {
443 0 : ptr->RightsIssuerURL = (char *)gf_malloc(sizeof(char)*(ri_len+1));
444 0 : if (!ptr->RightsIssuerURL) return GF_OUT_OF_MEM;
445 0 : gf_bs_read_data(bs, ptr->RightsIssuerURL, ri_len);
446 0 : ptr->RightsIssuerURL[ri_len]=0;
447 : }
448 :
449 1 : if (ptr->TextualHeadersLen) {
450 0 : ptr->TextualHeaders = (char *)gf_malloc(sizeof(char)*(ptr->TextualHeadersLen+1));
451 0 : if (!ptr->TextualHeaders) return GF_OUT_OF_MEM;
452 0 : gf_bs_read_data(bs, ptr->TextualHeaders, ptr->TextualHeadersLen);
453 0 : ptr->TextualHeaders[ptr->TextualHeadersLen] = 0;
454 : }
455 :
456 1 : ISOM_DECREASE_SIZE(ptr, (cid_len+ri_len+ptr->TextualHeadersLen) );
457 :
458 1 : return gf_isom_box_array_read(s, bs);
459 : }
460 :
461 : #ifndef GPAC_DISABLE_ISOM_WRITE
462 1 : GF_Err ohdr_box_write(GF_Box *s, GF_BitStream *bs)
463 : {
464 : u16 cid_len, ri_len;
465 : GF_Err e;
466 : GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox *)s;
467 1 : if (!s) return GF_BAD_PARAM;
468 1 : e = gf_isom_full_box_write(s, bs);
469 1 : if (e) return e;
470 1 : gf_bs_write_u8(bs, ptr->EncryptionMethod);
471 1 : gf_bs_write_u8(bs, ptr->PaddingScheme);
472 1 : gf_bs_write_u64(bs, ptr->PlaintextLength);
473 :
474 1 : cid_len = ptr->ContentID ? (u16) strlen(ptr->ContentID) : 0;
475 1 : gf_bs_write_u16(bs, cid_len);
476 1 : ri_len = ptr->RightsIssuerURL ? (u16) strlen(ptr->RightsIssuerURL) : 0;
477 1 : gf_bs_write_u16(bs, ri_len);
478 1 : gf_bs_write_u16(bs, ptr->TextualHeadersLen);
479 :
480 1 : if (cid_len) gf_bs_write_data(bs, ptr->ContentID, (u32) strlen(ptr->ContentID));
481 1 : if (ri_len) gf_bs_write_data(bs, ptr->RightsIssuerURL, (u32) strlen(ptr->RightsIssuerURL));
482 1 : if (ptr->TextualHeadersLen) gf_bs_write_data(bs, ptr->TextualHeaders, ptr->TextualHeadersLen);
483 :
484 1 : ISOM_DECREASE_SIZE(ptr, (cid_len+ri_len+ptr->TextualHeadersLen) );
485 1 : return GF_OK;
486 : }
487 :
488 1 : GF_Err ohdr_box_size(GF_Box *s)
489 : {
490 : GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox *)s;
491 1 : ptr->size += 1+1+8+2+2+2;
492 1 : if (ptr->ContentID) ptr->size += strlen(ptr->ContentID);
493 1 : if (ptr->RightsIssuerURL) ptr->size += strlen(ptr->RightsIssuerURL);
494 1 : if (ptr->TextualHeadersLen) ptr->size += ptr->TextualHeadersLen;
495 1 : return GF_OK;
496 : }
497 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
498 :
499 :
500 : /* OMADRMGroupID Box */
501 3 : GF_Box *grpi_box_new()
502 : {
503 6 : ISOM_DECL_BOX_ALLOC(GF_OMADRMGroupIDBox, GF_ISOM_BOX_TYPE_GRPI);
504 3 : return (GF_Box *)tmp;
505 : }
506 :
507 3 : void grpi_box_del(GF_Box *s)
508 : {
509 : GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s;
510 3 : if (ptr == NULL) return;
511 3 : if (ptr->GroupID) gf_free(ptr->GroupID);
512 3 : if (ptr->GroupKey) gf_free(ptr->GroupKey);
513 3 : gf_free(ptr);
514 : }
515 :
516 1 : GF_Err grpi_box_read(GF_Box *s, GF_BitStream *bs)
517 : {
518 : u16 gid_len;
519 : GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox*)s;
520 :
521 1 : ISOM_DECREASE_SIZE(ptr, (1+2+2) );
522 1 : gid_len = gf_bs_read_u16(bs);
523 1 : ptr->GKEncryptionMethod = gf_bs_read_u8(bs);
524 1 : ptr->GKLength = gf_bs_read_u16(bs);
525 :
526 1 : if (ptr->size<gid_len+ptr->GKLength) return GF_ISOM_INVALID_FILE;
527 :
528 1 : ptr->GroupID = gf_malloc(sizeof(char)*(gid_len+1));
529 1 : if (!ptr->GroupID) return GF_OUT_OF_MEM;
530 1 : gf_bs_read_data(bs, ptr->GroupID, gid_len);
531 1 : ptr->GroupID[gid_len]=0;
532 :
533 1 : ptr->GroupKey = (char *)gf_malloc(sizeof(char)*ptr->GKLength);
534 1 : if (!ptr->GroupKey) return GF_OUT_OF_MEM;
535 1 : gf_bs_read_data(bs, ptr->GroupKey, ptr->GKLength);
536 1 : ISOM_DECREASE_SIZE(ptr, (gid_len+ptr->GKLength) );
537 1 : return GF_OK;
538 : }
539 :
540 : #ifndef GPAC_DISABLE_ISOM_WRITE
541 1 : GF_Err grpi_box_write(GF_Box *s, GF_BitStream *bs)
542 : {
543 : GF_Err e;
544 : u16 gid_len;
545 : GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s;
546 1 : if (!s) return GF_BAD_PARAM;
547 1 : e = gf_isom_full_box_write(s, bs);
548 1 : if (e) return e;
549 1 : gid_len = ptr->GroupID ? (u16) strlen(ptr->GroupID) : 0;
550 1 : gf_bs_write_u16(bs, gid_len);
551 1 : gf_bs_write_u8(bs, ptr->GKEncryptionMethod);
552 1 : gf_bs_write_u16(bs, ptr->GKLength);
553 1 : gf_bs_write_data(bs, ptr->GroupID, gid_len);
554 1 : gf_bs_write_data(bs, ptr->GroupKey, ptr->GKLength);
555 1 : return GF_OK;
556 : }
557 :
558 1 : GF_Err grpi_box_size(GF_Box *s)
559 : {
560 : GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s;
561 1 : ptr->size += 2+2+1 + ptr->GKLength;
562 1 : if (ptr->GroupID) ptr->size += strlen(ptr->GroupID);
563 1 : return GF_OK;
564 : }
565 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
566 :
567 :
568 :
569 :
570 : /* OMADRMMutableInformation Box */
571 3 : GF_Box *mdri_box_new()
572 : {
573 6 : ISOM_DECL_BOX_ALLOC(GF_OMADRMMutableInformationBox, GF_ISOM_BOX_TYPE_MDRI);
574 3 : return (GF_Box *)tmp;
575 : }
576 :
577 3 : void mdri_box_del(GF_Box *s)
578 : {
579 : GF_OMADRMMutableInformationBox*ptr = (GF_OMADRMMutableInformationBox*)s;
580 3 : if (ptr == NULL) return;
581 3 : gf_free(ptr);
582 : }
583 :
584 1 : GF_Err mdri_box_read(GF_Box *s, GF_BitStream *bs)
585 : {
586 1 : return gf_isom_box_array_read(s, bs);
587 : }
588 :
589 : #ifndef GPAC_DISABLE_ISOM_WRITE
590 1 : GF_Err mdri_box_write(GF_Box *s, GF_BitStream *bs)
591 : {
592 : // GF_OMADRMMutableInformationBox*ptr = (GF_OMADRMMutableInformationBox*)s;
593 1 : GF_Err e = gf_isom_box_write_header(s, bs);
594 1 : if (e) return e;
595 1 : return GF_OK;
596 : }
597 :
598 1 : GF_Err mdri_box_size(GF_Box *s)
599 : {
600 1 : return GF_OK;
601 : }
602 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
603 :
604 :
605 : /* OMADRMTransactionTracking Box */
606 3 : GF_Box *odtt_box_new()
607 : {
608 6 : ISOM_DECL_BOX_ALLOC(GF_OMADRMTransactionTrackingBox, GF_ISOM_BOX_TYPE_ODTT);
609 3 : return (GF_Box *)tmp;
610 : }
611 :
612 3 : void odtt_box_del(GF_Box *s)
613 : {
614 : GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox*)s;
615 3 : gf_free(ptr);
616 3 : }
617 :
618 1 : GF_Err odtt_box_read(GF_Box *s, GF_BitStream *bs)
619 : {
620 : GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox *)s;
621 :
622 1 : gf_bs_read_data(bs, ptr->TransactionID, 16);
623 1 : ISOM_DECREASE_SIZE(ptr, 16);
624 1 : return GF_OK;
625 : }
626 :
627 : #ifndef GPAC_DISABLE_ISOM_WRITE
628 1 : GF_Err odtt_box_write(GF_Box *s, GF_BitStream *bs)
629 : {
630 : GF_Err e;
631 : GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox*)s;
632 1 : if (!s) return GF_BAD_PARAM;
633 1 : e = gf_isom_full_box_write(s, bs);
634 1 : if (e) return e;
635 1 : gf_bs_write_data(bs, ptr->TransactionID, 16);
636 1 : return GF_OK;
637 : }
638 :
639 1 : GF_Err odtt_box_size(GF_Box *s)
640 : {
641 1 : s->size += 16;
642 1 : return GF_OK;
643 : }
644 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
645 :
646 :
647 :
648 : /* OMADRMRightsObject Box */
649 3 : GF_Box *odrb_box_new()
650 : {
651 6 : ISOM_DECL_BOX_ALLOC(GF_OMADRMRightsObjectBox, GF_ISOM_BOX_TYPE_ODRB);
652 3 : return (GF_Box *)tmp;
653 : }
654 :
655 3 : void odrb_box_del(GF_Box *s)
656 : {
657 : GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox*)s;
658 3 : if (ptr->oma_ro) gf_free(ptr->oma_ro);
659 3 : gf_free(ptr);
660 3 : }
661 :
662 1 : GF_Err odrb_box_read(GF_Box *s, GF_BitStream *bs)
663 : {
664 : GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s;
665 :
666 1 : ptr->oma_ro_size = (u32) ptr->size;
667 1 : ptr->oma_ro = (char*) gf_malloc(sizeof(char)*ptr->oma_ro_size);
668 1 : if (!ptr->oma_ro) return GF_OUT_OF_MEM;
669 1 : gf_bs_read_data(bs, ptr->oma_ro, ptr->oma_ro_size);
670 1 : ptr->size = 0;
671 1 : return GF_OK;
672 : }
673 :
674 : #ifndef GPAC_DISABLE_ISOM_WRITE
675 1 : GF_Err odrb_box_write(GF_Box *s, GF_BitStream *bs)
676 : {
677 : GF_Err e;
678 : GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s;
679 1 : if (!s) return GF_BAD_PARAM;
680 1 : e = gf_isom_full_box_write(s, bs);
681 1 : if (e) return e;
682 1 : gf_bs_write_data(bs, ptr->oma_ro, ptr->oma_ro_size);
683 1 : return GF_OK;
684 : }
685 :
686 1 : GF_Err odrb_box_size(GF_Box *s)
687 : {
688 : GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s;
689 1 : s->size += ptr->oma_ro_size;
690 1 : return GF_OK;
691 : }
692 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
693 :
694 :
695 :
696 :
697 : /* OMADRMKMS Box */
698 3 : GF_Box *odkm_box_new()
699 : {
700 6 : ISOM_DECL_BOX_ALLOC(GF_OMADRMKMSBox, GF_ISOM_BOX_TYPE_ODKM);
701 3 : return (GF_Box *)tmp;
702 : }
703 :
704 3 : void odkm_box_del(GF_Box *s)
705 : {
706 3 : gf_free(s);
707 3 : }
708 :
709 0 : GF_Err odkm_Add(GF_Box *s, GF_Box *a, Bool is_rem)
710 : {
711 : GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s;
712 0 : switch (a->type) {
713 0 : case GF_ISOM_BOX_TYPE_OHDR:
714 0 : BOX_FIELD_ASSIGN(hdr, GF_OMADRMCommonHeaderBox)
715 0 : return GF_OK;
716 0 : case GF_ISOM_BOX_TYPE_ODAF:
717 0 : BOX_FIELD_ASSIGN(fmt, GF_OMADRMAUFormatBox)
718 0 : return GF_OK;
719 : }
720 : return GF_OK;
721 : }
722 :
723 1 : GF_Err odkm_box_read(GF_Box *s, GF_BitStream *bs)
724 : {
725 1 : return gf_isom_box_array_read(s, bs);
726 : }
727 :
728 : #ifndef GPAC_DISABLE_ISOM_WRITE
729 1 : GF_Err odkm_box_write(GF_Box *s, GF_BitStream *bs)
730 : {
731 1 : return gf_isom_full_box_write(s, bs);
732 : }
733 :
734 1 : GF_Err odkm_box_size(GF_Box *s)
735 : {
736 1 : u32 pos=0;
737 : GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s;
738 1 : gf_isom_check_position(s, (GF_Box *)ptr->hdr, &pos);
739 1 : gf_isom_check_position(s, (GF_Box *)ptr->fmt, &pos);
740 1 : return GF_OK;
741 : }
742 : #endif /*GPAC_DISABLE_ISOM_WRITE*/
743 :
744 :
745 :
746 :
747 976 : GF_Box *pssh_box_new()
748 : {
749 1952 : ISOM_DECL_BOX_ALLOC(GF_ProtectionSystemHeaderBox, GF_ISOM_BOX_TYPE_PSSH);
750 976 : return (GF_Box *)tmp;
751 : }
752 :
753 976 : void pssh_box_del(GF_Box *s)
754 : {
755 : GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox*)s;
756 976 : if (ptr == NULL) return;
757 976 : if (ptr->private_data) gf_free(ptr->private_data);
758 976 : if (ptr->KIDs) gf_free(ptr->KIDs);
759 976 : gf_free(ptr);
760 : }
761 :
762 656 : GF_Err pssh_box_read(GF_Box *s, GF_BitStream *bs)
763 : {
764 : GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox *)s;
765 :
766 656 : gf_bs_read_data(bs, (char *) ptr->SystemID, 16);
767 656 : ISOM_DECREASE_SIZE(ptr, 16);
768 656 : if (ptr->version > 0) {
769 474 : ptr->KID_count = gf_bs_read_u32(bs);
770 474 : ISOM_DECREASE_SIZE(ptr, 4);
771 474 : if (ptr->KID_count) {
772 : u32 i;
773 474 : if (ptr->size / sizeof(bin128) < ptr->KID_count)
774 : return GF_ISOM_INVALID_FILE;
775 474 : ptr->KIDs = gf_malloc(ptr->KID_count*sizeof(bin128));
776 474 : if (!ptr->KIDs)
777 : return GF_OUT_OF_MEM;
778 609 : for (i=0; i<ptr->KID_count; i++) {
779 609 : gf_bs_read_data(bs, (char *) ptr->KIDs[i], 16);
780 609 : ISOM_DECREASE_SIZE(ptr, 16);
781 : }
782 : }
783 : }
784 656 : ptr->private_data_size = gf_bs_read_u32(bs);
785 656 : ISOM_DECREASE_SIZE(ptr, 4);
786 656 : if (ptr->private_data_size) {
787 655 : if (ptr->size < ptr->private_data_size)
788 : return GF_ISOM_INVALID_FILE;
789 655 : ptr->private_data = gf_malloc(sizeof(char)*ptr->private_data_size);
790 655 : if (!ptr->private_data)
791 : return GF_OUT_OF_MEM;
792 655 : gf_bs_read_data(bs, (char *) ptr->private_data, ptr->private_data_size);
793 655 : ISOM_DECREASE_SIZE(ptr, ptr->private_data_size);
794 : }
795 : return GF_OK;
796 : }
797 :
798 : #ifndef GPAC_DISABLE_ISOM_WRITE
799 :
800 572 : GF_Err pssh_box_write(GF_Box *s, GF_BitStream *bs)
801 : {
802 : GF_Err e;
803 : GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox *) s;
804 572 : if (!s) return GF_BAD_PARAM;
805 572 : e = gf_isom_full_box_write(s, bs);
806 572 : if (e) return e;
807 :
808 572 : gf_bs_write_data(bs, (char *) ptr->SystemID, 16);
809 572 : if (ptr->version > 0) {
810 : u32 i;
811 417 : gf_bs_write_u32(bs, ptr->KID_count);
812 946 : for (i=0; i<ptr->KID_count; i++)
813 529 : gf_bs_write_data(bs, (char *) ptr->KIDs[i], 16);
814 : }
815 572 : if (ptr->private_data) {
816 571 : gf_bs_write_u32(bs, ptr->private_data_size);
817 571 : gf_bs_write_data(bs, (char *) ptr->private_data, ptr->private_data_size);
818 : } else
819 1 : gf_bs_write_u32(bs, 0);
820 : return GF_OK;
821 : }
822 :
823 916 : GF_Err pssh_box_size(GF_Box *s)
824 : {
825 : GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox*)s;
826 :
827 916 : if (ptr->KID_count && !ptr->version) {
828 2 : ptr->version = 1;
829 : }
830 :
831 916 : ptr->size += 16;
832 916 : if (ptr->version) ptr->size += 4 + 16*ptr->KID_count;
833 916 : ptr->size += 4 + (ptr->private_data ? ptr->private_data_size : 0);
834 916 : return GF_OK;
835 : }
836 : #endif //GPAC_DISABLE_ISOM_WRITE
837 :
838 :
839 986 : GF_Box *tenc_box_new()
840 : {
841 1972 : ISOM_DECL_BOX_ALLOC(GF_TrackEncryptionBox, GF_ISOM_BOX_TYPE_TENC);
842 986 : return (GF_Box *)tmp;
843 : }
844 :
845 986 : void tenc_box_del(GF_Box *s)
846 : {
847 986 : gf_free(s);
848 986 : }
849 :
850 778 : GF_Err tenc_box_read(GF_Box *s, GF_BitStream *bs)
851 : {
852 : u8 iv_size;
853 : GF_TrackEncryptionBox *ptr = (GF_TrackEncryptionBox*)s;
854 :
855 778 : ISOM_DECREASE_SIZE(ptr, 3);
856 :
857 778 : gf_bs_read_u8(bs); //reserved
858 :
859 778 : if (!ptr->version) {
860 666 : gf_bs_read_u8(bs); //reserved
861 : } else {
862 112 : ptr->crypt_byte_block = gf_bs_read_int(bs, 4);
863 112 : ptr->skip_byte_block = gf_bs_read_int(bs, 4);
864 : }
865 778 : ptr->isProtected = gf_bs_read_u8(bs);
866 :
867 :
868 778 : ISOM_DECREASE_SIZE(ptr, 17);
869 :
870 778 : ptr->key_info[0] = 0;
871 778 : ptr->key_info[1] = 0;
872 778 : ptr->key_info[2] = 0;
873 778 : ptr->key_info[3] = iv_size = gf_bs_read_u8(bs);
874 778 : gf_bs_read_data(bs, ptr->key_info+4, 16);
875 778 : if (!iv_size && ptr->isProtected) {
876 26 : ISOM_DECREASE_SIZE(ptr, 1);
877 26 : iv_size = ptr->key_info[20] = gf_bs_read_u8(bs);
878 26 : ISOM_DECREASE_SIZE(ptr, ptr->key_info[20]);
879 26 : if ((iv_size!=8) && (iv_size!=16)) {
880 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid constant IV size %d, must be 8 or 16\n", (u32) iv_size));
881 0 : ptr->key_info[20] = 16;
882 0 : return GF_NON_COMPLIANT_BITSTREAM;
883 : }
884 26 : gf_bs_read_data(bs, ptr->key_info+21, iv_size);
885 : }
886 752 : else if ((iv_size!=0) && (iv_size!=8) && (iv_size!=16)) {
887 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid IV size %d, must be 0, 8 or 16\n", (u32) iv_size));
888 : return GF_NON_COMPLIANT_BITSTREAM;
889 : }
890 : return GF_OK;
891 : }
892 :
893 : #ifndef GPAC_DISABLE_ISOM_WRITE
894 :
895 402 : GF_Err tenc_box_write(GF_Box *s, GF_BitStream *bs)
896 : {
897 : GF_Err e;
898 : GF_TrackEncryptionBox *ptr = (GF_TrackEncryptionBox *) s;
899 402 : if (!s) return GF_BAD_PARAM;
900 402 : e = gf_isom_full_box_write(s, bs);
901 402 : if (e) return e;
902 :
903 402 : gf_bs_write_u8(bs, 0); //reserved
904 :
905 402 : if (!ptr->version) {
906 306 : gf_bs_write_u8(bs, 0); //reserved
907 : } else {
908 96 : gf_bs_write_int(bs, ptr->crypt_byte_block, 4);
909 96 : gf_bs_write_int(bs, ptr->skip_byte_block, 4);
910 : }
911 402 : gf_bs_write_u8(bs, ptr->isProtected);
912 :
913 402 : gf_bs_write_u8(bs, ptr->key_info[3]);
914 402 : gf_bs_write_data(bs, ptr->key_info + 4, 16);
915 402 : if ((ptr->isProtected == 1) && !ptr->key_info[3]) {
916 23 : gf_bs_write_u8(bs, ptr->key_info[20]);
917 23 : gf_bs_write_data(bs, ptr->key_info + 21, ptr->key_info[20]);
918 : }
919 : return GF_OK;
920 : }
921 :
922 592 : GF_Err tenc_box_size(GF_Box *s)
923 : {
924 : GF_TrackEncryptionBox *ptr = (GF_TrackEncryptionBox*)s;
925 592 : ptr->size += 3;
926 :
927 592 : ptr->size += 17;
928 592 : if ((ptr->isProtected == 1) && ! ptr->key_info[3]) {
929 35 : ptr->size += 1 + ptr->key_info[20];
930 : }
931 592 : return GF_OK;
932 : }
933 : #endif //GPAC_DISABLE_ISOM_WRITE
934 :
935 6 : GF_Box *piff_tenc_box_new()
936 : {
937 12 : ISOM_DECL_BOX_ALLOC(GF_PIFFTrackEncryptionBox, GF_ISOM_BOX_TYPE_UUID);
938 6 : tmp->internal_4cc = GF_ISOM_BOX_UUID_TENC;
939 6 : return (GF_Box *)tmp;
940 : }
941 :
942 6 : void piff_tenc_box_del(GF_Box *s)
943 : {
944 6 : gf_free(s);
945 6 : }
946 :
947 4 : GF_Err piff_tenc_box_read(GF_Box *s, GF_BitStream *bs)
948 : {
949 : GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox*)s;
950 :
951 4 : ISOM_DECREASE_SIZE(ptr, 4);
952 : //PIFF TENC extends UUID and fullbox
953 4 : ptr->version = gf_bs_read_u8(bs);
954 4 : ptr->flags = gf_bs_read_u24(bs);
955 :
956 4 : ISOM_DECREASE_SIZE(ptr, 20);
957 4 : ptr->AlgorithmID = gf_bs_read_int(bs, 24);
958 4 : ptr->key_info[0] = 0;
959 4 : ptr->key_info[1] = 0;
960 4 : ptr->key_info[2] = 0;
961 4 : ptr->key_info[3] = gf_bs_read_u8(bs);
962 4 : gf_bs_read_data(bs, ptr->key_info+4, 16);
963 4 : return GF_OK;
964 : }
965 :
966 : #ifndef GPAC_DISABLE_ISOM_WRITE
967 :
968 2 : GF_Err piff_tenc_box_write(GF_Box *s, GF_BitStream *bs)
969 : {
970 : GF_Err e;
971 : GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox *) s;
972 2 : if (!s) return GF_BAD_PARAM;
973 :
974 2 : e = gf_isom_box_write_header(s, bs);
975 2 : if (e) return e;
976 2 : gf_bs_write_u8(bs, ptr->version);
977 2 : gf_bs_write_u24(bs, ptr->flags);
978 :
979 2 : gf_bs_write_int(bs, ptr->AlgorithmID, 24);
980 2 : gf_bs_write_u8(bs, ptr->key_info[3]);
981 2 : gf_bs_write_data(bs, ptr->key_info+4, 16);
982 2 : return GF_OK;
983 : }
984 :
985 2 : GF_Err piff_tenc_box_size(GF_Box *s)
986 : {
987 : GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox*)s;
988 2 : ptr->size += 24;
989 2 : return GF_OK;
990 : }
991 : #endif //GPAC_DISABLE_ISOM_WRITE
992 :
993 :
994 49 : GF_Box *piff_psec_box_new()
995 : {
996 98 : ISOM_DECL_BOX_ALLOC(GF_SampleEncryptionBox, GF_ISOM_BOX_TYPE_UUID);
997 49 : tmp->internal_4cc = GF_ISOM_BOX_UUID_PSEC;
998 49 : tmp->piff_type = 1;
999 49 : return (GF_Box *)tmp;
1000 : }
1001 :
1002 49 : void piff_psec_box_del(GF_Box *s)
1003 : {
1004 : GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s;
1005 3794 : while (gf_list_count(ptr->samp_aux_info)) {
1006 3696 : GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, 0);
1007 3696 : if (sai) gf_isom_cenc_samp_aux_info_del(sai);
1008 3696 : gf_list_rem(ptr->samp_aux_info, 0);
1009 : }
1010 49 : if (ptr->samp_aux_info) gf_list_del(ptr->samp_aux_info);
1011 49 : gf_free(s);
1012 49 : }
1013 :
1014 :
1015 21 : GF_Err piff_psec_box_read(GF_Box *s, GF_BitStream *bs)
1016 : {
1017 : GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s;
1018 :
1019 21 : ISOM_DECREASE_SIZE(ptr, 4);
1020 : //PIFF PSEC extends UUID and fullbox
1021 21 : ptr->version = gf_bs_read_u8(bs);
1022 21 : ptr->flags = gf_bs_read_u24(bs);
1023 :
1024 21 : if (ptr->flags & 1) {
1025 0 : ISOM_DECREASE_SIZE(ptr, 20);
1026 0 : ptr->AlgorithmID = gf_bs_read_int(bs, 24);
1027 0 : ptr->IV_size = gf_bs_read_u8(bs);
1028 0 : gf_bs_read_data(bs, (char *) ptr->KID, 16);
1029 : }
1030 21 : if (ptr->IV_size == 0)
1031 21 : ptr->IV_size = 8; //default to 8
1032 :
1033 21 : ptr->bs_offset = gf_bs_get_position(bs);
1034 :
1035 21 : /*u32 sample_count = */gf_bs_read_u32(bs);
1036 21 : ISOM_DECREASE_SIZE(ptr, 4);
1037 21 : if (ptr->IV_size != 8 && ptr->IV_size != 16) {
1038 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] PIFF PSEC box incorrect IV size: %u - shall be 8 or 16\n", ptr->IV_size));
1039 : return GF_BAD_PARAM;
1040 : }
1041 : //as for senc, we skip parsing of the box until we have all saiz/saio info
1042 21 : gf_bs_skip_bytes(bs, ptr->size);
1043 21 : ptr->size = 0;
1044 21 : return GF_OK;
1045 : }
1046 :
1047 : #ifndef GPAC_DISABLE_ISOM_WRITE
1048 :
1049 434 : GF_Err store_senc_info(GF_SampleEncryptionBox *ptr, GF_BitStream *bs)
1050 : {
1051 : GF_Err e;
1052 : u64 pos, new_pos;
1053 434 : if (!ptr->cenc_saio) return GF_OK;
1054 :
1055 433 : pos = gf_bs_get_position(bs);
1056 433 : if (pos>0xFFFFFFFFULL) {
1057 0 : if (ptr->cenc_saio && !ptr->cenc_saio->version) {
1058 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] saio offset larger than 32-bits but box version 0 enforced. Retry without \"saio32\" option\n"));
1059 : return GF_BAD_PARAM;
1060 : }
1061 : }
1062 433 : e = gf_bs_seek(bs, ptr->cenc_saio->offset_first_offset_field);
1063 433 : if (e) return e;
1064 : //force using version 1 for saio box i.e offset has 64 bits
1065 : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
1066 433 : if (ptr->traf) {
1067 337 : new_pos = pos - ptr->traf->moof_start_in_bs;
1068 : } else
1069 : #endif
1070 : {
1071 : new_pos = pos;
1072 : }
1073 :
1074 433 : if (ptr->cenc_saio->offsets) {
1075 : u32 i;
1076 0 : u64 old_offset = ptr->cenc_saio->offsets[0];
1077 0 : for (i=0; i<ptr->cenc_saio->entry_count; i++) {
1078 0 : if (ptr->cenc_saio->version) {
1079 0 : gf_bs_write_u64(bs, new_pos + ptr->cenc_saio->offsets[i] - old_offset);
1080 : } else {
1081 0 : gf_bs_write_u32(bs, (u32) (new_pos + ptr->cenc_saio->offsets[i] - old_offset));
1082 : }
1083 0 : ptr->cenc_saio->offsets[i] = new_pos + ptr->cenc_saio->offsets[i] - old_offset;
1084 : }
1085 : } else {
1086 433 : if (ptr->cenc_saio->version) {
1087 433 : gf_bs_write_u64(bs, new_pos);
1088 : } else {
1089 0 : gf_bs_write_u32(bs, (u32) new_pos);
1090 : }
1091 : }
1092 :
1093 433 : return gf_bs_seek(bs, pos);
1094 : }
1095 :
1096 19 : GF_Err piff_psec_box_write(GF_Box *s, GF_BitStream *bs)
1097 : {
1098 : GF_Err e;
1099 : u32 sample_count;
1100 : GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *) s;
1101 19 : if (!s) return GF_BAD_PARAM;
1102 :
1103 19 : sample_count = gf_list_count(ptr->samp_aux_info);
1104 19 : if (!sample_count) {
1105 0 : ptr->size = 0;
1106 0 : return GF_OK;
1107 : }
1108 19 : e = gf_isom_box_write_header(s, bs);
1109 19 : if (e) return e;
1110 19 : gf_bs_write_u8(bs, ptr->version);
1111 19 : gf_bs_write_u24(bs, ptr->flags);
1112 :
1113 19 : if (ptr->flags & 1) {
1114 0 : gf_bs_write_int(bs, ptr->AlgorithmID, 24);
1115 0 : gf_bs_write_u8(bs, ptr->IV_size);
1116 0 : gf_bs_write_data(bs, (char *) ptr->KID, 16);
1117 : }
1118 19 : sample_count = gf_list_count(ptr->samp_aux_info);
1119 19 : gf_bs_write_u32(bs, sample_count);
1120 19 : if (sample_count) {
1121 : u32 i;
1122 19 : e = store_senc_info((GF_SampleEncryptionBox *)ptr, bs);
1123 19 : if (e) return e;
1124 :
1125 2416 : for (i = 0; i < sample_count; i++) {
1126 2416 : GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
1127 2416 : if (! sai->cenc_data_size) continue;
1128 2416 : gf_bs_write_data(bs, (char *)sai->cenc_data, sai->cenc_data_size);
1129 : }
1130 : }
1131 : return GF_OK;
1132 : }
1133 :
1134 64 : GF_Err piff_psec_box_size(GF_Box *s)
1135 : {
1136 : u32 i, sample_count;
1137 : GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox*)s;
1138 :
1139 64 : sample_count = gf_list_count(ptr->samp_aux_info);
1140 64 : if (!sample_count) {
1141 7 : ptr->size = 0;
1142 7 : return GF_OK;
1143 : }
1144 :
1145 57 : ptr->size += 4;
1146 57 : if (ptr->flags & 1) {
1147 0 : ptr->size += 20;
1148 : }
1149 57 : ptr->size += 4;
1150 :
1151 7305 : for (i = 0; i < sample_count; i++) {
1152 7248 : GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
1153 7248 : if (! sai->cenc_data_size) continue;
1154 7248 : ptr->size += sai->cenc_data_size;
1155 : }
1156 : return GF_OK;
1157 : }
1158 : #endif //GPAC_DISABLE_ISOM_WRITE
1159 :
1160 :
1161 3 : GF_Box *piff_pssh_box_new()
1162 : {
1163 6 : ISOM_DECL_BOX_ALLOC(GF_PIFFProtectionSystemHeaderBox, GF_ISOM_BOX_TYPE_UUID);
1164 3 : tmp->internal_4cc = GF_ISOM_BOX_UUID_PSSH;
1165 3 : return (GF_Box *)tmp;
1166 : }
1167 :
1168 3 : void piff_pssh_box_del(GF_Box *s)
1169 : {
1170 : GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox*)s;
1171 3 : if (ptr->private_data) gf_free(ptr->private_data);
1172 3 : gf_free(s);
1173 3 : }
1174 :
1175 1 : GF_Err piff_pssh_box_read(GF_Box *s, GF_BitStream *bs)
1176 : {
1177 : GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox*)s;
1178 :
1179 1 : ISOM_DECREASE_SIZE(ptr, 24);
1180 : //PIFF PSSH extends UUID and fullbox
1181 1 : ptr->version = gf_bs_read_u8(bs);
1182 1 : ptr->flags = gf_bs_read_u24(bs);
1183 1 : gf_bs_read_data(bs, (char *) ptr->SystemID, 16);
1184 1 : ptr->private_data_size = gf_bs_read_u32(bs);
1185 :
1186 1 : if (ptr->size < ptr->private_data_size)
1187 : return GF_ISOM_INVALID_FILE;
1188 1 : ptr->private_data = gf_malloc(sizeof(char)*ptr->private_data_size);
1189 1 : if (!ptr->private_data)
1190 : return GF_OUT_OF_MEM;
1191 :
1192 1 : ISOM_DECREASE_SIZE(ptr, ptr->private_data_size);
1193 1 : gf_bs_read_data(bs, (char *) ptr->private_data, ptr->private_data_size);
1194 1 : return GF_OK;
1195 : }
1196 :
1197 : #ifndef GPAC_DISABLE_ISOM_WRITE
1198 :
1199 1 : GF_Err piff_pssh_box_write(GF_Box *s, GF_BitStream *bs)
1200 : {
1201 : GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox *) s;
1202 1 : GF_Err e = gf_isom_box_write_header(s, bs);
1203 1 : if (e) return e;
1204 1 : gf_bs_write_u8(bs, ptr->version);
1205 1 : gf_bs_write_u24(bs, ptr->flags);
1206 :
1207 1 : gf_bs_write_data(bs, (char *) ptr->SystemID, 16);
1208 1 : gf_bs_write_u32(bs, ptr->private_data_size);
1209 1 : gf_bs_write_data(bs, (char *) ptr->private_data, ptr->private_data_size);
1210 1 : return GF_OK;
1211 : }
1212 :
1213 1 : GF_Err piff_pssh_box_size(GF_Box *s)
1214 : {
1215 : GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox*)s;
1216 :
1217 1 : ptr->size += 24 + ptr->private_data_size;
1218 1 : return GF_OK;
1219 : }
1220 : #endif //GPAC_DISABLE_ISOM_WRITE
1221 :
1222 980 : GF_Box *senc_box_new()
1223 : {
1224 1960 : ISOM_DECL_BOX_ALLOC(GF_SampleEncryptionBox, GF_ISOM_BOX_TYPE_SENC);
1225 980 : return (GF_Box *)tmp;
1226 : }
1227 :
1228 980 : void senc_box_del(GF_Box *s)
1229 : {
1230 : GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s;
1231 56459 : while (gf_list_count(ptr->samp_aux_info)) {
1232 54499 : GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, 0);
1233 54499 : if (sai) gf_isom_cenc_samp_aux_info_del(sai);
1234 54499 : gf_list_rem(ptr->samp_aux_info, 0);
1235 : }
1236 980 : if (ptr->samp_aux_info) gf_list_del(ptr->samp_aux_info);
1237 980 : gf_free(s);
1238 980 : }
1239 :
1240 :
1241 22530 : u8 key_info_get_iv_size(const u8 *key_info, u32 key_info_size, u32 idx, u8 *const_iv_size, const u8 **const_iv)
1242 : {
1243 : u32 i=0, kpos=3;
1244 22530 : if (const_iv_size) *const_iv_size = 0;
1245 22530 : if (const_iv) *const_iv = NULL;
1246 :
1247 : while (1) {
1248 : u8 civ_size=0;
1249 : const u8 *civ = NULL;
1250 33044 : u8 iv_size = key_info[kpos];
1251 33044 : kpos += 17;
1252 :
1253 33044 : if (!iv_size) {
1254 0 : if (kpos>key_info_size)
1255 : break;
1256 0 : civ_size = key_info[kpos];
1257 0 : civ = key_info + kpos + 1;
1258 0 : kpos += 1 + civ_size;
1259 : }
1260 :
1261 33044 : if (kpos>key_info_size)
1262 : break;
1263 :
1264 33044 : if (i+1==idx) {
1265 22530 : if (const_iv_size) *const_iv_size = civ_size;
1266 22530 : if (const_iv) *const_iv = civ;
1267 : return iv_size;
1268 : }
1269 : i++;
1270 10514 : if (kpos==key_info_size)
1271 : break;
1272 : }
1273 : return 0;
1274 : }
1275 :
1276 : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
1277 85 : GF_Err senc_Parse(GF_BitStream *bs, GF_TrackBox *trak, GF_TrackFragmentBox *traf, GF_SampleEncryptionBox *senc)
1278 : #else
1279 : GF_Err senc_Parse(GF_BitStream *bs, GF_TrackBox *trak, void *traf, GF_SampleEncryptionBox *senc)
1280 : #endif
1281 : {
1282 : GF_Err e;
1283 : Bool parse_failed = GF_FALSE;
1284 : u32 i, count, sample_number;
1285 85 : u32 senc_size = (u32) senc->size;
1286 : u32 subs_size = 0, def_IV_size;
1287 85 : u64 pos = gf_bs_get_position(bs);
1288 : Bool do_warn = GF_TRUE;
1289 : Bool use_multikey = GF_FALSE;
1290 : Bool patch_subsamples_present = GF_FALSE;
1291 :
1292 : #ifdef GPAC_DISABLE_ISOM_FRAGMENTS
1293 : if (!traf)
1294 : return GF_BAD_PARAM;
1295 : #endif
1296 :
1297 : //BOX + version/flags
1298 85 : if (senc_size<12) return GF_BAD_PARAM;
1299 85 : senc_size -= 12;
1300 :
1301 85 : if (senc->piff_type==1) {
1302 : //UUID
1303 9 : if (senc_size<16) return GF_BAD_PARAM;
1304 9 : senc_size -= 16;
1305 76 : } else if (!senc->piff_type) {
1306 76 : if (senc->version==1)
1307 : use_multikey = GF_TRUE;
1308 : }
1309 85 : if (senc->flags & 2) subs_size = 8;
1310 :
1311 85 : if (senc_size<4) return GF_BAD_PARAM;
1312 :
1313 : sample_number = 1;
1314 : #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
1315 85 : if (trak) sample_number += trak->sample_count_at_seg_start;
1316 : #endif
1317 :
1318 85 : gf_bs_seek(bs, senc->bs_offset);
1319 :
1320 85 : count = gf_bs_read_u32(bs);
1321 85 : senc_size -= 4;
1322 :
1323 : def_IV_size = 0;
1324 : //check the target size if we have one subsample
1325 85 : if (senc_size >= count * (16 + subs_size)) {
1326 : def_IV_size = 16;
1327 : }
1328 14 : else if (senc_size >= count * (8 + subs_size)) {
1329 : def_IV_size = 8;
1330 : }
1331 : else if (senc_size >= count * (subs_size)) {
1332 : def_IV_size = 0;
1333 : }
1334 :
1335 85 : if (gf_opts_get_bool("core", "piff-force-subsamples") && !(senc->flags & 0x00000002))
1336 : patch_subsamples_present = GF_TRUE;
1337 :
1338 85 : if (!senc->samp_aux_info) senc->samp_aux_info = gf_list_new();
1339 28969 : for (i=0; i<count; i++) {
1340 14442 : const u8 *key_info=NULL;
1341 14442 : u32 key_info_size=0;
1342 : Bool is_encrypted;
1343 : GF_CENCSampleAuxInfo *sai;
1344 : u8 IV_size=0;
1345 : u32 nb_keys = 0;
1346 : u32 nb_bytes_subsample = 6;
1347 : u32 nb_subs_bits = 16;
1348 :
1349 14442 : GF_SAFEALLOC(sai, GF_CENCSampleAuxInfo);
1350 14442 : if (!sai) {
1351 0 : gf_bs_seek(bs, pos);
1352 0 : return GF_OUT_OF_MEM;
1353 : }
1354 14442 : if (trak) {
1355 14442 : e = gf_isom_get_sample_cenc_info_internal(trak, traf, senc, sample_number, &is_encrypted, NULL, NULL, &key_info, &key_info_size);
1356 14442 : if (! key_info) {
1357 292 : IV_size = key_info_size; //piff default
1358 : use_multikey = GF_FALSE;
1359 292 : senc->piff_type = 2;
1360 14150 : } else if (use_multikey) {
1361 : nb_keys = key_info[1];
1362 : nb_keys <<= 8;
1363 : nb_keys |= key_info[2];
1364 : nb_bytes_subsample = 8;
1365 : nb_subs_bits = 32;
1366 : } else {
1367 14150 : IV_size = key_info[3];
1368 : }
1369 :
1370 14442 : if (e) {
1371 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[isobmf] could not get cenc info for sample %d: %s\n", sample_number, gf_error_to_string(e) ));
1372 0 : gf_isom_cenc_samp_aux_info_del(sai);
1373 0 : gf_bs_seek(bs, pos);
1374 0 : if (trak->moov->mov->FragmentsFlags & GF_ISOM_FRAG_READ_DEBUG)
1375 : return GF_OK;
1376 0 : return e;
1377 : }
1378 : }
1379 : //no init movie setup (segment dump/inspaction, assume default encrypted and 16 bytes IV
1380 : else {
1381 0 : if (do_warn) {
1382 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[isobmf] no moov found, cannot get cenc default info, assuming isEncrypted, IV size %d (computed from senc size)\n", def_IV_size));
1383 : do_warn = GF_FALSE;
1384 : }
1385 0 : is_encrypted = GF_TRUE;
1386 0 : IV_size = def_IV_size;
1387 : }
1388 14442 : if (senc_size < IV_size) {
1389 : parse_failed = GF_TRUE;
1390 0 : gf_isom_cenc_samp_aux_info_del(sai);
1391 0 : break;
1392 : }
1393 :
1394 14442 : sample_number++;
1395 :
1396 : //subsample info is only signaled for encrypted samples
1397 14442 : if (is_encrypted) {
1398 13298 : u64 sai_start = gf_bs_get_position(bs);
1399 : u32 nb_subs = 0;
1400 :
1401 13298 : if (use_multikey) {
1402 : u32 j;
1403 0 : u32 nb_iv_init = gf_bs_read_u16(bs);
1404 0 : for (j=0; j<nb_iv_init; j++) {
1405 0 : u32 idx = gf_bs_read_u16(bs);
1406 0 : IV_size = key_info_get_iv_size(key_info, key_info_size, idx, NULL, NULL);
1407 0 : if (!IV_size) {
1408 0 : gf_isom_cenc_samp_aux_info_del(sai);
1409 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[isobmf] Failed to parse SENC box, invalid SAI multikey with IV size 0\n" ));
1410 0 : gf_bs_seek(bs, pos);
1411 0 : return GF_ISOM_INVALID_FILE;
1412 : }
1413 0 : gf_bs_skip_bytes(bs, IV_size);
1414 : }
1415 :
1416 : } else {
1417 13298 : if (IV_size > 16) {
1418 0 : gf_isom_cenc_samp_aux_info_del(sai);
1419 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[isobmf] Failed to parse SENC box, invalid SAI size\n" ));
1420 0 : gf_bs_seek(bs, pos);
1421 0 : return GF_ISOM_INVALID_FILE;
1422 : }
1423 13298 : if (IV_size) {
1424 12696 : gf_bs_skip_bytes(bs, IV_size);
1425 : }
1426 : }
1427 13298 : if (senc->flags & 0x00000002) {
1428 9338 : nb_subs = gf_bs_read_int(bs, nb_subs_bits);
1429 : }
1430 :
1431 13298 : sai->cenc_data_size = (u32) (gf_bs_get_position(bs) - sai_start);
1432 13298 : sai->cenc_data_size += nb_subs * nb_bytes_subsample;
1433 13298 : gf_bs_seek(bs, sai_start);
1434 :
1435 13298 : if ((s32) senc_size < sai->cenc_data_size) {
1436 : parse_failed = GF_TRUE;
1437 0 : gf_isom_cenc_samp_aux_info_del(sai);
1438 0 : break;
1439 : }
1440 :
1441 13298 : sai->cenc_data = gf_malloc(sizeof(u8) * sai->cenc_data_size);
1442 13298 : if (!sai->cenc_data) {
1443 0 : gf_isom_cenc_samp_aux_info_del(sai);
1444 0 : gf_bs_seek(bs, pos);
1445 0 : return GF_OUT_OF_MEM;
1446 : }
1447 13298 : gf_bs_read_data(bs, sai->cenc_data, sai->cenc_data_size);
1448 13298 : senc_size -= sai->cenc_data_size;
1449 :
1450 13298 : if (patch_subsamples_present) {
1451 0 : gf_bs_read_int(bs, nb_subs_bits);
1452 : }
1453 : } else {
1454 1144 : i--;
1455 1144 : sai->isNotProtected = 1;
1456 : }
1457 :
1458 14442 : if (senc->internal_4cc == GF_ISOM_BOX_UUID_PSEC) {
1459 1328 : sai->key_info_size = IV_size;
1460 : } else {
1461 13114 : sai->key_info = key_info;
1462 13114 : sai->key_info_size = key_info_size;
1463 : }
1464 14442 : gf_list_add(senc->samp_aux_info, sai);
1465 : }
1466 85 : gf_bs_seek(bs, pos);
1467 85 : if (parse_failed) {
1468 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[isobmf] cannot parse senc, missing IV/crypto state\n"));
1469 : }
1470 : return GF_OK;
1471 : }
1472 :
1473 :
1474 378 : GF_Err senc_box_read(GF_Box *s, GF_BitStream *bs)
1475 : {
1476 : GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s;
1477 378 : ISOM_DECREASE_SIZE(ptr, 4);
1478 : //WARNING - PSEC (UUID) IS TYPECASTED TO SENC (FULL BOX) SO WE CANNOT USE USUAL FULL BOX FUNCTIONS
1479 378 : ptr->version = gf_bs_read_u8(bs);
1480 378 : ptr->flags = gf_bs_read_u24(bs);
1481 :
1482 378 : ptr->bs_offset = gf_bs_get_position(bs);
1483 378 : gf_bs_skip_bytes(bs, ptr->size);
1484 378 : ptr->size = 0;
1485 378 : ptr->load_needed = GF_TRUE;
1486 378 : return GF_OK;
1487 : }
1488 :
1489 : #ifndef GPAC_DISABLE_ISOM_WRITE
1490 :
1491 :
1492 415 : GF_Err senc_box_write(GF_Box *s, GF_BitStream *bs)
1493 : {
1494 : GF_Err e;
1495 : u32 i;
1496 : u32 sample_count, nb_crypt_samples;
1497 : GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *) s;
1498 :
1499 415 : sample_count = gf_list_count(ptr->samp_aux_info);
1500 : //temp patch until we cleanup the spec...
1501 : nb_crypt_samples = 0;
1502 37506 : for (i = 0; i < sample_count; i++) {
1503 37091 : GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
1504 37091 : if (!sai->isNotProtected) nb_crypt_samples++;
1505 : }
1506 415 : if (!nb_crypt_samples) {
1507 0 : ptr->size = 0;
1508 0 : return GF_OK;
1509 : }
1510 :
1511 415 : e = gf_isom_box_write_header(s, bs);
1512 415 : if (e) return e;
1513 : //WARNING - PSEC (UUID) IS TYPECASTED TO SENC (FULL BOX) SO WE CANNOT USE USUAL FULL BOX FUNCTIONS
1514 415 : gf_bs_write_u8(bs, ptr->version);
1515 415 : gf_bs_write_u24(bs, ptr->flags);
1516 :
1517 415 : gf_bs_write_u32(bs, nb_crypt_samples);
1518 :
1519 415 : e = store_senc_info(ptr, bs);
1520 415 : if (e) return e;
1521 :
1522 37091 : for (i = 0; i < sample_count; i++) {
1523 37091 : GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
1524 37091 : if (sai->isNotProtected || !sai->cenc_data_size)
1525 2404 : continue;
1526 34687 : gf_bs_write_data(bs, sai->cenc_data, sai->cenc_data_size);
1527 : }
1528 : return GF_OK;
1529 : }
1530 :
1531 1302 : GF_Err senc_box_size(GF_Box *s)
1532 : {
1533 : u32 sample_count;
1534 : u32 i, nb_crypt_samples;
1535 : GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox*)s;
1536 1302 : sample_count = gf_list_count(ptr->samp_aux_info);
1537 : //temp patch until we cleanup the spec...
1538 : nb_crypt_samples=0;
1539 111594 : for (i = 0; i < sample_count; i++) {
1540 110292 : GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
1541 110292 : if (!sai->isNotProtected) nb_crypt_samples++;
1542 : }
1543 :
1544 1302 : if (!nb_crypt_samples) {
1545 117 : ptr->size = 0;
1546 117 : return GF_OK;
1547 : }
1548 :
1549 : //WARNING - PSEC (UUID) IS TYPECASTED TO SENC (FULL BOX) SO WE CANNOT USE USUAL FULL BOX FUNCTIONS
1550 1185 : ptr->size += 4; //version and flags
1551 :
1552 1185 : ptr->size += 4; //sample count
1553 110958 : for (i = 0; i < sample_count; i++) {
1554 109773 : GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
1555 109773 : if (sai->isNotProtected)
1556 7212 : continue;
1557 102561 : ptr->size += sai->cenc_data_size;
1558 : }
1559 : return GF_OK;
1560 : }
1561 : #endif //GPAC_DISABLE_ISOM_WRITE
1562 :
1563 38 : GF_Box *adkm_box_new()
1564 : {
1565 76 : ISOM_DECL_BOX_ALLOC(GF_AdobeDRMKeyManagementSystemBox, GF_ISOM_BOX_TYPE_ADKM);
1566 38 : tmp->version = 1;
1567 38 : tmp->flags = 0;
1568 38 : return (GF_Box *)tmp;
1569 : }
1570 :
1571 38 : void adkm_box_del(GF_Box *s)
1572 : {
1573 : GF_AdobeDRMKeyManagementSystemBox *ptr = (GF_AdobeDRMKeyManagementSystemBox *)s;
1574 38 : if (!ptr) return;
1575 38 : gf_free(s);
1576 : }
1577 :
1578 50 : GF_Err adkm_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
1579 : {
1580 : GF_AdobeDRMKeyManagementSystemBox *ptr = (GF_AdobeDRMKeyManagementSystemBox *)s;
1581 50 : switch (a->type) {
1582 25 : case GF_ISOM_BOX_TYPE_AHDR:
1583 25 : BOX_FIELD_ASSIGN(header, GF_AdobeDRMHeaderBox)
1584 25 : break;
1585 25 : case GF_ISOM_BOX_TYPE_ADAF:
1586 25 : BOX_FIELD_ASSIGN(au_format, GF_AdobeDRMAUFormatBox)
1587 25 : break;
1588 : }
1589 : return GF_OK;
1590 : }
1591 :
1592 26 : GF_Err adkm_box_read(GF_Box *s, GF_BitStream *bs)
1593 : {
1594 26 : return gf_isom_box_array_read(s, bs);
1595 : }
1596 :
1597 : #ifndef GPAC_DISABLE_ISOM_WRITE
1598 21 : GF_Err adkm_box_write(GF_Box *s, GF_BitStream *bs)
1599 : {
1600 21 : return gf_isom_full_box_write(s, bs);
1601 : }
1602 :
1603 31 : GF_Err adkm_box_size(GF_Box *s)
1604 : {
1605 31 : u32 pos=0;
1606 : GF_AdobeDRMKeyManagementSystemBox *ptr = (GF_AdobeDRMKeyManagementSystemBox *)s;
1607 31 : gf_isom_check_position(s, (GF_Box *)ptr->header, &pos);
1608 31 : gf_isom_check_position(s, (GF_Box *)ptr->au_format, &pos);
1609 31 : return GF_OK;
1610 : }
1611 : #endif //GPAC_DISABLE_ISOM_WRITE
1612 :
1613 38 : GF_Box *ahdr_box_new()
1614 : {
1615 76 : ISOM_DECL_BOX_ALLOC(GF_AdobeDRMHeaderBox, GF_ISOM_BOX_TYPE_AHDR);
1616 38 : tmp->version = 2;
1617 38 : tmp->flags = 0;
1618 38 : return (GF_Box *)tmp;
1619 : }
1620 :
1621 38 : void ahdr_box_del(GF_Box *s)
1622 : {
1623 38 : gf_free(s);
1624 38 : }
1625 :
1626 :
1627 25 : GF_Err ahdr_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
1628 : {
1629 : GF_AdobeDRMHeaderBox *ptr = (GF_AdobeDRMHeaderBox *)s;
1630 25 : switch (a->type) {
1631 25 : case GF_ISOM_BOX_TYPE_APRM:
1632 25 : BOX_FIELD_ASSIGN(std_enc_params, GF_AdobeStdEncryptionParamsBox)
1633 25 : break;
1634 : }
1635 : return GF_OK;
1636 : }
1637 :
1638 26 : GF_Err ahdr_box_read(GF_Box *s, GF_BitStream *bs)
1639 : {
1640 26 : return gf_isom_box_array_read(s, bs);
1641 : }
1642 :
1643 : #ifndef GPAC_DISABLE_ISOM_WRITE
1644 21 : GF_Err ahdr_box_write(GF_Box *s, GF_BitStream *bs)
1645 : {
1646 21 : return gf_isom_full_box_write(s, bs);
1647 : }
1648 :
1649 31 : GF_Err ahdr_box_size(GF_Box *s)
1650 : {
1651 31 : u32 pos=0;
1652 : GF_AdobeDRMHeaderBox *ptr = (GF_AdobeDRMHeaderBox *)s;
1653 31 : gf_isom_check_position(s, (GF_Box *)ptr->std_enc_params, &pos);
1654 31 : return GF_OK;
1655 : }
1656 : #endif //GPAC_DISABLE_ISOM_WRITE
1657 :
1658 38 : GF_Box *aprm_box_new()
1659 : {
1660 76 : ISOM_DECL_BOX_ALLOC(GF_AdobeStdEncryptionParamsBox, GF_ISOM_BOX_TYPE_APRM);
1661 38 : tmp->version = 1;
1662 38 : tmp->flags = 0;
1663 38 : return (GF_Box *)tmp;
1664 : }
1665 :
1666 38 : void aprm_box_del(GF_Box *s)
1667 : {
1668 38 : gf_free(s);
1669 38 : }
1670 :
1671 50 : GF_Err aprm_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
1672 : {
1673 : GF_AdobeStdEncryptionParamsBox *ptr = (GF_AdobeStdEncryptionParamsBox *)s;
1674 50 : switch (a->type) {
1675 25 : case GF_ISOM_BOX_TYPE_AEIB:
1676 25 : BOX_FIELD_ASSIGN(enc_info, GF_AdobeEncryptionInfoBox)
1677 25 : break;
1678 25 : case GF_ISOM_BOX_TYPE_AKEY:
1679 25 : BOX_FIELD_ASSIGN(key_info, GF_AdobeKeyInfoBox)
1680 25 : break;
1681 : }
1682 : return GF_OK;
1683 : }
1684 :
1685 26 : GF_Err aprm_box_read(GF_Box *s, GF_BitStream *bs)
1686 : {
1687 26 : return gf_isom_box_array_read(s, bs);
1688 : }
1689 :
1690 : #ifndef GPAC_DISABLE_ISOM_WRITE
1691 21 : GF_Err aprm_box_write(GF_Box *s, GF_BitStream *bs)
1692 : {
1693 21 : return gf_isom_full_box_write(s, bs);
1694 : }
1695 :
1696 31 : GF_Err aprm_box_size(GF_Box *s)
1697 : {
1698 31 : u32 pos=0;
1699 : GF_AdobeStdEncryptionParamsBox *ptr = (GF_AdobeStdEncryptionParamsBox *)s;
1700 31 : gf_isom_check_position(s, (GF_Box *)ptr->enc_info, &pos);
1701 31 : gf_isom_check_position(s, (GF_Box *)ptr->key_info, &pos);
1702 31 : return GF_OK;
1703 : }
1704 : #endif //GPAC_DISABLE_ISOM_WRITE
1705 :
1706 38 : GF_Box *aeib_box_new()
1707 : {
1708 76 : ISOM_DECL_BOX_ALLOC(GF_AdobeEncryptionInfoBox, GF_ISOM_BOX_TYPE_AEIB);
1709 38 : tmp->version = 1;
1710 38 : tmp->flags = 0;
1711 38 : return (GF_Box *)tmp;
1712 : }
1713 :
1714 38 : void aeib_box_del(GF_Box *s)
1715 : {
1716 : GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox*)s;
1717 38 : if (!ptr) return;
1718 38 : if (ptr->enc_algo) gf_free(ptr->enc_algo);
1719 38 : gf_free(ptr);
1720 : }
1721 :
1722 26 : GF_Err aeib_box_read(GF_Box *s, GF_BitStream *bs)
1723 : {
1724 : GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox*)s;
1725 : u32 len;
1726 :
1727 26 : len = (u32) ptr->size - 1;
1728 26 : if (len) {
1729 25 : ptr->enc_algo = (char *)gf_malloc(len*sizeof(char));
1730 25 : if (!ptr->enc_algo) return GF_OUT_OF_MEM;
1731 25 : gf_bs_read_data(bs, ptr->enc_algo, len);
1732 : }
1733 26 : ptr->key_length = gf_bs_read_u8(bs);
1734 26 : ptr->size = 0;
1735 26 : return GF_OK;
1736 : }
1737 :
1738 : #ifndef GPAC_DISABLE_ISOM_WRITE
1739 :
1740 21 : GF_Err aeib_box_write(GF_Box *s, GF_BitStream *bs)
1741 : {
1742 : GF_Err e;
1743 : GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox *) s;
1744 21 : if (!s) return GF_BAD_PARAM;
1745 21 : e = gf_isom_full_box_write(s, bs);
1746 21 : if (e) return e;
1747 21 : if (ptr->enc_algo) {
1748 20 : gf_bs_write_data(bs, (char *) ptr->enc_algo, (u32) strlen(ptr->enc_algo));
1749 20 : gf_bs_write_u8(bs, 0); //string end
1750 : }
1751 21 : gf_bs_write_u8(bs, ptr->key_length);
1752 21 : return GF_OK;
1753 : }
1754 :
1755 31 : GF_Err aeib_box_size(GF_Box *s)
1756 : {
1757 : GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox*)s;
1758 31 : if (ptr->enc_algo)
1759 30 : ptr->size += strlen(ptr->enc_algo) + 1;
1760 31 : ptr->size += 1; //KeyLength
1761 31 : return GF_OK;
1762 : }
1763 : #endif //GPAC_DISABLE_ISOM_WRITE
1764 :
1765 38 : GF_Box *akey_box_new()
1766 : {
1767 76 : ISOM_DECL_BOX_ALLOC(GF_AdobeKeyInfoBox, GF_ISOM_BOX_TYPE_AKEY);
1768 38 : tmp->version = 1;
1769 38 : tmp->flags = 0;
1770 38 : return (GF_Box *)tmp;
1771 : }
1772 :
1773 38 : void akey_box_del(GF_Box *s)
1774 : {
1775 38 : gf_free(s);
1776 38 : }
1777 :
1778 25 : GF_Err akey_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
1779 : {
1780 : GF_AdobeKeyInfoBox *ptr = (GF_AdobeKeyInfoBox *)s;
1781 25 : switch (a->type) {
1782 25 : case GF_ISOM_BOX_TYPE_FLXS:
1783 25 : BOX_FIELD_ASSIGN(params, GF_AdobeFlashAccessParamsBox)
1784 25 : break;
1785 : }
1786 : return GF_OK;
1787 : }
1788 :
1789 26 : GF_Err akey_box_read(GF_Box *s, GF_BitStream *bs)
1790 : {
1791 26 : return gf_isom_box_array_read(s, bs);
1792 : }
1793 :
1794 : #ifndef GPAC_DISABLE_ISOM_WRITE
1795 21 : GF_Err akey_box_write(GF_Box *s, GF_BitStream *bs)
1796 : {
1797 21 : return gf_isom_full_box_write(s, bs);
1798 : }
1799 :
1800 31 : GF_Err akey_box_size(GF_Box *s)
1801 : {
1802 31 : u32 pos=0;
1803 : GF_AdobeKeyInfoBox *ptr = (GF_AdobeKeyInfoBox *)s;
1804 31 : gf_isom_check_position(s, (GF_Box *)ptr->params, &pos);
1805 31 : return GF_OK;
1806 : }
1807 : #endif //GPAC_DISABLE_ISOM_WRITE
1808 :
1809 38 : GF_Box *flxs_box_new()
1810 : {
1811 76 : ISOM_DECL_BOX_ALLOC(GF_AdobeFlashAccessParamsBox, GF_ISOM_BOX_TYPE_FLXS);
1812 38 : return (GF_Box *)tmp;
1813 : }
1814 :
1815 38 : void flxs_box_del(GF_Box *s)
1816 : {
1817 : GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox*)s;
1818 38 : if (!ptr) return;
1819 38 : if (ptr->metadata)
1820 35 : gf_free(ptr->metadata);
1821 38 : gf_free(ptr);
1822 : }
1823 :
1824 26 : GF_Err flxs_box_read(GF_Box *s, GF_BitStream *bs)
1825 : {
1826 : GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox*)s;
1827 : u32 len;
1828 :
1829 26 : len = (u32) ptr->size;
1830 26 : if (len) {
1831 25 : ptr->metadata = (char *)gf_malloc(len*sizeof(char));
1832 25 : if (!ptr->metadata) return GF_OUT_OF_MEM;
1833 25 : gf_bs_read_data(bs, ptr->metadata, len);
1834 : }
1835 : return GF_OK;
1836 : }
1837 :
1838 : #ifndef GPAC_DISABLE_ISOM_WRITE
1839 :
1840 21 : GF_Err flxs_box_write(GF_Box *s, GF_BitStream *bs)
1841 : {
1842 : GF_Err e;
1843 : GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox *) s;
1844 21 : if (!s) return GF_BAD_PARAM;
1845 21 : e = gf_isom_box_write_header(s, bs);
1846 21 : if (e) return e;
1847 21 : if (ptr->metadata) {
1848 20 : gf_bs_write_data(bs, ptr->metadata, (u32) strlen(ptr->metadata));
1849 20 : gf_bs_write_u8(bs, 0); //string end
1850 : }
1851 : return GF_OK;
1852 : }
1853 :
1854 31 : GF_Err flxs_box_size(GF_Box *s)
1855 : {
1856 : GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox*)s;
1857 31 : if (ptr->metadata)
1858 30 : ptr->size += strlen(ptr->metadata) + 1;
1859 31 : return GF_OK;
1860 : }
1861 : #endif //GPAC_DISABLE_ISOM_WRITE
1862 :
1863 38 : GF_Box *adaf_box_new()
1864 : {
1865 76 : ISOM_DECL_BOX_ALLOC(GF_AdobeDRMAUFormatBox, GF_ISOM_BOX_TYPE_ADAF);
1866 38 : return (GF_Box *)tmp;
1867 : }
1868 :
1869 38 : void adaf_box_del(GF_Box *s)
1870 : {
1871 38 : gf_free(s);
1872 38 : }
1873 :
1874 26 : GF_Err adaf_box_read(GF_Box *s, GF_BitStream *bs)
1875 : {
1876 : GF_AdobeDRMAUFormatBox *ptr = (GF_AdobeDRMAUFormatBox*)s;
1877 :
1878 26 : ISOM_DECREASE_SIZE(ptr, 3);
1879 26 : ptr->selective_enc = gf_bs_read_u8(bs);
1880 26 : gf_bs_read_u8(bs);//resersed
1881 26 : ptr->IV_length = gf_bs_read_u8(bs);
1882 26 : return GF_OK;
1883 : }
1884 :
1885 : #ifndef GPAC_DISABLE_ISOM_WRITE
1886 :
1887 21 : GF_Err adaf_box_write(GF_Box *s, GF_BitStream *bs)
1888 : {
1889 : GF_Err e;
1890 : GF_AdobeDRMAUFormatBox *ptr = (GF_AdobeDRMAUFormatBox *) s;
1891 21 : if (!s) return GF_BAD_PARAM;
1892 21 : e = gf_isom_full_box_write(s, bs);
1893 21 : if (e) return e;
1894 :
1895 21 : gf_bs_write_u8(bs, ptr->selective_enc);
1896 21 : gf_bs_write_u8(bs, 0x0);
1897 21 : gf_bs_write_u8(bs, ptr->IV_length);
1898 21 : return GF_OK;
1899 : }
1900 :
1901 31 : GF_Err adaf_box_size(GF_Box *s)
1902 : {
1903 : GF_AdobeDRMAUFormatBox *ptr = (GF_AdobeDRMAUFormatBox*)s;
1904 31 : ptr->size += 3;
1905 31 : return GF_OK;
1906 : }
1907 : #endif //GPAC_DISABLE_ISOM_WRITE
1908 :
1909 :
1910 : #endif /*GPAC_DISABLE_ISOM*/
|