LCOV - code coverage report
Current view: top level - isomedia - box_code_adobe.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 171 410 41.7 %
Date: 2021-04-29 23:48:07 Functions: 20 20 100.0 %

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

Generated by: LCOV version 1.13