LCOV - code coverage report
Current view: top level - isomedia - box_code_drm.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 865 956 90.5 %
Date: 2021-04-29 23:48:07 Functions: 139 140 99.3 %

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

Generated by: LCOV version 1.13