This source file includes following definitions.
- co64_del
- co64_Read
- co64_New
- co64_Write
- co64_Size
- cprt_del
- chpl_New
- chpl_del
- chpl_Read
- chpl_Write
- chpl_Size
- cprt_Read
- cprt_New
- cprt_Write
- cprt_Size
- kind_del
- kind_Read
- kind_New
- kind_Write
- kind_Size
- ctts_del
- ctts_Read
- ctts_New
- ctts_Write
- ctts_Size
- cslg_del
- cslg_Read
- cslg_New
- cslg_Write
- cslg_Size
- ccst_del
- ccst_Read
- ccst_New
- ccst_Write
- ccst_Size
- url_del
- url_Read
- url_New
- url_Write
- url_Size
- urn_del
- urn_Read
- urn_New
- urn_Write
- urn_Size
- unkn_del
- unkn_Read
- unkn_New
- unkn_Write
- unkn_Size
- def_cont_box_del
- def_cont_box_Read
- def_cont_box_New
- def_cont_box_Write
- def_cont_box_Size
- uuid_del
- uuid_Read
- uuid_New
- uuid_Write
- uuid_Size
- dinf_del
- dinf_AddBox
- dinf_Read
- dinf_New
- dinf_Write
- dinf_Size
- dref_del
- dref_AddDataEntry
- dref_Read
- dref_New
- dref_Write
- dref_Size
- edts_del
- edts_AddBox
- edts_Read
- edts_New
- edts_Write
- edts_Size
- elst_del
- elst_Read
- elst_New
- elst_Write
- elst_Size
- esds_del
- esds_Read
- esds_New
- esds_Write
- esds_Size
- free_del
- free_Read
- free_New
- free_Write
- free_Size
- ftyp_del
- ftyp_New
- ftyp_Read
- ftyp_Write
- ftyp_Size
- gnrm_del
- gnrm_New
- gnrm_Read
- gnrm_Write
- gnrm_Size
- gnrv_del
- gnrv_New
- gnrv_Read
- gnrv_Write
- gnrv_Size
- gnra_del
- gnra_New
- gnra_Read
- gnra_Write
- gnra_Size
- hdlr_del
- hdlr_Read
- hdlr_New
- hdlr_Write
- hdlr_Size
- hinf_del
- hinf_New
- hinf_AddBox
- hinf_Read
- hinf_Write
- hinf_Size
- hmhd_del
- hmhd_Read
- hmhd_New
- hmhd_Write
- hmhd_Size
- hnti_New
- hnti_del
- hnti_AddBox
- hnti_Read
- hnti_Write
- hnti_Size
- sdp_del
- sdp_Read
- sdp_New
- sdp_Write
- sdp_Size
- rtp_hnti_del
- rtp_hnti_Read
- rtp_hnti_New
- rtp_hnti_Write
- rtp_hnti_Size
- trpy_del
- trpy_Read
- trpy_New
- trpy_Write
- trpy_Size
- totl_del
- totl_Read
- totl_New
- totl_Write
- totl_Size
- nump_del
- nump_Read
- nump_New
- nump_Write
- nump_Size
- npck_del
- npck_Read
- npck_New
- npck_Write
- npck_Size
- tpyl_del
- tpyl_Read
- tpyl_New
- tpyl_Write
- tpyl_Size
- tpay_del
- tpay_Read
- tpay_New
- tpay_Write
- tpay_Size
- maxr_del
- maxr_Read
- maxr_New
- maxr_Write
- maxr_Size
- dmed_del
- dmed_Read
- dmed_New
- dmed_Write
- dmed_Size
- dimm_del
- dimm_Read
- dimm_New
- dimm_Write
- dimm_Size
- drep_del
- drep_Read
- drep_New
- drep_Write
- drep_Size
- tmin_del
- tmin_Read
- tmin_New
- tmin_Write
- tmin_Size
- tmax_del
- tmax_Read
- tmax_New
- tmax_Write
- tmax_Size
- pmax_del
- pmax_Read
- pmax_New
- pmax_Write
- pmax_Size
- dmax_del
- dmax_Read
- dmax_New
- dmax_Write
- dmax_Size
- payt_del
- payt_Read
- payt_New
- payt_Write
- payt_Size
- name_del
- name_Read
- name_New
- name_Write
- name_Size
- tssy_del
- tssy_Read
- tssy_New
- tssy_Write
- tssy_Size
- srpp_del
- srpp_AddBox
- srpp_Read
- srpp_New
- srpp_Write
- srpp_Size
- rssr_del
- rssr_Read
- rssr_New
- rssr_Write
- rssr_Size
- iods_del
- iods_Read
- iods_New
- iods_Write
- iods_Size
- mdat_del
- mdat_Read
- mdat_New
- mdat_Write
- mdat_Size
- mdhd_del
- mdhd_Read
- mdhd_New
- mdhd_Write
- mdhd_Size
- mdia_del
- mdia_AddBox
- mdia_Read
- mdia_New
- mdia_Write
- mdia_Size
- mfra_del
- mfra_New
- mfra_AddBox
- mfra_Read
- mfra_Write
- mfra_Size
- tfra_del
- tfra_New
- tfra_Read
- tfra_Write
- tfra_Size
- mfro_del
- mfro_New
- mfro_Read
- mfro_Write
- mfro_Size
- elng_del
- elng_Read
- elng_New
- elng_Write
- elng_Size
- mfhd_del
- mfhd_Read
- mfhd_New
- mfhd_Write
- mfhd_Size
- minf_del
- minf_AddBox
- minf_Read
- minf_New
- minf_Write
- minf_Size
- moof_del
- moof_AddBox
- moof_Read
- moof_New
- moof_Write
- moof_Size
- moov_del
- moov_AddBox
- moov_Read
- moov_New
- moov_Write
- moov_Size
- audio_sample_entry_del
- audio_sample_entry_AddBox
- audio_sample_entry_Read
- audio_sample_entry_New
- enca_New
- audio_sample_entry_Write
- audio_sample_entry_Size
- mp4s_del
- mp4s_AddBox
- mp4s_Read
- mp4s_New
- encs_New
- mp4s_Write
- mp4s_Size
- video_sample_entry_del
- video_sample_entry_AddBox
- video_sample_entry_Read
- video_sample_entry_New
- video_sample_entry_Write
- video_sample_entry_Size
- mvex_del
- mvex_AddBox
- mvex_Read
- mvex_New
- mvex_Write
- mvex_Size
- mehd_New
- mehd_del
- mehd_Read
- mehd_Write
- mehd_Size
- mvhd_del
- mvhd_Read
- mvhd_New
- mvhd_Write
- mvhd_Size
- nmhd_del
- nmhd_Read
- nmhd_New
- nmhd_Write
- nmhd_Size
- padb_del
- padb_Read
- padb_New
- padb_Write
- padb_Size
- rely_del
- rely_Read
- rely_New
- rely_Write
- rely_Size
- rtpo_del
- rtpo_Read
- rtpo_New
- rtpo_Write
- rtpo_Size
- smhd_del
- smhd_Read
- smhd_New
- smhd_Write
- smhd_Size
- snro_del
- snro_Read
- snro_New
- snro_Write
- snro_Size
- stbl_del
- stbl_AddBox
- stbl_Read
- stbl_New
- stbl_Write
- stbl_Size
- stco_del
- stco_Read
- stco_New
- stco_Write
- stco_Size
- stdp_del
- stdp_Read
- stdp_New
- stdp_Write
- stdp_Size
- stsc_del
- stsc_Read
- stsc_New
- stsc_Write
- stsc_Size
- stsd_del
- stsd_AddBox
- stsd_Read
- stsd_New
- stsd_Write
- stsd_Size
- stsf_del
- stsf_Read
- stsf_New
- stsf_Write
- stsf_Size
- stsh_del
- stsh_Read
- stsh_New
- stsh_Write
- stsh_Size
- stss_del
- stss_Read
- stss_New
- stss_Write
- stss_Size
- stsz_del
- stsz_Read
- stsz_New
- stsz_Write
- stsz_Size
- stts_del
- stts_Read
- stts_New
- stts_Write
- stts_Size
- tfhd_del
- tfhd_Read
- tfhd_New
- tfhd_Write
- tfhd_Size
- tims_del
- tims_Read
- tims_New
- tims_Write
- tims_Size
- tkhd_del
- tkhd_Read
- tkhd_New
- tkhd_Write
- tkhd_Size
- traf_del
- traf_AddBox
- traf_Read
- traf_New
- tfxd_New
- tfxd_del
- tfxd_Read
- tfxd_Write
- tfxd_Size
- traf_Write
- traf_Size
- trak_del
- gf_isom_check_sample_desc
- trak_AddBox
- trak_Read
- trak_New
- trak_Write
- trak_Size
- stri_del
- stri_Read
- stri_New
- stri_Write
- stri_Size
- stsg_del
- stsg_Read
- stsg_New
- stsg_Write
- stsg_Size
- strk_del
- strk_AddBox
- strk_Read
- strk_New
- strk_Write
- strk_Size
- tref_AddBox
- tref_del
- tref_Read
- tref_New
- tref_Write
- tref_Size
- reftype_del
- reftype_Read
- reftype_New
- reftype_AddRefTrack
- reftype_Write
- reftype_Size
- trex_del
- trex_Read
- trex_New
- trex_Write
- trex_Size
- trep_del
- trep_Read
- trep_New
- trep_Write
- trep_Size
- trun_del
- trun_Read
- trun_New
- trun_Write
- trun_Size
- tsro_del
- tsro_Read
- tsro_New
- tsro_Write
- tsro_Size
- udta_del
- udta_getEntry
- udta_AddBox
- udta_Read
- udta_New
- udta_Write
- udta_Size
- vmhd_del
- vmhd_Read
- vmhd_New
- vmhd_Write
- vmhd_Size
- void_del
- void_Read
- void_New
- void_Write
- void_Size
- pdin_New
- pdin_del
- pdin_Read
- pdin_Write
- pdin_Size
- sdtp_New
- sdtp_del
- sdtp_Read
- sdtp_Write
- sdtp_Size
- pasp_New
- pasp_del
- pasp_Read
- pasp_Write
- pasp_Size
- clap_New
- clap_del
- clap_Read
- clap_Write
- clap_Size
- metx_New
- metx_del
- metx_AddBox
- metx_Read
- metx_Write
- metx_Size
- txtc_New
- txtc_del
- txtc_Read
- txtc_Write
- txtc_Size
- dac3_New
- dec3_New
- dac3_del
- dac3_Read
- dac3_Write
- dac3_Size
- lsrc_del
- lsrc_Read
- lsrc_New
- lsrc_Write
- lsrc_Size
- lsr1_del
- lsr1_AddBox
- lsr1_Read
- lsr1_New
- lsr1_Write
- lsr1_Size
- sidx_del
- sidx_Read
- sidx_New
- sidx_Write
- sidx_Size
- ssix_del
- ssix_Read
- ssix_New
- ssix_Write
- ssix_Size
- leva_del
- leva_Read
- leva_New
- leva_Write
- leva_Size
- pcrb_New
- pcrb_del
- pcrb_Read
- pcrb_Write
- pcrb_Size
- subs_New
- subs_del
- subs_Write
- subs_Size
- subs_Read
- tfdt_New
- tfdt_del
- tfdt_Read
- tfdt_Write
- tfdt_Size
- rvcc_New
- rvcc_del
- rvcc_Read
- rvcc_Write
- rvcc_Size
- sbgp_New
- sbgp_del
- sbgp_Read
- sbgp_Write
- sbgp_Size
- sgpd_parse_entry
- sgpd_del_entry
- sgpd_write_entry
- sgpd_size_entry
- sgpd_New
- sgpd_del
- sgpd_Read
- sgpd_Write
- sgpd_Size
- saiz_del
- saiz_Read
- saiz_New
- saiz_Write
- saiz_Size
- saio_del
- saio_Read
- saio_New
- saio_Write
- saio_Size
- prft_del
- prft_Read
- prft_New
- prft_Write
- prft_Size
- trgr_New
- trgr_del
- trgr_AddBox
- trgr_Read
- trgr_Write
- trgr_Size
- trgt_New
- trgt_del
- trgt_Read
- trgt_Write
- trgt_Size
- stvi_New
- stvi_del
- stvi_Read
- stvi_Write
- stvi_Size
- fiin_New
- fiin_del
- fiin_AddBox
- fiin_Read
- fiin_Write
- fiin_Size
- paen_New
- paen_del
- paen_AddBox
- paen_Read
- paen_Write
- paen_Size
- fpar_New
- fpar_del
- gf_isom_read_null_terminated_string
- fpar_Read
- fpar_Write
- fpar_Size
- fecr_New
- fecr_del
- fecr_Read
- fecr_Write
- fecr_Size
- segr_New
- segr_del
- segr_Read
- segr_Write
- segr_Size
- gitn_New
- gitn_del
- gitn_Read
- gitn_Write
- gitn_Size
- fdpa_New
- fdpa_del
- fdpa_Read
- fdpa_Write
- fdpa_Size
- extr_New
- extr_del
- extr_Read
- extr_Write
- extr_Size
- fdsa_New
- fdsa_del
- fdsa_AddBox
- fdsa_Read
- fdsa_Write
- fdsa_Size
- trik_del
- trik_Read
- trik_New
- trik_Write
- trik_Size
- bloc_del
- bloc_Read
- bloc_New
- bloc_Write
- bloc_Size
- ainf_del
- ainf_Read
- ainf_New
- ainf_Write
- ainf_Size
#include <gpac/internal/isomedia_dev.h>
#ifndef GPAC_DISABLE_ISOM
void co64_del(GF_Box *s)
{
GF_ChunkLargeOffsetBox *ptr;
ptr = (GF_ChunkLargeOffsetBox *) s;
if (ptr == NULL) return;
if (ptr->offsets) gf_free(ptr->offsets);
gf_free(ptr);
}
GF_Err co64_Read(GF_Box *s,GF_BitStream *bs)
{
u32 entries;
GF_ChunkLargeOffsetBox *ptr = (GF_ChunkLargeOffsetBox *) s;
ptr->nb_entries = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4)
if (ptr->nb_entries > ptr->size / 8) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in co64\n", ptr->nb_entries));
return GF_ISOM_INVALID_FILE;
}
ptr->offsets = (u64 *) gf_malloc(ptr->nb_entries * sizeof(u64) );
if (ptr->offsets == NULL) return GF_OUT_OF_MEM;
ptr->alloc_size = ptr->nb_entries;
for (entries = 0; entries < ptr->nb_entries; entries++) {
ptr->offsets[entries] = gf_bs_read_u64(bs);
}
return GF_OK;
}
GF_Box *co64_New()
{
ISOM_DECL_BOX_ALLOC(GF_ChunkLargeOffsetBox, GF_ISOM_BOX_TYPE_CO64);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err co64_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_ChunkLargeOffsetBox *ptr = (GF_ChunkLargeOffsetBox *) s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->nb_entries);
for (i = 0; i < ptr->nb_entries; i++ ) {
gf_bs_write_u64(bs, ptr->offsets[i]);
}
return GF_OK;
}
GF_Err co64_Size(GF_Box *s)
{
GF_ChunkLargeOffsetBox *ptr = (GF_ChunkLargeOffsetBox *) s;
ptr->size += 4 + (8 * ptr->nb_entries);
return GF_OK;
}
#endif
void cprt_del(GF_Box *s)
{
GF_CopyrightBox *ptr = (GF_CopyrightBox *) s;
if (ptr == NULL) return;
if (ptr->notice)
gf_free(ptr->notice);
gf_free(ptr);
}
GF_Box *chpl_New()
{
ISOM_DECL_BOX_ALLOC(GF_ChapterListBox, GF_ISOM_BOX_TYPE_CHPL);
tmp->list = gf_list_new();
tmp->version = 1;
return (GF_Box *)tmp;
}
void chpl_del(GF_Box *s)
{
GF_ChapterListBox *ptr = (GF_ChapterListBox *) s;
if (ptr == NULL) return;
while (gf_list_count(ptr->list)) {
GF_ChapterEntry *ce = (GF_ChapterEntry *)gf_list_get(ptr->list, 0);
if (ce->name) gf_free(ce->name);
gf_free(ce);
gf_list_rem(ptr->list, 0);
}
gf_list_del(ptr->list);
gf_free(ptr);
}
GF_Err chpl_Read(GF_Box *s,GF_BitStream *bs)
{
GF_ChapterEntry *ce;
u32 nb_chaps, len, i, count;
GF_ChapterListBox *ptr = (GF_ChapterListBox *)s;
gf_bs_read_u32(bs);
nb_chaps = gf_bs_read_u8(bs);
count = 0;
while (nb_chaps) {
GF_SAFEALLOC(ce, GF_ChapterEntry);
if (!ce) return GF_OUT_OF_MEM;
ce->start_time = gf_bs_read_u64(bs);
len = gf_bs_read_u8(bs);
if (len) {
ce->name = (char *)gf_malloc(sizeof(char)*(len+1));
gf_bs_read_data(bs, ce->name, len);
ce->name[len] = 0;
} else {
ce->name = gf_strdup("");
}
for (i=0; i<count; i++) {
GF_ChapterEntry *ace = (GF_ChapterEntry *) gf_list_get(ptr->list, i);
if (ace->start_time >= ce->start_time) {
gf_list_insert(ptr->list, ce, i);
ce = NULL;
break;
}
}
if (ce) gf_list_add(ptr->list, ce);
count++;
nb_chaps--;
}
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err chpl_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 count, i;
GF_ChapterListBox *ptr = (GF_ChapterListBox *) s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
count = gf_list_count(ptr->list);
gf_bs_write_u32(bs, 0);
gf_bs_write_u8(bs, count);
for (i=0; i<count; i++) {
u32 len;
GF_ChapterEntry *ce = (GF_ChapterEntry *)gf_list_get(ptr->list, i);
gf_bs_write_u64(bs, ce->start_time);
if (ce->name) {
len = (u32) strlen(ce->name);
if (len>255) len = 255;
gf_bs_write_u8(bs, len);
gf_bs_write_data(bs, ce->name, len);
} else {
gf_bs_write_u8(bs, 0);
}
}
return GF_OK;
}
GF_Err chpl_Size(GF_Box *s)
{
u32 count, i;
GF_ChapterListBox *ptr = (GF_ChapterListBox *)s;
ptr->size += 5;
count = gf_list_count(ptr->list);
for (i=0; i<count; i++) {
GF_ChapterEntry *ce = (GF_ChapterEntry *)gf_list_get(ptr->list, i);
ptr->size += 9;
if (ce->name) ptr->size += strlen(ce->name);
}
return GF_OK;
}
#endif
GF_Err cprt_Read(GF_Box *s,GF_BitStream *bs)
{
GF_CopyrightBox *ptr = (GF_CopyrightBox *)s;
gf_bs_read_int(bs, 1);
ptr->packedLanguageCode[0] = gf_bs_read_int(bs, 5);
ptr->packedLanguageCode[1] = gf_bs_read_int(bs, 5);
ptr->packedLanguageCode[2] = gf_bs_read_int(bs, 5);
ISOM_DECREASE_SIZE(ptr, 2);
if (ptr->packedLanguageCode[0] || ptr->packedLanguageCode[1] || ptr->packedLanguageCode[2]) {
ptr->packedLanguageCode[0] += 0x60;
ptr->packedLanguageCode[1] += 0x60;
ptr->packedLanguageCode[2] += 0x60;
} else {
ptr->packedLanguageCode[0] = 'u';
ptr->packedLanguageCode[1] = 'n';
ptr->packedLanguageCode[2] = 'd';
}
if (ptr->size) {
u32 bytesToRead = (u32) ptr->size;
ptr->notice = (char*)gf_malloc(bytesToRead * sizeof(char));
if (ptr->notice == NULL) return GF_OUT_OF_MEM;
gf_bs_read_data(bs, ptr->notice, bytesToRead);
}
return GF_OK;
}
GF_Box *cprt_New()
{
ISOM_DECL_BOX_ALLOC(GF_CopyrightBox, GF_ISOM_BOX_TYPE_CPRT);
tmp->packedLanguageCode[0] = 'u';
tmp->packedLanguageCode[1] = 'n';
tmp->packedLanguageCode[2] = 'd';
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err cprt_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_CopyrightBox *ptr = (GF_CopyrightBox *) s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_int(bs, 0, 1);
if (ptr->packedLanguageCode[0]) {
gf_bs_write_int(bs, ptr->packedLanguageCode[0] - 0x60, 5);
gf_bs_write_int(bs, ptr->packedLanguageCode[1] - 0x60, 5);
gf_bs_write_int(bs, ptr->packedLanguageCode[2] - 0x60, 5);
} else {
gf_bs_write_int(bs, 0, 15);
}
if (ptr->notice) {
gf_bs_write_data(bs, ptr->notice, (u32) (strlen(ptr->notice) + 1) );
}
return GF_OK;
}
GF_Err cprt_Size(GF_Box *s)
{
GF_CopyrightBox *ptr = (GF_CopyrightBox *)s;
ptr->size += 2;
if (ptr->notice)
ptr->size += strlen(ptr->notice) + 1;
return GF_OK;
}
#endif
void kind_del(GF_Box *s)
{
GF_KindBox *ptr = (GF_KindBox *) s;
if (ptr == NULL) return;
if (ptr->schemeURI) gf_free(ptr->schemeURI);
if (ptr->value) gf_free(ptr->value);
gf_free(ptr);
}
GF_Err kind_Read(GF_Box *s,GF_BitStream *bs)
{
GF_KindBox *ptr = (GF_KindBox *)s;
if (ptr->size) {
u32 bytesToRead = (u32) ptr->size;
char *data;
u32 schemeURIlen;
data = (char*)gf_malloc(bytesToRead * sizeof(char));
if (data == NULL) return GF_OUT_OF_MEM;
gf_bs_read_data(bs, data, bytesToRead);
if (data[bytesToRead-1]) {
char *str = (char*)gf_malloc((u32) bytesToRead + 1);
memcpy(str, data, (u32) bytesToRead);
str[ptr->size] = 0;
gf_free(data);
data = str;
bytesToRead++;
}
ptr->schemeURI = gf_strdup(data);
schemeURIlen = (u32) strlen(data);
if (bytesToRead > schemeURIlen+1) {
char *data_value = data + schemeURIlen +1;
ptr->value = gf_strdup(data_value);
}
gf_free(data);
}
return GF_OK;
}
GF_Box *kind_New()
{
ISOM_DECL_BOX_ALLOC(GF_KindBox, GF_ISOM_BOX_TYPE_KIND);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err kind_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_KindBox *ptr = (GF_KindBox *) s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_data(bs, ptr->schemeURI, (u32) (strlen(ptr->schemeURI) + 1 ));
if (ptr->value) {
gf_bs_write_data(bs, ptr->value, (u32) (strlen(ptr->value) + 1) );
}
return GF_OK;
}
GF_Err kind_Size(GF_Box *s)
{
GF_KindBox *ptr = (GF_KindBox *)s;
ptr->size += strlen(ptr->schemeURI) + 1;
if (ptr->value) {
ptr->size += strlen(ptr->value) + 1;
}
return GF_OK;
}
#endif
void ctts_del(GF_Box *s)
{
GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s;
if (ptr->entries) gf_free(ptr->entries);
gf_free(ptr);
}
GF_Err ctts_Read(GF_Box *s, GF_BitStream *bs)
{
u32 i;
u32 sampleCount;
GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s;
ptr->nb_entries = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
if (ptr->nb_entries > ptr->size / 8) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in ctts\n", ptr->nb_entries));
return GF_ISOM_INVALID_FILE;
}
ptr->alloc_size = ptr->nb_entries;
ptr->entries = (GF_DttsEntry *)gf_malloc(sizeof(GF_DttsEntry)*ptr->alloc_size);
if (!ptr->entries) return GF_OUT_OF_MEM;
sampleCount = 0;
for (i=0; i<ptr->nb_entries; i++) {
ptr->entries[i].sampleCount = gf_bs_read_u32(bs);
if (ptr->version)
ptr->entries[i].decodingOffset = gf_bs_read_int(bs, 32);
else
ptr->entries[i].decodingOffset = (s32) gf_bs_read_u32(bs);
sampleCount += ptr->entries[i].sampleCount;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
ptr->w_LastSampleNumber = sampleCount;
#endif
return GF_OK;
}
GF_Box *ctts_New()
{
ISOM_DECL_BOX_ALLOC(GF_CompositionOffsetBox, GF_ISOM_BOX_TYPE_CTTS);
return (GF_Box *) tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err ctts_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->nb_entries);
for (i=0; i<ptr->nb_entries; i++ ) {
gf_bs_write_u32(bs, ptr->entries[i].sampleCount);
if (ptr->version) {
gf_bs_write_int(bs, ptr->entries[i].decodingOffset, 32);
} else {
gf_bs_write_u32(bs, (u32) ptr->entries[i].decodingOffset);
}
}
return GF_OK;
}
GF_Err ctts_Size(GF_Box *s)
{
GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *) s;
ptr->size += 4 + (8 * ptr->nb_entries);
return GF_OK;
}
#endif
void cslg_del(GF_Box *s)
{
GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
if (ptr == NULL) return;
gf_free(ptr);
return;
}
GF_Err cslg_Read(GF_Box *s, GF_BitStream *bs)
{
GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
ptr->compositionToDTSShift = gf_bs_read_int(bs, 32);
ptr->leastDecodeToDisplayDelta = gf_bs_read_int(bs, 32);
ptr->greatestDecodeToDisplayDelta = gf_bs_read_int(bs, 32);
ptr->compositionStartTime = gf_bs_read_int(bs, 32);
ptr->compositionEndTime = gf_bs_read_int(bs, 32);
return GF_OK;
}
GF_Box *cslg_New()
{
ISOM_DECL_BOX_ALLOC(GF_CompositionToDecodeBox, GF_ISOM_BOX_TYPE_CSLG);
return (GF_Box *) tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err cslg_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_int(bs, ptr->compositionToDTSShift, 32);
gf_bs_write_int(bs, ptr->leastDecodeToDisplayDelta, 32);
gf_bs_write_int(bs, ptr->greatestDecodeToDisplayDelta, 32);
gf_bs_write_int(bs, ptr->compositionStartTime, 32);
gf_bs_write_int(bs, ptr->compositionEndTime, 32);
return GF_OK;
}
GF_Err cslg_Size(GF_Box *s)
{
GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s;
ptr->size += 20;
return GF_OK;
}
#endif
void ccst_del(GF_Box *s)
{
GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s;
if (ptr) gf_free(ptr);
return;
}
GF_Err ccst_Read(GF_Box *s, GF_BitStream *bs)
{
GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s;
ISOM_DECREASE_SIZE(ptr, 4);
ptr->all_ref_pics_intra = gf_bs_read_int(bs, 1);
ptr->intra_pred_used = gf_bs_read_int(bs, 1);
ptr->max_ref_per_pic = gf_bs_read_int(bs, 4);
ptr->reserved = gf_bs_read_int(bs, 26);
return GF_OK;
}
GF_Box *ccst_New()
{
ISOM_DECL_BOX_ALLOC(GF_CodingConstraintsBox, GF_ISOM_BOX_TYPE_CCST);
return (GF_Box *) tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err ccst_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_int(bs, ptr->all_ref_pics_intra, 1);
gf_bs_write_int(bs, ptr->intra_pred_used, 1);
gf_bs_write_int(bs, ptr->max_ref_per_pic, 4);
gf_bs_write_int(bs, 0, 26);
return GF_OK;
}
GF_Err ccst_Size(GF_Box *s)
{
GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s;
ptr->size += 4;
return GF_OK;
}
#endif
void url_del(GF_Box *s)
{
GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;
if (ptr == NULL) return;
if (ptr->location) gf_free(ptr->location);
gf_free(ptr);
return;
}
GF_Err url_Read(GF_Box *s, GF_BitStream *bs)
{
GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;
if (ptr->size) {
ptr->location = (char*)gf_malloc((u32) ptr->size);
if (! ptr->location) return GF_OUT_OF_MEM;
gf_bs_read_data(bs, ptr->location, (u32)ptr->size);
}
return GF_OK;
}
GF_Box *url_New()
{
ISOM_DECL_BOX_ALLOC(GF_DataEntryURLBox, GF_ISOM_BOX_TYPE_URL);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err url_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
if ( !(ptr->flags & 1)) {
if (ptr->location) {
gf_bs_write_data(bs, ptr->location, (u32)strlen(ptr->location) + 1);
}
}
return GF_OK;
}
GF_Err url_Size(GF_Box *s)
{
GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s;
if ( !(ptr->flags & 1)) {
if (ptr->location) ptr->size += 1 + strlen(ptr->location);
}
return GF_OK;
}
#endif
void urn_del(GF_Box *s)
{
GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;
if (ptr == NULL) return;
if (ptr->location) gf_free(ptr->location);
if (ptr->nameURN) gf_free(ptr->nameURN);
gf_free(ptr);
}
GF_Err urn_Read(GF_Box *s, GF_BitStream *bs)
{
u32 i, to_read;
char *tmpName;
GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;
if (! ptr->size ) return GF_OK;
to_read = (u32) ptr->size;
tmpName = (char*)gf_malloc(sizeof(char) * to_read);
if (!tmpName) return GF_OUT_OF_MEM;
gf_bs_read_data(bs, tmpName, to_read);
i = 0;
while ( (tmpName[i] != 0) && (i < to_read) ) {
i++;
}
if (i == to_read) {
gf_free(tmpName);
return GF_ISOM_INVALID_FILE;
}
if (i == to_read - 1) {
ptr->nameURN = tmpName;
ptr->location = NULL;
return GF_OK;
}
ptr->nameURN = (char*)gf_malloc(sizeof(char) * (i+1));
if (!ptr->nameURN) {
gf_free(tmpName);
return GF_OUT_OF_MEM;
}
ptr->location = (char*)gf_malloc(sizeof(char) * (to_read - i - 1));
if (!ptr->location) {
gf_free(tmpName);
gf_free(ptr->nameURN);
ptr->nameURN = NULL;
return GF_OUT_OF_MEM;
}
memcpy(ptr->nameURN, tmpName, i + 1);
memcpy(ptr->location, tmpName + i + 1, (to_read - i - 1));
gf_free(tmpName);
return GF_OK;
}
GF_Box *urn_New()
{
ISOM_DECL_BOX_ALLOC(GF_DataEntryURNBox, GF_ISOM_BOX_TYPE_URN);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err urn_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
if ( !(ptr->flags & 1)) {
if (ptr->nameURN) {
gf_bs_write_data(bs, ptr->nameURN, (u32)strlen(ptr->nameURN) + 1);
}
if (ptr->location) {
gf_bs_write_data(bs, ptr->location, (u32)strlen(ptr->location) + 1);
}
}
return GF_OK;
}
GF_Err urn_Size(GF_Box *s)
{
GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s;
if ( !(ptr->flags & 1)) {
if (ptr->nameURN) ptr->size += 1 + strlen(ptr->nameURN);
if (ptr->location) ptr->size += 1 + strlen(ptr->location);
}
return GF_OK;
}
#endif
void unkn_del(GF_Box *s)
{
GF_UnknownBox *ptr = (GF_UnknownBox *) s;
if (!s) return;
if (ptr->data) gf_free(ptr->data);
gf_free(ptr);
}
GF_Err unkn_Read(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 bytesToRead, sub_size, sub_a;
GF_BitStream *sub_bs;
GF_UnknownBox *ptr = (GF_UnknownBox *)s;
if (ptr->size > 0xFFFFFFFF) return GF_ISOM_INVALID_FILE;
bytesToRead = (u32) (ptr->size);
if (!bytesToRead) return GF_OK;
if (bytesToRead>1000000) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Unknown box %s (0x%08X) with payload larger than 1 MBytes, ignoring\n", gf_4cc_to_str(ptr->type), ptr->type ));
gf_bs_skip_bytes(bs, ptr->dataSize);
return GF_OK;
}
ptr->data = (char*)gf_malloc(bytesToRead);
if (ptr->data == NULL ) return GF_OUT_OF_MEM;
ptr->dataSize = bytesToRead;
gf_bs_read_data(bs, ptr->data, ptr->dataSize);
sub_bs = gf_bs_new(ptr->data, ptr->dataSize, GF_BITSTREAM_READ);
sub_size = gf_bs_read_u32(sub_bs);
sub_a = gf_bs_read_u8(sub_bs);
e = (sub_size && (sub_size <= ptr->dataSize)) ? GF_OK : GF_NOT_SUPPORTED;
if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED;
sub_a = gf_bs_read_u8(sub_bs);
if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED;
sub_a = gf_bs_read_u8(sub_bs);
if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED;
sub_a = gf_bs_read_u8(sub_bs);
if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED;
if (e == GF_OK) {
gf_bs_seek(sub_bs, 0);
e = gf_isom_box_array_read(s, sub_bs, gf_isom_box_add_default);
}
gf_bs_del(sub_bs);
if (e==GF_OK) {
gf_free(ptr->data);
ptr->data = NULL;
ptr->dataSize = 0;
} else if (s->other_boxes) {
gf_isom_box_array_del(s->other_boxes);
s->other_boxes=NULL;
}
return GF_OK;
}
GF_Box *unkn_New(u32 box_type)
{
ISOM_DECL_BOX_ALLOC(GF_UnknownBox, GF_ISOM_BOX_TYPE_UNKNOWN);
tmp->original_4cc = box_type;
return (GF_Box *) tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err unkn_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 type = s->type;
GF_UnknownBox *ptr = (GF_UnknownBox *)s;
if (!s) return GF_BAD_PARAM;
s->type = ptr->original_4cc;
e = gf_isom_box_write_header(s, bs);
s->type = type;
if (e) return e;
if (ptr->dataSize && ptr->data) {
gf_bs_write_data(bs, ptr->data, ptr->dataSize);
}
return GF_OK;
}
GF_Err unkn_Size(GF_Box *s)
{
GF_UnknownBox *ptr = (GF_UnknownBox *)s;
if (ptr->dataSize && ptr->data) {
ptr->size += ptr->dataSize;
}
return GF_OK;
}
#endif
void def_cont_box_del(GF_Box *s)
{
if (s) gf_free(s);
}
GF_Err def_cont_box_Read(GF_Box *s, GF_BitStream *bs)
{
return gf_isom_box_array_read(s, bs, gf_isom_box_add_default);
}
GF_Box *def_cont_box_New()
{
ISOM_DECL_BOX_ALLOC(GF_Box, 0);
return (GF_Box *) tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITEHintSa
GF_Err def_cont_box_Write(GF_Box *s, GF_BitStream *bs)
{
return gf_isom_box_write_header(s, bs);
}
GF_Err def_cont_box_Size(GF_Box *s)
{
return GF_OK;
}
#endif
void uuid_del(GF_Box *s)
{
GF_UnknownUUIDBox *ptr = (GF_UnknownUUIDBox *) s;
if (!s) return;
if (ptr->data) gf_free(ptr->data);
gf_free(ptr);
}
GF_Err uuid_Read(GF_Box *s, GF_BitStream *bs)
{
u32 bytesToRead;
GF_UnknownUUIDBox *ptr = (GF_UnknownUUIDBox *)s;
if (ptr->size > 0xFFFFFFFF) return GF_ISOM_INVALID_FILE;
bytesToRead = (u32) (ptr->size);
if (bytesToRead) {
ptr->data = (char*)gf_malloc(bytesToRead);
if (ptr->data == NULL ) return GF_OUT_OF_MEM;
ptr->dataSize = bytesToRead;
gf_bs_read_data(bs, ptr->data, ptr->dataSize);
}
return GF_OK;
}
GF_Box *uuid_New()
{
ISOM_DECL_BOX_ALLOC(GF_UnknownUUIDBox, GF_ISOM_BOX_TYPE_UUID);
return (GF_Box *) tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err uuid_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_UnknownUUIDBox *ptr = (GF_UnknownUUIDBox*)s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
if (ptr->data) {
gf_bs_write_data(bs, ptr->data, ptr->dataSize);
}
return GF_OK;
}
GF_Err uuid_Size(GF_Box *s)
{
GF_UnknownUUIDBox*ptr = (GF_UnknownUUIDBox*)s;
ptr->size += ptr->dataSize;
return GF_OK;
}
#endif
void dinf_del(GF_Box *s)
{
GF_DataInformationBox *ptr = (GF_DataInformationBox *)s;
if (ptr == NULL) return;
gf_isom_box_del((GF_Box *)ptr->dref);
gf_free(ptr);
}
GF_Err dinf_AddBox(GF_Box *s, GF_Box *a)
{
GF_DataInformationBox *ptr = (GF_DataInformationBox *)s;
switch(a->type) {
case GF_ISOM_BOX_TYPE_DREF:
if (ptr->dref) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->dref = (GF_DataReferenceBox *)a;
return GF_OK;
default:
return gf_isom_box_add_default(s, a);
}
return GF_OK;
}
GF_Err dinf_Read(GF_Box *s, GF_BitStream *bs)
{
GF_Err e = gf_isom_box_array_read(s, bs, dinf_AddBox);
if (e) {
return e;
}
if (!((GF_DataInformationBox *)s)->dref) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing dref box in dinf\n"));
((GF_DataInformationBox *)s)->dref = (GF_DataReferenceBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_DREF);
}
return GF_OK;
}
GF_Box *dinf_New()
{
ISOM_DECL_BOX_ALLOC(GF_DataInformationBox, GF_ISOM_BOX_TYPE_DINF);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err dinf_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_DataInformationBox *ptr = (GF_DataInformationBox *)s;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
if (ptr->dref) {
e = gf_isom_box_write((GF_Box *)ptr->dref, bs);
if (e) return e;
}
return GF_OK;
}
GF_Err dinf_Size(GF_Box *s)
{
GF_Err e;
GF_DataInformationBox *ptr = (GF_DataInformationBox *)s;
if (ptr->dref) {
e = gf_isom_box_size((GF_Box *) ptr->dref);
if (e) return e;
ptr->size += ptr->dref->size;
}
return GF_OK;
}
#endif
void dref_del(GF_Box *s)
{
GF_DataReferenceBox *ptr = (GF_DataReferenceBox *) s;
if (ptr == NULL) return;
gf_free(ptr);
}
GF_Err dref_AddDataEntry(GF_Box *ptr, GF_Box *entry)
{
if (entry->type==GF_4CC('a','l','i','s')) {
GF_DataEntryURLBox *urle = (GF_DataEntryURLBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_URL);
urle->flags = 1;
gf_isom_box_del(entry);
gf_isom_box_add_default(ptr, (GF_Box *)urle);
GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[iso file] Apple \'alis\' box found, not supported - converting to self-pointing \'url \' \n" ));
} else {
return gf_isom_box_add_default(ptr, entry);
}
return GF_OK;
}
GF_Err dref_Read(GF_Box *s, GF_BitStream *bs)
{
GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
return gf_isom_box_array_read(s, bs, dref_AddDataEntry);
}
GF_Box *dref_New()
{
ISOM_DECL_BOX_ALLOC(GF_DataReferenceBox, GF_ISOM_BOX_TYPE_DREF);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err dref_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 count;
GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
count = ptr->other_boxes ? gf_list_count(ptr->other_boxes) : 0;
gf_bs_write_u32(bs, count);
return GF_OK;
}
GF_Err dref_Size(GF_Box *s)
{
GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s;
if (!s) return GF_BAD_PARAM;
ptr->size += 4;
return GF_OK;
}
#endif
void edts_del(GF_Box *s)
{
GF_EditBox *ptr = (GF_EditBox *) s;
gf_isom_box_del((GF_Box *)ptr->editList);
gf_free(ptr);
}
GF_Err edts_AddBox(GF_Box *s, GF_Box *a)
{
GF_EditBox *ptr = (GF_EditBox *)s;
if (a->type == GF_ISOM_BOX_TYPE_ELST) {
if (ptr->editList) return GF_BAD_PARAM;
ptr->editList = (GF_EditListBox *)a;
return GF_OK;
} else {
return gf_isom_box_add_default(s, a);
}
return GF_OK;
}
GF_Err edts_Read(GF_Box *s, GF_BitStream *bs)
{
return gf_isom_box_array_read(s, bs, edts_AddBox);
}
GF_Box *edts_New()
{
ISOM_DECL_BOX_ALLOC(GF_EditBox, GF_ISOM_BOX_TYPE_EDTS);
return (GF_Box *) tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err edts_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_EditBox *ptr = (GF_EditBox *)s;
if (ptr->editList && gf_list_count(ptr->editList->entryList)) {
e = gf_isom_box_write_header(s, bs);
if (e) return e;
e = gf_isom_box_write((GF_Box *) ptr->editList, bs);
if (e) return e;
}
return GF_OK;
}
GF_Err edts_Size(GF_Box *s)
{
GF_Err e;
GF_EditBox *ptr = (GF_EditBox *)s;
if (!ptr->editList || ! gf_list_count(ptr->editList->entryList)) {
ptr->size = 0;
} else {
e = gf_isom_box_size((GF_Box *)ptr->editList);
if (e) return e;
ptr->size += ptr->editList->size;
}
return GF_OK;
}
#endif
void elst_del(GF_Box *s)
{
GF_EditListBox *ptr;
GF_EdtsEntry *p;
u32 nb_entries;
u32 i;
ptr = (GF_EditListBox *)s;
if (ptr == NULL) return;
nb_entries = gf_list_count(ptr->entryList);
for (i = 0; i < nb_entries; i++) {
p = (GF_EdtsEntry*)gf_list_get(ptr->entryList, i);
if (p) gf_free(p);
}
gf_list_del(ptr->entryList);
gf_free(ptr);
}
GF_Err elst_Read(GF_Box *s, GF_BitStream *bs)
{
u32 entries;
s32 tr;
u32 nb_entries;
GF_EdtsEntry *p;
GF_EditListBox *ptr = (GF_EditListBox *)s;
nb_entries = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
if (ptr->version == 1) {
if (nb_entries > ptr->size / 20) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in ctts\n", nb_entries));
return GF_ISOM_INVALID_FILE;
}
} else {
if (nb_entries > ptr->size / 12) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in ctts\n", nb_entries));
return GF_ISOM_INVALID_FILE;
}
}
for (entries = 0; entries < nb_entries; entries++ ) {
p = (GF_EdtsEntry *) gf_malloc(sizeof(GF_EdtsEntry));
if (!p) return GF_OUT_OF_MEM;
if (ptr->version == 1) {
p->segmentDuration = gf_bs_read_u64(bs);
p->mediaTime = (s64) gf_bs_read_u64(bs);
} else {
p->segmentDuration = gf_bs_read_u32(bs);
tr = gf_bs_read_u32(bs);
p->mediaTime = (s64) tr;
}
p->mediaRate = gf_bs_read_u16(bs);
gf_bs_read_u16(bs);
gf_list_add(ptr->entryList, p);
}
return GF_OK;
}
GF_Box *elst_New()
{
ISOM_DECL_BOX_ALLOC(GF_EditListBox, GF_ISOM_BOX_TYPE_ELST);
tmp->entryList = gf_list_new();
if (!tmp->entryList) {
gf_free(tmp);
return NULL;
}
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err elst_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
u32 nb_entries;
GF_EdtsEntry *p;
GF_EditListBox *ptr = (GF_EditListBox *)s;
if (!ptr) return GF_BAD_PARAM;
nb_entries = gf_list_count(ptr->entryList);
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, nb_entries);
for (i = 0; i < nb_entries; i++ ) {
p = (GF_EdtsEntry*)gf_list_get(ptr->entryList, i);
if (ptr->version == 1) {
gf_bs_write_u64(bs, p->segmentDuration);
gf_bs_write_u64(bs, p->mediaTime);
} else {
gf_bs_write_u32(bs, (u32) p->segmentDuration);
gf_bs_write_u32(bs, (s32) p->mediaTime);
}
gf_bs_write_u16(bs, p->mediaRate);
gf_bs_write_u16(bs, 0);
}
return GF_OK;
}
GF_Err elst_Size(GF_Box *s)
{
u32 durtimebytes;
u32 i, nb_entries;
GF_EditListBox *ptr = (GF_EditListBox *)s;
ptr->size += 4;
nb_entries = gf_list_count(ptr->entryList);
ptr->version = 0;
for (i=0; i<nb_entries; i++) {
GF_EdtsEntry *p = (GF_EdtsEntry*)gf_list_get(ptr->entryList, i);
if ((p->segmentDuration>0xFFFFFFFF) || (p->mediaTime>0xFFFFFFFF)) {
ptr->version = 1;
break;
}
}
durtimebytes = (ptr->version == 1 ? 16 : 8) + 4;
ptr->size += (nb_entries * durtimebytes);
return GF_OK;
}
#endif
void esds_del(GF_Box *s)
{
GF_ESDBox *ptr = (GF_ESDBox *)s;
if (ptr == NULL) return;
if (ptr->desc) gf_odf_desc_del((GF_Descriptor *)ptr->desc);
gf_free(ptr);
}
GF_Err esds_Read(GF_Box *s, GF_BitStream *bs)
{
GF_Err e=GF_OK;
u32 descSize;
char *enc_desc;
u32 SLIsPredefined(GF_SLConfig *sl);
GF_ESDBox *ptr = (GF_ESDBox *)s;
descSize = (u32) (ptr->size);
if (descSize) {
enc_desc = (char*)gf_malloc(sizeof(char) * descSize);
if (!enc_desc) return GF_OUT_OF_MEM;
gf_bs_read_data(bs, enc_desc, descSize);
e = gf_odf_desc_read(enc_desc, descSize, (GF_Descriptor **) &ptr->desc);
gf_free(enc_desc);
if (ptr->desc && (ptr->desc->tag!=GF_ODF_ESD_TAG) ) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid descriptor tag 0x%x in esds\n", ptr->desc->tag));
gf_odf_desc_del((GF_Descriptor*)ptr->desc);
ptr->desc=NULL;
return GF_ISOM_INVALID_FILE;
}
if (e) {
ptr->desc = NULL;
} else {
if (!ptr->desc->URLString) {
if (!ptr->desc->slConfig) {
ptr->desc->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG);
ptr->desc->slConfig->predefined = SLPredef_MP4;
} else if (ptr->desc->slConfig->predefined != SLPredef_MP4) {
ptr->desc->slConfig->predefined = SLPredef_MP4;
gf_odf_slc_set_pref(ptr->desc->slConfig);
}
}
}
}
return e;
}
GF_Box *esds_New()
{
ISOM_DECL_BOX_ALLOC(GF_ESDBox, GF_ISOM_BOX_TYPE_ESDS);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err esds_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
char *enc_desc;
u32 descSize = 0;
GF_ESDBox *ptr = (GF_ESDBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
e = gf_odf_desc_write((GF_Descriptor *)ptr->desc, &enc_desc, &descSize);
if (e) return e;
gf_bs_write_data(bs, enc_desc, descSize);
gf_free(enc_desc);
return GF_OK;
}
GF_Err esds_Size(GF_Box *s)
{
u32 descSize = 0;
GF_ESDBox *ptr = (GF_ESDBox *)s;
descSize = gf_odf_desc_size((GF_Descriptor *)ptr->desc);
ptr->size += descSize;
return GF_OK;
}
#endif
void free_del(GF_Box *s)
{
GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;
if (ptr->data) gf_free(ptr->data);
gf_free(ptr);
}
GF_Err free_Read(GF_Box *s, GF_BitStream *bs)
{
u32 bytesToRead;
GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;
if (ptr->size > 0xFFFFFFFF) return GF_IO_ERR;
bytesToRead = (u32) (ptr->size);
if (bytesToRead) {
ptr->data = (char*)gf_malloc(bytesToRead * sizeof(char));
gf_bs_read_data(bs, ptr->data, bytesToRead);
ptr->dataSize = bytesToRead;
}
return GF_OK;
}
GF_Box *free_New()
{
ISOM_DECL_BOX_ALLOC(GF_FreeSpaceBox, GF_ISOM_BOX_TYPE_FREE);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err free_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;
if (ptr->original_4cc) {
u32 t = s->type;
s->type=ptr->original_4cc;
e = gf_isom_box_write_header(s, bs);
s->type=t;
} else {
e = gf_isom_box_write_header(s, bs);
}
if (e) return e;
if (ptr->dataSize) {
if (ptr->data) {
gf_bs_write_data(bs, ptr->data, ptr->dataSize);
} else {
u32 i = 0;
while (i<ptr->dataSize) {
gf_bs_write_u8(bs, 0);
i++;
}
}
}
return GF_OK;
}
GF_Err free_Size(GF_Box *s)
{
GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s;
ptr->size += ptr->dataSize;
return GF_OK;
}
#endif
void ftyp_del(GF_Box *s)
{
GF_FileTypeBox *ptr = (GF_FileTypeBox *) s;
if (ptr->altBrand) gf_free(ptr->altBrand);
gf_free(ptr);
}
GF_Box *ftyp_New()
{
ISOM_DECL_BOX_ALLOC(GF_FileTypeBox, GF_ISOM_BOX_TYPE_FTYP);
return (GF_Box *)tmp;
}
GF_Err ftyp_Read(GF_Box *s,GF_BitStream *bs)
{
u32 i;
GF_FileTypeBox *ptr = (GF_FileTypeBox *)s;
if (ptr->size < 8) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Found ftyp with size < 8, likely broken!\n"));
return GF_BAD_PARAM;
}
ptr->majorBrand = gf_bs_read_u32(bs);
ptr->minorVersion = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 8);
ptr->altCount = ( (u32) (ptr->size)) / 4;
if (!ptr->altCount) return GF_OK;
if (ptr->altCount * 4 != (u32) (ptr->size)) return GF_ISOM_INVALID_FILE;
ptr->altBrand = (u32*)gf_malloc(sizeof(u32)*ptr->altCount);
for (i = 0; i<ptr->altCount; i++) {
ptr->altBrand[i] = gf_bs_read_u32(bs);
}
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err ftyp_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_FileTypeBox *ptr = (GF_FileTypeBox *) s;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->majorBrand);
gf_bs_write_u32(bs, ptr->minorVersion);
for (i=0; i<ptr->altCount; i++) {
gf_bs_write_u32(bs, ptr->altBrand[i]);
}
return GF_OK;
}
GF_Err ftyp_Size(GF_Box *s)
{
GF_FileTypeBox *ptr = (GF_FileTypeBox *)s;
ptr->size += 8 + ptr->altCount * 4;
return GF_OK;
}
#endif
void gnrm_del(GF_Box *s)
{
GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s;
gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
if (ptr->data) gf_free(ptr->data);
gf_free(ptr);
}
GF_Box *gnrm_New()
{
ISOM_DECL_BOX_ALLOC(GF_GenericSampleEntryBox, GF_ISOM_BOX_TYPE_GNRM);
gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
return (GF_Box *)tmp;
}
GF_Err gnrm_Read(GF_Box *s, GF_BitStream *bs)
{
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err gnrm_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s;
ptr->type = ptr->EntryType;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
ptr->type = GF_ISOM_BOX_TYPE_GNRM;
gf_bs_write_data(bs, ptr->reserved, 6);
gf_bs_write_u16(bs, ptr->dataReferenceIndex);
gf_bs_write_data(bs, ptr->data, ptr->data_size);
return GF_OK;
}
GF_Err gnrm_Size(GF_Box *s)
{
GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s;
s->type = GF_ISOM_BOX_TYPE_GNRM;
ptr->size += 8+ptr->data_size;
return GF_OK;
}
#endif
void gnrv_del(GF_Box *s)
{
GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s;
gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
if (ptr->data) gf_free(ptr->data);
gf_free(ptr);
}
GF_Box *gnrv_New()
{
ISOM_DECL_BOX_ALLOC(GF_GenericVisualSampleEntryBox, GF_ISOM_BOX_TYPE_GNRV);
gf_isom_video_sample_entry_init((GF_VisualSampleEntryBox*) tmp);
return (GF_Box *)tmp;
}
GF_Err gnrv_Read(GF_Box *s, GF_BitStream *bs)
{
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err gnrv_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s;
ptr->type = ptr->EntryType;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
ptr->type = GF_ISOM_BOX_TYPE_GNRV;
gf_isom_video_sample_entry_write((GF_VisualSampleEntryBox *)ptr, bs);
gf_bs_write_data(bs, ptr->data, ptr->data_size);
return GF_OK;
}
GF_Err gnrv_Size(GF_Box *s)
{
GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s;
s->type = GF_ISOM_BOX_TYPE_GNRV;
gf_isom_video_sample_entry_size((GF_VisualSampleEntryBox *)s);
ptr->size += ptr->data_size;
return GF_OK;
}
#endif
void gnra_del(GF_Box *s)
{
GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s;
gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
if (ptr->data) gf_free(ptr->data);
gf_free(ptr);
}
GF_Box *gnra_New()
{
ISOM_DECL_BOX_ALLOC(GF_GenericAudioSampleEntryBox, GF_ISOM_BOX_TYPE_GNRA);
gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*) tmp);
return (GF_Box *)tmp;
}
GF_Err gnra_Read(GF_Box *s, GF_BitStream *bs)
{
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err gnra_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s;
ptr->type = ptr->EntryType;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
ptr->type = GF_ISOM_BOX_TYPE_GNRA;
gf_isom_audio_sample_entry_write((GF_AudioSampleEntryBox *)ptr, bs);
if (ptr->data) {
gf_bs_write_data(bs, ptr->data, ptr->data_size);
}
return GF_OK;
}
GF_Err gnra_Size(GF_Box *s)
{
GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s;
s->type = GF_ISOM_BOX_TYPE_GNRA;
gf_isom_audio_sample_entry_size((GF_AudioSampleEntryBox *)s);
ptr->size += ptr->data_size;
return GF_OK;
}
#endif
void hdlr_del(GF_Box *s)
{
GF_HandlerBox *ptr = (GF_HandlerBox *)s;
if (ptr == NULL) return;
if (ptr->nameUTF8) gf_free(ptr->nameUTF8);
gf_free(ptr);
}
GF_Err hdlr_Read(GF_Box *s, GF_BitStream *bs)
{
GF_HandlerBox *ptr = (GF_HandlerBox *)s;
ptr->reserved1 = gf_bs_read_u32(bs);
ptr->handlerType = gf_bs_read_u32(bs);
gf_bs_read_data(bs, (char*)ptr->reserved2, 12);
ISOM_DECREASE_SIZE(ptr, 20);
if (ptr->size) {
size_t len;
ptr->nameUTF8 = (char*)gf_malloc((u32) ptr->size);
if (ptr->nameUTF8 == NULL) return GF_OUT_OF_MEM;
gf_bs_read_data(bs, ptr->nameUTF8, (u32) ptr->size);
if (ptr->nameUTF8[ptr->size-1]) {
char *str = (char*)gf_malloc((u32) ptr->size + 1);
memcpy(str, ptr->nameUTF8, (u32) ptr->size);
str[ptr->size] = 0;
gf_free(ptr->nameUTF8);
ptr->nameUTF8 = str;
}
if (ptr->size > 1 && ptr->nameUTF8[0] == ptr->size-1) {
len = strlen(ptr->nameUTF8 + 1);
memmove(ptr->nameUTF8, ptr->nameUTF8+1, len );
ptr->nameUTF8[len] = 0;
ptr->store_counted_string = GF_TRUE;
}
}
return GF_OK;
}
GF_Box *hdlr_New()
{
ISOM_DECL_BOX_ALLOC(GF_HandlerBox, GF_ISOM_BOX_TYPE_HDLR);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err hdlr_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_HandlerBox *ptr = (GF_HandlerBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->reserved1);
gf_bs_write_u32(bs, ptr->handlerType);
gf_bs_write_data(bs, (char*)ptr->reserved2, 12);
if (ptr->nameUTF8) {
u32 len = (u32)strlen(ptr->nameUTF8);
if (ptr->store_counted_string) {
gf_bs_write_u8(bs, len);
gf_bs_write_data(bs, ptr->nameUTF8, len);
} else {
gf_bs_write_data(bs, ptr->nameUTF8, len);
gf_bs_write_u8(bs, 0);
}
} else {
gf_bs_write_u8(bs, 0);
}
return GF_OK;
}
GF_Err hdlr_Size(GF_Box *s)
{
GF_HandlerBox *ptr = (GF_HandlerBox *)s;
ptr->size += 20 + 1;
if (ptr->nameUTF8) {
ptr->size += strlen(ptr->nameUTF8);
}
return GF_OK;
}
#endif
void hinf_del(GF_Box *s)
{
GF_HintInfoBox *hinf = (GF_HintInfoBox *)s;
gf_free(hinf);
}
GF_Box *hinf_New()
{
ISOM_DECL_BOX_ALLOC(GF_HintInfoBox, GF_ISOM_BOX_TYPE_HINF);
tmp->other_boxes = gf_list_new();
return (GF_Box *)tmp;
}
GF_Err hinf_AddBox(GF_Box *s, GF_Box *a)
{
GF_MAXRBox *maxR;
GF_HintInfoBox *hinf = (GF_HintInfoBox *)s;
u32 i;
switch (a->type) {
case GF_ISOM_BOX_TYPE_MAXR:
i=0;
while ((maxR = (GF_MAXRBox *)gf_list_enum(hinf->other_boxes, &i))) {
if ((maxR->type==GF_ISOM_BOX_TYPE_MAXR) && (maxR->granularity == ((GF_MAXRBox *)a)->granularity))
return GF_ISOM_INVALID_FILE;
}
break;
}
return gf_isom_box_add_default(s, a);
}
GF_Err hinf_Read(GF_Box *s, GF_BitStream *bs)
{
return gf_isom_box_array_read(s, bs, hinf_AddBox);
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err hinf_Write(GF_Box *s, GF_BitStream *bs)
{
if (!s) return GF_BAD_PARAM;
return gf_isom_box_write_header(s, bs);
}
GF_Err hinf_Size(GF_Box *s)
{
return GF_OK;
}
#endif
void hmhd_del(GF_Box *s)
{
GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;
if (ptr == NULL) return;
gf_free(ptr);
}
GF_Err hmhd_Read(GF_Box *s,GF_BitStream *bs)
{
GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;
ptr->maxPDUSize = gf_bs_read_u16(bs);
ptr->avgPDUSize = gf_bs_read_u16(bs);
ptr->maxBitrate = gf_bs_read_u32(bs);
ptr->avgBitrate = gf_bs_read_u32(bs);
ptr->slidingAverageBitrate = gf_bs_read_u32(bs);
return GF_OK;
}
GF_Box *hmhd_New()
{
ISOM_DECL_BOX_ALLOC(GF_HintMediaHeaderBox, GF_ISOM_BOX_TYPE_HMHD);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err hmhd_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u16(bs, ptr->maxPDUSize);
gf_bs_write_u16(bs, ptr->avgPDUSize);
gf_bs_write_u32(bs, ptr->maxBitrate);
gf_bs_write_u32(bs, ptr->avgBitrate);
gf_bs_write_u32(bs, ptr->slidingAverageBitrate);
return GF_OK;
}
GF_Err hmhd_Size(GF_Box *s)
{
GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s;
ptr->size += 16;
return GF_OK;
}
#endif
GF_Box *hnti_New()
{
ISOM_DECL_BOX_ALLOC(GF_HintTrackInfoBox, GF_ISOM_BOX_TYPE_HNTI);
return (GF_Box *)tmp;
}
void hnti_del(GF_Box *a)
{
gf_free(a);
}
GF_Err hnti_AddBox(GF_Box *s, GF_Box *a)
{
GF_HintTrackInfoBox *hnti = (GF_HintTrackInfoBox *)s;
if (!hnti || !a) return GF_BAD_PARAM;
switch (a->type) {
case GF_ISOM_BOX_TYPE_RTP:
case GF_ISOM_BOX_TYPE_SDP:
if (hnti->SDP) return GF_BAD_PARAM;
hnti->SDP = a;
break;
default:
break;
}
return gf_isom_box_add_default(s, a);
}
GF_Err hnti_Read(GF_Box *s, GF_BitStream *bs)
{
return gf_isom_box_array_read_ex(s, bs, hnti_AddBox, s->type);
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err hnti_Write(GF_Box *s, GF_BitStream *bs)
{
return gf_isom_box_write_header(s, bs);
}
GF_Err hnti_Size(GF_Box *s)
{
return GF_OK;
}
#endif
void sdp_del(GF_Box *s)
{
GF_SDPBox *ptr = (GF_SDPBox *)s;
if (ptr->sdpText) gf_free(ptr->sdpText);
gf_free(ptr);
}
GF_Err sdp_Read(GF_Box *s, GF_BitStream *bs)
{
u32 length;
GF_SDPBox *ptr = (GF_SDPBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
length = (u32) (ptr->size);
ptr->sdpText = (char*)gf_malloc(sizeof(char) * (length+1));
if (!ptr->sdpText) return GF_OUT_OF_MEM;
gf_bs_read_data(bs, ptr->sdpText, length);
ptr->sdpText[length] = 0;
return GF_OK;
}
GF_Box *sdp_New()
{
ISOM_DECL_BOX_ALLOC(GF_SDPBox, GF_ISOM_BOX_TYPE_SDP);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err sdp_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_SDPBox *ptr = (GF_SDPBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_data(bs, ptr->sdpText, (u32) strlen(ptr->sdpText));
return GF_OK;
}
GF_Err sdp_Size(GF_Box *s)
{
GF_SDPBox *ptr = (GF_SDPBox *)s;
ptr->size += strlen(ptr->sdpText);
return GF_OK;
}
#endif
void rtp_hnti_del(GF_Box *s)
{
GF_RTPBox *ptr = (GF_RTPBox *)s;
if (ptr->sdpText) gf_free(ptr->sdpText);
gf_free(ptr);
}
GF_Err rtp_hnti_Read(GF_Box *s, GF_BitStream *bs)
{
u32 length;
GF_RTPBox *ptr = (GF_RTPBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
ISOM_DECREASE_SIZE(ptr, 4)
ptr->subType = gf_bs_read_u32(bs);
length = (u32) (ptr->size);
ptr->sdpText = (char*)gf_malloc(sizeof(char) * (length+1));
if (!ptr->sdpText) return GF_OUT_OF_MEM;
gf_bs_read_data(bs, ptr->sdpText, length);
ptr->sdpText[length] = 0;
return GF_OK;
}
GF_Box *rtp_hnti_New()
{
ISOM_DECL_BOX_ALLOC(GF_RTPBox, GF_ISOM_BOX_TYPE_RTP);
tmp->subType = GF_ISOM_BOX_TYPE_SDP;
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err rtp_hnti_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_RTPBox *ptr = (GF_RTPBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->subType);
gf_bs_write_data(bs, ptr->sdpText, (u32) strlen(ptr->sdpText));
return GF_OK;
}
GF_Err rtp_hnti_Size(GF_Box *s)
{
GF_RTPBox *ptr = (GF_RTPBox *)s;
ptr->size += 4 + strlen(ptr->sdpText);
return GF_OK;
}
#endif
void trpy_del(GF_Box *s)
{
gf_free((GF_TRPYBox *)s);
}
GF_Err trpy_Read(GF_Box *s, GF_BitStream *bs)
{
GF_TRPYBox *ptr = (GF_TRPYBox *)s;
ptr->nbBytes = gf_bs_read_u64(bs);
return GF_OK;
}
GF_Box *trpy_New()
{
ISOM_DECL_BOX_ALLOC(GF_TRPYBox, GF_ISOM_BOX_TYPE_TRPY);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err trpy_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_TRPYBox *ptr = (GF_TRPYBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u64(bs, ptr->nbBytes);
return GF_OK;
}
GF_Err trpy_Size(GF_Box *s)
{
s->size += 8;
return GF_OK;
}
#endif
void totl_del(GF_Box *s)
{
gf_free((GF_TRPYBox *)s);
}
GF_Err totl_Read(GF_Box *s, GF_BitStream *bs)
{
GF_TOTLBox *ptr = (GF_TOTLBox *)s;
ptr->nbBytes = gf_bs_read_u32(bs);
return GF_OK;
}
GF_Box *totl_New()
{
ISOM_DECL_BOX_ALLOC(GF_TOTLBox, GF_ISOM_BOX_TYPE_TOTL);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err totl_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_TOTLBox *ptr = (GF_TOTLBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->nbBytes);
return GF_OK;
}
GF_Err totl_Size(GF_Box *s)
{
s->size += 4;
return GF_OK;
}
#endif
void nump_del(GF_Box *s)
{
gf_free((GF_NUMPBox *)s);
}
GF_Err nump_Read(GF_Box *s, GF_BitStream *bs)
{
GF_NUMPBox *ptr = (GF_NUMPBox *)s;
ptr->nbPackets = gf_bs_read_u64(bs);
return GF_OK;
}
GF_Box *nump_New()
{
ISOM_DECL_BOX_ALLOC(GF_NUMPBox, GF_ISOM_BOX_TYPE_NUMP);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err nump_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_NUMPBox *ptr = (GF_NUMPBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u64(bs, ptr->nbPackets);
return GF_OK;
}
GF_Err nump_Size(GF_Box *s)
{
s->size += 8;
return GF_OK;
}
#endif
void npck_del(GF_Box *s)
{
gf_free((GF_NPCKBox *)s);
}
GF_Err npck_Read(GF_Box *s, GF_BitStream *bs)
{
GF_NPCKBox *ptr = (GF_NPCKBox *)s;
ptr->nbPackets = gf_bs_read_u32(bs);
return GF_OK;
}
GF_Box *npck_New()
{
ISOM_DECL_BOX_ALLOC(GF_NPCKBox, GF_ISOM_BOX_TYPE_NPCK);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err npck_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_NPCKBox *ptr = (GF_NPCKBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->nbPackets);
return GF_OK;
}
GF_Err npck_Size(GF_Box *s)
{
s->size += 4;
return GF_OK;
}
#endif
void tpyl_del(GF_Box *s)
{
gf_free((GF_NTYLBox *)s);
}
GF_Err tpyl_Read(GF_Box *s, GF_BitStream *bs)
{
GF_NTYLBox *ptr = (GF_NTYLBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
ptr->nbBytes = gf_bs_read_u64(bs);
return GF_OK;
}
GF_Box *tpyl_New()
{
ISOM_DECL_BOX_ALLOC(GF_NTYLBox, GF_ISOM_BOX_TYPE_TPYL);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err tpyl_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_NTYLBox *ptr = (GF_NTYLBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u64(bs, ptr->nbBytes);
return GF_OK;
}
GF_Err tpyl_Size(GF_Box *s)
{
s->size += 8;
return GF_OK;
}
#endif
void tpay_del(GF_Box *s)
{
gf_free((GF_TPAYBox *)s);
}
GF_Err tpay_Read(GF_Box *s, GF_BitStream *bs)
{
GF_TPAYBox *ptr = (GF_TPAYBox *)s;
ptr->nbBytes = gf_bs_read_u32(bs);
return GF_OK;
}
GF_Box *tpay_New()
{
ISOM_DECL_BOX_ALLOC(GF_TPAYBox, GF_ISOM_BOX_TYPE_TPAY);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err tpay_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_TPAYBox *ptr = (GF_TPAYBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->nbBytes);
return GF_OK;
}
GF_Err tpay_Size(GF_Box *s)
{
s->size += 4;
return GF_OK;
}
#endif
void maxr_del(GF_Box *s)
{
gf_free((GF_MAXRBox *)s);
}
GF_Err maxr_Read(GF_Box *s, GF_BitStream *bs)
{
GF_MAXRBox *ptr = (GF_MAXRBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
ptr->granularity = gf_bs_read_u32(bs);
ptr->maxDataRate = gf_bs_read_u32(bs);
return GF_OK;
}
GF_Box *maxr_New()
{
ISOM_DECL_BOX_ALLOC(GF_MAXRBox, GF_ISOM_BOX_TYPE_MAXR);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err maxr_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_MAXRBox *ptr = (GF_MAXRBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->granularity);
gf_bs_write_u32(bs, ptr->maxDataRate);
return GF_OK;
}
GF_Err maxr_Size(GF_Box *s)
{
s->size += 8;
return GF_OK;
}
#endif
void dmed_del(GF_Box *s)
{
gf_free((GF_DMEDBox *)s);
}
GF_Err dmed_Read(GF_Box *s, GF_BitStream *bs)
{
GF_DMEDBox *ptr = (GF_DMEDBox *)s;
ptr->nbBytes = gf_bs_read_u64(bs);
return GF_OK;
}
GF_Box *dmed_New()
{
ISOM_DECL_BOX_ALLOC(GF_DMEDBox, GF_ISOM_BOX_TYPE_DMED);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err dmed_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_DMEDBox *ptr = (GF_DMEDBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u64(bs, ptr->nbBytes);
return GF_OK;
}
GF_Err dmed_Size(GF_Box *s)
{
s->size += 8;
return GF_OK;
}
#endif
void dimm_del(GF_Box *s)
{
gf_free((GF_DIMMBox *)s);
}
GF_Err dimm_Read(GF_Box *s, GF_BitStream *bs)
{
GF_DIMMBox *ptr = (GF_DIMMBox *)s;
ptr->nbBytes = gf_bs_read_u64(bs);
return GF_OK;
}
GF_Box *dimm_New()
{
ISOM_DECL_BOX_ALLOC(GF_DIMMBox, GF_ISOM_BOX_TYPE_DIMM);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err dimm_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_DIMMBox *ptr = (GF_DIMMBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u64(bs, ptr->nbBytes);
return GF_OK;
}
GF_Err dimm_Size(GF_Box *s)
{
s->size += 8;
return GF_OK;
}
#endif
void drep_del(GF_Box *s)
{
gf_free((GF_DREPBox *)s);
}
GF_Err drep_Read(GF_Box *s, GF_BitStream *bs)
{
GF_DREPBox *ptr = (GF_DREPBox *)s;
ptr->nbBytes = gf_bs_read_u64(bs);
return GF_OK;
}
GF_Box *drep_New()
{
ISOM_DECL_BOX_ALLOC(GF_DREPBox, GF_ISOM_BOX_TYPE_DREP);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err drep_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_DREPBox *ptr = (GF_DREPBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u64(bs, ptr->nbBytes);
return GF_OK;
}
GF_Err drep_Size(GF_Box *s)
{
s->size += 8;
return GF_OK;
}
#endif
void tmin_del(GF_Box *s)
{
gf_free((GF_TMINBox *)s);
}
GF_Err tmin_Read(GF_Box *s, GF_BitStream *bs)
{
GF_TMINBox *ptr = (GF_TMINBox *)s;
ptr->minTime = gf_bs_read_u32(bs);
return GF_OK;
}
GF_Box *tmin_New()
{
ISOM_DECL_BOX_ALLOC(GF_TMINBox, GF_ISOM_BOX_TYPE_TMIN);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err tmin_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_TMINBox *ptr = (GF_TMINBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->minTime);
return GF_OK;
}
GF_Err tmin_Size(GF_Box *s)
{
s->size += 4;
return GF_OK;
}
#endif
void tmax_del(GF_Box *s)
{
gf_free((GF_TMAXBox *)s);
}
GF_Err tmax_Read(GF_Box *s, GF_BitStream *bs)
{
GF_TMAXBox *ptr = (GF_TMAXBox *)s;
ptr->maxTime = gf_bs_read_u32(bs);
return GF_OK;
}
GF_Box *tmax_New()
{
ISOM_DECL_BOX_ALLOC(GF_TMAXBox, GF_ISOM_BOX_TYPE_TMAX);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err tmax_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_TMAXBox *ptr = (GF_TMAXBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->maxTime);
return GF_OK;
}
GF_Err tmax_Size(GF_Box *s)
{
s->size += 4;
return GF_OK;
}
#endif
void pmax_del(GF_Box *s)
{
gf_free((GF_PMAXBox *)s);
}
GF_Err pmax_Read(GF_Box *s, GF_BitStream *bs)
{
GF_PMAXBox *ptr = (GF_PMAXBox *)s;
ptr->maxSize = gf_bs_read_u32(bs);
return GF_OK;
}
GF_Box *pmax_New()
{
ISOM_DECL_BOX_ALLOC(GF_PMAXBox, GF_ISOM_BOX_TYPE_PMAX);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err pmax_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_PMAXBox *ptr = (GF_PMAXBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->maxSize);
return GF_OK;
}
GF_Err pmax_Size(GF_Box *s)
{
s->size += 4;
return GF_OK;
}
#endif
void dmax_del(GF_Box *s)
{
gf_free((GF_DMAXBox *)s);
}
GF_Err dmax_Read(GF_Box *s, GF_BitStream *bs)
{
GF_DMAXBox *ptr = (GF_DMAXBox *)s;
ptr->maxDur = gf_bs_read_u32(bs);
return GF_OK;
}
GF_Box *dmax_New()
{
ISOM_DECL_BOX_ALLOC(GF_DMAXBox, GF_ISOM_BOX_TYPE_DMAX);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err dmax_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_DMAXBox *ptr = (GF_DMAXBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->maxDur);
return GF_OK;
}
GF_Err dmax_Size(GF_Box *s)
{
s->size += 4;
return GF_OK;
}
#endif
void payt_del(GF_Box *s)
{
GF_PAYTBox *payt = (GF_PAYTBox *)s;
if (payt->payloadString) gf_free(payt->payloadString);
gf_free(payt);
}
GF_Err payt_Read(GF_Box *s, GF_BitStream *bs)
{
u32 length;
GF_PAYTBox *ptr = (GF_PAYTBox *)s;
ptr->payloadCode = gf_bs_read_u32(bs);
length = gf_bs_read_u8(bs);
ptr->payloadString = (char*)gf_malloc(sizeof(char) * (length+1) );
if (! ptr->payloadString) return GF_OUT_OF_MEM;
gf_bs_read_data(bs, ptr->payloadString, length);
ptr->payloadString[length] = 0;
ISOM_DECREASE_SIZE(ptr, (4+length+1) );
return GF_OK;
}
GF_Box *payt_New()
{
ISOM_DECL_BOX_ALLOC(GF_PAYTBox, GF_ISOM_BOX_TYPE_PAYT);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err payt_Write(GF_Box *s, GF_BitStream *bs)
{
u32 len;
GF_Err e;
GF_PAYTBox *ptr = (GF_PAYTBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->payloadCode);
len = (u32) strlen(ptr->payloadString);
gf_bs_write_u8(bs, len);
if (len) gf_bs_write_data(bs, ptr->payloadString, len);
return GF_OK;
}
GF_Err payt_Size(GF_Box *s)
{
GF_PAYTBox *ptr = (GF_PAYTBox *)s;
s->size += 4;
if (ptr->payloadString) ptr->size += strlen(ptr->payloadString) + 1;
return GF_OK;
}
#endif
void name_del(GF_Box *s)
{
GF_NameBox *name = (GF_NameBox *)s;
if (name->string) gf_free(name->string);
gf_free(name);
}
GF_Err name_Read(GF_Box *s, GF_BitStream *bs)
{
u32 length;
GF_NameBox *ptr = (GF_NameBox *)s;
length = (u32) (ptr->size);
ptr->string = (char*)gf_malloc(sizeof(char) * (length+1));
if (! ptr->string) return GF_OUT_OF_MEM;
gf_bs_read_data(bs, ptr->string, length);
ptr->string[length] = 0;
return GF_OK;
}
GF_Box *name_New()
{
ISOM_DECL_BOX_ALLOC(GF_NameBox, GF_ISOM_BOX_TYPE_NAME);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err name_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_NameBox *ptr = (GF_NameBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
if (ptr->string) {
gf_bs_write_data(bs, ptr->string, (u32) strlen(ptr->string) + 1);
}
return GF_OK;
}
GF_Err name_Size(GF_Box *s)
{
GF_NameBox *ptr = (GF_NameBox *)s;
if (ptr->string) ptr->size += strlen(ptr->string) + 1;
return GF_OK;
}
#endif
void tssy_del(GF_Box *s)
{
gf_free(s);
}
GF_Err tssy_Read(GF_Box *s, GF_BitStream *bs)
{
GF_TimeStampSynchronyBox *ptr = (GF_TimeStampSynchronyBox *)s;
gf_bs_read_int(bs, 6);
ptr->timestamp_sync = gf_bs_read_int(bs, 2);
return GF_OK;
}
GF_Box *tssy_New()
{
ISOM_DECL_BOX_ALLOC(GF_TimeStampSynchronyBox, GF_ISOM_BOX_TYPE_TSSY);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err tssy_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_TimeStampSynchronyBox *ptr = (GF_TimeStampSynchronyBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_int(bs, 0, 6);
gf_bs_write_int(bs, ptr->timestamp_sync, 2);
return GF_OK;
}
GF_Err tssy_Size(GF_Box *s)
{
s->size += 1;
return GF_OK;
}
#endif
void srpp_del(GF_Box *s)
{
GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s;
if (ptr->info) gf_isom_box_del((GF_Box*)ptr->info);
if (ptr->scheme_type) gf_isom_box_del((GF_Box*)ptr->scheme_type);
gf_free(s);
}
GF_Err srpp_AddBox(GF_Box *s, GF_Box *a)
{
GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s;
switch(a->type) {
case GF_ISOM_BOX_TYPE_SCHI:
if (ptr->info) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->info = (GF_SchemeInformationBox *)a;
return GF_OK;
case GF_ISOM_BOX_TYPE_SCHM:
if (ptr->scheme_type) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->scheme_type = (GF_SchemeTypeBox *)a;
return GF_OK;
}
return gf_isom_box_add_default(s, a);
}
GF_Err srpp_Read(GF_Box *s, GF_BitStream *bs)
{
GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s;
ISOM_DECREASE_SIZE(s, 16)
ptr->encryption_algorithm_rtp = gf_bs_read_u32(bs);
ptr->encryption_algorithm_rtcp = gf_bs_read_u32(bs);
ptr->integrity_algorithm_rtp = gf_bs_read_u32(bs);
ptr->integrity_algorithm_rtp = gf_bs_read_u32(bs);
return gf_isom_box_array_read(s, bs, gf_isom_box_add_default);
}
GF_Box *srpp_New()
{
ISOM_DECL_BOX_ALLOC(GF_SRTPProcessBox, GF_ISOM_BOX_TYPE_SRPP);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err srpp_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->encryption_algorithm_rtp);
gf_bs_write_u32(bs, ptr->encryption_algorithm_rtcp);
gf_bs_write_u32(bs, ptr->integrity_algorithm_rtp);
gf_bs_write_u32(bs, ptr->integrity_algorithm_rtcp);
if (ptr->info) {
e = gf_isom_box_write((GF_Box*)ptr->info, bs);
if (e) return e;
}
if (ptr->scheme_type) {
e = gf_isom_box_write((GF_Box*)ptr->scheme_type, bs);
if (e) return e;
}
return GF_OK;
}
GF_Err srpp_Size(GF_Box *s)
{
GF_Err e;
GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s;
s->size += 16;
if (ptr->info) {
e = gf_isom_box_size((GF_Box*)ptr->info);
if (e) return e;
ptr->size += ptr->info->size;
}
if (ptr->scheme_type) {
e = gf_isom_box_size((GF_Box*)ptr->scheme_type);
if (e) return e;
ptr->size += ptr->scheme_type->size;
}
return GF_OK;
}
#endif
void rssr_del(GF_Box *s)
{
gf_free(s);
}
GF_Err rssr_Read(GF_Box *s, GF_BitStream *bs)
{
GF_ReceivedSsrcBox *ptr = (GF_ReceivedSsrcBox *)s;
ptr->ssrc = gf_bs_read_u32(bs);
return GF_OK;
}
GF_Box *rssr_New()
{
ISOM_DECL_BOX_ALLOC(GF_ReceivedSsrcBox, GF_ISOM_BOX_TYPE_RSSR);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err rssr_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_ReceivedSsrcBox *ptr = (GF_ReceivedSsrcBox *)s;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->ssrc);
return GF_OK;
}
GF_Err rssr_Size(GF_Box *s)
{
s->size += 4;
return GF_OK;
}
#endif
void iods_del(GF_Box *s)
{
GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;
if (ptr == NULL) return;
if (ptr->descriptor) gf_odf_desc_del(ptr->descriptor);
gf_free(ptr);
}
GF_Err iods_Read(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 descSize;
char *desc;
GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;
descSize = (u32) (ptr->size);
desc = (char*)gf_malloc(sizeof(char) * descSize);
gf_bs_read_data(bs, desc, descSize);
e = gf_odf_desc_read(desc, descSize, &ptr->descriptor);
gf_free(desc);
return e;
}
GF_Box *iods_New()
{
ISOM_DECL_BOX_ALLOC(GF_ObjectDescriptorBox, GF_ISOM_BOX_TYPE_IODS);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err iods_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 descSize;
char *desc;
GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
e = gf_odf_desc_write(ptr->descriptor, &desc, &descSize);
if (e) return e;
gf_bs_write_data(bs, desc, descSize);
gf_free(desc);
return GF_OK;
}
GF_Err iods_Size(GF_Box *s)
{
GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s;
ptr->size += gf_odf_desc_size(ptr->descriptor);
return GF_OK;
}
#endif
void mdat_del(GF_Box *s)
{
GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
if (!s) return;
if (ptr->data) gf_free(ptr->data);
gf_free(ptr);
}
GF_Err mdat_Read(GF_Box *s, GF_BitStream *bs)
{
GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
ptr->dataSize = s->size;
gf_bs_skip_bytes(bs, ptr->dataSize);
return GF_OK;
}
GF_Box *mdat_New()
{
ISOM_DECL_BOX_ALLOC(GF_MediaDataBox, GF_ISOM_BOX_TYPE_MDAT);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err mdat_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
if (ptr->data) {
gf_bs_write_data(bs, ptr->data, (u32) ptr->dataSize);
}
return GF_OK;
}
GF_Err mdat_Size(GF_Box *s)
{
GF_MediaDataBox *ptr = (GF_MediaDataBox *)s;
ptr->size += ptr->dataSize;
return GF_OK;
}
#endif
void mdhd_del(GF_Box *s)
{
GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;
if (ptr == NULL) return;
gf_free(ptr);
}
GF_Err mdhd_Read(GF_Box *s, GF_BitStream *bs)
{
GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;
if (ptr->version == 1) {
ptr->creationTime = gf_bs_read_u64(bs);
ptr->modificationTime = gf_bs_read_u64(bs);
ptr->timeScale = gf_bs_read_u32(bs);
ptr->duration = gf_bs_read_u64(bs);
} else {
ptr->creationTime = gf_bs_read_u32(bs);
ptr->modificationTime = gf_bs_read_u32(bs);
ptr->timeScale = gf_bs_read_u32(bs);
ptr->duration = gf_bs_read_u32(bs);
}
if (!ptr->timeScale) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Media header timescale is 0 - defaulting to 90000\n" ));
ptr->timeScale = 90000;
}
ptr->original_duration = ptr->duration;
gf_bs_read_int(bs, 1);
ptr->packedLanguage[0] = gf_bs_read_int(bs, 5);
ptr->packedLanguage[1] = gf_bs_read_int(bs, 5);
ptr->packedLanguage[2] = gf_bs_read_int(bs, 5);
if (ptr->packedLanguage[0] || ptr->packedLanguage[1] || ptr->packedLanguage[2]) {
ptr->packedLanguage[0] += 0x60;
ptr->packedLanguage[1] += 0x60;
ptr->packedLanguage[2] += 0x60;
} else {
ptr->packedLanguage[0] = 'u';
ptr->packedLanguage[1] = 'n';
ptr->packedLanguage[2] = 'd';
}
ptr->reserved = gf_bs_read_u16(bs);
return GF_OK;
}
GF_Box *mdhd_New()
{
ISOM_DECL_BOX_ALLOC(GF_MediaHeaderBox, GF_ISOM_BOX_TYPE_MDHD);
tmp->packedLanguage[0] = 'u';
tmp->packedLanguage[1] = 'n';
tmp->packedLanguage[2] = 'd';
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err mdhd_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
if (ptr->version == 1) {
gf_bs_write_u64(bs, ptr->creationTime);
gf_bs_write_u64(bs, ptr->modificationTime);
gf_bs_write_u32(bs, ptr->timeScale);
gf_bs_write_u64(bs, ptr->duration);
} else {
gf_bs_write_u32(bs, (u32) ptr->creationTime);
gf_bs_write_u32(bs, (u32) ptr->modificationTime);
gf_bs_write_u32(bs, ptr->timeScale);
gf_bs_write_u32(bs, (u32) ptr->duration);
}
gf_bs_write_int(bs, 0, 1);
gf_bs_write_int(bs, ptr->packedLanguage[0] - 0x60, 5);
gf_bs_write_int(bs, ptr->packedLanguage[1] - 0x60, 5);
gf_bs_write_int(bs, ptr->packedLanguage[2] - 0x60, 5);
gf_bs_write_u16(bs, ptr->reserved);
return GF_OK;
}
GF_Err mdhd_Size(GF_Box *s)
{
GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s;
ptr->version = (ptr->duration>0xFFFFFFFF) ? 1 : 0;
ptr->size += 4;
ptr->size += (ptr->version == 1) ? 28 : 16;
return GF_OK;
}
#endif
void mdia_del(GF_Box *s)
{
GF_MediaBox *ptr = (GF_MediaBox *)s;
if (ptr == NULL) return;
if (ptr->mediaHeader) gf_isom_box_del((GF_Box *)ptr->mediaHeader);
if (ptr->information) gf_isom_box_del((GF_Box *)ptr->information);
if (ptr->handler) gf_isom_box_del((GF_Box *)ptr->handler);
gf_free(ptr);
}
GF_Err mdia_AddBox(GF_Box *s, GF_Box *a)
{
GF_MediaBox *ptr = (GF_MediaBox *)s;
switch(a->type) {
case GF_ISOM_BOX_TYPE_MDHD:
if (ptr->mediaHeader) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->mediaHeader = (GF_MediaHeaderBox *)a;
return GF_OK;
case GF_ISOM_BOX_TYPE_HDLR:
if (ptr->handler) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->handler = (GF_HandlerBox *)a;
return GF_OK;
case GF_ISOM_BOX_TYPE_MINF:
if (ptr->information) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->information = (GF_MediaInformationBox *)a;
return GF_OK;
default:
return gf_isom_box_add_default(s, a);
}
return GF_OK;
}
GF_Err mdia_Read(GF_Box *s, GF_BitStream *bs)
{
GF_Err e = gf_isom_box_array_read(s, bs, mdia_AddBox);
if (e) return e;
if (!((GF_MediaBox *)s)->information) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing MediaInformationBox\n"));
return GF_ISOM_INVALID_FILE;
}
if (!((GF_MediaBox *)s)->handler) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing HandlerBox\n"));
return GF_ISOM_INVALID_FILE;
}
if (!((GF_MediaBox *)s)->mediaHeader) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing MediaHeaderBox\n"));
return GF_ISOM_INVALID_FILE;
}
return GF_OK;
}
GF_Box *mdia_New()
{
ISOM_DECL_BOX_ALLOC(GF_MediaBox, GF_ISOM_BOX_TYPE_MDIA);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err mdia_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_MediaBox *ptr = (GF_MediaBox *)s;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
if (ptr->mediaHeader) {
e = gf_isom_box_write((GF_Box *) ptr->mediaHeader, bs);
if (e) return e;
}
if (ptr->handler) {
e = gf_isom_box_write((GF_Box *) ptr->handler, bs);
if (e) return e;
}
if (ptr->information) {
e = gf_isom_box_write((GF_Box *) ptr->information, bs);
if (e) return e;
}
return GF_OK;
}
GF_Err mdia_Size(GF_Box *s)
{
GF_Err e;
GF_MediaBox *ptr = (GF_MediaBox *)s;
if (ptr->mediaHeader) {
e = gf_isom_box_size((GF_Box *) ptr->mediaHeader);
if (e) return e;
ptr->size += ptr->mediaHeader->size;
}
if (ptr->handler) {
e = gf_isom_box_size((GF_Box *) ptr->handler);
if (e) return e;
ptr->size += ptr->handler->size;
}
if (ptr->information) {
e = gf_isom_box_size((GF_Box *) ptr->information);
if (e) return e;
ptr->size += ptr->information->size;
}
return GF_OK;
}
#endif
void mfra_del(GF_Box *s)
{
GF_MovieFragmentRandomAccessBox *ptr = (GF_MovieFragmentRandomAccessBox *)s;
if (ptr == NULL) return;
if (ptr->mfro) gf_isom_box_del((GF_Box*)ptr->mfro);
gf_isom_box_array_del(ptr->tfra_list);
gf_free(ptr);
}
GF_Box *mfra_New()
{
ISOM_DECL_BOX_ALLOC(GF_MovieFragmentRandomAccessBox, GF_ISOM_BOX_TYPE_MFRA);
tmp->tfra_list = gf_list_new();
return (GF_Box *)tmp;
}
GF_Err mfra_AddBox(GF_Box *s, GF_Box *a)
{
GF_MovieFragmentRandomAccessBox *ptr = (GF_MovieFragmentRandomAccessBox *)s;
switch(a->type) {
case GF_ISOM_BOX_TYPE_TFRA:
return gf_list_add(ptr->tfra_list, a);
case GF_ISOM_BOX_TYPE_MFRO:
if (ptr->mfro) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->mfro = (GF_MovieFragmentRandomAccessOffsetBox *)a;
return GF_OK;
default:
return gf_isom_box_add_default(s, a);
}
return GF_OK;
}
GF_Err mfra_Read(GF_Box *s, GF_BitStream *bs)
{
return gf_isom_box_array_read(s, bs, mfra_AddBox);
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err mfra_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_MovieFragmentRandomAccessBox *ptr = (GF_MovieFragmentRandomAccessBox *)s;
e = gf_isom_box_array_write(s, ptr->tfra_list, bs);
if (e) return e;
if (ptr->mfro) {
e = gf_isom_box_write((GF_Box *) ptr->mfro, bs);
if (e) return e;
}
return GF_OK;
}
GF_Err mfra_Size(GF_Box *s)
{
GF_Err e;
GF_MovieFragmentRandomAccessBox *ptr = (GF_MovieFragmentRandomAccessBox *)s;
if (ptr->mfro) {
e = gf_isom_box_size((GF_Box *)ptr->mfro);
if (e) return e;
ptr->size += ptr->mfro->size;
}
return gf_isom_box_array_size(s, ptr->tfra_list);
}
#endif
void tfra_del(GF_Box *s)
{
GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s;
if (ptr == NULL) return;
if (ptr->entries) gf_free(ptr->entries);
gf_free(ptr);
}
GF_Box *tfra_New()
{
ISOM_DECL_BOX_ALLOC(GF_TrackFragmentRandomAccessBox, GF_ISOM_BOX_TYPE_TFRA);
return (GF_Box *)tmp;
}
GF_Err tfra_Read(GF_Box *s, GF_BitStream *bs)
{
u32 i;
GF_RandomAccessEntry *p = 0;
GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s;
if (ptr->size<12) return GF_ISOM_INVALID_FILE;
ptr->track_id = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
if (gf_bs_read_int(bs, 26) !=0) return GF_ISOM_INVALID_FILE;
ptr->traf_bits = (gf_bs_read_int(bs, 2)+1)*8;
ptr->trun_bits = (gf_bs_read_int(bs, 2)+1)*8;
ptr->sample_bits = (gf_bs_read_int(bs, 2)+1)*8;
ISOM_DECREASE_SIZE(ptr, 4);
ptr->nb_entries = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
if (ptr->version==1) {
if (ptr->nb_entries > ptr->size / (16+(ptr->traf_bits+ptr->trun_bits+ptr->sample_bits)/8)) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in traf\n", ptr->nb_entries));
return GF_ISOM_INVALID_FILE;
}
} else {
if (ptr->nb_entries > ptr->size / (8+(ptr->traf_bits+ptr->trun_bits+ptr->sample_bits)/8)) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in traf\n", ptr->nb_entries));
return GF_ISOM_INVALID_FILE;
}
}
if (ptr->nb_entries)
{
p = (GF_RandomAccessEntry *) gf_malloc(sizeof(GF_RandomAccessEntry) * ptr->nb_entries);
if (!p) return GF_OUT_OF_MEM;
}
ptr->entries = p;
for (i=0; i<ptr->nb_entries; i++) {
memset(p, 0, sizeof(GF_RandomAccessEntry));
if (ptr->version==1) {
p->time = gf_bs_read_u64(bs);
p->moof_offset = gf_bs_read_u64(bs);
}
else
{
p->time = gf_bs_read_u32(bs);
p->moof_offset = gf_bs_read_u32(bs);
}
p->traf_number = gf_bs_read_int(bs, ptr->traf_bits);
p->trun_number = gf_bs_read_int(bs, ptr->trun_bits);
p->sample_number = gf_bs_read_int(bs, ptr->sample_bits);
++p;
}
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err tfra_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->track_id);
gf_bs_write_int(bs, 0, 26);
gf_bs_write_int(bs, ptr->traf_bits/8 - 1, 2);
gf_bs_write_int(bs, ptr->trun_bits/8 - 1, 2);
gf_bs_write_int(bs, ptr->sample_bits/8 - 1, 2);
gf_bs_write_u32(bs, ptr->nb_entries);
for (i=0; i<ptr->nb_entries; i++) {
GF_RandomAccessEntry *p = &ptr->entries[i];;
if (ptr->version==1) {
gf_bs_write_u64(bs, p->time);
gf_bs_write_u64(bs, p->moof_offset);
} else {
gf_bs_write_u32(bs, (u32) p->time);
gf_bs_write_u32(bs, (u32) p->moof_offset);
}
gf_bs_write_int(bs, p->traf_number, ptr->traf_bits);
gf_bs_write_int(bs, p->trun_number, ptr->trun_bits);
gf_bs_write_int(bs, p->sample_number, ptr->sample_bits);
}
return GF_OK;
}
GF_Err tfra_Size(GF_Box *s)
{
GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s;
ptr->size += 12;
ptr->size += ptr->nb_entries * ( ((ptr->version==1) ? 16 : 8 ) + ptr->traf_bits + ptr->trun_bits + ptr->sample_bits);
return GF_OK;
}
#endif
void mfro_del(GF_Box *s)
{
GF_MovieFragmentRandomAccessOffsetBox *ptr = (GF_MovieFragmentRandomAccessOffsetBox *)s;
if (ptr == NULL) return;
gf_free(ptr);
}
GF_Box *mfro_New()
{
ISOM_DECL_BOX_ALLOC(GF_MovieFragmentRandomAccessOffsetBox, GF_ISOM_BOX_TYPE_MFRO);
return (GF_Box *)tmp;
}
GF_Err mfro_Read(GF_Box *s, GF_BitStream *bs)
{
GF_MovieFragmentRandomAccessOffsetBox *ptr = (GF_MovieFragmentRandomAccessOffsetBox *)s;
ptr->container_size = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err mfro_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_MovieFragmentRandomAccessOffsetBox *ptr = (GF_MovieFragmentRandomAccessOffsetBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->container_size);
return GF_OK;
}
GF_Err mfro_Size(GF_Box *s)
{
s->size += 4;
return GF_OK;
}
#endif
void elng_del(GF_Box *s)
{
GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;
if (ptr == NULL) return;
if (ptr->extended_language) gf_free(ptr->extended_language);
gf_free(ptr);
}
GF_Err elng_Read(GF_Box *s, GF_BitStream *bs)
{
GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;
if (ptr->size) {
ptr->extended_language = (char*)gf_malloc((u32) ptr->size);
if (ptr->extended_language == NULL) return GF_OUT_OF_MEM;
gf_bs_read_data(bs, ptr->extended_language, (u32) ptr->size);
if (ptr->extended_language[ptr->size-1]) {
char *str = (char*)gf_malloc((u32) ptr->size + 1);
memcpy(str, ptr->extended_language, (u32) ptr->size);
str[ptr->size] = 0;
gf_free(ptr->extended_language);
ptr->extended_language = str;
}
}
return GF_OK;
}
GF_Box *elng_New()
{
ISOM_DECL_BOX_ALLOC(GF_MediaBox, GF_ISOM_BOX_TYPE_ELNG);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err elng_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
if (ptr->extended_language) {
gf_bs_write_data(bs, ptr->extended_language, (u32)(strlen(ptr->extended_language)+1));
}
return GF_OK;
}
GF_Err elng_Size(GF_Box *s)
{
GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s;
if (ptr->extended_language) {
ptr->size += strlen(ptr->extended_language)+1;
}
return GF_OK;
}
#endif
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
void mfhd_del(GF_Box *s)
{
GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *)s;
if (ptr == NULL) return;
gf_free(ptr);
}
GF_Err mfhd_Read(GF_Box *s, GF_BitStream *bs)
{
GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *)s;
ptr->sequence_number = gf_bs_read_u32(bs);
return GF_OK;
}
GF_Box *mfhd_New()
{
ISOM_DECL_BOX_ALLOC(GF_MovieFragmentHeaderBox, GF_ISOM_BOX_TYPE_MFHD);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err mfhd_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *) s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->sequence_number);
return GF_OK;
}
GF_Err mfhd_Size(GF_Box *s)
{
s->size += 4;
return GF_OK;
}
#endif
#endif
void minf_del(GF_Box *s)
{
GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
if (ptr == NULL) return;
if (ptr->dataHandler) {
gf_isom_datamap_close(ptr);
}
if (ptr->InfoHeader) gf_isom_box_del((GF_Box *)ptr->InfoHeader);
if (ptr->dataInformation) gf_isom_box_del((GF_Box *)ptr->dataInformation);
if (ptr->sampleTable) gf_isom_box_del((GF_Box *)ptr->sampleTable);
gf_free(ptr);
}
GF_Err minf_AddBox(GF_Box *s, GF_Box *a)
{
GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
switch (a->type) {
case GF_ISOM_BOX_TYPE_NMHD:
case GF_ISOM_BOX_TYPE_STHD:
case GF_ISOM_BOX_TYPE_VMHD:
case GF_ISOM_BOX_TYPE_SMHD:
case GF_ISOM_BOX_TYPE_HMHD:
case GF_ISOM_BOX_TYPE_GMHD:
if (ptr->InfoHeader) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->InfoHeader = a;
return GF_OK;
case GF_ISOM_BOX_TYPE_DINF:
if (ptr->dataInformation) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->dataInformation = (GF_DataInformationBox *)a;
return GF_OK;
case GF_ISOM_BOX_TYPE_STBL:
if (ptr->sampleTable ) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->sampleTable = (GF_SampleTableBox *)a;
return GF_OK;
default:
return gf_isom_box_add_default(s, a);
}
return GF_OK;
}
GF_Err minf_Read(GF_Box *s, GF_BitStream *bs)
{
GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
GF_Err e;
e = gf_isom_box_array_read(s, bs, minf_AddBox);
if (! ptr->dataInformation) {
GF_Box *dinf, *dref, *url;
Bool dump_mode = GF_FALSE;
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing DataInformationBox\n"));
dinf = gf_isom_box_new(GF_ISOM_BOX_TYPE_DINF);
if (!dinf) return GF_OUT_OF_MEM;
if (ptr->InfoHeader && gf_list_find(ptr->other_boxes, ptr->InfoHeader)>=0) dump_mode = GF_TRUE;
if (ptr->sampleTable && gf_list_find(ptr->other_boxes, ptr->sampleTable)>=0) dump_mode = GF_TRUE;
ptr->dataInformation = (GF_DataInformationBox *)dinf;
dref = gf_isom_box_new(GF_ISOM_BOX_TYPE_DREF);
if (!dref) return GF_OUT_OF_MEM;
e = dinf_AddBox(dinf, dref);
url = gf_isom_box_new(GF_ISOM_BOX_TYPE_URL);
if (!url) return GF_OUT_OF_MEM;
((GF_FullBox*)url)->flags = 1;
e = gf_isom_box_add_default(dref, url);
if (dump_mode) {
gf_list_add(ptr->other_boxes, ptr->dataInformation);
if (!dinf->other_boxes) dinf->other_boxes = gf_list_new();
gf_list_add(dinf->other_boxes, dref);
}
}
return e;
}
GF_Box *minf_New()
{
ISOM_DECL_BOX_ALLOC(GF_MediaInformationBox, GF_ISOM_BOX_TYPE_MINF);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err minf_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
if (ptr->InfoHeader) {
e = gf_isom_box_write((GF_Box *) ptr->InfoHeader, bs);
if (e) return e;
}
if (ptr->dataInformation) {
e = gf_isom_box_write((GF_Box *) ptr->dataInformation, bs);
if (e) return e;
}
if (ptr->sampleTable) {
e = gf_isom_box_write((GF_Box *) ptr->sampleTable, bs);
if (e) return e;
}
return GF_OK;
}
GF_Err minf_Size(GF_Box *s)
{
GF_Err e;
GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s;
if (ptr->InfoHeader) {
e = gf_isom_box_size((GF_Box *) ptr->InfoHeader);
if (e) return e;
ptr->size += ptr->InfoHeader->size;
}
if (ptr->dataInformation) {
e = gf_isom_box_size((GF_Box *) ptr->dataInformation);
if (e) return e;
ptr->size += ptr->dataInformation->size;
}
if (ptr->sampleTable) {
e = gf_isom_box_size((GF_Box *) ptr->sampleTable);
if (e) return e;
ptr->size += ptr->sampleTable->size;
}
return GF_OK;
}
#endif
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
void moof_del(GF_Box *s)
{
GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *)s;
if (ptr == NULL) return;
if (ptr->mfhd) gf_isom_box_del((GF_Box *) ptr->mfhd);
gf_isom_box_array_del(ptr->TrackList);
if (ptr->mdat) gf_free(ptr->mdat);
gf_free(ptr);
}
GF_Err moof_AddBox(GF_Box *s, GF_Box *a)
{
GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *)s;
switch (a->type) {
case GF_ISOM_BOX_TYPE_MFHD:
if (ptr->mfhd) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->mfhd = (GF_MovieFragmentHeaderBox *) a;
return GF_OK;
case GF_ISOM_BOX_TYPE_TRAF:
return gf_list_add(ptr->TrackList, a);
case GF_ISOM_BOX_TYPE_PSSH:
default:
return gf_isom_box_add_default(s, a);
}
}
GF_Err moof_Read(GF_Box *s, GF_BitStream *bs)
{
return gf_isom_box_array_read(s, bs, moof_AddBox);
}
GF_Box *moof_New()
{
ISOM_DECL_BOX_ALLOC(GF_MovieFragmentBox, GF_ISOM_BOX_TYPE_MOOF);
tmp->TrackList = gf_list_new();
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err moof_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *) s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
if (ptr->mfhd) {
e = gf_isom_box_write((GF_Box *) ptr->mfhd, bs);
if (e) return e;
}
return gf_isom_box_array_write(s, ptr->TrackList, bs);
}
GF_Err moof_Size(GF_Box *s)
{
GF_Err e;
GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *)s;
if (ptr->mfhd) {
e = gf_isom_box_size((GF_Box *)ptr->mfhd);
if (e) return e;
ptr->size += ptr->mfhd->size;
}
return gf_isom_box_array_size(s, ptr->TrackList);
}
#endif
#endif
void moov_del(GF_Box *s)
{
GF_MovieBox *ptr = (GF_MovieBox *)s;
if (ptr == NULL) return;
if (ptr->mvhd) gf_isom_box_del((GF_Box *)ptr->mvhd);
if (ptr->meta) gf_isom_box_del((GF_Box *)ptr->meta);
if (ptr->iods) gf_isom_box_del((GF_Box *)ptr->iods);
if (ptr->udta) gf_isom_box_del((GF_Box *)ptr->udta);
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
if (ptr->mvex) gf_isom_box_del((GF_Box *)ptr->mvex);
#endif
gf_isom_box_array_del(ptr->trackList);
gf_free(ptr);
}
GF_Err moov_AddBox(GF_Box *s, GF_Box *a)
{
GF_MovieBox *ptr = (GF_MovieBox *)s;
switch (a->type) {
case GF_ISOM_BOX_TYPE_IODS:
if (ptr->iods) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->iods = (GF_ObjectDescriptorBox *)a;
if (!ptr->iods->descriptor) {
ptr->iods = NULL;
gf_isom_box_del(a);
}
return GF_OK;
case GF_ISOM_BOX_TYPE_MVHD:
if (ptr->mvhd) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->mvhd = (GF_MovieHeaderBox *)a;
return GF_OK;
case GF_ISOM_BOX_TYPE_UDTA:
if (ptr->udta) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->udta = (GF_UserDataBox *)a;
return GF_OK;
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
case GF_ISOM_BOX_TYPE_MVEX:
if (ptr->mvex) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->mvex = (GF_MovieExtendsBox *)a;
ptr->mvex->mov = ptr->mov;
return GF_OK;
#endif
case GF_ISOM_BOX_TYPE_META:
if (ptr->meta) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->meta = (GF_MetaBox *)a;
return GF_OK;
case GF_ISOM_BOX_TYPE_TRAK:
((GF_TrackBox *)a)->moov = ptr;
return gf_list_add(ptr->trackList, a);
case GF_ISOM_BOX_TYPE_PSSH:
default:
return gf_isom_box_add_default(s, a);
}
}
GF_Err moov_Read(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
e = gf_isom_box_array_read(s, bs, moov_AddBox);
if (e) {
return e;
}
else {
if (!((GF_MovieBox *)s)->mvhd) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing MovieHeaderBox\n"));
return GF_ISOM_INVALID_FILE;
}
}
return e;
}
GF_Box *moov_New()
{
ISOM_DECL_BOX_ALLOC(GF_MovieBox, GF_ISOM_BOX_TYPE_MOOV);
tmp->trackList = gf_list_new();
if (!tmp->trackList) {
gf_free(tmp);
return NULL;
}
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err moov_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_MovieBox *ptr = (GF_MovieBox *)s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
if (ptr->mvhd) {
e = gf_isom_box_write((GF_Box *) ptr->mvhd, bs);
if (e) return e;
}
if (ptr->iods) {
e = gf_isom_box_write((GF_Box *) ptr->iods, bs);
if (e) return e;
}
if (ptr->meta) {
e = gf_isom_box_write((GF_Box *) ptr->meta, bs);
if (e) return e;
}
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
if (ptr->mvex) {
e = gf_isom_box_write((GF_Box *) ptr->mvex, bs);
if (e) return e;
}
#endif
e = gf_isom_box_array_write(s, ptr->trackList, bs);
if (e) return e;
if (ptr->udta) {
e = gf_isom_box_write((GF_Box *) ptr->udta, bs);
if (e) return e;
}
return GF_OK;
}
GF_Err moov_Size(GF_Box *s)
{
GF_Err e;
GF_MovieBox *ptr = (GF_MovieBox *)s;
if (ptr->mvhd) {
e = gf_isom_box_size((GF_Box *) ptr->mvhd);
if (e) return e;
ptr->size += ptr->mvhd->size;
}
if (ptr->iods) {
e = gf_isom_box_size((GF_Box *) ptr->iods);
if (e) return e;
ptr->size += ptr->iods->size;
}
if (ptr->udta) {
e = gf_isom_box_size((GF_Box *) ptr->udta);
if (e) return e;
ptr->size += ptr->udta->size;
}
if (ptr->meta) {
e = gf_isom_box_size((GF_Box *) ptr->meta);
if (e) return e;
ptr->size += ptr->meta->size;
}
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
if (ptr->mvex) {
e = gf_isom_box_size((GF_Box *) ptr->mvex);
if (e) return e;
ptr->size += ptr->mvex->size;
}
#endif
return gf_isom_box_array_size(s, ptr->trackList);
}
#endif
void audio_sample_entry_del(GF_Box *s)
{
GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s;
if (ptr == NULL) return;
gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
if (ptr->esd) gf_isom_box_del((GF_Box *)ptr->esd);
if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
if (ptr->cfg_ac3) gf_isom_box_del((GF_Box *)ptr->cfg_ac3);
if (ptr->cfg_3gpp) gf_isom_box_del((GF_Box *)ptr->cfg_3gpp);
gf_free(ptr);
}
GF_Err audio_sample_entry_AddBox(GF_Box *s, GF_Box *a)
{
GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s;
switch (a->type) {
case GF_ISOM_BOX_TYPE_ESDS:
if (ptr->esd) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->esd = (GF_ESDBox *)a;
break;
case GF_ISOM_BOX_TYPE_SINF:
gf_list_add(ptr->protections, a);
break;
case GF_ISOM_BOX_TYPE_DAMR:
case GF_ISOM_BOX_TYPE_DEVC:
case GF_ISOM_BOX_TYPE_DQCP:
case GF_ISOM_BOX_TYPE_DSMV:
ptr->cfg_3gpp = (GF_3GPPConfigBox *) a;
ptr->cfg_3gpp->cfg.type = ptr->type;
break;
case GF_ISOM_BOX_TYPE_DAC3:
ptr->cfg_ac3 = (GF_AC3ConfigBox *) a;
break;
case GF_ISOM_BOX_TYPE_DEC3:
ptr->cfg_ac3 = (GF_AC3ConfigBox *) a;
break;
case GF_ISOM_BOX_TYPE_UNKNOWN:
if (ptr->esd) ERROR_ON_DUPLICATED_BOX(a, ptr)
{
GF_UnknownBox *wave = (GF_UnknownBox *)a;
if (wave->original_4cc == GF_4CC('w','a','v','e')) {
u32 offset = 0;
while ((wave->data[offset + 4] != 'e') && (wave->data[offset + 5] != 's')) {
offset++;
if (offset == wave->dataSize) break;
}
if (offset < wave->dataSize) {
GF_Box *a;
GF_Err e;
GF_BitStream *bs = gf_bs_new(wave->data + offset, wave->dataSize - offset, GF_BITSTREAM_READ);
e = gf_isom_box_parse(&a, bs);
gf_bs_del(bs);
if (e) return e;
ptr->esd = (GF_ESDBox *)a;
gf_isom_box_add_for_dump_mode((GF_Box *)ptr, a);
}
}
else {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Cannot process box %s\n!", gf_4cc_to_str(a->type)));
}
gf_isom_box_del(a);
return GF_ISOM_INVALID_MEDIA;
}
break;
default:
return gf_isom_box_add_default(s, a);
}
return GF_OK;
}
GF_Err audio_sample_entry_Read(GF_Box *s, GF_BitStream *bs)
{
GF_MPEGAudioSampleEntryBox *ptr;
char *data;
u32 i, size;
GF_Err e;
u64 pos;
e = gf_isom_audio_sample_entry_read((GF_AudioSampleEntryBox*)s, bs);
if (e) return e;
pos = gf_bs_get_position(bs);
size = (u32) s->size;
e = gf_isom_box_array_read(s, bs, audio_sample_entry_AddBox);
if (!e) return GF_OK;
if (size<8) return GF_ISOM_INVALID_FILE;
ptr = (GF_MPEGAudioSampleEntryBox *)s;
gf_bs_seek(bs, pos);
data = (char*)gf_malloc(sizeof(char) * size);
gf_bs_read_data(bs, data, size);
for (i=0; i<size-8; i++) {
if (GF_4CC(data[i+4], data[i+5], data[i+6], data[i+7]) == GF_ISOM_BOX_TYPE_ESDS) {
GF_BitStream *mybs = gf_bs_new(data + i, size - i, GF_BITSTREAM_READ);
e = gf_isom_box_parse((GF_Box **)&ptr->esd, mybs);
gf_bs_del(mybs);
break;
}
}
gf_free(data);
return e;
}
GF_Box *audio_sample_entry_New()
{
ISOM_DECL_BOX_ALLOC(GF_MPEGAudioSampleEntryBox, GF_ISOM_BOX_TYPE_MP4A);
gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*)tmp);
return (GF_Box *)tmp;
}
GF_Box *enca_New()
{
ISOM_DECL_BOX_ALLOC(GF_MPEGAudioSampleEntryBox, GF_ISOM_BOX_TYPE_ENCA);
gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*)tmp);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err audio_sample_entry_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_isom_audio_sample_entry_write((GF_AudioSampleEntryBox*)s, bs);
if (ptr->esd) {
e = gf_isom_box_write((GF_Box *)ptr->esd, bs);
if (e) return e;
}
if (ptr->cfg_3gpp) {
e = gf_isom_box_write((GF_Box *)ptr->cfg_3gpp, bs);
if (e) return e;
}
if (ptr->cfg_ac3) {
e = gf_isom_box_write((GF_Box *)ptr->cfg_ac3, bs);
if (e) return e;
}
return gf_isom_box_array_write(s, ptr->protections, bs);
}
GF_Err audio_sample_entry_Size(GF_Box *s)
{
GF_Err e;
GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s;
gf_isom_audio_sample_entry_size((GF_AudioSampleEntryBox*)s);
if (ptr->esd) {
e = gf_isom_box_size((GF_Box *)ptr->esd);
if (e) return e;
ptr->size += ptr->esd->size;
}
if (ptr->cfg_3gpp) {
e = gf_isom_box_size((GF_Box *)ptr->cfg_3gpp);
if (e) return e;
ptr->size += ptr->cfg_3gpp->size;
}
if (ptr->cfg_ac3) {
e = gf_isom_box_size((GF_Box *)ptr->cfg_ac3);
if (e) return e;
ptr->size += ptr->cfg_ac3->size;
}
return gf_isom_box_array_size(s, ptr->protections);
}
#endif
void mp4s_del(GF_Box *s)
{
GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
if (ptr == NULL) return;
gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
if (ptr->esd) gf_isom_box_del((GF_Box *)ptr->esd);
if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
gf_free(ptr);
}
GF_Err mp4s_AddBox(GF_Box *s, GF_Box *a)
{
GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
switch (a->type) {
case GF_ISOM_BOX_TYPE_ESDS:
if (ptr->esd) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->esd = (GF_ESDBox *)a;
break;
case GF_ISOM_BOX_TYPE_SINF:
gf_list_add(ptr->protections, a);
break;
default:
return gf_isom_box_add_default(s, a);
}
return GF_OK;
}
GF_Err mp4s_Read(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs);
if (e) return e;
ISOM_DECREASE_SIZE(ptr, 8);
return gf_isom_box_array_read(s, bs, mp4s_AddBox);
}
GF_Box *mp4s_New()
{
ISOM_DECL_BOX_ALLOC(GF_MPEGSampleEntryBox, GF_ISOM_BOX_TYPE_MP4S);
gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
return (GF_Box *)tmp;
}
GF_Box *encs_New()
{
ISOM_DECL_BOX_ALLOC(GF_MPEGSampleEntryBox, GF_ISOM_BOX_TYPE_ENCS);
gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err mp4s_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_data(bs, ptr->reserved, 6);
gf_bs_write_u16(bs, ptr->dataReferenceIndex);
e = gf_isom_box_write((GF_Box *)ptr->esd, bs);
if (e) return e;
return gf_isom_box_array_write(s, ptr->protections, bs);
}
GF_Err mp4s_Size(GF_Box *s)
{
GF_Err e;
GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s;
ptr->size += 8;
e = gf_isom_box_size((GF_Box *)ptr->esd);
if (e) return e;
ptr->size += ptr->esd->size;
return gf_isom_box_array_size(s, ptr->protections);
}
#endif
void video_sample_entry_del(GF_Box *s)
{
GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
if (ptr == NULL) return;
gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
if (ptr->esd) gf_isom_box_del((GF_Box *)ptr->esd);
if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
if (ptr->emul_esd) gf_odf_desc_del((GF_Descriptor *)ptr->emul_esd);
if (ptr->avc_config) gf_isom_box_del((GF_Box *) ptr->avc_config);
if (ptr->svc_config) gf_isom_box_del((GF_Box *) ptr->svc_config);
if (ptr->mvc_config) gf_isom_box_del((GF_Box *) ptr->mvc_config);
if (ptr->hevc_config) gf_isom_box_del((GF_Box *) ptr->hevc_config);
if (ptr->lhvc_config) gf_isom_box_del((GF_Box *) ptr->lhvc_config);
if (ptr->cfg_3gpp) gf_isom_box_del((GF_Box *)ptr->cfg_3gpp);
if (ptr->descr) gf_isom_box_del((GF_Box *) ptr->descr);
if (ptr->ipod_ext) gf_isom_box_del((GF_Box *)ptr->ipod_ext);
if (ptr->pasp) gf_isom_box_del((GF_Box *)ptr->pasp);
if (ptr->clap) gf_isom_box_del((GF_Box *)ptr->clap);
if (ptr->rinf) gf_isom_box_del((GF_Box *)ptr->rinf);
if (ptr->rvcc) gf_isom_box_del((GF_Box *)ptr->rvcc);
gf_free(ptr);
}
GF_Err video_sample_entry_AddBox(GF_Box *s, GF_Box *a)
{
GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
switch (a->type) {
case GF_ISOM_BOX_TYPE_ESDS:
if (ptr->esd) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->esd = (GF_ESDBox *)a;
break;
case GF_ISOM_BOX_TYPE_SINF:
gf_list_add(ptr->protections, a);
break;
case GF_ISOM_BOX_TYPE_RINF:
if (ptr->rinf) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->rinf = (GF_RestrictedSchemeInfoBox *) a;
break;
case GF_ISOM_BOX_TYPE_AVCC:
if (ptr->avc_config) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->avc_config = (GF_AVCConfigurationBox *)a;
break;
case GF_ISOM_BOX_TYPE_HVCC:
if (ptr->hevc_config) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->hevc_config = (GF_HEVCConfigurationBox *)a;
break;
case GF_ISOM_BOX_TYPE_SVCC:
if (ptr->svc_config) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->svc_config = (GF_AVCConfigurationBox *)a;
break;
case GF_ISOM_BOX_TYPE_MVCC:
if (ptr->mvc_config) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->mvc_config = (GF_AVCConfigurationBox *)a;
break;
case GF_ISOM_BOX_TYPE_LHVC:
if (ptr->lhvc_config) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->lhvc_config = (GF_HEVCConfigurationBox *)a;
break;
case GF_ISOM_BOX_TYPE_M4DS:
if (ptr->descr) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->descr = (GF_MPEG4ExtensionDescriptorsBox *)a;
break;
case GF_ISOM_BOX_TYPE_UUID:
if (! memcmp(((GF_UnknownUUIDBox*)a)->uuid, GF_ISOM_IPOD_EXT, 16)) {
if (ptr->ipod_ext) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->ipod_ext = (GF_UnknownUUIDBox *)a;
} else {
return gf_isom_box_add_default(s, a);
}
break;
case GF_ISOM_BOX_TYPE_D263:
ptr->cfg_3gpp = (GF_3GPPConfigBox *)a;
ptr->cfg_3gpp->cfg.type = ptr->type;
break;
break;
case GF_ISOM_BOX_TYPE_PASP:
if (ptr->pasp) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->pasp = (GF_PixelAspectRatioBox *)a;
break;
case GF_ISOM_BOX_TYPE_CLAP:
if (ptr->clap) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->clap = (GF_CleanAppertureBox *)a;
break;
case GF_ISOM_BOX_TYPE_RVCC:
if (ptr->rvcc) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->rvcc = (GF_RVCConfigurationBox *)a;
break;
default:
return gf_isom_box_add_default(s, a);
}
return GF_OK;
}
GF_Err video_sample_entry_Read(GF_Box *s, GF_BitStream *bs)
{
GF_MPEGVisualSampleEntryBox *mp4v = (GF_MPEGVisualSampleEntryBox*)s;
GF_Err e;
e = gf_isom_video_sample_entry_read((GF_VisualSampleEntryBox *)s, bs);
if (e) return e;
e = gf_isom_box_array_read(s, bs, video_sample_entry_AddBox);
if (e) return e;
if (mp4v->avc_config || mp4v->svc_config || mp4v->mvc_config) AVC_RewriteESDescriptor(mp4v);
if (mp4v->hevc_config || mp4v->lhvc_config || (mp4v->type==GF_ISOM_BOX_TYPE_HVT1))
HEVC_RewriteESDescriptor(mp4v);
return GF_OK;
}
GF_Box *video_sample_entry_New()
{
GF_MPEGVisualSampleEntryBox *tmp;
GF_SAFEALLOC(tmp, GF_MPEGVisualSampleEntryBox);
if (tmp == NULL) return NULL;
gf_isom_video_sample_entry_init((GF_VisualSampleEntryBox *)tmp);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err video_sample_entry_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_isom_video_sample_entry_write((GF_VisualSampleEntryBox *)s, bs);
if (ptr->esd) {
e = gf_isom_box_write((GF_Box *)ptr->esd, bs);
if (e) return e;
}
else if (ptr->cfg_3gpp) {
e = gf_isom_box_write((GF_Box *)ptr->cfg_3gpp, bs);
if (e) return e;
}
else {
if (ptr->avc_config && ptr->avc_config->config) {
e = gf_isom_box_write((GF_Box *) ptr->avc_config, bs);
if (e) return e;
}
if (ptr->hevc_config && ptr->hevc_config->config) {
e = gf_isom_box_write((GF_Box *) ptr->hevc_config, bs);
if (e) return e;
}
if (ptr->ipod_ext) {
e = gf_isom_box_write((GF_Box *) ptr->ipod_ext, bs);
if (e) return e;
}
if (ptr->descr) {
e = gf_isom_box_write((GF_Box *) ptr->descr, bs);
if (e) return e;
}
if (ptr->svc_config && ptr->svc_config->config) {
e = gf_isom_box_write((GF_Box *) ptr->svc_config, bs);
if (e) return e;
}
if (ptr->mvc_config && ptr->mvc_config->config) {
e = gf_isom_box_write((GF_Box *) ptr->mvc_config, bs);
if (e) return e;
}
if (ptr->lhvc_config && ptr->lhvc_config->config) {
e = gf_isom_box_write((GF_Box *) ptr->lhvc_config, bs);
if (e) return e;
}
}
if (ptr->pasp) {
e = gf_isom_box_write((GF_Box *)ptr->pasp, bs);
if (e) return e;
}
if (ptr->clap) {
e = gf_isom_box_write((GF_Box *)ptr->clap, bs);
if (e) return e;
}
if (ptr->rvcc) {
e = gf_isom_box_write((GF_Box *)ptr->rvcc, bs);
if (e) return e;
}
if (ptr->rinf) {
e = gf_isom_box_write((GF_Box *)ptr->rinf, bs);
if (e) return e;
}
return gf_isom_box_array_write(s, ptr->protections, bs);
}
GF_Err video_sample_entry_Size(GF_Box *s)
{
GF_Err e;
GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s;
gf_isom_video_sample_entry_size((GF_VisualSampleEntryBox *)s);
if (ptr->esd) {
e = gf_isom_box_size((GF_Box *)ptr->esd);
if (e) return e;
ptr->size += ptr->esd->size;
} else if (ptr->cfg_3gpp) {
e = gf_isom_box_size((GF_Box *)ptr->cfg_3gpp);
if (e) return e;
ptr->size += ptr->cfg_3gpp->size;
} else {
if (!ptr->avc_config && !ptr->svc_config && !ptr->hevc_config && !ptr->lhvc_config && (ptr->type!=GF_ISOM_BOX_TYPE_HVT1) ) {
return GF_ISOM_INVALID_FILE;
}
if (ptr->hevc_config && ptr->hevc_config->config) {
e = gf_isom_box_size((GF_Box *)ptr->hevc_config);
if (e) return e;
ptr->size += ptr->hevc_config->size;
}
if (ptr->avc_config && ptr->avc_config->config) {
e = gf_isom_box_size((GF_Box *) ptr->avc_config);
if (e) return e;
ptr->size += ptr->avc_config->size;
}
if (ptr->svc_config && ptr->svc_config->config) {
e = gf_isom_box_size((GF_Box *) ptr->svc_config);
if (e) return e;
ptr->size += ptr->svc_config->size;
}
if (ptr->mvc_config && ptr->mvc_config->config) {
e = gf_isom_box_size((GF_Box *) ptr->mvc_config);
if (e) return e;
ptr->size += ptr->mvc_config->size;
}
if (ptr->lhvc_config && ptr->lhvc_config->config) {
e = gf_isom_box_size((GF_Box *) ptr->lhvc_config);
if (e) return e;
ptr->size += ptr->lhvc_config->size;
}
if (ptr->ipod_ext) {
e = gf_isom_box_size((GF_Box *) ptr->ipod_ext);
if (e) return e;
ptr->size += ptr->ipod_ext->size;
}
if (ptr->descr) {
e = gf_isom_box_size((GF_Box *) ptr->descr);
if (e) return e;
ptr->size += ptr->descr->size;
}
}
if (ptr->pasp) {
e = gf_isom_box_size((GF_Box *)ptr->pasp);
if (e) return e;
ptr->size += ptr->pasp->size;
}
if (ptr->clap) {
e = gf_isom_box_size((GF_Box *)ptr->clap);
if (e) return e;
ptr->size += ptr->clap->size;
}
if (ptr->rvcc) {
e = gf_isom_box_size((GF_Box *)ptr->rvcc);
if (e) return e;
ptr->size += ptr->rvcc->size;
}
if (ptr->rinf) {
e = gf_isom_box_size((GF_Box *)ptr->rinf);
if (e) return e;
ptr->size += ptr->rinf->size;
}
return gf_isom_box_array_size(s, ptr->protections);
}
#endif
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
void mvex_del(GF_Box *s)
{
GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *)s;
if (ptr == NULL) return;
if (ptr->mehd) gf_isom_box_del((GF_Box*)ptr->mehd);
gf_isom_box_array_del(ptr->TrackExList);
gf_isom_box_array_del(ptr->TrackExPropList);
gf_free(ptr);
}
GF_Err mvex_AddBox(GF_Box *s, GF_Box *a)
{
GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *)s;
switch (a->type) {
case GF_ISOM_BOX_TYPE_TREX:
return gf_list_add(ptr->TrackExList, a);
case GF_ISOM_BOX_TYPE_TREP:
return gf_list_add(ptr->TrackExPropList, a);
case GF_ISOM_BOX_TYPE_MEHD:
if (ptr->mehd) break;
ptr->mehd = (GF_MovieExtendsHeaderBox*)a;
return GF_OK;
default:
return gf_isom_box_add_default(s, a);
}
return GF_OK;
}
GF_Err mvex_Read(GF_Box *s, GF_BitStream *bs)
{
return gf_isom_box_array_read(s, bs, mvex_AddBox);
}
GF_Box *mvex_New()
{
ISOM_DECL_BOX_ALLOC(GF_MovieExtendsBox, GF_ISOM_BOX_TYPE_MVEX);
tmp->TrackExList = gf_list_new();
if (!tmp->TrackExList) {
gf_free(tmp);
return NULL;
}
tmp->TrackExPropList = gf_list_new();
if (!tmp->TrackExPropList) {
gf_list_del(tmp->TrackExList);
gf_free(tmp);
return NULL;
}
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err mvex_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *) s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
if (ptr->mehd) {
e = gf_isom_box_write((GF_Box *)ptr->mehd, bs);
if (e) return e;
}
e = gf_isom_box_array_write(s, ptr->TrackExList, bs);
if (e) return e;
return gf_isom_box_array_write(s, ptr->TrackExPropList, bs);
}
GF_Err mvex_Size(GF_Box *s)
{
GF_Err e;
GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *)s;
if (ptr->mehd) {
e = gf_isom_box_size((GF_Box *)ptr->mehd);
if (e) return e;
ptr->size += ptr->mehd->size;
}
e = gf_isom_box_array_size(s, ptr->TrackExList);
if (e) return e;
return gf_isom_box_array_size(s, ptr->TrackExPropList);
}
#endif
GF_Box *mehd_New()
{
ISOM_DECL_BOX_ALLOC(GF_MovieExtendsHeaderBox, GF_ISOM_BOX_TYPE_MEHD);
return (GF_Box *)tmp;
}
void mehd_del(GF_Box *s)
{
gf_free(s);
}
GF_Err mehd_Read(GF_Box *s, GF_BitStream *bs)
{
GF_MovieExtendsHeaderBox *ptr = (GF_MovieExtendsHeaderBox *)s;
if (ptr->version==1) {
ptr->fragment_duration = gf_bs_read_u64(bs);
} else {
ptr->fragment_duration = (u64) gf_bs_read_u32(bs);
}
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err mehd_Write(GF_Box *s, GF_BitStream *bs)
{
GF_MovieExtendsHeaderBox *ptr = (GF_MovieExtendsHeaderBox *)s;
GF_Err e = gf_isom_full_box_write(s, bs);
if (e) return e;
if (ptr->version == 1) {
gf_bs_write_u64(bs, ptr->fragment_duration);
} else {
gf_bs_write_u32(bs, (u32) ptr->fragment_duration);
}
return GF_OK;
}
GF_Err mehd_Size(GF_Box *s)
{
GF_MovieExtendsHeaderBox *ptr = (GF_MovieExtendsHeaderBox *)s;
ptr->version = (ptr->fragment_duration>0xFFFFFFFF) ? 1 : 0;
s->size += (ptr->version == 1) ? 8 : 4;
return GF_OK;
}
#endif
#endif
void mvhd_del(GF_Box *s)
{
GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
if (ptr == NULL) return;
gf_free(ptr);
}
GF_Err mvhd_Read(GF_Box *s, GF_BitStream *bs)
{
GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
if (ptr->version == 1) {
ptr->creationTime = gf_bs_read_u64(bs);
ptr->modificationTime = gf_bs_read_u64(bs);
ptr->timeScale = gf_bs_read_u32(bs);
ptr->duration = gf_bs_read_u64(bs);
} else {
ptr->creationTime = gf_bs_read_u32(bs);
ptr->modificationTime = gf_bs_read_u32(bs);
ptr->timeScale = gf_bs_read_u32(bs);
ptr->duration = gf_bs_read_u32(bs);
}
if (!ptr->timeScale) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Movie header timescale is invalid (0) - defaulting to 600\n" ));
ptr->timeScale = 600;
}
ptr->preferredRate = gf_bs_read_u32(bs);
ptr->preferredVolume = gf_bs_read_u16(bs);
gf_bs_read_data(bs, ptr->reserved, 10);
ptr->matrixA = gf_bs_read_u32(bs);
ptr->matrixB = gf_bs_read_u32(bs);
ptr->matrixU = gf_bs_read_u32(bs);
ptr->matrixC = gf_bs_read_u32(bs);
ptr->matrixD = gf_bs_read_u32(bs);
ptr->matrixV = gf_bs_read_u32(bs);
ptr->matrixX = gf_bs_read_u32(bs);
ptr->matrixY = gf_bs_read_u32(bs);
ptr->matrixW = gf_bs_read_u32(bs);
ptr->previewTime = gf_bs_read_u32(bs);
ptr->previewDuration = gf_bs_read_u32(bs);
ptr->posterTime = gf_bs_read_u32(bs);
ptr->selectionTime = gf_bs_read_u32(bs);
ptr->selectionDuration = gf_bs_read_u32(bs);
ptr->currentTime = gf_bs_read_u32(bs);
ptr->nextTrackID = gf_bs_read_u32(bs);
ptr->original_duration = ptr->duration;
return GF_OK;
}
GF_Box *mvhd_New()
{
ISOM_DECL_BOX_ALLOC(GF_MovieHeaderBox, GF_ISOM_BOX_TYPE_MVHD);
tmp->preferredRate = (1<<16);
tmp->preferredVolume = (1<<8);
tmp->matrixA = (1<<16);
tmp->matrixD = (1<<16);
tmp->matrixW = (1<<30);
tmp->nextTrackID = 1;
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err mvhd_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
if (ptr->version == 1) {
gf_bs_write_u64(bs, ptr->creationTime);
gf_bs_write_u64(bs, ptr->modificationTime);
gf_bs_write_u32(bs, ptr->timeScale);
gf_bs_write_u64(bs, ptr->duration);
} else {
gf_bs_write_u32(bs, (u32) ptr->creationTime);
gf_bs_write_u32(bs, (u32) ptr->modificationTime);
gf_bs_write_u32(bs, ptr->timeScale);
gf_bs_write_u32(bs, (u32) ptr->duration);
}
gf_bs_write_u32(bs, ptr->preferredRate);
gf_bs_write_u16(bs, ptr->preferredVolume);
gf_bs_write_data(bs, ptr->reserved, 10);
gf_bs_write_u32(bs, ptr->matrixA);
gf_bs_write_u32(bs, ptr->matrixB);
gf_bs_write_u32(bs, ptr->matrixU);
gf_bs_write_u32(bs, ptr->matrixC);
gf_bs_write_u32(bs, ptr->matrixD);
gf_bs_write_u32(bs, ptr->matrixV);
gf_bs_write_u32(bs, ptr->matrixX);
gf_bs_write_u32(bs, ptr->matrixY);
gf_bs_write_u32(bs, ptr->matrixW);
gf_bs_write_u32(bs, ptr->previewTime);
gf_bs_write_u32(bs, ptr->previewDuration);
gf_bs_write_u32(bs, ptr->posterTime);
gf_bs_write_u32(bs, ptr->selectionTime);
gf_bs_write_u32(bs, ptr->selectionDuration);
gf_bs_write_u32(bs, ptr->currentTime);
gf_bs_write_u32(bs, ptr->nextTrackID);
return GF_OK;
}
GF_Err mvhd_Size(GF_Box *s)
{
GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s;
if (ptr->duration==(u64) -1) ptr->version = 0;
else ptr->version = (ptr->duration>0xFFFFFFFF) ? 1 : 0;
ptr->size += (ptr->version == 1) ? 28 : 16;
ptr->size += 80;
return GF_OK;
}
#endif
void nmhd_del(GF_Box *s)
{
GF_MPEGMediaHeaderBox *ptr = (GF_MPEGMediaHeaderBox *)s;
if (ptr == NULL) return;
gf_free(ptr);
}
GF_Err nmhd_Read(GF_Box *s, GF_BitStream *bs)
{
return GF_OK;
}
GF_Box *nmhd_New()
{
ISOM_DECL_BOX_ALLOC(GF_MPEGMediaHeaderBox, GF_ISOM_BOX_TYPE_NMHD);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err nmhd_Write(GF_Box *s, GF_BitStream *bs)
{
return gf_isom_full_box_write(s, bs);
}
GF_Err nmhd_Size(GF_Box *s)
{
return GF_OK;
}
#endif
void padb_del(GF_Box *s)
{
GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *) s;
if (ptr == NULL) return;
if (ptr->padbits) gf_free(ptr->padbits);
gf_free(ptr);
}
GF_Err padb_Read(GF_Box *s,GF_BitStream *bs)
{
u32 i;
GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *)s;
ptr->SampleCount = gf_bs_read_u32(bs);
ptr->padbits = (u8 *)gf_malloc(sizeof(u8)*ptr->SampleCount);
for (i=0; i<ptr->SampleCount; i += 2) {
gf_bs_read_int(bs, 1);
if (i+1 < ptr->SampleCount) {
ptr->padbits[i+1] = gf_bs_read_int(bs, 3);
} else {
gf_bs_read_int(bs, 3);
}
gf_bs_read_int(bs, 1);
ptr->padbits[i] = gf_bs_read_int(bs, 3);
}
return GF_OK;
}
GF_Box *padb_New()
{
ISOM_DECL_BOX_ALLOC(GF_PaddingBitsBox, GF_ISOM_BOX_TYPE_PADB);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err padb_Write(GF_Box *s, GF_BitStream *bs)
{
u32 i;
GF_Err e;
GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *) s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_int(bs, ptr->SampleCount, 32);
for (i=0 ; i<ptr->SampleCount; i += 2) {
gf_bs_write_int(bs, 0, 1);
if (i+1 < ptr->SampleCount) {
gf_bs_write_int(bs, ptr->padbits[i+1], 3);
} else {
gf_bs_write_int(bs, 0, 3);
}
gf_bs_write_int(bs, 0, 1);
gf_bs_write_int(bs, ptr->padbits[i], 3);
}
return GF_OK;
}
GF_Err padb_Size(GF_Box *s)
{
GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *)s;
ptr->size += 4;
if (ptr->SampleCount) ptr->size += (ptr->SampleCount + 1) / 2;
return GF_OK;
}
#endif
void rely_del(GF_Box *s)
{
GF_RelyHintBox *rely = (GF_RelyHintBox *)s;
gf_free(rely);
}
GF_Err rely_Read(GF_Box *s, GF_BitStream *bs)
{
GF_RelyHintBox *ptr = (GF_RelyHintBox *)s;
ptr->reserved = gf_bs_read_int(bs, 6);
ptr->prefered = gf_bs_read_int(bs, 1);
ptr->required = gf_bs_read_int(bs, 1);
return GF_OK;
}
GF_Box *rely_New()
{
ISOM_DECL_BOX_ALLOC(GF_RelyHintBox, GF_ISOM_BOX_TYPE_RELY);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err rely_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_RelyHintBox *ptr = (GF_RelyHintBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_int(bs, ptr->reserved, 6);
gf_bs_write_int(bs, ptr->prefered, 1);
gf_bs_write_int(bs, ptr->required, 1);
return GF_OK;
}
GF_Err rely_Size(GF_Box *s)
{
s->size += 1;
return GF_OK;
}
#endif
void rtpo_del(GF_Box *s)
{
GF_RTPOBox *rtpo = (GF_RTPOBox *)s;
gf_free(rtpo);
}
GF_Err rtpo_Read(GF_Box *s, GF_BitStream *bs)
{
GF_RTPOBox *ptr = (GF_RTPOBox *)s;
ptr->timeOffset = gf_bs_read_u32(bs);
return GF_OK;
}
GF_Box *rtpo_New()
{
ISOM_DECL_BOX_ALLOC(GF_RTPOBox, GF_ISOM_BOX_TYPE_RTPO);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err rtpo_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_RTPOBox *ptr = (GF_RTPOBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->timeOffset);
return GF_OK;
}
GF_Err rtpo_Size(GF_Box *s)
{
s->size += 4;
return GF_OK;
}
#endif
void smhd_del(GF_Box *s)
{
GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;
if (ptr == NULL ) return;
gf_free(ptr);
}
GF_Err smhd_Read(GF_Box *s, GF_BitStream *bs)
{
GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;
ptr->balance = gf_bs_read_u16(bs);
ptr->reserved = gf_bs_read_u16(bs);
return GF_OK;
}
GF_Box *smhd_New()
{
ISOM_DECL_BOX_ALLOC(GF_SoundMediaHeaderBox, GF_ISOM_BOX_TYPE_SMHD);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err smhd_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u16(bs, ptr->balance);
gf_bs_write_u16(bs, ptr->reserved);
return GF_OK;
}
GF_Err smhd_Size(GF_Box *s)
{
GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s;
ptr->reserved = 0;
ptr->size += 4;
return GF_OK;
}
#endif
void snro_del(GF_Box *s)
{
GF_SeqOffHintEntryBox *snro = (GF_SeqOffHintEntryBox *)s;
gf_free(snro);
}
GF_Err snro_Read(GF_Box *s, GF_BitStream *bs)
{
GF_SeqOffHintEntryBox *ptr = (GF_SeqOffHintEntryBox *)s;
ptr->SeqOffset = gf_bs_read_u32(bs);
return GF_OK;
}
GF_Box *snro_New()
{
ISOM_DECL_BOX_ALLOC(GF_SeqOffHintEntryBox, GF_ISOM_BOX_TYPE_SNRO);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err snro_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_SeqOffHintEntryBox *ptr = (GF_SeqOffHintEntryBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->SeqOffset);
return GF_OK;
}
GF_Err snro_Size(GF_Box *s)
{
s->size += 4;
return GF_OK;
}
#endif
#define WRITE_SAMPLE_FRAGMENTS 1
void stbl_del(GF_Box *s)
{
GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
if (ptr == NULL) return;
if (ptr->ChunkOffset) gf_isom_box_del(ptr->ChunkOffset);
if (ptr->CompositionOffset) gf_isom_box_del((GF_Box *) ptr->CompositionOffset);
if (ptr->CompositionToDecode) gf_isom_box_del((GF_Box *) ptr->CompositionToDecode);
if (ptr->DegradationPriority) gf_isom_box_del((GF_Box *) ptr->DegradationPriority);
if (ptr->SampleDescription) gf_isom_box_del((GF_Box *) ptr->SampleDescription);
if (ptr->SampleSize) gf_isom_box_del((GF_Box *) ptr->SampleSize);
if (ptr->SampleToChunk) gf_isom_box_del((GF_Box *) ptr->SampleToChunk);
if (ptr->ShadowSync) gf_isom_box_del((GF_Box *) ptr->ShadowSync);
if (ptr->SyncSample) gf_isom_box_del((GF_Box *) ptr->SyncSample);
if (ptr->TimeToSample) gf_isom_box_del((GF_Box *) ptr->TimeToSample);
if (ptr->SampleDep) gf_isom_box_del((GF_Box *) ptr->SampleDep);
if (ptr->PaddingBits) gf_isom_box_del((GF_Box *) ptr->PaddingBits);
if (ptr->Fragments) gf_isom_box_del((GF_Box *) ptr->Fragments);
if (ptr->sub_samples) gf_isom_box_array_del(ptr->sub_samples);
if (ptr->sampleGroups) gf_isom_box_array_del(ptr->sampleGroups);
if (ptr->sampleGroupsDescription) gf_isom_box_array_del(ptr->sampleGroupsDescription);
if (ptr->sai_sizes) gf_isom_box_array_del(ptr->sai_sizes);
if (ptr->sai_offsets) gf_isom_box_array_del(ptr->sai_offsets);
gf_free(ptr);
}
GF_Err stbl_AddBox(GF_Box *s, GF_Box *a)
{
GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
if (!a) return GF_OK;
switch (a->type) {
case GF_ISOM_BOX_TYPE_STTS:
if (ptr->TimeToSample) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->TimeToSample = (GF_TimeToSampleBox *)a;
break;
case GF_ISOM_BOX_TYPE_CTTS:
if (ptr->CompositionOffset) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->CompositionOffset = (GF_CompositionOffsetBox *)a;
break;
case GF_ISOM_BOX_TYPE_CSLG:
if (ptr->CompositionToDecode) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->CompositionToDecode = (GF_CompositionToDecodeBox *)a;
break;
case GF_ISOM_BOX_TYPE_STSS:
if (ptr->SyncSample) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->SyncSample = (GF_SyncSampleBox *)a;
break;
case GF_ISOM_BOX_TYPE_STSD:
if (ptr->SampleDescription) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->SampleDescription =(GF_SampleDescriptionBox *)a;
break;
case GF_ISOM_BOX_TYPE_STZ2:
case GF_ISOM_BOX_TYPE_STSZ:
if (ptr->SampleSize) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->SampleSize = (GF_SampleSizeBox *)a;
break;
case GF_ISOM_BOX_TYPE_STSC:
if (ptr->SampleToChunk) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->SampleToChunk = (GF_SampleToChunkBox *)a;
break;
case GF_ISOM_BOX_TYPE_PADB:
if (ptr->PaddingBits) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->PaddingBits = (GF_PaddingBitsBox *) a;
break;
case GF_ISOM_BOX_TYPE_CO64:
case GF_ISOM_BOX_TYPE_STCO:
if (ptr->ChunkOffset) {
gf_isom_box_del(ptr->ChunkOffset);
}
ptr->ChunkOffset = a;
return GF_OK;
case GF_ISOM_BOX_TYPE_STSH:
if (ptr->ShadowSync) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->ShadowSync = (GF_ShadowSyncBox *)a;
break;
case GF_ISOM_BOX_TYPE_STDP:
if (ptr->DegradationPriority) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->DegradationPriority = (GF_DegradationPriorityBox *)a;
break;
case GF_ISOM_BOX_TYPE_SDTP:
if (ptr->SampleDep) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->SampleDep= (GF_SampleDependencyTypeBox *)a;
break;
case GF_ISOM_BOX_TYPE_STSF:
if (ptr->Fragments) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->Fragments = (GF_SampleFragmentBox *)a;
break;
case GF_ISOM_BOX_TYPE_SUBS:
if (!ptr->sub_samples) ptr->sub_samples = gf_list_new();
gf_list_add(ptr->sub_samples, a);
{
GF_SubSampleInformationBox *subs = (GF_SubSampleInformationBox *)a;
GF_SubSampleInfoEntry *ent = gf_list_get(subs->Samples, 0);
if (ent->sample_delta==0) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] first entry in SubSample in track SampleTable has sample_delta of 0, should be one. Fixing\n"));
ent->sample_delta = 1;
}
}
break;
case GF_ISOM_BOX_TYPE_SBGP:
if (!ptr->sampleGroups) ptr->sampleGroups = gf_list_new();
gf_list_add(ptr->sampleGroups, a);
break;
case GF_ISOM_BOX_TYPE_SGPD:
if (!ptr->sampleGroupsDescription) ptr->sampleGroupsDescription = gf_list_new();
gf_list_add(ptr->sampleGroupsDescription, a);
break;
case GF_ISOM_BOX_TYPE_SAIZ:
if (!ptr->sai_sizes) ptr->sai_sizes = gf_list_new();
gf_list_add(ptr->sai_sizes, a);
break;
case GF_ISOM_BOX_TYPE_SAIO:
if (!ptr->sai_offsets) ptr->sai_offsets = gf_list_new();
gf_list_add(ptr->sai_offsets, a);
break;
default:
return gf_isom_box_add_default((GF_Box *)ptr, a);
}
return GF_OK;
}
GF_Err stbl_Read(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
e = gf_isom_box_array_read(s, bs, stbl_AddBox);
if (e) return e;
if (!ptr->SyncSample)
ptr->no_sync_found = 1;
ptr->nb_sgpd_in_stbl = gf_list_count(ptr->sampleGroupsDescription);
ptr->nb_other_boxes_in_stbl = gf_list_count(ptr->other_boxes);
return GF_OK;
}
GF_Box *stbl_New()
{
ISOM_DECL_BOX_ALLOC(GF_SampleTableBox, GF_ISOM_BOX_TYPE_STBL);
tmp->MaxSamplePerChunk = 10;
tmp->groupID = 1;
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err stbl_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
if (ptr->SampleDescription) {
e = gf_isom_box_write((GF_Box *) ptr->SampleDescription, bs);
if (e) return e;
}
if (ptr->TimeToSample) {
e = gf_isom_box_write((GF_Box *) ptr->TimeToSample, bs);
if (e) return e;
}
if (ptr->CompositionOffset) {
e = gf_isom_box_write((GF_Box *) ptr->CompositionOffset, bs);
if (e) return e;
}
if (ptr->CompositionToDecode) {
e = gf_isom_box_write((GF_Box *) ptr->CompositionToDecode, bs);
if (e) return e;
}
if (ptr->SyncSample) {
e = gf_isom_box_write((GF_Box *) ptr->SyncSample, bs);
if (e) return e;
}
if (ptr->ShadowSync) {
e = gf_isom_box_write((GF_Box *) ptr->ShadowSync, bs);
if (e) return e;
}
if (ptr->SampleToChunk) {
e = gf_isom_box_write((GF_Box *) ptr->SampleToChunk, bs);
if (e) return e;
}
if (ptr->SampleSize) {
e = gf_isom_box_write((GF_Box *) ptr->SampleSize, bs);
if (e) return e;
}
if (ptr->ChunkOffset) {
e = gf_isom_box_write(ptr->ChunkOffset, bs);
if (e) return e;
}
if (ptr->DegradationPriority) {
e = gf_isom_box_write((GF_Box *) ptr->DegradationPriority, bs);
if (e) return e;
}
if (ptr->SampleDep && ptr->SampleDep->sampleCount) {
e = gf_isom_box_write((GF_Box *) ptr->SampleDep, bs);
if (e) return e;
}
if (ptr->PaddingBits) {
e = gf_isom_box_write((GF_Box *) ptr->PaddingBits, bs);
if (e) return e;
}
if (ptr->sub_samples) {
e = gf_isom_box_array_write(s, ptr->sub_samples, bs);
if (e) return e;
}
if (ptr->sampleGroupsDescription) {
e = gf_isom_box_array_write(s, ptr->sampleGroupsDescription, bs);
if (e) return e;
}
if (ptr->sampleGroups) {
e = gf_isom_box_array_write(s, ptr->sampleGroups, bs);
if (e) return e;
}
if (ptr->sai_sizes) {
e = gf_isom_box_array_write(s, ptr->sai_sizes, bs);
if (e) return e;
}
if (ptr->sai_offsets) {
e = gf_isom_box_array_write(s, ptr->sai_offsets, bs);
if (e) return e;
}
#if WRITE_SAMPLE_FRAGMENTS
if (ptr->Fragments) {
e = gf_isom_box_write((GF_Box *) ptr->Fragments, bs);
if (e) return e;
}
#endif
return GF_OK;
}
GF_Err stbl_Size(GF_Box *s)
{
GF_Err e;
GF_SampleTableBox *ptr = (GF_SampleTableBox *)s;
if (ptr->SampleDescription) {
e = gf_isom_box_size((GF_Box *) ptr->SampleDescription);
if (e) return e;
ptr->size += ptr->SampleDescription->size;
}
if (ptr->SampleSize) {
e = gf_isom_box_size((GF_Box *) ptr->SampleSize);
if (e) return e;
ptr->size += ptr->SampleSize->size;
}
if (ptr->SampleToChunk) {
e = gf_isom_box_size((GF_Box *) ptr->SampleToChunk);
if (e) return e;
ptr->size += ptr->SampleToChunk->size;
}
if (ptr->TimeToSample) {
e = gf_isom_box_size((GF_Box *) ptr->TimeToSample);
if (e) return e;
ptr->size += ptr->TimeToSample->size;
}
if (ptr->ChunkOffset) {
e = gf_isom_box_size(ptr->ChunkOffset);
if (e) return e;
ptr->size += ptr->ChunkOffset->size;
}
if (ptr->CompositionOffset) {
e = gf_isom_box_size((GF_Box *) ptr->CompositionOffset);
if (e) return e;
ptr->size += ptr->CompositionOffset->size;
}
if (ptr->CompositionToDecode) {
e = gf_isom_box_size((GF_Box *) ptr->CompositionToDecode);
if (e) return e;
ptr->size += ptr->CompositionToDecode->size;
}
if (ptr->DegradationPriority) {
e = gf_isom_box_size((GF_Box *) ptr->DegradationPriority);
if (e) return e;
ptr->size += ptr->DegradationPriority->size;
}
if (ptr->ShadowSync) {
e = gf_isom_box_size((GF_Box *) ptr->ShadowSync);
if (e) return e;
ptr->size += ptr->ShadowSync->size;
}
if (ptr->SyncSample) {
e = gf_isom_box_size((GF_Box *) ptr->SyncSample);
if (e) return e;
ptr->size += ptr->SyncSample->size;
}
if (ptr->SampleDep && ptr->SampleDep->sampleCount) {
e = gf_isom_box_size((GF_Box *) ptr->SampleDep);
if (e) return e;
ptr->size += ptr->SampleDep->size;
}
if (ptr->PaddingBits) {
e = gf_isom_box_size((GF_Box *) ptr->PaddingBits);
if (e) return e;
ptr->size += ptr->PaddingBits->size;
}
#if WRITE_SAMPLE_FRAGMENTS
if (ptr->Fragments) {
e = gf_isom_box_size((GF_Box *) ptr->Fragments);
if (e) return e;
ptr->size += ptr->Fragments->size;
}
#endif
if (ptr->sub_samples) {
e = gf_isom_box_array_size(s, ptr->sub_samples);
if (e) return e;
}
if (ptr->sampleGroups) {
e = gf_isom_box_array_size(s, ptr->sampleGroups);
if (e) return e;
}
if (ptr->sampleGroupsDescription) {
e = gf_isom_box_array_size(s, ptr->sampleGroupsDescription);
if (e) return e;
}
if (ptr->sai_sizes) {
e = gf_isom_box_array_size(s, ptr->sai_sizes);
if (e) return e;
}
if (ptr->sai_offsets) {
e = gf_isom_box_array_size(s, ptr->sai_offsets);
if (e) return e;
}
return GF_OK;
}
#endif
void stco_del(GF_Box *s)
{
GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;
if (ptr == NULL) return;
if (ptr->offsets) gf_free(ptr->offsets);
gf_free(ptr);
}
GF_Err stco_Read(GF_Box *s, GF_BitStream *bs)
{
u32 entries;
GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;
ptr->nb_entries = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
if (ptr->nb_entries > ptr->size / 4) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stco\n", ptr->nb_entries));
return GF_ISOM_INVALID_FILE;
}
if (ptr->nb_entries) {
ptr->offsets = (u32 *) gf_malloc(ptr->nb_entries * sizeof(u32) );
if (ptr->offsets == NULL) return GF_OUT_OF_MEM;
ptr->alloc_size = ptr->nb_entries;
for (entries = 0; entries < ptr->nb_entries; entries++) {
ptr->offsets[entries] = gf_bs_read_u32(bs);
}
}
return GF_OK;
}
GF_Box *stco_New()
{
ISOM_DECL_BOX_ALLOC(GF_ChunkOffsetBox, GF_ISOM_BOX_TYPE_STCO);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err stco_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->nb_entries);
for (i = 0; i < ptr->nb_entries; i++) {
gf_bs_write_u32(bs, ptr->offsets[i]);
}
return GF_OK;
}
GF_Err stco_Size(GF_Box *s)
{
GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s;
ptr->size += 4 + (4 * ptr->nb_entries);
return GF_OK;
}
#endif
void stdp_del(GF_Box *s)
{
GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;
if (ptr == NULL ) return;
if (ptr->priorities) gf_free(ptr->priorities);
gf_free(ptr);
}
GF_Err stdp_Read(GF_Box *s, GF_BitStream *bs)
{
u32 entry;
GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;
if (!ptr->nb_entries) ptr->nb_entries = (u32) ptr->size / 2;
else if (ptr->nb_entries > ptr->size / 2) return GF_ISOM_INVALID_FILE;
ptr->priorities = (u16 *) gf_malloc(ptr->nb_entries * sizeof(u16));
if (ptr->priorities == NULL) return GF_OUT_OF_MEM;
for (entry = 0; entry < ptr->nb_entries; entry++) {
ptr->priorities[entry] = gf_bs_read_u16(bs);
}
ISOM_DECREASE_SIZE(ptr, (2*ptr->nb_entries) );
return GF_OK;
}
GF_Box *stdp_New()
{
ISOM_DECL_BOX_ALLOC(GF_DegradationPriorityBox, GF_ISOM_BOX_TYPE_STDP);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err stdp_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
for (i = 0; i < ptr->nb_entries; i++) {
gf_bs_write_u16(bs, ptr->priorities[i]);
}
return GF_OK;
}
GF_Err stdp_Size(GF_Box *s)
{
GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s;
ptr->size += (2 * ptr->nb_entries);
return GF_OK;
}
#endif
void stsc_del(GF_Box *s)
{
GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;
if (ptr == NULL) return;
if (ptr->entries) gf_free(ptr->entries);
gf_free(ptr);
}
GF_Err stsc_Read(GF_Box *s, GF_BitStream *bs)
{
u32 i;
GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;
ptr->nb_entries = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
if (ptr->nb_entries > ptr->size / 12) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsc\n", ptr->nb_entries));
return GF_ISOM_INVALID_FILE;
}
ptr->alloc_size = ptr->nb_entries;
ptr->entries = gf_malloc(sizeof(GF_StscEntry)*ptr->alloc_size);
if (!ptr->entries) return GF_OUT_OF_MEM;
for (i = 0; i < ptr->nb_entries; i++) {
ptr->entries[i].firstChunk = gf_bs_read_u32(bs);
ptr->entries[i].samplesPerChunk = gf_bs_read_u32(bs);
ptr->entries[i].sampleDescriptionIndex = gf_bs_read_u32(bs);
ptr->entries[i].isEdited = 0;
ptr->entries[i].nextChunk = 0;
if (!ptr->entries[i].firstChunk) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] invalid first chunk 0 in stsc entry\n", ptr->nb_entries));
return GF_ISOM_INVALID_FILE;
}
if (i) ptr->entries[i-1].nextChunk = ptr->entries[i].firstChunk;
}
ptr->currentIndex = 0;
ptr->firstSampleInCurrentChunk = 0;
ptr->currentChunk = 0;
ptr->ghostNumber = 0;
return GF_OK;
}
GF_Box *stsc_New()
{
ISOM_DECL_BOX_ALLOC(GF_SampleToChunkBox, GF_ISOM_BOX_TYPE_STSC);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err stsc_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->nb_entries);
for (i=0; i<ptr->nb_entries; i++) {
gf_bs_write_u32(bs, ptr->entries[i].firstChunk);
gf_bs_write_u32(bs, ptr->entries[i].samplesPerChunk);
gf_bs_write_u32(bs, ptr->entries[i].sampleDescriptionIndex);
}
return GF_OK;
}
GF_Err stsc_Size(GF_Box *s)
{
GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s;
ptr->size += 4 + (12 * ptr->nb_entries);
return GF_OK;
}
#endif
void stsd_del(GF_Box *s)
{
GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s;
if (ptr == NULL) return;
gf_free(ptr);
}
GF_Err stsd_AddBox(GF_Box *s, GF_Box *a)
{
GF_UnknownBox *def;
GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s;
if (!a) return GF_OK;
switch (a->type) {
case GF_ISOM_BOX_TYPE_MP4S:
case GF_ISOM_BOX_TYPE_ENCS:
case GF_ISOM_BOX_TYPE_MP4A:
case GF_ISOM_BOX_TYPE_ENCA:
case GF_ISOM_BOX_TYPE_MP4V:
case GF_ISOM_BOX_TYPE_ENCV:
case GF_ISOM_BOX_TYPE_RESV:
case GF_ISOM_BOX_TYPE_GHNT:
case GF_ISOM_BOX_TYPE_RTP_STSD:
case GF_ISOM_BOX_TYPE_SRTP_STSD:
case GF_ISOM_BOX_TYPE_FDP_STSD:
case GF_ISOM_BOX_TYPE_RRTP_STSD:
case GF_ISOM_BOX_TYPE_RTCP_STSD:
case GF_ISOM_BOX_TYPE_AVC1:
case GF_ISOM_BOX_TYPE_AVC2:
case GF_ISOM_BOX_TYPE_AVC3:
case GF_ISOM_BOX_TYPE_AVC4:
case GF_ISOM_BOX_TYPE_SVC1:
case GF_ISOM_BOX_TYPE_MVC1:
case GF_ISOM_BOX_TYPE_HVC1:
case GF_ISOM_BOX_TYPE_HEV1:
case GF_ISOM_BOX_TYPE_HVC2:
case GF_ISOM_BOX_TYPE_HEV2:
case GF_ISOM_BOX_TYPE_HVT1:
case GF_ISOM_BOX_TYPE_LHV1:
case GF_ISOM_BOX_TYPE_LHE1:
case GF_ISOM_BOX_TYPE_TX3G:
case GF_ISOM_BOX_TYPE_TEXT:
case GF_ISOM_BOX_TYPE_ENCT:
case GF_ISOM_BOX_TYPE_METX:
case GF_ISOM_BOX_TYPE_METT:
case GF_ISOM_BOX_TYPE_STXT:
case GF_ISOM_BOX_TYPE_DIMS:
case GF_ISOM_BOX_TYPE_AC3:
case GF_ISOM_BOX_TYPE_EC3:
case GF_ISOM_BOX_TYPE_LSR1:
case GF_ISOM_BOX_TYPE_WVTT:
case GF_ISOM_BOX_TYPE_STPP:
case GF_ISOM_BOX_TYPE_SBTT:
case GF_ISOM_BOX_TYPE_ELNG:
case GF_ISOM_BOX_TYPE_MP3:
case GF_ISOM_SUBTYPE_3GP_AMR:
case GF_ISOM_SUBTYPE_3GP_AMR_WB:
case GF_ISOM_SUBTYPE_3GP_EVRC:
case GF_ISOM_SUBTYPE_3GP_QCELP:
case GF_ISOM_SUBTYPE_3GP_SMV:
case GF_ISOM_SUBTYPE_3GP_H263:
return gf_isom_box_add_default((GF_Box*)ptr, a);
case GF_ISOM_BOX_TYPE_UNKNOWN:
def = (GF_UnknownBox *)a;
if (def->dataSize < 8) {
gf_isom_box_del(a);
return GF_OK;
}
return gf_isom_box_add_default((GF_Box*)ptr, a);
default:
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Cannot process box of type %s\n", gf_4cc_to_str(a->type)));
return GF_ISOM_INVALID_FILE;
}
}
GF_Err stsd_Read(GF_Box *s, GF_BitStream *bs)
{
gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(s, 4)
return gf_isom_box_array_read(s, bs, stsd_AddBox);
}
GF_Box *stsd_New()
{
ISOM_DECL_BOX_ALLOC(GF_SampleDescriptionBox, GF_ISOM_BOX_TYPE_STSD);
tmp->other_boxes = gf_list_new();
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err stsd_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 nb_entries;
GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
nb_entries = gf_list_count(ptr->other_boxes);
gf_bs_write_u32(bs, nb_entries);
return GF_OK;
}
GF_Err stsd_Size(GF_Box *s)
{
GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s;
ptr->size += 4;
return GF_OK;
}
#endif
void stsf_del(GF_Box *s)
{
u32 nb_entries;
u32 i;
GF_StsfEntry *pe;
GF_SampleFragmentBox *ptr = (GF_SampleFragmentBox *)s;
if (ptr == NULL) return;
if (ptr->entryList) {
nb_entries = gf_list_count(ptr->entryList);
for ( i = 0; i < nb_entries; i++ ) {
pe = (GF_StsfEntry*)gf_list_get(ptr->entryList, i);
if (pe->fragmentSizes) gf_free(pe->fragmentSizes);
gf_free(pe);
}
gf_list_del(ptr->entryList);
}
gf_free(ptr);
}
GF_Err stsf_Read(GF_Box *s, GF_BitStream *bs)
{
u32 entries, i;
u32 nb_entries;
GF_StsfEntry *p;
GF_SampleFragmentBox *ptr = (GF_SampleFragmentBox *)s;
p = NULL;
if (!ptr) return GF_BAD_PARAM;
nb_entries = gf_bs_read_u32(bs);
p = NULL;
for ( entries = 0; entries < nb_entries; entries++ ) {
p = (GF_StsfEntry *) gf_malloc(sizeof(GF_StsfEntry));
if (!p) return GF_OUT_OF_MEM;
p->SampleNumber = gf_bs_read_u32(bs);
p->fragmentCount = gf_bs_read_u32(bs);
p->fragmentSizes = (u16*)gf_malloc(sizeof(GF_StsfEntry) * p->fragmentCount);
for (i=0; i<p->fragmentCount; i++) {
p->fragmentSizes[i] = gf_bs_read_u16(bs);
}
gf_list_add(ptr->entryList, p);
}
#ifndef GPAC_DISABLE_ISOM_WRITE
ptr->w_currentEntry = p;
ptr->w_currentEntryIndex = nb_entries-1;
#endif
return GF_OK;
}
GF_Box *stsf_New()
{
ISOM_DECL_BOX_ALLOC(GF_SampleFragmentBox, GF_ISOM_BOX_TYPE_STSF);
tmp->entryList = gf_list_new();
if (! tmp->entryList) {
gf_free(tmp);
return NULL;
}
return (GF_Box *) tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err stsf_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i, j;
u32 nb_entries;
GF_StsfEntry *p;
GF_SampleFragmentBox *ptr = (GF_SampleFragmentBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
nb_entries = gf_list_count(ptr->entryList);
gf_bs_write_u32(bs, nb_entries);
for ( i = 0; i < nb_entries; i++ ) {
p = (GF_StsfEntry*)gf_list_get(ptr->entryList, i);
gf_bs_write_u32(bs, p->SampleNumber);
gf_bs_write_u32(bs, p->fragmentCount);
for (j=0; j<p->fragmentCount; j++) {
gf_bs_write_u16(bs, p->fragmentSizes[j]);
}
}
return GF_OK;
}
GF_Err stsf_Size(GF_Box *s)
{
GF_StsfEntry *p;
u32 nb_entries, i;
GF_SampleFragmentBox *ptr = (GF_SampleFragmentBox *) s;
nb_entries = gf_list_count(ptr->entryList);
ptr->size += 4;
for (i=0; i<nb_entries; i++) {
p = (GF_StsfEntry *)gf_list_get(ptr->entryList, i);
ptr->size += 8 + 2*p->fragmentCount;
}
return GF_OK;
}
#endif
void stsh_del(GF_Box *s)
{
u32 i = 0;
GF_StshEntry *ent;
GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;
if (ptr == NULL) return;
while ( (ent = (GF_StshEntry *)gf_list_enum(ptr->entries, &i)) ) {
gf_free(ent);
}
gf_list_del(ptr->entries);
gf_free(ptr);
}
GF_Err stsh_Read(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 count, i;
GF_StshEntry *ent;
GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;
count = gf_bs_read_u32(bs);
for (i = 0; i < count; i++) {
ent = (GF_StshEntry *) gf_malloc(sizeof(GF_StshEntry));
if (!ent) return GF_OUT_OF_MEM;
ent->shadowedSampleNumber = gf_bs_read_u32(bs);
ent->syncSampleNumber = gf_bs_read_u32(bs);
e = gf_list_add(ptr->entries, ent);
if (e) return e;
}
return GF_OK;
}
GF_Box *stsh_New()
{
ISOM_DECL_BOX_ALLOC(GF_ShadowSyncBox, GF_ISOM_BOX_TYPE_STSH);
tmp->entries = gf_list_new();
if (!tmp->entries) {
gf_free(tmp);
return NULL;
}
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err stsh_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_StshEntry *ent;
GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, gf_list_count(ptr->entries));
i=0;
while ((ent = (GF_StshEntry *)gf_list_enum(ptr->entries, &i))) {
gf_bs_write_u32(bs, ent->shadowedSampleNumber);
gf_bs_write_u32(bs, ent->syncSampleNumber);
}
return GF_OK;
}
GF_Err stsh_Size(GF_Box *s)
{
GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s;
ptr->size += 4 + (8 * gf_list_count(ptr->entries));
return GF_OK;
}
#endif
void stss_del(GF_Box *s)
{
GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;
if (ptr == NULL) return;
if (ptr->sampleNumbers) gf_free(ptr->sampleNumbers);
gf_free(ptr);
}
GF_Err stss_Read(GF_Box *s, GF_BitStream *bs)
{
u32 i;
GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;
ptr->nb_entries = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
if (ptr->nb_entries > ptr->size / 4) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stss\n", ptr->nb_entries));
return GF_ISOM_INVALID_FILE;
}
ptr->alloc_size = ptr->nb_entries;
ptr->sampleNumbers = (u32 *) gf_malloc( ptr->alloc_size * sizeof(u32));
if (ptr->sampleNumbers == NULL) return GF_OUT_OF_MEM;
for (i = 0; i < ptr->nb_entries; i++) {
ptr->sampleNumbers[i] = gf_bs_read_u32(bs);
}
return GF_OK;
}
GF_Box *stss_New()
{
ISOM_DECL_BOX_ALLOC(GF_SyncSampleBox, GF_ISOM_BOX_TYPE_STSS);
return (GF_Box*)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err stss_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->nb_entries);
for (i = 0; i < ptr->nb_entries; i++) {
gf_bs_write_u32(bs, ptr->sampleNumbers[i]);
}
return GF_OK;
}
GF_Err stss_Size(GF_Box *s)
{
GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s;
ptr->size += 4 + (4 * ptr->nb_entries);
return GF_OK;
}
#endif
void stsz_del(GF_Box *s)
{
GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;
if (ptr == NULL) return;
if (ptr->sizes) gf_free(ptr->sizes);
gf_free(ptr);
}
GF_Err stsz_Read(GF_Box *s, GF_BitStream *bs)
{
u32 i, estSize;
GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
if (s->type == GF_ISOM_BOX_TYPE_STSZ) {
ptr->sampleSize = gf_bs_read_u32(bs);
ptr->sampleCount = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 8);
} else {
gf_bs_read_int(bs, 24);
i = gf_bs_read_u8(bs);
ptr->sampleCount = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 8);
switch (i) {
case 4:
case 8:
case 16:
ptr->sampleSize = i;
break;
default:
if (!ptr->sampleCount) {
ptr->sampleSize = 16;
return GF_OK;
}
estSize = (u32) (ptr->size) / ptr->sampleCount;
if (!estSize && ((ptr->sampleCount+1)/2 == (ptr->size)) ) {
ptr->sampleSize = 4;
break;
} else if (estSize == 1 || estSize == 2) {
ptr->sampleSize = 8 * estSize;
} else {
return GF_ISOM_INVALID_FILE;
}
}
}
if (s->type == GF_ISOM_BOX_TYPE_STSZ) {
if (! ptr->sampleSize && ptr->sampleCount) {
if (ptr->sampleCount > ptr->size / 4) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsz\n", ptr->sampleCount));
return GF_ISOM_INVALID_FILE;
}
ptr->sizes = (u32 *) gf_malloc(ptr->sampleCount * sizeof(u32));
ptr->alloc_size = ptr->sampleCount;
if (! ptr->sizes) return GF_OUT_OF_MEM;
for (i = 0; i < ptr->sampleCount; i++) {
ptr->sizes[i] = gf_bs_read_u32(bs);
}
}
} else {
if (ptr->sampleSize==4) {
if (ptr->sampleCount / 2 > ptr->size) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsz\n", ptr->sampleCount));
return GF_ISOM_INVALID_FILE;
}
} else {
if (ptr->sampleCount > ptr->size / (ptr->sampleSize/8)) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsz\n", ptr->sampleCount));
return GF_ISOM_INVALID_FILE;
}
}
ptr->sizes = (u32 *) gf_malloc(ptr->sampleCount * sizeof(u32));
if (! ptr->sizes) return GF_OUT_OF_MEM;
ptr->alloc_size = ptr->sampleCount;
for (i = 0; i < ptr->sampleCount; ) {
switch (ptr->sampleSize) {
case 4:
ptr->sizes[i] = gf_bs_read_int(bs, 4);
if (i+1 < ptr->sampleCount) {
ptr->sizes[i+1] = gf_bs_read_int(bs, 4);
} else {
gf_bs_read_int(bs, 4);
}
i += 2;
break;
default:
ptr->sizes[i] = gf_bs_read_int(bs, ptr->sampleSize);
i += 1;
break;
}
}
}
return GF_OK;
}
GF_Box *stsz_New()
{
ISOM_DECL_BOX_ALLOC(GF_SampleSizeBox, 0);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err stsz_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
if (ptr->type == GF_ISOM_BOX_TYPE_STSZ) {
gf_bs_write_u32(bs, ptr->sampleSize);
} else {
gf_bs_write_u24(bs, 0);
gf_bs_write_u8(bs, ptr->sampleSize);
}
gf_bs_write_u32(bs, ptr->sampleCount);
if (ptr->type == GF_ISOM_BOX_TYPE_STSZ) {
if (! ptr->sampleSize) {
for (i = 0; i < ptr->sampleCount; i++) {
gf_bs_write_u32(bs, ptr->sizes ? ptr->sizes[i] : 0);
}
}
} else {
for (i = 0; i < ptr->sampleCount; ) {
switch (ptr->sampleSize) {
case 4:
gf_bs_write_int(bs, ptr->sizes[i], 4);
if (i+1 < ptr->sampleCount) {
gf_bs_write_int(bs, ptr->sizes[i+1], 4);
} else {
gf_bs_write_int(bs, 0, 4);
}
i += 2;
break;
default:
gf_bs_write_int(bs, ptr->sizes[i], ptr->sampleSize);
i += 1;
break;
}
}
}
return GF_OK;
}
GF_Err stsz_Size(GF_Box *s)
{
u32 i, fieldSize, size;
GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s;
ptr->size += 8;
if (!ptr->sampleCount) return GF_OK;
if (ptr->type == GF_ISOM_BOX_TYPE_STSZ) {
if (ptr->sampleSize) return GF_OK;
ptr->size += (4 * ptr->sampleCount);
return GF_OK;
}
fieldSize = 4;
size = ptr->sizes[0];
for (i=0; i < ptr->sampleCount; i++) {
if (ptr->sizes[i] <= 0xF) continue;
else if (ptr->sizes[i] <= 0xFF) {
fieldSize = 8;
}
else if (ptr->sizes[i] <= 0xFFFF) {
fieldSize = 16;
}
else {
fieldSize = 32;
}
if (size != ptr->sizes[i]) size = 0;
}
if (size) {
ptr->type = GF_ISOM_BOX_TYPE_STSZ;
ptr->sampleSize = size;
gf_free(ptr->sizes);
ptr->sizes = NULL;
}
if (fieldSize == 32) {
ptr->type = GF_ISOM_BOX_TYPE_STSZ;
ptr->size += (4 * ptr->sampleCount);
return GF_OK;
}
ptr->type = GF_ISOM_BOX_TYPE_STZ2;
ptr->sampleSize = fieldSize;
if (fieldSize == 4) {
ptr->size += (ptr->sampleCount + 1) / 2;
} else {
ptr->size += (ptr->sampleCount) * (fieldSize/8);
}
return GF_OK;
}
#endif
void stts_del(GF_Box *s)
{
GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;
if (ptr->entries) gf_free(ptr->entries);
gf_free(ptr);
}
GF_Err stts_Read(GF_Box *s, GF_BitStream *bs)
{
u32 i;
GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;
#ifndef GPAC_DISABLE_ISOM_WRITE
ptr->w_LastDTS = 0;
#endif
ptr->nb_entries = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
if (ptr->nb_entries > ptr->size / 8) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stts\n", ptr->nb_entries));
return GF_ISOM_INVALID_FILE;
}
ptr->alloc_size = ptr->nb_entries;
ptr->entries = gf_malloc(sizeof(GF_SttsEntry)*ptr->alloc_size);
if (!ptr->entries) return GF_OUT_OF_MEM;
for (i=0; i<ptr->nb_entries; i++) {
ptr->entries[i].sampleCount = gf_bs_read_u32(bs);
ptr->entries[i].sampleDelta = gf_bs_read_u32(bs);
#ifndef GPAC_DISABLE_ISOM_WRITE
ptr->w_currentSampleNum += ptr->entries[i].sampleCount;
ptr->w_LastDTS += ptr->entries[i].sampleCount * ptr->entries[i].sampleDelta;
#endif
if (!ptr->entries[i].sampleDelta) {
if ((i+1<ptr->nb_entries) ) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Found stts entry with sample_delta=0 - forbidden ! Fixing to 1\n" ));
ptr->entries[i].sampleDelta = 1;
} else if (ptr->entries[i].sampleCount>1) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] more than one stts entry at the end of the track with sample_delta=0 - forbidden ! Fixing to 1\n" ));
ptr->entries[i].sampleDelta = 1;
}
} else if ((s32) ptr->entries[i].sampleDelta < 0) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] stts entry %d has negative duration %d - forbidden ! Fixing to 1, sync may get lost (consider reimport raw media)\n", i, (s32) ptr->entries[i].sampleDelta ));
ptr->entries[i].sampleDelta = 1;
}
}
if (ptr->size<(ptr->nb_entries*8)) return GF_ISOM_INVALID_FILE;
ISOM_DECREASE_SIZE(ptr, ptr->nb_entries*8);
#ifndef GPAC_DISABLE_ISOM_WRITE
if (ptr->nb_entries) ptr->w_LastDTS -= ptr->entries[ptr->nb_entries-1].sampleDelta;
#endif
return GF_OK;
}
GF_Box *stts_New()
{
ISOM_DECL_BOX_ALLOC(GF_TimeToSampleBox, GF_ISOM_BOX_TYPE_STTS);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err stts_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->nb_entries);
for (i=0; i<ptr->nb_entries; i++) {
gf_bs_write_u32(bs, ptr->entries[i].sampleCount);
gf_bs_write_u32(bs, ptr->entries[i].sampleDelta);
}
return GF_OK;
}
GF_Err stts_Size(GF_Box *s)
{
GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s;
ptr->size += 4 + (8 * ptr->nb_entries);
return GF_OK;
}
#endif
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
void tfhd_del(GF_Box *s)
{
GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s;
if (ptr == NULL) return;
gf_free(ptr);
}
GF_Err tfhd_Read(GF_Box *s, GF_BitStream *bs)
{
GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s;
ptr->trackID = gf_bs_read_u32(bs);
if (ptr->flags & GF_ISOM_TRAF_BASE_OFFSET) {
ptr->base_data_offset = gf_bs_read_u64(bs);
}
if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DESC) {
ptr->sample_desc_index = gf_bs_read_u32(bs);
}
if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DUR) {
ptr->def_sample_duration = gf_bs_read_u32(bs);
}
if (ptr->flags & GF_ISOM_TRAF_SAMPLE_SIZE) {
ptr->def_sample_size = gf_bs_read_u32(bs);
}
if (ptr->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) {
ptr->def_sample_flags = gf_bs_read_u32(bs);
}
return GF_OK;
}
GF_Box *tfhd_New()
{
ISOM_DECL_BOX_ALLOC(GF_TrackFragmentHeaderBox, GF_ISOM_BOX_TYPE_TFHD);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err tfhd_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *) s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->trackID);
if (ptr->flags & GF_ISOM_TRAF_BASE_OFFSET) {
gf_bs_write_u64(bs, ptr->base_data_offset);
}
if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DESC) {
gf_bs_write_u32(bs, ptr->sample_desc_index);
}
if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DUR) {
gf_bs_write_u32(bs, ptr->def_sample_duration);
}
if (ptr->flags & GF_ISOM_TRAF_SAMPLE_SIZE) {
gf_bs_write_u32(bs, ptr->def_sample_size);
}
if (ptr->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) {
gf_bs_write_u32(bs, ptr->def_sample_flags);
}
return GF_OK;
}
GF_Err tfhd_Size(GF_Box *s)
{
GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s;
ptr->size += 4;
if (ptr->flags & GF_ISOM_TRAF_BASE_OFFSET) ptr->size += 8;
if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DESC) ptr->size += 4;
if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DUR) ptr->size += 4;
if (ptr->flags & GF_ISOM_TRAF_SAMPLE_SIZE) ptr->size += 4;
if (ptr->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) ptr->size += 4;
return GF_OK;
}
#endif
#endif
void tims_del(GF_Box *s)
{
GF_TSHintEntryBox *tims = (GF_TSHintEntryBox *)s;
gf_free(tims);
}
GF_Err tims_Read(GF_Box *s, GF_BitStream *bs)
{
GF_TSHintEntryBox *ptr = (GF_TSHintEntryBox *)s;
ptr->timeScale = gf_bs_read_u32(bs);
return GF_OK;
}
GF_Box *tims_New()
{
ISOM_DECL_BOX_ALLOC(GF_TSHintEntryBox, GF_ISOM_BOX_TYPE_TIMS);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err tims_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_TSHintEntryBox *ptr = (GF_TSHintEntryBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->timeScale);
return GF_OK;
}
GF_Err tims_Size(GF_Box *s)
{
s->size += 4;
return GF_OK;
}
#endif
void tkhd_del(GF_Box *s)
{
GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;
if (ptr == NULL) return;
gf_free(ptr);
return;
}
GF_Err tkhd_Read(GF_Box *s, GF_BitStream *bs)
{
GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;
if (ptr->version == 1) {
ptr->creationTime = gf_bs_read_u64(bs);
ptr->modificationTime = gf_bs_read_u64(bs);
ptr->trackID = gf_bs_read_u32(bs);
ptr->reserved1 = gf_bs_read_u32(bs);
ptr->duration = gf_bs_read_u64(bs);
} else {
ptr->creationTime = gf_bs_read_u32(bs);
ptr->modificationTime = gf_bs_read_u32(bs);
ptr->trackID = gf_bs_read_u32(bs);
ptr->reserved1 = gf_bs_read_u32(bs);
ptr->duration = gf_bs_read_u32(bs);
}
ptr->reserved2[0] = gf_bs_read_u32(bs);
ptr->reserved2[1] = gf_bs_read_u32(bs);
ptr->layer = gf_bs_read_u16(bs);
ptr->alternate_group = gf_bs_read_u16(bs);
ptr->volume = gf_bs_read_u16(bs);
ptr->reserved3 = gf_bs_read_u16(bs);
ptr->matrix[0] = gf_bs_read_u32(bs);
ptr->matrix[1] = gf_bs_read_u32(bs);
ptr->matrix[2] = gf_bs_read_u32(bs);
ptr->matrix[3] = gf_bs_read_u32(bs);
ptr->matrix[4] = gf_bs_read_u32(bs);
ptr->matrix[5] = gf_bs_read_u32(bs);
ptr->matrix[6] = gf_bs_read_u32(bs);
ptr->matrix[7] = gf_bs_read_u32(bs);
ptr->matrix[8] = gf_bs_read_u32(bs);
ptr->width = gf_bs_read_u32(bs);
ptr->height = gf_bs_read_u32(bs);
return GF_OK;
}
GF_Box *tkhd_New()
{
ISOM_DECL_BOX_ALLOC(GF_TrackHeaderBox, GF_ISOM_BOX_TYPE_TKHD);
tmp->matrix[0] = 0x00010000;
tmp->matrix[4] = 0x00010000;
tmp->matrix[8] = 0x40000000;
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err tkhd_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
if (ptr->version == 1) {
gf_bs_write_u64(bs, ptr->creationTime);
gf_bs_write_u64(bs, ptr->modificationTime);
gf_bs_write_u32(bs, ptr->trackID);
gf_bs_write_u32(bs, ptr->reserved1);
gf_bs_write_u64(bs, ptr->duration);
} else {
gf_bs_write_u32(bs, (u32) ptr->creationTime);
gf_bs_write_u32(bs, (u32) ptr->modificationTime);
gf_bs_write_u32(bs, ptr->trackID);
gf_bs_write_u32(bs, ptr->reserved1);
gf_bs_write_u32(bs, (u32) ptr->duration);
}
gf_bs_write_u32(bs, ptr->reserved2[0]);
gf_bs_write_u32(bs, ptr->reserved2[1]);
gf_bs_write_u16(bs, ptr->layer);
gf_bs_write_u16(bs, ptr->alternate_group);
gf_bs_write_u16(bs, ptr->volume);
gf_bs_write_u16(bs, ptr->reserved3);
gf_bs_write_u32(bs, ptr->matrix[0]);
gf_bs_write_u32(bs, ptr->matrix[1]);
gf_bs_write_u32(bs, ptr->matrix[2]);
gf_bs_write_u32(bs, ptr->matrix[3]);
gf_bs_write_u32(bs, ptr->matrix[4]);
gf_bs_write_u32(bs, ptr->matrix[5]);
gf_bs_write_u32(bs, ptr->matrix[6]);
gf_bs_write_u32(bs, ptr->matrix[7]);
gf_bs_write_u32(bs, ptr->matrix[8]);
gf_bs_write_u32(bs, ptr->width);
gf_bs_write_u32(bs, ptr->height);
return GF_OK;
}
GF_Err tkhd_Size(GF_Box *s)
{
GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s;
if (ptr->duration==(u64) -1) ptr->version = 0;
else ptr->version = (ptr->duration>0xFFFFFFFF) ? 1 : 0;
ptr->size += (ptr->version == 1) ? 32 : 20;
ptr->size += 60;
return GF_OK;
}
#endif
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
void traf_del(GF_Box *s)
{
GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s;
if (ptr == NULL) return;
if (ptr->tfhd) gf_isom_box_del((GF_Box *) ptr->tfhd);
if (ptr->sdtp) gf_isom_box_del((GF_Box *) ptr->sdtp);
if (ptr->sub_samples) gf_isom_box_array_del(ptr->sub_samples);
if (ptr->tfdt) gf_isom_box_del((GF_Box *) ptr->tfdt);
if (ptr->sample_encryption) gf_isom_box_del((GF_Box *) ptr->sample_encryption);
gf_isom_box_array_del(ptr->TrackRuns);
if (ptr->sampleGroups) gf_isom_box_array_del(ptr->sampleGroups);
if (ptr->sampleGroupsDescription) gf_isom_box_array_del(ptr->sampleGroupsDescription);
if (ptr->sai_sizes) gf_isom_box_array_del(ptr->sai_sizes);
if (ptr->sai_offsets) gf_isom_box_array_del(ptr->sai_offsets);
gf_free(ptr);
}
GF_Err traf_AddBox(GF_Box *s, GF_Box *a)
{
GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s;
switch (a->type) {
case GF_ISOM_BOX_TYPE_TFHD:
if (ptr->tfhd) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->tfhd = (GF_TrackFragmentHeaderBox *) a;
return GF_OK;
case GF_ISOM_BOX_TYPE_TRUN:
return gf_list_add(ptr->TrackRuns, a);
case GF_ISOM_BOX_TYPE_SDTP:
if (ptr->sdtp) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->sdtp = (GF_SampleDependencyTypeBox *)a;
return GF_OK;
case GF_ISOM_BOX_TYPE_TFDT:
if (ptr->tfdt) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->tfdt = (GF_TFBaseMediaDecodeTimeBox*) a;
return GF_OK;
case GF_ISOM_BOX_TYPE_SUBS:
if (!ptr->sub_samples) ptr->sub_samples = gf_list_new();
return gf_list_add(ptr->sub_samples, a);
case GF_ISOM_BOX_TYPE_SBGP:
if (!ptr->sampleGroups) ptr->sampleGroups = gf_list_new();
gf_list_add(ptr->sampleGroups, a);
return GF_OK;
case GF_ISOM_BOX_TYPE_SGPD:
if (!ptr->sampleGroupsDescription) ptr->sampleGroupsDescription = gf_list_new();
gf_list_add(ptr->sampleGroupsDescription, a);
return GF_OK;
case GF_ISOM_BOX_TYPE_SAIZ:
if (!ptr->sai_sizes) ptr->sai_sizes = gf_list_new();
gf_list_add(ptr->sai_sizes, a);
return GF_OK;
case GF_ISOM_BOX_TYPE_SAIO:
if (!ptr->sai_offsets) ptr->sai_offsets = gf_list_new();
gf_list_add(ptr->sai_offsets, a);
return GF_OK;
case GF_ISOM_BOX_TYPE_UUID:
if ( ((GF_UUIDBox *)a)->internal_4cc==GF_ISOM_BOX_UUID_PSEC) {
if (ptr->sample_encryption) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->sample_encryption = (GF_SampleEncryptionBox *)a;
ptr->sample_encryption->traf = ptr;
return GF_OK;
} else {
return gf_isom_box_add_default(s, a);
}
case GF_ISOM_BOX_TYPE_SENC:
if (ptr->sample_encryption) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->sample_encryption = (GF_SampleEncryptionBox *)a;
ptr->sample_encryption->traf = ptr;
return GF_OK;
default:
return gf_isom_box_add_default(s, a);
}
return GF_OK;
}
GF_Err traf_Read(GF_Box *s, GF_BitStream *bs)
{
GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s;
GF_Err e = gf_isom_box_array_read(s, bs, traf_AddBox);
if (e) return e;
if (!ptr->tfhd) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing TrackFragmentHeaderBox \n"));
return GF_ISOM_INVALID_FILE;
}
return GF_OK;
}
GF_Box *traf_New()
{
ISOM_DECL_BOX_ALLOC(GF_TrackFragmentBox, GF_ISOM_BOX_TYPE_TRAF);
tmp->TrackRuns = gf_list_new();
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Box *tfxd_New()
{
ISOM_DECL_BOX_ALLOC(GF_MSSTimeExtBox, GF_ISOM_BOX_TYPE_UUID);
tmp->internal_4cc = GF_ISOM_BOX_UUID_TFXD;
return (GF_Box *)tmp;
}
void tfxd_del(GF_Box *s)
{
gf_free(s);
}
GF_Err tfxd_Read(GF_Box *s, GF_BitStream *bs)
{
GF_MSSTimeExtBox *ptr = (GF_MSSTimeExtBox *)s;
if (ptr->size<4) return GF_ISOM_INVALID_FILE;
ptr->version = gf_bs_read_u8(bs);
ptr->flags = gf_bs_read_u24(bs);
ISOM_DECREASE_SIZE(ptr, 4);
if (ptr->version == 0x01) {
ptr->absolute_time_in_track_timescale = gf_bs_read_u64(bs);
ptr->fragment_duration_in_track_timescale = gf_bs_read_u64(bs);
} else {
ptr->absolute_time_in_track_timescale = gf_bs_read_u32(bs);
ptr->fragment_duration_in_track_timescale = gf_bs_read_u32(bs);
}
return GF_OK;
}
GF_Err tfxd_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e = GF_OK;
GF_MSSTimeExtBox *uuid = (GF_MSSTimeExtBox*)s;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u8(bs, 1);
gf_bs_write_u24(bs, 0);
gf_bs_write_u64(bs, uuid->absolute_time_in_track_timescale);
gf_bs_write_u64(bs, uuid->fragment_duration_in_track_timescale);
return GF_OK;
}
GF_Err tfxd_Size(GF_Box *s)
{
s->size += 20;
return GF_OK;
}
GF_Err traf_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *) s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
if (ptr->tfhd) {
e = gf_isom_box_write((GF_Box *) ptr->tfhd, bs);
if (e) return e;
}
if (ptr->sub_samples) {
e = gf_isom_box_array_write(s, ptr->sub_samples, bs);
if (e) return e;
}
if (ptr->tfdt) {
e = gf_isom_box_write((GF_Box *) ptr->tfdt, bs);
if (e) return e;
}
if (ptr->sdtp) {
e = gf_isom_box_write((GF_Box *) ptr->sdtp, bs);
if (e) return e;
}
if (ptr->sampleGroupsDescription) {
e = gf_isom_box_array_write(s, ptr->sampleGroupsDescription, bs);
if (e) return e;
}
if (ptr->sampleGroups) {
e = gf_isom_box_array_write(s, ptr->sampleGroups, bs);
if (e) return e;
}
if (ptr->sai_sizes) {
e = gf_isom_box_array_write(s, ptr->sai_sizes, bs);
if (e) return e;
}
if (ptr->sai_offsets) {
e = gf_isom_box_array_write(s, ptr->sai_offsets, bs);
if (e) return e;
}
e = gf_isom_box_array_write(s, ptr->TrackRuns, bs);
if (e) return e;
if (ptr->sample_encryption) {
e = gf_isom_box_write((GF_Box *) ptr->sample_encryption, bs);
if (e) return e;
}
if (ptr->tfxd) {
e = gf_isom_box_write((GF_Box *) ptr->tfxd, bs);
if (e) return e;
}
return GF_OK;
}
GF_Err traf_Size(GF_Box *s)
{
GF_Err e;
GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s;
if (ptr->tfhd) {
e = gf_isom_box_size((GF_Box *) ptr->tfhd);
if (e) return e;
ptr->size += ptr->tfhd->size;
}
if (ptr->sub_samples) {
e = gf_isom_box_array_size(s, ptr->sub_samples);
if (e) return e;
}
if (ptr->sdtp) {
e = gf_isom_box_size((GF_Box *) ptr->sdtp);
if (e) return e;
ptr->size += ptr->sdtp->size;
}
if (ptr->tfdt) {
e = gf_isom_box_size((GF_Box *) ptr->tfdt);
if (e) return e;
ptr->size += ptr->tfdt->size;
}
if (ptr->sampleGroups) {
e = gf_isom_box_array_size(s, ptr->sampleGroups);
if (e) return e;
}
if (ptr->sampleGroupsDescription) {
e = gf_isom_box_array_size(s, ptr->sampleGroupsDescription);
if (e) return e;
}
if (ptr->sai_sizes) {
e = gf_isom_box_array_size(s, ptr->sai_sizes);
if (e) return e;
}
if (ptr->sai_offsets) {
e = gf_isom_box_array_size(s, ptr->sai_offsets);
if (e) return e;
}
if (ptr->sample_encryption) {
e = gf_isom_box_size((GF_Box *) ptr->sample_encryption);
if (e) return e;
ptr->size += ptr->sample_encryption->size;
}
if (ptr->tfxd) {
e = gf_isom_box_size((GF_Box *)ptr->tfxd);
if (e) return e;
s->size += ptr->tfxd->size;
}
return gf_isom_box_array_size(s, ptr->TrackRuns);
}
#endif
#endif
void trak_del(GF_Box *s)
{
GF_TrackBox *ptr = (GF_TrackBox *) s;
if (ptr == NULL) return;
if (ptr->Header) gf_isom_box_del((GF_Box *)ptr->Header);
if (ptr->udta) gf_isom_box_del((GF_Box *)ptr->udta);
if (ptr->Media) gf_isom_box_del((GF_Box *)ptr->Media);
if (ptr->References) gf_isom_box_del((GF_Box *)ptr->References);
if (ptr->editBox) gf_isom_box_del((GF_Box *)ptr->editBox);
if (ptr->meta) gf_isom_box_del((GF_Box *)ptr->meta);
if (ptr->name) gf_free(ptr->name);
if (ptr->groups) gf_isom_box_del((GF_Box *)ptr->groups);
gf_free(ptr);
}
static void gf_isom_check_sample_desc(GF_TrackBox *trak)
{
GF_BitStream *bs;
GF_UnknownBox *a;
u32 i;
if (!trak->Media || !trak->Media->information) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no media box !\n" ));
return;
}
if (!trak->Media->information->sampleTable) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no sample table !\n" ));
trak->Media->information->sampleTable = (GF_SampleTableBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STBL);
}
if (!trak->Media->information->sampleTable->SampleDescription) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no sample description box !\n" ));
trak->Media->information->sampleTable->SampleDescription = (GF_SampleDescriptionBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STSD);
return;
}
i=0;
while ((a = (GF_UnknownBox*)gf_list_enum(trak->Media->information->sampleTable->SampleDescription->other_boxes, &i))) {
switch (a->type) {
case GF_ISOM_BOX_TYPE_MP4S:
case GF_ISOM_BOX_TYPE_ENCS:
case GF_ISOM_BOX_TYPE_MP4A:
case GF_ISOM_BOX_TYPE_ENCA:
case GF_ISOM_BOX_TYPE_MP4V:
case GF_ISOM_BOX_TYPE_ENCV:
case GF_ISOM_BOX_TYPE_RESV:
case GF_ISOM_SUBTYPE_3GP_AMR:
case GF_ISOM_SUBTYPE_3GP_AMR_WB:
case GF_ISOM_SUBTYPE_3GP_EVRC:
case GF_ISOM_SUBTYPE_3GP_QCELP:
case GF_ISOM_SUBTYPE_3GP_SMV:
case GF_ISOM_SUBTYPE_3GP_H263:
case GF_ISOM_BOX_TYPE_GHNT:
case GF_ISOM_BOX_TYPE_RTP_STSD:
case GF_ISOM_BOX_TYPE_SRTP_STSD:
case GF_ISOM_BOX_TYPE_FDP_STSD:
case GF_ISOM_BOX_TYPE_RRTP_STSD:
case GF_ISOM_BOX_TYPE_RTCP_STSD:
case GF_ISOM_BOX_TYPE_METX:
case GF_ISOM_BOX_TYPE_METT:
case GF_ISOM_BOX_TYPE_STXT:
case GF_ISOM_BOX_TYPE_AVC1:
case GF_ISOM_BOX_TYPE_AVC2:
case GF_ISOM_BOX_TYPE_AVC3:
case GF_ISOM_BOX_TYPE_AVC4:
case GF_ISOM_BOX_TYPE_SVC1:
case GF_ISOM_BOX_TYPE_MVC1:
case GF_ISOM_BOX_TYPE_HVC1:
case GF_ISOM_BOX_TYPE_HEV1:
case GF_ISOM_BOX_TYPE_HVC2:
case GF_ISOM_BOX_TYPE_HEV2:
case GF_ISOM_BOX_TYPE_HVT1:
case GF_ISOM_BOX_TYPE_LHV1:
case GF_ISOM_BOX_TYPE_LHE1:
case GF_ISOM_BOX_TYPE_TX3G:
case GF_ISOM_BOX_TYPE_TEXT:
case GF_ISOM_BOX_TYPE_ENCT:
case GF_ISOM_BOX_TYPE_DIMS:
case GF_ISOM_BOX_TYPE_AC3:
case GF_ISOM_BOX_TYPE_EC3:
case GF_ISOM_BOX_TYPE_LSR1:
case GF_ISOM_BOX_TYPE_WVTT:
case GF_ISOM_BOX_TYPE_STPP:
case GF_ISOM_BOX_TYPE_SBTT:
case GF_ISOM_BOX_TYPE_MP3:
continue;
case GF_ISOM_BOX_TYPE_UNKNOWN:
break;
default:
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Unexpected box %s in stsd!\n", gf_4cc_to_str(a->type)));
continue;
}
assert(a->type==GF_ISOM_BOX_TYPE_UNKNOWN);
if (!a->data || (a->dataSize<8) ) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Sample description %s does not have at least 8 bytes!\n", gf_4cc_to_str(a->original_4cc) ));
continue;
}
else if (a->dataSize > a->size) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Sample description %s has wrong data size %d!\n", gf_4cc_to_str(a->original_4cc), a->dataSize));
continue;
}
switch (trak->Media->handler->handlerType) {
case GF_ISOM_MEDIA_VISUAL:
{
GF_GenericVisualSampleEntryBox *genv;
gf_list_rem(trak->Media->information->sampleTable->SampleDescription->other_boxes, i-1);
genv = (GF_GenericVisualSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRV);
bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);
genv->size = a->size-8;
gf_isom_video_sample_entry_read((GF_VisualSampleEntryBox *) genv, bs);
if (gf_bs_available(bs)) {
u64 pos = gf_bs_get_position(bs);
GF_Err e = gf_isom_box_array_read((GF_Box *) genv, bs, gf_isom_box_add_default);
if (e) {
gf_bs_seek(bs, pos);
genv->data_size = (u32) gf_bs_available(bs);
if (genv->data_size) {
genv->data = a->data;
a->data = NULL;
memmove(genv->data, genv->data + pos, genv->data_size);
}
} else {
genv->data_size = 0;
}
}
gf_bs_del(bs);
if (!genv->data_size && genv->data) {
gf_free(genv->data);
genv->data = NULL;
}
genv->size = 0;
genv->EntryType = a->original_4cc;
gf_isom_box_del((GF_Box *)a);
gf_list_insert(trak->Media->information->sampleTable->SampleDescription->other_boxes, genv, i-1);
}
break;
case GF_ISOM_MEDIA_AUDIO:
{
GF_GenericAudioSampleEntryBox *gena;
gf_list_rem(trak->Media->information->sampleTable->SampleDescription->other_boxes, i-1);
gena = (GF_GenericAudioSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRA);
gena->size = a->size-8;
bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);
gf_isom_audio_sample_entry_read((GF_AudioSampleEntryBox *) gena, bs);
if (gf_bs_available(bs)) {
u64 pos = gf_bs_get_position(bs);
GF_Err e = gf_isom_box_array_read((GF_Box *) gena, bs, gf_isom_box_add_default);
if (e) {
gf_bs_seek(bs, pos);
gena->data_size = (u32) gf_bs_available(bs);
if (gena->data_size) {
gena->data = a->data;
a->data = NULL;
memmove(gena->data, gena->data + pos, gena->data_size);
}
} else {
gena->data_size = 0;
}
}
gf_bs_del(bs);
if (!gena->data_size && gena->data) {
gf_free(gena->data);
gena->data = NULL;
}
gena->size = 0;
gena->EntryType = a->original_4cc;
gf_isom_box_del((GF_Box *)a);
gf_list_insert(trak->Media->information->sampleTable->SampleDescription->other_boxes, gena, i-1);
}
break;
default:
{
GF_Err e;
GF_GenericSampleEntryBox *genm;
gf_list_rem(trak->Media->information->sampleTable->SampleDescription->other_boxes, i-1);
genm = (GF_GenericSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRM);
genm->size = a->size-8;
bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ);
e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)genm, bs);
if (e) return;
genm->size -= 8;
if (gf_bs_available(bs)) {
u64 pos = gf_bs_get_position(bs);
GF_Err e = gf_isom_box_array_read((GF_Box *) genm, bs, gf_isom_box_add_default);
if (e) {
gf_bs_seek(bs, pos);
genm->data_size = (u32) gf_bs_available(bs);
if (genm->data_size) {
genm->data = a->data;
a->data = NULL;
memmove(genm->data, genm->data + pos, genm->data_size);
}
} else {
genm->data_size = 0;
}
}
gf_bs_del(bs);
if (!genm->data_size && genm->data) {
gf_free(genm->data);
genm->data = NULL;
}
genm->size = 0;
genm->EntryType = a->original_4cc;
gf_isom_box_del((GF_Box *)a);
gf_list_insert(trak->Media->information->sampleTable->SampleDescription->other_boxes, genm, i-1);
}
break;
}
}
}
GF_Err trak_AddBox(GF_Box *s, GF_Box *a)
{
GF_TrackBox *ptr = (GF_TrackBox *)s;
if (!a) return GF_OK;
switch(a->type) {
case GF_ISOM_BOX_TYPE_TKHD:
if (ptr->Header) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->Header = (GF_TrackHeaderBox *)a;
return GF_OK;
case GF_ISOM_BOX_TYPE_EDTS:
if (ptr->editBox) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->editBox = (GF_EditBox *)a;
return GF_OK;
case GF_ISOM_BOX_TYPE_UDTA:
if (ptr->udta) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->udta = (GF_UserDataBox *)a;
return GF_OK;
case GF_ISOM_BOX_TYPE_META:
if (ptr->meta) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->meta = (GF_MetaBox *)a;
return GF_OK;
case GF_ISOM_BOX_TYPE_TREF:
if (ptr->References) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->References = (GF_TrackReferenceBox *)a;
return GF_OK;
case GF_ISOM_BOX_TYPE_MDIA:
if (ptr->Media) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->Media = (GF_MediaBox *)a;
((GF_MediaBox *)a)->mediaTrack = ptr;
return GF_OK;
case GF_ISOM_BOX_TYPE_TRGR:
if (ptr->groups) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->groups = (GF_TrackGroupBox *)a;
return GF_OK;
case GF_ISOM_BOX_TYPE_SENC:
ptr->sample_encryption = (GF_SampleEncryptionBox*)a;
return gf_isom_box_add_default((GF_Box *)ptr, a);
case GF_ISOM_BOX_TYPE_UUID:
if (((GF_UnknownUUIDBox *)a)->internal_4cc == GF_ISOM_BOX_UUID_PSEC) {
ptr->sample_encryption = (GF_SampleEncryptionBox*) a;
return gf_isom_box_add_default((GF_Box *)ptr, a);
}
default:
return gf_isom_box_add_default(s, a);
}
return GF_OK;
}
GF_Err trak_Read(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_TrackBox *ptr = (GF_TrackBox *)s;
e = gf_isom_box_array_read(s, bs, trak_AddBox);
if (e) return e;
gf_isom_check_sample_desc(ptr);
if (!ptr->Header) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing TrackHeaderBox\n"));
return GF_ISOM_INVALID_FILE;
}
if (!ptr->Media) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing MediaBox\n"));
return GF_ISOM_INVALID_FILE;
}
return e;
}
GF_Box *trak_New()
{
ISOM_DECL_BOX_ALLOC(GF_TrackBox, GF_ISOM_BOX_TYPE_TRAK);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err trak_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_TrackBox *ptr = (GF_TrackBox *)s;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
if (ptr->Header) {
e = gf_isom_box_write((GF_Box *) ptr->Header, bs);
if (e) return e;
}
if (ptr->References) {
e = gf_isom_box_write((GF_Box *) ptr->References, bs);
if (e) return e;
}
if (ptr->editBox) {
e = gf_isom_box_write((GF_Box *) ptr->editBox, bs);
if (e) return e;
}
if (ptr->Media) {
e = gf_isom_box_write((GF_Box *) ptr->Media, bs);
if (e) return e;
}
if (ptr->meta) {
e = gf_isom_box_write((GF_Box *) ptr->meta, bs);
if (e) return e;
}
if (ptr->groups) {
e = gf_isom_box_write((GF_Box *) ptr->groups, bs);
if (e) return e;
}
if (ptr->udta) {
e = gf_isom_box_write((GF_Box *) ptr->udta, bs);
if (e) return e;
}
return GF_OK;
}
GF_Err trak_Size(GF_Box *s)
{
GF_Err e;
GF_TrackBox *ptr = (GF_TrackBox *)s;
if (ptr->Header) {
e = gf_isom_box_size((GF_Box *) ptr->Header);
if (e) return e;
ptr->size += ptr->Header->size;
}
if (ptr->udta) {
e = gf_isom_box_size((GF_Box *) ptr->udta);
if (e) return e;
ptr->size += ptr->udta->size;
}
if (ptr->References) {
e = gf_isom_box_size((GF_Box *) ptr->References);
if (e) return e;
ptr->size += ptr->References->size;
}
if (ptr->editBox) {
e = gf_isom_box_size((GF_Box *) ptr->editBox);
if (e) return e;
ptr->size += ptr->editBox->size;
}
if (ptr->Media) {
e = gf_isom_box_size((GF_Box *) ptr->Media);
if (e) return e;
ptr->size += ptr->Media->size;
}
if (ptr->meta) {
e = gf_isom_box_size((GF_Box *) ptr->meta);
if (e) return e;
ptr->size += ptr->meta->size;
}
if (ptr->groups) {
e = gf_isom_box_size((GF_Box *) ptr->groups);
if (e) return e;
ptr->size += ptr->groups->size;
}
return GF_OK;
}
#endif
void stri_del(GF_Box *s)
{
GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s;
if (ptr == NULL) return;
if (ptr->attribute_list) gf_free(ptr->attribute_list);
gf_free(ptr);
}
GF_Err stri_Read(GF_Box *s, GF_BitStream *bs)
{
size_t i;
GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s;
ptr->switch_group = gf_bs_read_u16(bs);
ptr->alternate_group = gf_bs_read_u16(bs);
ptr->sub_track_id = gf_bs_read_u32(bs);
ptr->size -= 8;
ptr->attribute_count = ptr->size / 4;
GF_SAFE_ALLOC_N(ptr->attribute_list, (size_t)ptr->attribute_count, u32);
if (!ptr->attribute_list) return GF_OUT_OF_MEM;
for (i = 0; i < ptr->attribute_count; i++) {
ptr->attribute_list[i] = gf_bs_read_u32(bs);
}
return GF_OK;
}
GF_Box *stri_New()
{
ISOM_DECL_BOX_ALLOC(GF_SubTrackInformationBox, GF_ISOM_BOX_TYPE_STRI);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err stri_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u16(bs, ptr->switch_group);
gf_bs_write_u16(bs, ptr->alternate_group);
gf_bs_write_u32(bs, ptr->sub_track_id);
for (i = 0; i < ptr->attribute_count; i++) {
gf_bs_write_u32(bs, ptr->attribute_list[i]);
}
return GF_OK;
}
GF_Err stri_Size(GF_Box *s)
{
GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s;
ptr->size += 8 + 4 * ptr->attribute_count;
return GF_OK;
}
#endif
void stsg_del(GF_Box *s)
{
GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s;
if (ptr == NULL) return;
if (ptr->group_description_index) gf_free(ptr->group_description_index);
gf_free(ptr);
}
GF_Err stsg_Read(GF_Box *s, GF_BitStream *bs)
{
u32 i;
GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s;
ISOM_DECREASE_SIZE(s, 6);
ptr->grouping_type = gf_bs_read_u32(bs);
ptr->nb_groups = gf_bs_read_u16(bs);
ISOM_DECREASE_SIZE(s, ptr->nb_groups*4);
GF_SAFE_ALLOC_N(ptr->group_description_index, ptr->nb_groups, u32);
if (!ptr->group_description_index) return GF_OUT_OF_MEM;
for (i = 0; i < ptr->nb_groups; i++) {
ptr->group_description_index[i] = gf_bs_read_u32(bs);
}
return GF_OK;
}
GF_Box *stsg_New()
{
ISOM_DECL_BOX_ALLOC(GF_SubTrackSampleGroupBox, GF_ISOM_BOX_TYPE_STSG);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err stsg_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->grouping_type);
gf_bs_write_u16(bs, ptr->nb_groups);
for (i = 0; i < ptr->nb_groups; i++) {
gf_bs_write_u32(bs, ptr->group_description_index[i]);
}
return GF_OK;
}
GF_Err stsg_Size(GF_Box *s)
{
GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s;
ptr->size += 6 + 4 * ptr->nb_groups;
return GF_OK;
}
#endif
void strk_del(GF_Box *s)
{
GF_SubTrackBox *ptr = (GF_SubTrackBox *)s;
if (ptr == NULL) return;
if (ptr->info) gf_isom_box_del((GF_Box *)ptr->info);
gf_free(ptr);
}
GF_Err strk_AddBox(GF_Box *s, GF_Box *a)
{
GF_SubTrackBox *ptr = (GF_SubTrackBox *)s;
if (!a) return GF_OK;
switch (a->type) {
case GF_ISOM_BOX_TYPE_STRI:
if (ptr->info) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->info = (GF_SubTrackInformationBox *)a;
return GF_OK;
case GF_ISOM_BOX_TYPE_STRD:
if (ptr->strd) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->strd = a;
return GF_OK;
default:
return gf_isom_box_add_default(s, a);
}
return GF_OK;
}
GF_Err strk_Read(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_SubTrackBox *ptr = (GF_SubTrackBox *)s;
e = gf_isom_box_array_read(s, bs, strk_AddBox);
if (e) return e;
if (!ptr->info) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing SubTrackInformationBox\n"));
return GF_ISOM_INVALID_FILE;
}
return e;
}
GF_Box *strk_New()
{
ISOM_DECL_BOX_ALLOC(GF_SubTrackBox, GF_ISOM_BOX_TYPE_STRK);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err strk_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_SubTrackBox *ptr = (GF_SubTrackBox *)s;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
if (ptr->info) {
e = gf_isom_box_write((GF_Box *)ptr->info, bs);
if (e) return e;
}
return GF_OK;
}
GF_Err strk_Size(GF_Box *s)
{
GF_Err e;
GF_SubTrackBox *ptr = (GF_SubTrackBox *)s;
if (ptr->info) {
e = gf_isom_box_size((GF_Box *)ptr->info);
if (e) return e;
ptr->size += ptr->info->size;
}
return GF_OK;
}
#endif
GF_Err tref_AddBox(GF_Box *ptr, GF_Box *a)
{
return gf_isom_box_add_default(ptr, a);
}
void tref_del(GF_Box *s)
{
GF_TrackReferenceBox *ptr = (GF_TrackReferenceBox *)s;
if (ptr == NULL) return;
gf_free(ptr);
}
GF_Err tref_Read(GF_Box *s, GF_BitStream *bs)
{
return gf_isom_box_array_read_ex(s, bs, gf_isom_box_add_default, s->type);
}
GF_Box *tref_New()
{
ISOM_DECL_BOX_ALLOC(GF_TrackReferenceBox, GF_ISOM_BOX_TYPE_TREF);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err tref_Write(GF_Box *s, GF_BitStream *bs)
{
return gf_isom_box_write_header(s, bs);
}
GF_Err tref_Size(GF_Box *s)
{
return GF_OK;
}
#endif
void reftype_del(GF_Box *s)
{
GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
if (!ptr) return;
if (ptr->trackIDs) gf_free(ptr->trackIDs);
gf_free(ptr);
}
GF_Err reftype_Read(GF_Box *s, GF_BitStream *bs)
{
u32 bytesToRead;
u32 i;
GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
bytesToRead = (u32) (ptr->size);
if (!bytesToRead) return GF_OK;
ptr->trackIDCount = (u32) (bytesToRead) / sizeof(u32);
ptr->trackIDs = (u32 *) gf_malloc(ptr->trackIDCount * sizeof(u32));
if (!ptr->trackIDs) return GF_OUT_OF_MEM;
for (i = 0; i < ptr->trackIDCount; i++) {
ptr->trackIDs[i] = gf_bs_read_u32(bs);
}
return GF_OK;
}
GF_Box *reftype_New()
{
ISOM_DECL_BOX_ALLOC(GF_TrackReferenceTypeBox, GF_ISOM_BOX_TYPE_REFT);
return (GF_Box *)tmp;
}
GF_Err reftype_AddRefTrack(GF_TrackReferenceTypeBox *ref, u32 trackID, u16 *outRefIndex)
{
u32 i;
if (!ref || !trackID) return GF_BAD_PARAM;
if (outRefIndex) *outRefIndex = 0;
for (i = 0; i < ref->trackIDCount; i++) {
if (ref->trackIDs[i] == trackID) {
if (outRefIndex) *outRefIndex = i+1;
return GF_OK;
}
}
ref->trackIDs = (u32 *) gf_realloc(ref->trackIDs, (ref->trackIDCount + 1) * sizeof(u32) );
if (!ref->trackIDs) return GF_OUT_OF_MEM;
ref->trackIDs[ref->trackIDCount] = trackID;
ref->trackIDCount++;
if (outRefIndex) *outRefIndex = ref->trackIDCount;
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err reftype_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
ptr->type = ptr->reference_type;
if (!ptr->trackIDCount) return GF_OK;
e = gf_isom_box_write_header(s, bs);
ptr->type = GF_ISOM_BOX_TYPE_REFT;
if (e) return e;
for (i = 0; i < ptr->trackIDCount; i++) {
gf_bs_write_u32(bs, ptr->trackIDs[i]);
}
return GF_OK;
}
GF_Err reftype_Size(GF_Box *s)
{
GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s;
if (!ptr->trackIDCount)
ptr->size=0;
else
ptr->size += (ptr->trackIDCount * sizeof(u32));
return GF_OK;
}
#endif
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
void trex_del(GF_Box *s)
{
GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s;
if (ptr == NULL) return;
gf_free(ptr);
}
GF_Err trex_Read(GF_Box *s, GF_BitStream *bs)
{
GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s;
ptr->trackID = gf_bs_read_u32(bs);
ptr->def_sample_desc_index = gf_bs_read_u32(bs);
ptr->def_sample_duration = gf_bs_read_u32(bs);
ptr->def_sample_size = gf_bs_read_u32(bs);
ptr->def_sample_flags = gf_bs_read_u32(bs);
if (!ptr->def_sample_desc_index) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] TREX with default sample description set to 0, likely broken ! Fixing to 1\n" ));
ptr->def_sample_desc_index = 1;
}
return GF_OK;
}
GF_Box *trex_New()
{
ISOM_DECL_BOX_ALLOC(GF_TrackExtendsBox, GF_ISOM_BOX_TYPE_TREX);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err trex_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *) s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->trackID);
gf_bs_write_u32(bs, ptr->def_sample_desc_index);
gf_bs_write_u32(bs, ptr->def_sample_duration);
gf_bs_write_u32(bs, ptr->def_sample_size);
gf_bs_write_u32(bs, ptr->def_sample_flags);
return GF_OK;
}
GF_Err trex_Size(GF_Box *s)
{
GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s;
ptr->size += 20;
return GF_OK;
}
#endif
void trep_del(GF_Box *s)
{
GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *)s;
if (ptr == NULL) return;
gf_free(ptr);
}
GF_Err trep_Read(GF_Box *s, GF_BitStream *bs)
{
GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *)s;
ptr->trackID = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
return gf_isom_box_array_read(s, bs, gf_isom_box_add_default);
}
GF_Box *trep_New()
{
ISOM_DECL_BOX_ALLOC(GF_TrackExtensionPropertiesBox, GF_ISOM_BOX_TYPE_TREP);
tmp->other_boxes = gf_list_new();
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err trep_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *) s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->trackID);
return GF_OK;
}
GF_Err trep_Size(GF_Box *s)
{
GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *)s;
ptr->size += 4;
return GF_OK;
}
#endif
#endif
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
void trun_del(GF_Box *s)
{
GF_TrunEntry *p;
GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;
if (ptr == NULL) return;
while (gf_list_count(ptr->entries)) {
p = (GF_TrunEntry*)gf_list_get(ptr->entries, 0);
gf_list_rem(ptr->entries, 0);
gf_free(p);
}
gf_list_del(ptr->entries);
if (ptr->cache) gf_bs_del(ptr->cache);
gf_free(ptr);
}
GF_Err trun_Read(GF_Box *s, GF_BitStream *bs)
{
u32 i;
GF_TrunEntry *p;
GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;
if ((ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) && (ptr->flags & GF_ISOM_TRUN_FLAGS))
return GF_ISOM_INVALID_FILE;
ptr->sample_count = gf_bs_read_u32(bs);
if (ptr->flags & GF_ISOM_TRUN_DATA_OFFSET) {
ptr->data_offset = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
}
if (ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) {
ptr->first_sample_flags = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
}
for (i=0; i<ptr->sample_count; i++) {
u32 trun_size = 0;
p = (GF_TrunEntry *) gf_malloc(sizeof(GF_TrunEntry));
if (!p) return GF_OUT_OF_MEM;
memset(p, 0, sizeof(GF_TrunEntry));
if (ptr->flags & GF_ISOM_TRUN_DURATION) {
p->Duration = gf_bs_read_u32(bs);
trun_size += 4;
}
if (ptr->flags & GF_ISOM_TRUN_SIZE) {
p->size = gf_bs_read_u32(bs);
trun_size += 4;
}
if (ptr->flags & GF_ISOM_TRUN_FLAGS) {
p->flags = gf_bs_read_u32(bs);
trun_size += 4;
}
if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) {
if (ptr->version==0) {
p->CTS_Offset = (u32) gf_bs_read_u32(bs);
} else {
p->CTS_Offset = (s32) gf_bs_read_u32(bs);
}
}
gf_list_add(ptr->entries, p);
ISOM_DECREASE_SIZE(ptr, trun_size);
}
return GF_OK;
}
GF_Box *trun_New()
{
ISOM_DECL_BOX_ALLOC(GF_TrackFragmentRunBox, GF_ISOM_BOX_TYPE_TRUN);
tmp->entries = gf_list_new();
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err trun_Write(GF_Box *s, GF_BitStream *bs)
{
GF_TrunEntry *p;
GF_Err e;
u32 i, count;
GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *) s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->sample_count);
if (ptr->flags & GF_ISOM_TRUN_DATA_OFFSET) {
gf_bs_write_u32(bs, ptr->data_offset);
}
if (ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) {
gf_bs_write_u32(bs, ptr->first_sample_flags);
}
count = gf_list_count(ptr->entries);
for (i=0; i<count; i++) {
p = (GF_TrunEntry*)gf_list_get(ptr->entries, i);
if (ptr->flags & GF_ISOM_TRUN_DURATION) {
gf_bs_write_u32(bs, p->Duration);
}
if (ptr->flags & GF_ISOM_TRUN_SIZE) {
gf_bs_write_u32(bs, p->size);
}
if (ptr->flags & GF_ISOM_TRUN_FLAGS) {
gf_bs_write_u32(bs, p->flags);
}
if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) {
if (ptr->version==0) {
gf_bs_write_u32(bs, p->CTS_Offset);
} else {
gf_bs_write_u32(bs, (u32) p->CTS_Offset);
}
}
}
return GF_OK;
}
GF_Err trun_Size(GF_Box *s)
{
u32 i, count;
GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s;
ptr->size += 4;
if (ptr->flags & GF_ISOM_TRUN_DATA_OFFSET) ptr->size += 4;
if (ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) ptr->size += 4;
count = gf_list_count(ptr->entries);
for (i=0; i<count; i++) {
if (ptr->flags & GF_ISOM_TRUN_DURATION) ptr->size += 4;
if (ptr->flags & GF_ISOM_TRUN_SIZE) ptr->size += 4;
if (ptr->flags & GF_ISOM_TRUN_FLAGS) ptr->size += 4;
if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) ptr->size += 4;
}
return GF_OK;
}
#endif
#endif
void tsro_del(GF_Box *s)
{
GF_TimeOffHintEntryBox *tsro = (GF_TimeOffHintEntryBox *)s;
gf_free(tsro);
}
GF_Err tsro_Read(GF_Box *s, GF_BitStream *bs)
{
GF_TimeOffHintEntryBox *ptr = (GF_TimeOffHintEntryBox *)s;
ptr->TimeOffset = gf_bs_read_u32(bs);
return GF_OK;
}
GF_Box *tsro_New()
{
ISOM_DECL_BOX_ALLOC(GF_TimeOffHintEntryBox, GF_ISOM_BOX_TYPE_TSRO);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err tsro_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_TimeOffHintEntryBox *ptr = (GF_TimeOffHintEntryBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->TimeOffset);
return GF_OK;
}
GF_Err tsro_Size(GF_Box *s)
{
s->size += 4;
return GF_OK;
}
#endif
void udta_del(GF_Box *s)
{
u32 i;
GF_UserDataMap *map;
GF_UserDataBox *ptr = (GF_UserDataBox *)s;
if (ptr == NULL) return;
i=0;
while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
gf_isom_box_array_del(map->other_boxes);
gf_free(map);
}
gf_list_del(ptr->recordList);
gf_free(ptr);
}
GF_UserDataMap *udta_getEntry(GF_UserDataBox *ptr, u32 box_type, bin128 *uuid)
{
u32 i;
GF_UserDataMap *map;
if (ptr == NULL) return NULL;
i=0;
while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
if (map->boxType == box_type) {
if ((box_type != GF_ISOM_BOX_TYPE_UUID) || !uuid) return map;
if (!memcmp(map->uuid, *uuid, 16)) return map;
}
}
return NULL;
}
GF_Err udta_AddBox(GF_Box *s, GF_Box *a)
{
GF_Err e;
u32 box_type;
GF_UserDataMap *map;
GF_UserDataBox *ptr = (GF_UserDataBox *)s;
if (!ptr) return GF_BAD_PARAM;
if (!a) return GF_OK;
box_type = a->type;
if (box_type == GF_ISOM_BOX_TYPE_UNKNOWN) {
GF_UnknownBox* unkn = (GF_UnknownBox *)a;
if (unkn)
box_type = unkn->original_4cc;
}
map = udta_getEntry(ptr, box_type, (a->type==GF_ISOM_BOX_TYPE_UUID) ? & ((GF_UUIDBox *)a)->uuid : NULL);
if (map == NULL) {
map = (GF_UserDataMap *) gf_malloc(sizeof(GF_UserDataMap));
if (map == NULL) return GF_OUT_OF_MEM;
memset(map, 0, sizeof(GF_UserDataMap));
map->boxType = box_type;
if (a->type == GF_ISOM_BOX_TYPE_UUID)
memcpy(map->uuid, ((GF_UUIDBox *)a)->uuid, 16);
map->other_boxes = gf_list_new();
if (!map->other_boxes) {
gf_free(map);
return GF_OUT_OF_MEM;
}
e = gf_list_add(ptr->recordList, map);
if (e) return e;
}
return gf_list_add(map->other_boxes, a);
}
GF_Err udta_Read(GF_Box *s, GF_BitStream *bs)
{
return gf_isom_box_array_read(s, bs, udta_AddBox);
}
GF_Box *udta_New()
{
ISOM_DECL_BOX_ALLOC(GF_UserDataBox, GF_ISOM_BOX_TYPE_UDTA);
tmp->recordList = gf_list_new();
if (!tmp->recordList) {
gf_free(tmp);
return NULL;
}
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err udta_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_UserDataMap *map;
GF_UserDataBox *ptr = (GF_UserDataBox *)s;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
i=0;
while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
e = gf_isom_box_array_write(s, map->other_boxes, bs);
if (e) return e;
}
return GF_OK;
}
GF_Err udta_Size(GF_Box *s)
{
GF_Err e;
u32 i;
GF_UserDataMap *map;
GF_UserDataBox *ptr = (GF_UserDataBox *)s;
i=0;
while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) {
e = gf_isom_box_array_size(s, map->other_boxes);
if (e) return e;
}
return GF_OK;
}
#endif
void vmhd_del(GF_Box *s)
{
GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
if (ptr == NULL) return;
gf_free(ptr);
}
GF_Err vmhd_Read(GF_Box *s, GF_BitStream *bs)
{
GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
ptr->reserved = gf_bs_read_u64(bs);
return GF_OK;
}
GF_Box *vmhd_New()
{
ISOM_DECL_BOX_ALLOC(GF_VideoMediaHeaderBox, GF_ISOM_BOX_TYPE_VMHD);
tmp->flags = 1;
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err vmhd_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u64(bs, ptr->reserved);
return GF_OK;
}
GF_Err vmhd_Size(GF_Box *s)
{
GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s;
ptr->size += 8;
return GF_OK;
}
#endif
void void_del(GF_Box *s)
{
gf_free(s);
}
GF_Err void_Read(GF_Box *s, GF_BitStream *bs)
{
if (s->size) return GF_ISOM_INVALID_FILE;
return GF_OK;
}
GF_Box *void_New()
{
ISOM_DECL_BOX_ALLOC(GF_Box, GF_ISOM_BOX_TYPE_VOID);
return tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err void_Write(GF_Box *s, GF_BitStream *bs)
{
gf_bs_write_u32(bs, 0);
return GF_OK;
}
GF_Err void_Size(GF_Box *s)
{
s->size = 4;
return GF_OK;
}
#endif
GF_Box *pdin_New()
{
ISOM_DECL_BOX_ALLOC(GF_ProgressiveDownloadBox, GF_ISOM_BOX_TYPE_PDIN);
tmp->flags = 1;
return (GF_Box *)tmp;
}
void pdin_del(GF_Box *s)
{
GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox*)s;
if (ptr == NULL) return;
if (ptr->rates) gf_free(ptr->rates);
if (ptr->times) gf_free(ptr->times);
gf_free(ptr);
}
GF_Err pdin_Read(GF_Box *s, GF_BitStream *bs)
{
u32 i;
GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox*)s;
ptr->count = (u32) (ptr->size) / 8;
ptr->rates = (u32*)gf_malloc(sizeof(u32)*ptr->count);
ptr->times = (u32*)gf_malloc(sizeof(u32)*ptr->count);
for (i=0; i<ptr->count; i++) {
ptr->rates[i] = gf_bs_read_u32(bs);
ptr->times[i] = gf_bs_read_u32(bs);
}
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err pdin_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
for (i=0; i<ptr->count; i++) {
gf_bs_write_u32(bs, ptr->rates[i]);
gf_bs_write_u32(bs, ptr->times[i]);
}
return GF_OK;
}
GF_Err pdin_Size(GF_Box *s)
{
GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox *)s;
ptr->size += 8*ptr->count;
return GF_OK;
}
#endif
GF_Box *sdtp_New()
{
ISOM_DECL_BOX_ALLOC(GF_SampleDependencyTypeBox, GF_ISOM_BOX_TYPE_SDTP);
tmp->flags = 1;
return (GF_Box *)tmp;
}
void sdtp_del(GF_Box *s)
{
GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox*)s;
if (ptr == NULL) return;
if (ptr->sample_info) gf_free(ptr->sample_info);
gf_free(ptr);
}
GF_Err sdtp_Read(GF_Box *s, GF_BitStream *bs)
{
GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox*)s;
if (!ptr->sampleCount) ptr->sampleCount = (u32) ptr->size;
else if (ptr->sampleCount > (u32) ptr->size) return GF_ISOM_INVALID_FILE;
ptr->sample_info = (u8 *) gf_malloc(sizeof(u8)*ptr->sampleCount);
gf_bs_read_data(bs, (char*)ptr->sample_info, ptr->sampleCount);
ISOM_DECREASE_SIZE(ptr, ptr->sampleCount);
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err sdtp_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox *)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_data(bs, (char*)ptr->sample_info, ptr->sampleCount);
return GF_OK;
}
GF_Err sdtp_Size(GF_Box *s)
{
GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox *)s;
ptr->size += ptr->sampleCount;
return GF_OK;
}
#endif
GF_Box *pasp_New()
{
ISOM_DECL_BOX_ALLOC(GF_PixelAspectRatioBox, GF_ISOM_BOX_TYPE_PASP);
return (GF_Box *)tmp;
}
void pasp_del(GF_Box *s)
{
GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox*)s;
if (ptr == NULL) return;
gf_free(ptr);
}
GF_Err pasp_Read(GF_Box *s, GF_BitStream *bs)
{
GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox*)s;
ptr->hSpacing = gf_bs_read_u32(bs);
ptr->vSpacing = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 8);
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err pasp_Write(GF_Box *s, GF_BitStream *bs)
{
GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox *)s;
GF_Err e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->hSpacing);
gf_bs_write_u32(bs, ptr->vSpacing);
return GF_OK;
}
GF_Err pasp_Size(GF_Box *s)
{
s->size += 8;
return GF_OK;
}
#endif
GF_Box *clap_New()
{
ISOM_DECL_BOX_ALLOC(GF_CleanAppertureBox, GF_ISOM_BOX_TYPE_CLAP);
return (GF_Box *)tmp;
}
void clap_del(GF_Box *s)
{
GF_CleanAppertureBox *ptr = (GF_CleanAppertureBox*)s;
if (ptr == NULL) return;
gf_free(ptr);
}
GF_Err clap_Read(GF_Box *s, GF_BitStream *bs)
{
GF_CleanAppertureBox *ptr = (GF_CleanAppertureBox*)s;
ISOM_DECREASE_SIZE(ptr, 32);
ptr->cleanApertureWidthN = gf_bs_read_u32(bs);
ptr->cleanApertureWidthD = gf_bs_read_u32(bs);
ptr->cleanApertureHeightN = gf_bs_read_u32(bs);
ptr->cleanApertureHeightD = gf_bs_read_u32(bs);
ptr->horizOffN = gf_bs_read_u32(bs);
ptr->horizOffD = gf_bs_read_u32(bs);
ptr->vertOffN = gf_bs_read_u32(bs);
ptr->vertOffD = gf_bs_read_u32(bs);
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err clap_Write(GF_Box *s, GF_BitStream *bs)
{
GF_CleanAppertureBox *ptr = (GF_CleanAppertureBox *)s;
GF_Err e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->cleanApertureWidthN);
gf_bs_write_u32(bs, ptr->cleanApertureWidthD);
gf_bs_write_u32(bs, ptr->cleanApertureHeightN);
gf_bs_write_u32(bs, ptr->cleanApertureHeightD);
gf_bs_write_u32(bs, ptr->horizOffN);
gf_bs_write_u32(bs, ptr->horizOffD);
gf_bs_write_u32(bs, ptr->vertOffN);
gf_bs_write_u32(bs, ptr->vertOffD);
return GF_OK;
}
GF_Err clap_Size(GF_Box *s)
{
s->size += 32;
return GF_OK;
}
#endif
GF_Box *metx_New()
{
ISOM_DECL_BOX_ALLOC(GF_MetaDataSampleEntryBox, GF_ISOM_BOX_TYPE_METX);
gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
return (GF_Box *)tmp;
}
void metx_del(GF_Box *s)
{
GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox*)s;
if (ptr == NULL) return;
gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
if (ptr->content_encoding) gf_free(ptr->content_encoding);
if (ptr->xml_namespace) gf_free(ptr->xml_namespace);
if (ptr->xml_schema_loc) gf_free(ptr->xml_schema_loc);
if (ptr->mime_type) gf_free(ptr->mime_type);
if (ptr->config) gf_isom_box_del((GF_Box *)ptr->config);
gf_free(ptr);
}
GF_Err metx_AddBox(GF_Box *s, GF_Box *a)
{
GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox *)s;
switch (a->type) {
case GF_ISOM_BOX_TYPE_SINF:
gf_list_add(ptr->protections, a);
break;
case GF_ISOM_BOX_TYPE_TXTC:
if (ptr->config) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->config = (GF_TextConfigBox *)a;
break;
default:
return gf_isom_box_add_default(s, a);
}
return GF_OK;
}
GF_Err metx_Read(GF_Box *s, GF_BitStream *bs)
{
u32 size, i;
GF_Err e;
char *str;
GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox*)s;
e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs);
if (e) return e;
size = (u32) ptr->size - 8;
str = gf_malloc(sizeof(char)*size);
i=0;
while (size) {
str[i] = gf_bs_read_u8(bs);
size--;
if (!str[i])
break;
i++;
}
if (i) {
if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
ptr->xml_namespace = gf_strdup(str);
} else {
ptr->content_encoding = gf_strdup(str);
}
}
i=0;
while (size) {
str[i] = gf_bs_read_u8(bs);
size--;
if (!str[i])
break;
i++;
}
if ((ptr->type==GF_ISOM_BOX_TYPE_METX) || (ptr->type==GF_ISOM_BOX_TYPE_STPP)) {
if (i) {
if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
ptr->xml_schema_loc = gf_strdup(str);
} else {
ptr->xml_namespace = gf_strdup(str);
}
}
i=0;
while (size) {
str[i] = gf_bs_read_u8(bs);
size--;
if (!str[i])
break;
i++;
}
if (i) {
if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
ptr->mime_type = gf_strdup(str);
} else {
ptr->xml_schema_loc = gf_strdup(str);
}
}
}
else {
if (i) ptr->mime_type = gf_strdup(str);
}
ptr->size = size;
gf_free(str);
return gf_isom_box_array_read(s, bs, metx_AddBox);
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err metx_Write(GF_Box *s, GF_BitStream *bs)
{
GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox *)s;
GF_Err e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_data(bs, ptr->reserved, 6);
gf_bs_write_u16(bs, ptr->dataReferenceIndex);
if (ptr->type!=GF_ISOM_BOX_TYPE_STPP) {
if (ptr->content_encoding)
gf_bs_write_data(bs, ptr->content_encoding, (u32) strlen(ptr->content_encoding));
gf_bs_write_u8(bs, 0);
}
if ((ptr->type==GF_ISOM_BOX_TYPE_METX) || (ptr->type==GF_ISOM_BOX_TYPE_STPP)) {
if (ptr->xml_namespace)
gf_bs_write_data(bs, ptr->xml_namespace, (u32) strlen(ptr->xml_namespace));
gf_bs_write_u8(bs, 0);
if (ptr->xml_schema_loc)
gf_bs_write_data(bs, ptr->xml_schema_loc, (u32) strlen(ptr->xml_schema_loc));
gf_bs_write_u8(bs, 0);
if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
if (ptr->mime_type)
gf_bs_write_data(bs, ptr->mime_type, (u32) strlen(ptr->mime_type));
gf_bs_write_u8(bs, 0);
}
}
else {
if (ptr->mime_type)
gf_bs_write_data(bs, ptr->mime_type, (u32) strlen(ptr->mime_type));
gf_bs_write_u8(bs, 0);
if (ptr->config) {
gf_isom_box_write((GF_Box *)ptr->config, bs);
}
}
return gf_isom_box_array_write(s, ptr->protections, bs);
}
GF_Err metx_Size(GF_Box *s)
{
GF_Err e;
GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox *)s;
ptr->size += 8;
if (ptr->type!=GF_ISOM_BOX_TYPE_STPP) {
if (ptr->content_encoding)
ptr->size += strlen(ptr->content_encoding);
ptr->size++;
}
if ((ptr->type==GF_ISOM_BOX_TYPE_METX) || (ptr->type==GF_ISOM_BOX_TYPE_STPP)) {
if (ptr->xml_namespace)
ptr->size += strlen(ptr->xml_namespace);
ptr->size++;
if (ptr->xml_schema_loc)
ptr->size += strlen(ptr->xml_schema_loc);
ptr->size++;
if (ptr->type==GF_ISOM_BOX_TYPE_STPP) {
if (ptr->mime_type)
ptr->size += strlen(ptr->mime_type);
ptr->size++;
}
}
else {
if (ptr->mime_type)
ptr->size += strlen(ptr->mime_type);
ptr->size++;
if (ptr->config) {
e = gf_isom_box_size((GF_Box *)ptr->config);
if (e) return e;
ptr->size += ptr->config->size;
}
}
return gf_isom_box_array_size(s, ptr->protections);
}
#endif
GF_Box *txtc_New()
{
ISOM_DECL_BOX_ALLOC(GF_TextConfigBox, GF_ISOM_BOX_TYPE_TXTC);
return (GF_Box *)tmp;
}
void txtc_del(GF_Box *s)
{
GF_TextConfigBox *ptr = (GF_TextConfigBox*)s;
if (ptr == NULL) return;
if (ptr->config) gf_free(ptr->config);
gf_free(ptr);
}
GF_Err txtc_Read(GF_Box *s, GF_BitStream *bs)
{
u32 size, i;
char *str;
GF_TextConfigBox *ptr = (GF_TextConfigBox*)s;
size = (u32) ptr->size;
str = (char *)gf_malloc(sizeof(char)*size);
i=0;
while (size) {
str[i] = gf_bs_read_u8(bs);
size--;
if (!str[i])
break;
i++;
}
if (i) ptr->config = gf_strdup(str);
gf_free(str);
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err txtc_Write(GF_Box *s, GF_BitStream *bs)
{
GF_TextConfigBox *ptr = (GF_TextConfigBox *)s;
GF_Err e = gf_isom_full_box_write(s, bs);
if (e) return e;
if (ptr->config)
gf_bs_write_data(bs, ptr->config, (u32) strlen(ptr->config));
gf_bs_write_u8(bs, 0);
return GF_OK;
}
GF_Err txtc_Size(GF_Box *s)
{
GF_TextConfigBox *ptr = (GF_TextConfigBox *)s;
if (ptr->config)
ptr->size += strlen(ptr->config);
ptr->size++;
return GF_OK;
}
#endif
GF_Box *dac3_New()
{
ISOM_DECL_BOX_ALLOC(GF_AC3ConfigBox, GF_ISOM_BOX_TYPE_DAC3);
return (GF_Box *)tmp;
}
GF_Box *dec3_New()
{
ISOM_DECL_BOX_ALLOC(GF_AC3ConfigBox, GF_ISOM_BOX_TYPE_DAC3);
tmp->cfg.is_ec3 = 1;
return (GF_Box *)tmp;
}
void dac3_del(GF_Box *s)
{
GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
gf_free(ptr);
}
GF_Err dac3_Read(GF_Box *s, GF_BitStream *bs)
{
GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
if (ptr == NULL) return GF_BAD_PARAM;
if (ptr->cfg.is_ec3) {
u32 i;
ptr->cfg.brcode = gf_bs_read_int(bs, 13);
ptr->cfg.nb_streams = gf_bs_read_int(bs, 3) + 1;
for (i=0; i<ptr->cfg.nb_streams; i++) {
ptr->cfg.streams[i].fscod = gf_bs_read_int(bs, 2);
ptr->cfg.streams[i].bsid = gf_bs_read_int(bs, 5);
ptr->cfg.streams[i].bsmod = gf_bs_read_int(bs, 5);
ptr->cfg.streams[i].acmod = gf_bs_read_int(bs, 3);
ptr->cfg.streams[i].lfon = gf_bs_read_int(bs, 1);
gf_bs_read_int(bs, 3);
ptr->cfg.streams[i].nb_dep_sub = gf_bs_read_int(bs, 4);
if (ptr->cfg.streams[i].nb_dep_sub) {
ptr->cfg.streams[i].chan_loc = gf_bs_read_int(bs, 9);
} else {
gf_bs_read_int(bs, 1);
}
}
} else {
ptr->cfg.nb_streams = 1;
ptr->cfg.streams[0].fscod = gf_bs_read_int(bs, 2);
ptr->cfg.streams[0].bsid = gf_bs_read_int(bs, 5);
ptr->cfg.streams[0].bsmod = gf_bs_read_int(bs, 3);
ptr->cfg.streams[0].acmod = gf_bs_read_int(bs, 3);
ptr->cfg.streams[0].lfon = gf_bs_read_int(bs, 1);
ptr->cfg.brcode = gf_bs_read_int(bs, 5);
gf_bs_read_int(bs, 5);
}
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err dac3_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
if (ptr->cfg.is_ec3) s->type = GF_ISOM_BOX_TYPE_DEC3;
e = gf_isom_box_write_header(s, bs);
if (ptr->cfg.is_ec3) s->type = GF_ISOM_BOX_TYPE_DAC3;
if (e) return e;
if (ptr->cfg.is_ec3) {
u32 i;
gf_bs_write_int(bs, ptr->cfg.brcode, 13);
gf_bs_write_int(bs, ptr->cfg.nb_streams - 1, 3);
for (i=0; i<ptr->cfg.nb_streams; i++) {
gf_bs_write_int(bs, ptr->cfg.streams[i].fscod, 2);
gf_bs_write_int(bs, ptr->cfg.streams[i].bsid, 5);
gf_bs_write_int(bs, ptr->cfg.streams[i].bsmod, 5);
gf_bs_write_int(bs, ptr->cfg.streams[i].acmod, 3);
gf_bs_write_int(bs, ptr->cfg.streams[i].lfon, 1);
gf_bs_write_int(bs, 0, 3);
gf_bs_write_int(bs, ptr->cfg.streams[i].nb_dep_sub, 4);
if (ptr->cfg.streams[i].nb_dep_sub) {
gf_bs_write_int(bs, ptr->cfg.streams[i].chan_loc, 9);
} else {
gf_bs_write_int(bs, 0, 1);
}
}
} else {
gf_bs_write_int(bs, ptr->cfg.streams[0].fscod, 2);
gf_bs_write_int(bs, ptr->cfg.streams[0].bsid, 5);
gf_bs_write_int(bs, ptr->cfg.streams[0].bsmod, 3);
gf_bs_write_int(bs, ptr->cfg.streams[0].acmod, 3);
gf_bs_write_int(bs, ptr->cfg.streams[0].lfon, 1);
gf_bs_write_int(bs, ptr->cfg.brcode, 5);
gf_bs_write_int(bs, 0, 5);
}
return GF_OK;
}
GF_Err dac3_Size(GF_Box *s)
{
GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s;
if (ptr->cfg.is_ec3) {
u32 i;
s->size += 2;
for (i=0; i<ptr->cfg.nb_streams; i++) {
s->size += 3;
if (ptr->cfg.streams[i].nb_dep_sub)
s->size += 1;
}
} else {
s->size += 3;
}
return GF_OK;
}
#endif
void lsrc_del(GF_Box *s)
{
GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
if (ptr == NULL) return;
if (ptr->hdr) gf_free(ptr->hdr);
gf_free(ptr);
}
GF_Err lsrc_Read(GF_Box *s, GF_BitStream *bs)
{
GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
ptr->hdr_size = (u32) ptr->size;
ptr->hdr = gf_malloc(sizeof(char)*ptr->hdr_size);
gf_bs_read_data(bs, ptr->hdr, ptr->hdr_size);
return GF_OK;
}
GF_Box *lsrc_New()
{
ISOM_DECL_BOX_ALLOC(GF_LASERConfigurationBox, GF_ISOM_BOX_TYPE_LSRC);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err lsrc_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_data(bs, ptr->hdr, ptr->hdr_size);
return GF_OK;
}
GF_Err lsrc_Size(GF_Box *s)
{
GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s;
ptr->size += ptr->hdr_size;
return GF_OK;
}
#endif
void lsr1_del(GF_Box *s)
{
GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
if (ptr == NULL) return;
gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc);
if (ptr->lsr_config) gf_isom_box_del((GF_Box *) ptr->lsr_config);
if (ptr->descr) gf_isom_box_del((GF_Box *) ptr->descr);
gf_free(ptr);
}
GF_Err lsr1_AddBox(GF_Box *s, GF_Box *a)
{
GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
switch (a->type) {
case GF_ISOM_BOX_TYPE_LSRC:
if (ptr->lsr_config) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->lsr_config = (GF_LASERConfigurationBox *)a;
break;
case GF_ISOM_BOX_TYPE_M4DS:
if (ptr->descr) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->descr = (GF_MPEG4ExtensionDescriptorsBox *)a;
break;
default:
return gf_isom_box_add_default(s, a);
}
return GF_OK;
}
GF_Err lsr1_Read(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox*)s;
e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs);
if (e) return e;
ISOM_DECREASE_SIZE(ptr, 8);
return gf_isom_box_array_read(s, bs, lsr1_AddBox);
}
GF_Box *lsr1_New()
{
ISOM_DECL_BOX_ALLOC(GF_LASeRSampleEntryBox, GF_ISOM_BOX_TYPE_LSR1);
gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err lsr1_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_data(bs, ptr->reserved, 6);
gf_bs_write_u16(bs, ptr->dataReferenceIndex);
if (ptr->lsr_config) {
e = gf_isom_box_write((GF_Box *)ptr->lsr_config, bs);
if (e) return e;
}
if (ptr->descr) {
e = gf_isom_box_write((GF_Box *)ptr->descr, bs);
if (e) return e;
}
return e;
}
GF_Err lsr1_Size(GF_Box *s)
{
GF_Err e;
GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s;
s->size += 8;
if (ptr->lsr_config) {
e = gf_isom_box_size((GF_Box *)ptr->lsr_config);
if (e) return e;
ptr->size += ptr->lsr_config->size;
}
if (ptr->descr) {
e = gf_isom_box_size((GF_Box *)ptr->descr);
if (e) return e;
ptr->size += ptr->descr->size;
}
return GF_OK;
}
#endif
void sidx_del(GF_Box *s)
{
GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox *) s;
if (ptr == NULL) return;
if (ptr->refs) gf_free(ptr->refs);
gf_free(ptr);
}
GF_Err sidx_Read(GF_Box *s,GF_BitStream *bs)
{
u32 i;
GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*) s;
ptr->reference_ID = gf_bs_read_u32(bs);
ptr->timescale = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 8);
if (ptr->version==0) {
ptr->earliest_presentation_time = gf_bs_read_u32(bs);
ptr->first_offset = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 8);
} else {
ptr->earliest_presentation_time = gf_bs_read_u64(bs);
ptr->first_offset = gf_bs_read_u64(bs);
ISOM_DECREASE_SIZE(ptr, 16);
}
gf_bs_read_u16(bs);
ptr->nb_refs = gf_bs_read_u16(bs);
ISOM_DECREASE_SIZE(ptr, 4);
ptr->refs = gf_malloc(sizeof(GF_SIDXReference)*ptr->nb_refs);
for (i=0; i<ptr->nb_refs; i++) {
ptr->refs[i].reference_type = gf_bs_read_int(bs, 1);
ptr->refs[i].reference_size = gf_bs_read_int(bs, 31);
ptr->refs[i].subsegment_duration = gf_bs_read_u32(bs);
ptr->refs[i].starts_with_SAP = gf_bs_read_int(bs, 1);
ptr->refs[i].SAP_type = gf_bs_read_int(bs, 3);
ptr->refs[i].SAP_delta_time = gf_bs_read_int(bs, 28);
ISOM_DECREASE_SIZE(ptr, 12);
}
return GF_OK;
}
GF_Box *sidx_New()
{
ISOM_DECL_BOX_ALLOC(GF_SegmentIndexBox, GF_ISOM_BOX_TYPE_SIDX);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err sidx_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*) s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->reference_ID);
gf_bs_write_u32(bs, ptr->timescale);
if (ptr->version==0) {
gf_bs_write_u32(bs, (u32) ptr->earliest_presentation_time);
gf_bs_write_u32(bs, (u32) ptr->first_offset);
} else {
gf_bs_write_u64(bs, ptr->earliest_presentation_time);
gf_bs_write_u64(bs, ptr->first_offset);
}
gf_bs_write_u16(bs, 0);
gf_bs_write_u16(bs, ptr->nb_refs);
for (i=0; i<ptr->nb_refs; i++ ) {
gf_bs_write_int(bs, ptr->refs[i].reference_type, 1);
gf_bs_write_int(bs, ptr->refs[i].reference_size, 31);
gf_bs_write_u32(bs, ptr->refs[i].subsegment_duration);
gf_bs_write_int(bs, ptr->refs[i].starts_with_SAP, 1);
gf_bs_write_int(bs, ptr->refs[i].SAP_type, 3);
gf_bs_write_int(bs, ptr->refs[i].SAP_delta_time, 28);
}
return GF_OK;
}
GF_Err sidx_Size(GF_Box *s)
{
GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*) s;
ptr->size += 12;
if (ptr->version==0) {
ptr->size += 8;
} else {
ptr->size += 16;
}
ptr->size += ptr->nb_refs * 12;
return GF_OK;
}
#endif
void ssix_del(GF_Box *s)
{
u32 i;
GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox *)s;
if (ptr == NULL) return;
if (ptr->subsegments) {
for (i = 0; i < ptr->subsegment_count; i++) {
GF_Subsegment *subsegment = &ptr->subsegments[i];
if (subsegment->levels) gf_free(subsegment->levels);
if (subsegment->range_sizes) gf_free(subsegment->range_sizes);
}
gf_free(ptr->subsegments);
}
gf_free(ptr);
}
GF_Err ssix_Read(GF_Box *s, GF_BitStream *bs)
{
u32 i,j;
GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox*)s;
if (ptr->size < 4) return GF_BAD_PARAM;
ptr->subsegment_count = gf_bs_read_u32(bs);
ptr->size -= 4;
ptr->subsegments = gf_malloc(ptr->subsegment_count*sizeof(GF_Subsegment));
for (i = 0; i < ptr->subsegment_count; i++) {
GF_Subsegment *subseg = &ptr->subsegments[i];
if (ptr->size < 4) return GF_BAD_PARAM;
subseg->range_count = gf_bs_read_u32(bs);
ptr->size -= 4;
if (ptr->size < subseg->range_count*4) return GF_BAD_PARAM;
subseg->levels = gf_malloc(sizeof(u8)*subseg->range_count);
subseg->range_sizes = gf_malloc(sizeof(u32)*subseg->range_count);
for (j = 0; j < subseg->range_count; j++) {
subseg->levels[j] = gf_bs_read_u8(bs);
subseg->range_sizes[j] = gf_bs_read_u24(bs);
ptr->size -= 4;
}
}
return GF_OK;
}
GF_Box *ssix_New()
{
ISOM_DECL_BOX_ALLOC(GF_SubsegmentIndexBox, GF_ISOM_BOX_TYPE_SSIX);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err ssix_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i, j;
GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox*)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->subsegment_count);
for (i = 0; i<ptr->subsegment_count; i++) {
gf_bs_write_u32(bs, ptr->subsegments[i].range_count);
for (j = 0; j < ptr->subsegment_count; j++) {
gf_bs_write_u8(bs, ptr->subsegments[i].levels[j]);
gf_bs_write_u24(bs, ptr->subsegments[i].range_sizes[j]);
}
}
return GF_OK;
}
GF_Err ssix_Size(GF_Box *s)
{
u32 i;
GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox*)s;
ptr->size += 4;
for (i = 0; i < ptr->subsegment_count; i++) {
ptr->size += 4 + 4 * ptr->subsegments[i].range_count;
}
return GF_OK;
}
#endif
void leva_del(GF_Box *s)
{
GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox *)s;
if (ptr == NULL) return;
if (ptr->levels) gf_free(ptr->levels);
gf_free(ptr);
}
GF_Err leva_Read(GF_Box *s, GF_BitStream *bs)
{
u32 i;
GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox*)s;
if (ptr->size < 4) return GF_BAD_PARAM;
ptr->level_count = gf_bs_read_u8(bs);
ptr->size -= 4;
GF_SAFE_ALLOC_N(ptr->levels, ptr->level_count, GF_LevelAssignment);
for (i = 0; i < ptr->level_count; i++) {
GF_LevelAssignment *level = &ptr->levels[i];
u8 tmp;
if (ptr->size < 5) return GF_BAD_PARAM;
level->track_id = gf_bs_read_u32(bs);
tmp = gf_bs_read_u8(bs);
level->padding_flag = tmp >> 7;
level->type = tmp & 0x7F;
if (level->type == 0) {
level->grouping_type = gf_bs_read_u32(bs);
}
else if (level->type == 1) {
level->grouping_type = gf_bs_read_u32(bs);
level->grouping_type_parameter = gf_bs_read_u32(bs);
}
else if (level->type == 4) {
level->sub_track_id = gf_bs_read_u32(bs);
}
}
return GF_OK;
}
GF_Box *leva_New()
{
ISOM_DECL_BOX_ALLOC(GF_LevelAssignmentBox, GF_ISOM_BOX_TYPE_LEVA);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err leva_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox*)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u8(bs, ptr->level_count);
for (i = 0; i<ptr->level_count; i++) {
gf_bs_write_u32(bs, ptr->levels[i].track_id);
gf_bs_write_u8(bs, ptr->levels[i].padding_flag << 7 | (ptr->levels[i].type & 0x7F));
if (ptr->levels[i].type == 0) {
gf_bs_write_u32(bs, ptr->levels[i].grouping_type);
}
else if (ptr->levels[i].type == 1) {
gf_bs_write_u32(bs, ptr->levels[i].grouping_type);
gf_bs_write_u32(bs, ptr->levels[i].grouping_type_parameter);
}
else if (ptr->levels[i].type == 4) {
gf_bs_write_u32(bs, ptr->levels[i].sub_track_id);
}
}
return GF_OK;
}
GF_Err leva_Size(GF_Box *s)
{
u32 i;
GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox*)s;
ptr->size += 1;
for (i = 0; i < ptr->level_count; i++) {
ptr->size += 5;
if (ptr->levels[i].type == 0 || ptr->levels[i].type == 4) {
ptr->size += 4;
}
else if (ptr->levels[i].type == 1) {
ptr->size += 8;
}
}
return GF_OK;
}
#endif
GF_Box *pcrb_New()
{
ISOM_DECL_BOX_ALLOC(GF_PcrInfoBox, GF_ISOM_BOX_TYPE_PCRB);
return (GF_Box *)tmp;
}
void pcrb_del(GF_Box *s)
{
GF_PcrInfoBox *ptr = (GF_PcrInfoBox *) s;
if (ptr == NULL) return;
if (ptr->pcr_values) gf_free(ptr->pcr_values);
gf_free(ptr);
}
GF_Err pcrb_Read(GF_Box *s,GF_BitStream *bs)
{
u32 i;
GF_PcrInfoBox *ptr = (GF_PcrInfoBox*) s;
ptr->subsegment_count = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
ptr->pcr_values = gf_malloc(sizeof(u64)*ptr->subsegment_count);
for (i=0; i<ptr->subsegment_count; i++) {
u64 data1 = gf_bs_read_u32(bs);
u64 data2 = gf_bs_read_u16(bs);
ISOM_DECREASE_SIZE(ptr, 6);
ptr->pcr_values[i] = (data1 << 10) | (data2 >> 6);
}
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err pcrb_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_PcrInfoBox *ptr = (GF_PcrInfoBox*) s;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->subsegment_count);
for (i=0; i<ptr->subsegment_count; i++ ) {
u32 data1 = (u32) (ptr->pcr_values[i] >> 10);
u16 data2 = (u16) (ptr->pcr_values[i] << 6);
gf_bs_write_u32(bs, data1);
gf_bs_write_u16(bs, data2);
}
return GF_OK;
}
GF_Err pcrb_Size(GF_Box *s)
{
GF_PcrInfoBox *ptr = (GF_PcrInfoBox*) s;
ptr->size += 4;
ptr->size += ptr->subsegment_count * 6;
return GF_OK;
}
#endif
GF_Box *subs_New()
{
ISOM_DECL_BOX_ALLOC(GF_SubSampleInformationBox, GF_ISOM_BOX_TYPE_SUBS);
tmp->Samples = gf_list_new();
return (GF_Box *)tmp;
}
void subs_del(GF_Box *s)
{
GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *)s;
if (ptr == NULL) return;
while (gf_list_count(ptr->Samples)) {
GF_SubSampleInfoEntry *pSamp;
pSamp = (GF_SubSampleInfoEntry*)gf_list_get(ptr->Samples, 0);
while (gf_list_count(pSamp->SubSamples)) {
GF_SubSampleEntry *pSubSamp;
pSubSamp = (GF_SubSampleEntry*) gf_list_get(pSamp->SubSamples, 0);
gf_free(pSubSamp);
gf_list_rem(pSamp->SubSamples, 0);
}
gf_list_del(pSamp->SubSamples);
gf_free(pSamp);
gf_list_rem(ptr->Samples, 0);
}
gf_list_del(ptr->Samples);
gf_free(ptr);
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err subs_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i, j, entry_count;
u16 subsample_count;
GF_SubSampleInfoEntry *pSamp;
GF_SubSampleEntry *pSubSamp;
GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *) s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
entry_count = gf_list_count(ptr->Samples);
gf_bs_write_u32(bs, entry_count);
for (i=0; i<entry_count; i++) {
pSamp = (GF_SubSampleInfoEntry*) gf_list_get(ptr->Samples, i);
subsample_count = gf_list_count(pSamp->SubSamples);
gf_bs_write_u32(bs, pSamp->sample_delta);
gf_bs_write_u16(bs, subsample_count);
for (j=0; j<subsample_count; j++) {
pSubSamp = (GF_SubSampleEntry*) gf_list_get(pSamp->SubSamples, j);
if (ptr->version == 1) {
gf_bs_write_u32(bs, pSubSamp->subsample_size);
} else {
gf_bs_write_u16(bs, pSubSamp->subsample_size);
}
gf_bs_write_u8(bs, pSubSamp->subsample_priority);
gf_bs_write_u8(bs, pSubSamp->discardable);
gf_bs_write_u32(bs, pSubSamp->reserved);
}
}
return e;
}
GF_Err subs_Size(GF_Box *s)
{
GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *) s;
GF_SubSampleInfoEntry *pSamp;
u32 entry_count, i;
u16 subsample_count;
ptr->size += 4;
entry_count = gf_list_count(ptr->Samples);
for (i=0; i<entry_count; i++) {
pSamp = (GF_SubSampleInfoEntry*) gf_list_get(ptr->Samples, i);
subsample_count = gf_list_count(pSamp->SubSamples);
ptr->size += 4 + 2 + subsample_count * (6 + (ptr->version==1 ? 4 : 2));
}
return GF_OK;
}
#endif
GF_Err subs_Read(GF_Box *s, GF_BitStream *bs)
{
GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *)s;
u32 entry_count, i, j;
u16 subsample_count;
entry_count = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
for (i=0; i<entry_count; i++) {
u32 subs_size=0;
GF_SubSampleInfoEntry *pSamp = (GF_SubSampleInfoEntry*) gf_malloc(sizeof(GF_SubSampleInfoEntry));
if (!pSamp) return GF_OUT_OF_MEM;
memset(pSamp, 0, sizeof(GF_SubSampleInfoEntry));
pSamp->SubSamples = gf_list_new();
pSamp->sample_delta = gf_bs_read_u32(bs);
subsample_count = gf_bs_read_u16(bs);
subs_size=6;
for (j=0; j<subsample_count; j++) {
GF_SubSampleEntry *pSubSamp = (GF_SubSampleEntry*) gf_malloc(sizeof(GF_SubSampleEntry));
if (!pSubSamp) return GF_OUT_OF_MEM;
memset(pSubSamp, 0, sizeof(GF_SubSampleEntry));
if (ptr->version==1) {
pSubSamp->subsample_size = gf_bs_read_u32(bs);
subs_size+=4;
} else {
pSubSamp->subsample_size = gf_bs_read_u16(bs);
subs_size+=2;
}
pSubSamp->subsample_priority = gf_bs_read_u8(bs);
pSubSamp->discardable = gf_bs_read_u8(bs);
pSubSamp->reserved = gf_bs_read_u32(bs);
subs_size+=6;
gf_list_add(pSamp->SubSamples, pSubSamp);
}
gf_list_add(ptr->Samples, pSamp);
ISOM_DECREASE_SIZE(ptr, subs_size);
}
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
GF_Box *tfdt_New()
{
ISOM_DECL_BOX_ALLOC(GF_TFBaseMediaDecodeTimeBox, GF_ISOM_BOX_TYPE_TFDT);
return (GF_Box *)tmp;
}
void tfdt_del(GF_Box *s)
{
gf_free(s);
}
GF_Err tfdt_Read(GF_Box *s,GF_BitStream *bs)
{
GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *)s;
if (ptr->version==1) {
ptr->baseMediaDecodeTime = gf_bs_read_u64(bs);
ISOM_DECREASE_SIZE(ptr, 8);
} else {
ptr->baseMediaDecodeTime = (u32) gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
}
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err tfdt_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *) s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
if (ptr->version==1) {
gf_bs_write_u64(bs, ptr->baseMediaDecodeTime);
} else {
gf_bs_write_u32(bs, (u32) ptr->baseMediaDecodeTime);
}
return GF_OK;
}
GF_Err tfdt_Size(GF_Box *s)
{
GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *)s;
if (ptr->baseMediaDecodeTime<=0xFFFFFFFF) {
ptr->version = 0;
ptr->size += 4;
} else {
ptr->version = 1;
ptr->size += 8;
}
return GF_OK;
}
#endif
#endif
GF_Box *rvcc_New()
{
ISOM_DECL_BOX_ALLOC(GF_RVCConfigurationBox, GF_ISOM_BOX_TYPE_RVCC);
return (GF_Box *)tmp;
}
void rvcc_del(GF_Box *s)
{
gf_free(s);
}
GF_Err rvcc_Read(GF_Box *s,GF_BitStream *bs)
{
GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox*)s;
ptr->predefined_rvc_config = gf_bs_read_u16(bs);
ISOM_DECREASE_SIZE(ptr, 2);
if (!ptr->predefined_rvc_config) {
ptr->rvc_meta_idx = gf_bs_read_u16(bs);
ISOM_DECREASE_SIZE(ptr, 2);
}
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err rvcc_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox*) s;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
gf_bs_write_u16(bs, ptr->predefined_rvc_config);
if (!ptr->predefined_rvc_config) {
gf_bs_write_u16(bs, ptr->rvc_meta_idx);
}
return GF_OK;
}
GF_Err rvcc_Size(GF_Box *s)
{
GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox *)s;
ptr->size += 2;
if (! ptr->predefined_rvc_config) ptr->size += 2;
return GF_OK;
}
#endif
GF_Box *sbgp_New()
{
ISOM_DECL_BOX_ALLOC(GF_SampleGroupBox, GF_ISOM_BOX_TYPE_SBGP);
return (GF_Box *)tmp;
}
void sbgp_del(GF_Box *a)
{
GF_SampleGroupBox *p = (GF_SampleGroupBox *)a;
if (p->sample_entries) gf_free(p->sample_entries);
gf_free(p);
}
GF_Err sbgp_Read(GF_Box *s, GF_BitStream *bs)
{
u32 i;
GF_SampleGroupBox *ptr = (GF_SampleGroupBox *)s;
ptr->grouping_type = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
if (ptr->version==1) {
ptr->grouping_type_parameter = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
}
ptr->entry_count = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
ptr->sample_entries = gf_malloc(sizeof(GF_SampleGroupEntry)*ptr->entry_count);
if (!ptr->sample_entries) return GF_IO_ERR;
for (i=0; i<ptr->entry_count; i++) {
ptr->sample_entries[i].sample_count = gf_bs_read_u32(bs);
ptr->sample_entries[i].group_description_index = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 8);
}
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err sbgp_Write(GF_Box *s, GF_BitStream *bs)
{
u32 i;
GF_Err e;
GF_SampleGroupBox *p = (GF_SampleGroupBox*)s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, p->grouping_type);
if (p->version==1)
gf_bs_write_u32(bs, p->grouping_type_parameter);
gf_bs_write_u32(bs, p->entry_count);
for (i = 0; i<p->entry_count; i++ ) {
gf_bs_write_u32(bs, p->sample_entries[i].sample_count);
gf_bs_write_u32(bs, p->sample_entries[i].group_description_index);
}
return GF_OK;
}
GF_Err sbgp_Size(GF_Box *s)
{
GF_SampleGroupBox *p = (GF_SampleGroupBox*)s;
p->size += 8;
if (p->grouping_type_parameter) p->version=1;
if (p->version==1) p->size += 4;
p->size += 8*p->entry_count;
return GF_OK;
}
#endif
static void *sgpd_parse_entry(u32 grouping_type, GF_BitStream *bs, u32 entry_size, u32 *total_bytes)
{
GF_DefaultSampleGroupDescriptionEntry *ptr;
switch (grouping_type) {
case GF_ISOM_SAMPLE_GROUP_ROLL:
case GF_ISOM_SAMPLE_GROUP_PROL:
{
GF_RollRecoveryEntry *ptr;
GF_SAFEALLOC(ptr, GF_RollRecoveryEntry);
if (!ptr) return NULL;
ptr->roll_distance = gf_bs_read_int(bs, 16);
*total_bytes = 2;
return ptr;
}
case GF_ISOM_SAMPLE_GROUP_RAP:
{
GF_VisualRandomAccessEntry *ptr;
GF_SAFEALLOC(ptr, GF_VisualRandomAccessEntry);
if (!ptr) return NULL;
ptr->num_leading_samples_known = gf_bs_read_int(bs, 1);
ptr->num_leading_samples = gf_bs_read_int(bs, 7);
*total_bytes = 1;
return ptr;
}
case GF_ISOM_SAMPLE_GROUP_SAP:
{
GF_SAPEntry *ptr;
GF_SAFEALLOC(ptr, GF_SAPEntry);
if (!ptr) return NULL;
ptr->dependent_flag = gf_bs_read_int(bs, 1);
gf_bs_read_int(bs, 3);
ptr->SAP_type = gf_bs_read_int(bs, 4);
*total_bytes = 1;
return ptr;
}
case GF_ISOM_SAMPLE_GROUP_TELE:
{
GF_TemporalLevelEntry *ptr;
GF_SAFEALLOC(ptr, GF_TemporalLevelEntry);
if (!ptr) return NULL;
ptr->level_independently_decodable = gf_bs_read_int(bs, 1);
gf_bs_read_int(bs, 7);
*total_bytes = 1;
return ptr;
}
case GF_ISOM_SAMPLE_GROUP_SEIG:
{
GF_CENCSampleEncryptionGroupEntry *ptr;
GF_SAFEALLOC(ptr, GF_CENCSampleEncryptionGroupEntry);
if (!ptr) return NULL;
gf_bs_read_u8(bs);
ptr->crypt_byte_block = gf_bs_read_int(bs, 4);
ptr->skip_byte_block = gf_bs_read_int(bs, 4);
ptr->IsProtected = gf_bs_read_u8(bs);
ptr->Per_Sample_IV_size = gf_bs_read_u8(bs);
gf_bs_read_data(bs, (char *)ptr->KID, 16);
*total_bytes = 20;
if ((ptr->IsProtected == 1) && !ptr->Per_Sample_IV_size) {
ptr->constant_IV_size = gf_bs_read_u8(bs);
assert((ptr->constant_IV_size == 8) || (ptr->constant_IV_size == 16));
gf_bs_read_data(bs, (char *)ptr->constant_IV, ptr->constant_IV_size);
*total_bytes += 1 + ptr->constant_IV_size;
}
if (!entry_size) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] seig sample group does not indicate entry size, deprecated in spec\n"));
}
return ptr;
}
case GF_ISOM_SAMPLE_GROUP_OINF:
{
GF_OperatingPointsInformation *ptr = gf_isom_oinf_new_entry();
u32 s = (u32) gf_bs_get_position(bs);
gf_isom_oinf_read_entry(ptr, bs);
*total_bytes = (u32) gf_bs_get_position(bs) - s;
if (!entry_size) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] oinf sample group does not indicate entry size, deprecated in spec\n"));
}
return ptr;
}
case GF_ISOM_SAMPLE_GROUP_LINF:
{
GF_LHVCLayerInformation *ptr = gf_isom_linf_new_entry();
u32 s = (u32) gf_bs_get_position(bs);
gf_isom_linf_read_entry(ptr, bs);
*total_bytes = (u32) gf_bs_get_position(bs) - s;
if (!entry_size) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] linf sample group does not indicate entry size, deprecated in spec\n"));
}
return ptr;
}
case GF_ISOM_SAMPLE_GROUP_TRIF:
if (! entry_size) {
u32 flags = gf_bs_peek_bits(bs, 24, 0);
if (flags & 0x10000) entry_size=3;
else {
if (flags & 0x80000) entry_size=7;
else entry_size=11;
if (flags & 0x200000) {
u32 nb_entries = gf_bs_peek_bits(bs, 16, entry_size);
entry_size += 2 + 2*nb_entries;
}
}
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] trif sample group does not indicate entry size, deprecated in spec\n"));
}
break;
case GF_ISOM_SAMPLE_GROUP_NALM:
if (! entry_size) {
u64 start = gf_bs_get_position(bs);
Bool rle, large_size;
u32 entry_count;
gf_bs_read_int(bs, 6);
large_size = gf_bs_read_int(bs, 1);
rle = gf_bs_read_int(bs, 1);
entry_count = gf_bs_read_int(bs, large_size ? 16 : 8);
gf_bs_seek(bs, start);
entry_size = 1 + large_size ? 2 : 1;
entry_size += entry_count * 2;
if (rle) entry_size += entry_count * (large_size ? 2 : 1);
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] nalm sample group does not indicate entry size, deprecated in spec\n"));
}
break;
default:
break;
}
if (!entry_size) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] %s sample group does not indicate entry size, cannot parse!\n", gf_4cc_to_str( grouping_type) ));
return NULL;
}
GF_SAFEALLOC(ptr, GF_DefaultSampleGroupDescriptionEntry);
if (!ptr) return NULL;
ptr->length = entry_size;
ptr->data = (u8 *) gf_malloc(sizeof(u8)*ptr->length);
gf_bs_read_data(bs, (char *) ptr->data, ptr->length);
*total_bytes = entry_size;
return ptr;
}
static void sgpd_del_entry(u32 grouping_type, void *entry)
{
switch (grouping_type) {
case GF_ISOM_SAMPLE_GROUP_ROLL:
case GF_ISOM_SAMPLE_GROUP_PROL:
case GF_ISOM_SAMPLE_GROUP_RAP:
case GF_ISOM_SAMPLE_GROUP_SEIG:
case GF_ISOM_SAMPLE_GROUP_TELE:
case GF_ISOM_SAMPLE_GROUP_SAP:
gf_free(entry);
return;
case GF_ISOM_SAMPLE_GROUP_OINF:
gf_isom_oinf_del_entry(entry);
return;
case GF_ISOM_SAMPLE_GROUP_LINF:
gf_isom_linf_del_entry(entry);
return;
default:
{
GF_DefaultSampleGroupDescriptionEntry *ptr = (GF_DefaultSampleGroupDescriptionEntry *)entry;
if (ptr->data) gf_free(ptr->data);
gf_free(ptr);
}
}
}
void sgpd_write_entry(u32 grouping_type, void *entry, GF_BitStream *bs)
{
switch (grouping_type) {
case GF_ISOM_SAMPLE_GROUP_ROLL:
case GF_ISOM_SAMPLE_GROUP_PROL:
gf_bs_write_int(bs, ((GF_RollRecoveryEntry*)entry)->roll_distance, 16);
return;
case GF_ISOM_SAMPLE_GROUP_RAP:
gf_bs_write_int(bs, ((GF_VisualRandomAccessEntry*)entry)->num_leading_samples_known, 1);
gf_bs_write_int(bs, ((GF_VisualRandomAccessEntry*)entry)->num_leading_samples, 7);
return;
case GF_ISOM_SAMPLE_GROUP_SAP:
gf_bs_write_int(bs, ((GF_SAPEntry*)entry)->dependent_flag, 1);
gf_bs_write_int(bs, 0, 3);
gf_bs_write_int(bs, ((GF_SAPEntry*)entry)->SAP_type, 4);
return;
case GF_ISOM_SAMPLE_GROUP_TELE:
gf_bs_write_int(bs, ((GF_TemporalLevelEntry*)entry)->level_independently_decodable, 1);
gf_bs_write_int(bs, 0, 7);
return;
case GF_ISOM_SAMPLE_GROUP_SEIG:
gf_bs_write_u8(bs, 0x0);
gf_bs_write_int(bs, ((GF_CENCSampleEncryptionGroupEntry*)entry)->crypt_byte_block, 4);
gf_bs_write_int(bs, ((GF_CENCSampleEncryptionGroupEntry*)entry)->skip_byte_block, 4);
gf_bs_write_u8(bs, ((GF_CENCSampleEncryptionGroupEntry *)entry)->IsProtected);
gf_bs_write_u8(bs, ((GF_CENCSampleEncryptionGroupEntry *)entry)->Per_Sample_IV_size);
gf_bs_write_data(bs, (char *)((GF_CENCSampleEncryptionGroupEntry *)entry)->KID, 16);
if ((((GF_CENCSampleEncryptionGroupEntry *)entry)->IsProtected == 1) && !((GF_CENCSampleEncryptionGroupEntry *)entry)->Per_Sample_IV_size) {
gf_bs_write_u8(bs, ((GF_CENCSampleEncryptionGroupEntry *)entry)->constant_IV_size);
gf_bs_write_data(bs, (char *)((GF_CENCSampleEncryptionGroupEntry *)entry)->constant_IV, ((GF_CENCSampleEncryptionGroupEntry *)entry)->constant_IV_size);
}
return;
case GF_ISOM_SAMPLE_GROUP_OINF:
gf_isom_oinf_write_entry(entry, bs);
return;
case GF_ISOM_SAMPLE_GROUP_LINF:
gf_isom_linf_write_entry(entry, bs);
return;
default:
{
GF_DefaultSampleGroupDescriptionEntry *ptr = (GF_DefaultSampleGroupDescriptionEntry *)entry;
gf_bs_write_data(bs, (char *) ptr->data, ptr->length);
}
}
}
#ifndef GPAC_DISABLE_ISOM_WRITE
static u32 sgpd_size_entry(u32 grouping_type, void *entry)
{
switch (grouping_type) {
case GF_ISOM_SAMPLE_GROUP_ROLL:
case GF_ISOM_SAMPLE_GROUP_PROL:
return 2;
case GF_ISOM_SAMPLE_GROUP_TELE:
case GF_ISOM_SAMPLE_GROUP_RAP:
case GF_ISOM_SAMPLE_GROUP_SAP:
return 1;
case GF_ISOM_SAMPLE_GROUP_SEIG:
return ((((GF_CENCSampleEncryptionGroupEntry *)entry)->IsProtected == 1) && !((GF_CENCSampleEncryptionGroupEntry *)entry)->Per_Sample_IV_size) ? 21 + ((GF_CENCSampleEncryptionGroupEntry *)entry)->constant_IV_size : 20;
case GF_ISOM_SAMPLE_GROUP_OINF:
return gf_isom_oinf_size_entry(entry);
case GF_ISOM_SAMPLE_GROUP_LINF:
return gf_isom_linf_size_entry(entry);
default:
return ((GF_DefaultSampleGroupDescriptionEntry *)entry)->length;
}
}
#endif
GF_Box *sgpd_New()
{
ISOM_DECL_BOX_ALLOC(GF_SampleGroupDescriptionBox, GF_ISOM_BOX_TYPE_SGPD);
tmp->version = 1;
tmp->group_descriptions = gf_list_new();
return (GF_Box *)tmp;
}
void sgpd_del(GF_Box *a)
{
GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)a;
while (gf_list_count(p->group_descriptions)) {
void *ptr = gf_list_last(p->group_descriptions);
sgpd_del_entry(p->grouping_type, ptr);
gf_list_rem_last(p->group_descriptions);
}
gf_list_del(p->group_descriptions);
gf_free(p);
}
GF_Err sgpd_Read(GF_Box *s, GF_BitStream *bs)
{
u32 entry_count;
GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)s;
p->grouping_type = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(p, 4);
if (p->version>=1) {
p->default_length = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(p, 4);
}
if (p->version>=2) {
p->default_description_index = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(p, 4);
}
entry_count = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(p, 4);
if (entry_count>p->size)
return GF_ISOM_INVALID_FILE;
while (entry_count) {
void *ptr;
u32 parsed_bytes;
u32 size = p->default_length;
if ((p->version>=1) && !size) {
size = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(p, 4);
}
ptr = sgpd_parse_entry(p->grouping_type, bs, size, &parsed_bytes);
if (!ptr) return GF_ISOM_INVALID_FILE;
ISOM_DECREASE_SIZE(p, parsed_bytes);
gf_list_add(p->group_descriptions, ptr);
entry_count--;
}
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err sgpd_Write(GF_Box *s, GF_BitStream *bs)
{
u32 i;
GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)s;
GF_Err e;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, p->grouping_type);
if (p->version>=1) gf_bs_write_u32(bs, p->default_length);
if (p->version>=2) gf_bs_write_u32(bs, p->default_description_index);
gf_bs_write_u32(bs, gf_list_count(p->group_descriptions) );
for (i=0; i<gf_list_count(p->group_descriptions); i++) {
void *ptr = gf_list_get(p->group_descriptions, i);
if ((p->version >= 1) && !p->default_length) {
u32 size = sgpd_size_entry(p->grouping_type, ptr);
gf_bs_write_u32(bs, size);
}
sgpd_write_entry(p->grouping_type, ptr, bs);
}
return GF_OK;
}
GF_Err sgpd_Size(GF_Box *s)
{
u32 i;
GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)s;
p->size += 8;
p->version=1;
p->size += 4;
if (p->version>=2) p->size += 4;
p->default_length = 0;
for (i=0; i<gf_list_count(p->group_descriptions); i++) {
void *ptr = gf_list_get(p->group_descriptions, i);
u32 size = sgpd_size_entry(p->grouping_type, ptr);
p->size += size;
if (!p->default_length) {
p->default_length = size;
} else if (p->default_length != size) {
p->default_length = 0;
}
}
if (p->version>=1) {
if (!p->default_length) p->size += gf_list_count(p->group_descriptions)*4;
}
return GF_OK;
}
#endif
void saiz_del(GF_Box *s)
{
GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*)s;
if (ptr == NULL) return;
if (ptr->sample_info_size) gf_free(ptr->sample_info_size);
gf_free(ptr);
}
GF_Err saiz_Read(GF_Box *s, GF_BitStream *bs)
{
GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*)s;
if (ptr->flags & 1) {
ptr->aux_info_type = gf_bs_read_u32(bs);
ptr->aux_info_type_parameter = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 8);
}
ptr->default_sample_info_size = gf_bs_read_u8(bs);
ptr->sample_count = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 5);
if (ptr->default_sample_info_size == 0) {
ptr->sample_info_size = gf_malloc(sizeof(u8)*ptr->sample_count);
gf_bs_read_data(bs, (char *) ptr->sample_info_size, ptr->sample_count);
ISOM_DECREASE_SIZE(ptr, ptr->sample_count);
}
return GF_OK;
}
GF_Box *saiz_New()
{
ISOM_DECL_BOX_ALLOC(GF_SampleAuxiliaryInfoSizeBox, GF_ISOM_BOX_TYPE_SAIZ);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err saiz_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*) s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
if (ptr->flags & 1) {
gf_bs_write_u32(bs, ptr->aux_info_type);
gf_bs_write_u32(bs, ptr->aux_info_type_parameter);
}
gf_bs_write_u8(bs, ptr->default_sample_info_size);
gf_bs_write_u32(bs, ptr->sample_count);
if (!ptr->default_sample_info_size) {
gf_bs_write_data(bs, (char *) ptr->sample_info_size, ptr->sample_count);
}
return GF_OK;
}
GF_Err saiz_Size(GF_Box *s)
{
GF_SampleAuxiliaryInfoSizeBox *ptr = (GF_SampleAuxiliaryInfoSizeBox*)s;
if (ptr->aux_info_type || ptr->aux_info_type_parameter) {
ptr->flags |= 1;
}
if (ptr->flags & 1) ptr->size += 8;
ptr->size += 5;
if (ptr->default_sample_info_size==0) ptr->size += ptr->sample_count;
return GF_OK;
}
#endif
void saio_del(GF_Box *s)
{
GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox*)s;
if (ptr == NULL) return;
if (ptr->offsets) gf_free(ptr->offsets);
if (ptr->offsets_large) gf_free(ptr->offsets_large);
gf_free(ptr);
}
GF_Err saio_Read(GF_Box *s, GF_BitStream *bs)
{
GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox *)s;
if (ptr->flags & 1) {
ptr->aux_info_type = gf_bs_read_u32(bs);
ptr->aux_info_type_parameter = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 8);
}
ptr->entry_count = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
if (ptr->entry_count) {
u32 i;
if (ptr->version==0) {
ptr->offsets = gf_malloc(sizeof(u32)*ptr->entry_count);
for (i=0; i<ptr->entry_count; i++)
ptr->offsets[i] = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4*ptr->entry_count);
} else {
ptr->offsets_large = gf_malloc(sizeof(u64)*ptr->entry_count);
for (i=0; i<ptr->entry_count; i++)
ptr->offsets_large[i] = gf_bs_read_u64(bs);
ISOM_DECREASE_SIZE(ptr, 8*ptr->entry_count);
}
}
return GF_OK;
}
GF_Box *saio_New()
{
ISOM_DECL_BOX_ALLOC(GF_SampleAuxiliaryInfoOffsetBox, GF_ISOM_BOX_TYPE_SAIO);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err saio_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox *) s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
if (ptr->flags & 1) {
gf_bs_write_u32(bs, ptr->aux_info_type);
gf_bs_write_u32(bs, ptr->aux_info_type_parameter);
}
gf_bs_write_u32(bs, ptr->entry_count);
if (ptr->entry_count) {
u32 i;
ptr->offset_first_offset_field = gf_bs_get_position(bs);
if (ptr->version==0) {
if (!ptr->offsets) {
gf_bs_write_u32(bs, 0);
} else {
for (i=0; i<ptr->entry_count; i++)
gf_bs_write_u32(bs, ptr->offsets[i]);
}
} else {
if (!ptr->offsets_large) {
gf_bs_write_u64(bs, 0);
} else {
for (i=0; i<ptr->entry_count; i++)
gf_bs_write_u64(bs, ptr->offsets_large[i]);
}
}
}
return GF_OK;
}
GF_Err saio_Size(GF_Box *s)
{
GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox*)s;
if (ptr->aux_info_type || ptr->aux_info_type_parameter) {
ptr->flags |= 1;
}
if (ptr->offsets_large) {
ptr->version = 1;
}
if (ptr->flags & 1) ptr->size += 8;
ptr->size += 4;
if (ptr->aux_info_type == GF_4CC('c', 'e', 'n', 'c')) {
if (ptr->offsets_large) gf_free(ptr->offsets_large);
if (ptr->offsets) gf_free(ptr->offsets);
ptr->offsets_large = NULL;
ptr->offsets = NULL;
ptr->entry_count = 1;
}
ptr->size += ((ptr->version==1) ? 8 : 4) * ptr->entry_count;
return GF_OK;
}
#endif
void prft_del(GF_Box *s)
{
gf_free(s);
}
GF_Err prft_Read(GF_Box *s,GF_BitStream *bs)
{
GF_ProducerReferenceTimeBox *ptr = (GF_ProducerReferenceTimeBox *) s;
ptr->refTrackID = gf_bs_read_u32(bs);
ptr->ntp = gf_bs_read_u64(bs);
if (ptr->version==0) {
ptr->timestamp = gf_bs_read_u32(bs);
} else {
ptr->timestamp = gf_bs_read_u64(bs);
}
return GF_OK;
}
GF_Box *prft_New()
{
ISOM_DECL_BOX_ALLOC(GF_ProducerReferenceTimeBox, GF_ISOM_BOX_TYPE_PRFT);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err prft_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_ProducerReferenceTimeBox *ptr = (GF_ProducerReferenceTimeBox *) s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->refTrackID);
gf_bs_write_u64(bs, ptr->ntp);
if (ptr->version==0) {
gf_bs_write_u32(bs, (u32) ptr->timestamp);
} else {
gf_bs_write_u64(bs, ptr->timestamp);
}
return GF_OK;
}
GF_Err prft_Size(GF_Box *s)
{
GF_ProducerReferenceTimeBox *ptr = (GF_ProducerReferenceTimeBox*)s;
ptr->size += 4+8+ (ptr->version ? 8 : 4);
return GF_OK;
}
#endif
GF_Box *trgr_New()
{
ISOM_DECL_BOX_ALLOC(GF_TrackGroupBox, GF_ISOM_BOX_TYPE_TRGR);
tmp->groups = gf_list_new();
if (!tmp->groups) {
gf_free(tmp);
return NULL;
}
return (GF_Box *)tmp;
}
void trgr_del(GF_Box *s)
{
GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s;
if (ptr == NULL) return;
gf_isom_box_array_del(ptr->groups);
gf_free(ptr);
}
GF_Err trgr_AddBox(GF_Box *s, GF_Box *a)
{
GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s;
return gf_list_add(ptr->groups, a);
}
GF_Err trgr_Read(GF_Box *s, GF_BitStream *bs)
{
return gf_isom_box_array_read_ex(s, bs, trgr_AddBox, s->type);
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err trgr_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_TrackGroupBox *ptr = (GF_TrackGroupBox *) s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_box_write_header(s, bs);
if (e) return e;
return gf_isom_box_array_write(s, ptr->groups, bs);
}
GF_Err trgr_Size(GF_Box *s)
{
GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s;
return gf_isom_box_array_size(s, ptr->groups);
}
#endif
GF_Box *trgt_New()
{
ISOM_DECL_BOX_ALLOC(GF_TrackGroupTypeBox, GF_ISOM_BOX_TYPE_TRGT);
return (GF_Box *)tmp;
}
void trgt_del(GF_Box *s)
{
GF_TrackGroupTypeBox *ptr = (GF_TrackGroupTypeBox *)s;
if (ptr == NULL) return;
gf_free(ptr);
}
GF_Err trgt_Read(GF_Box *s, GF_BitStream *bs)
{
GF_TrackGroupTypeBox *ptr = (GF_TrackGroupTypeBox *)s;
ptr->track_group_id = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, 4);
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err trgt_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_TrackGroupTypeBox *ptr = (GF_TrackGroupTypeBox *) s;
if (!s) return GF_BAD_PARAM;
s->type = ptr->group_type;
e = gf_isom_full_box_write(s, bs);
s->type = GF_ISOM_BOX_TYPE_TRGT;
if (e) return e;
gf_bs_write_u32(bs, ptr->track_group_id);
return GF_OK;
}
GF_Err trgt_Size(GF_Box *s)
{
GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s;
ptr->size+= 4;
return GF_OK;
}
#endif
GF_Box *stvi_New()
{
ISOM_DECL_BOX_ALLOC(GF_StereoVideoBox, GF_ISOM_BOX_TYPE_STVI);
return (GF_Box *)tmp;
}
void stvi_del(GF_Box *s)
{
GF_StereoVideoBox *ptr = (GF_StereoVideoBox *)s;
if (ptr == NULL) return;
if (ptr->stereo_indication_type) gf_free(ptr->stereo_indication_type);
gf_free(ptr);
}
GF_Err stvi_Read(GF_Box *s, GF_BitStream *bs)
{
GF_StereoVideoBox *ptr = (GF_StereoVideoBox *)s;
ISOM_DECREASE_SIZE(ptr, 12);
gf_bs_read_int(bs, 30);
ptr->single_view_allowed = gf_bs_read_int(bs, 2);
ptr->stereo_scheme = gf_bs_read_u32(bs);
ptr->sit_len = gf_bs_read_u32(bs);
ISOM_DECREASE_SIZE(ptr, ptr->sit_len);
ptr->stereo_indication_type = gf_malloc(sizeof(char)*ptr->sit_len);
gf_bs_read_data(bs, ptr->stereo_indication_type, ptr->sit_len);
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err stvi_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_StereoVideoBox *ptr = (GF_StereoVideoBox *) s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_int(bs, 0, 30);
gf_bs_write_int(bs, ptr->single_view_allowed, 2);
gf_bs_write_u32(bs, ptr->stereo_scheme);
gf_bs_write_u32(bs, ptr->sit_len);
gf_bs_write_data(bs, ptr->stereo_indication_type, ptr->sit_len);
return GF_OK;
}
GF_Err stvi_Size(GF_Box *s)
{
GF_StereoVideoBox *ptr = (GF_StereoVideoBox *)s;
ptr->size+= 12 + ptr->sit_len;
return GF_OK;
}
#endif
GF_Box *fiin_New()
{
ISOM_DECL_BOX_ALLOC(FDItemInformationBox, GF_ISOM_BOX_TYPE_FIIN);
return (GF_Box *)tmp;
}
void fiin_del(GF_Box *s)
{
FDItemInformationBox *ptr = (FDItemInformationBox *)s;
if (ptr == NULL) return;
if (ptr->partition_entries) gf_isom_box_array_del(ptr->partition_entries);
if (ptr->session_info) gf_isom_box_del((GF_Box*)ptr->session_info);
if (ptr->group_id_to_name) gf_isom_box_del((GF_Box*)ptr->group_id_to_name);
gf_free(ptr);
}
GF_Err fiin_AddBox(GF_Box *s, GF_Box *a)
{
FDItemInformationBox *ptr = (FDItemInformationBox *)s;
switch(a->type) {
case GF_ISOM_BOX_TYPE_PAEN:
if (!ptr->partition_entries) ptr->partition_entries = gf_list_new();
return gf_list_add(ptr->partition_entries, a);
case GF_ISOM_BOX_TYPE_SEGR:
if (ptr->session_info) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->session_info = (FDSessionGroupBox *)a;
return GF_OK;
case GF_ISOM_BOX_TYPE_GITN:
if (ptr->group_id_to_name) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->group_id_to_name = (GroupIdToNameBox *)a;
return GF_OK;
default:
return gf_isom_box_add_default(s, a);
}
return GF_OK;
}
GF_Err fiin_Read(GF_Box *s, GF_BitStream *bs)
{
FDItemInformationBox *ptr = (FDItemInformationBox *)s;
ISOM_DECREASE_SIZE(ptr, 2);
gf_bs_read_u16(bs);
return gf_isom_box_array_read(s, bs, fiin_AddBox);
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err fiin_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
FDItemInformationBox *ptr = (FDItemInformationBox *) s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u16(bs, gf_list_count(ptr->partition_entries) );
e = gf_isom_box_array_write(s, ptr->partition_entries, bs);
if (e) return e;
if (ptr->session_info) gf_isom_box_write((GF_Box*)ptr->session_info, bs);
if (ptr->group_id_to_name) gf_isom_box_write((GF_Box*)ptr->group_id_to_name, bs);
return GF_OK;
}
GF_Err fiin_Size(GF_Box *s)
{
GF_Err e;
FDItemInformationBox *ptr = (FDItemInformationBox *)s;
ptr->size+= 2;
if (ptr->partition_entries) {
e = gf_isom_box_array_size(s, ptr->partition_entries);
if (e) return e;
}
if (ptr->session_info) {
e = gf_isom_box_size((GF_Box *)ptr->session_info);
if (e) return e;
ptr->size += ptr->session_info->size;
}
if (ptr->group_id_to_name) {
e = gf_isom_box_size((GF_Box *) ptr->group_id_to_name);
if (e) return e;
ptr->size += ptr->group_id_to_name->size;
}
return GF_OK;
}
#endif
GF_Box *paen_New()
{
ISOM_DECL_BOX_ALLOC(FDPartitionEntryBox, GF_ISOM_BOX_TYPE_PAEN);
return (GF_Box *)tmp;
}
void paen_del(GF_Box *s)
{
FDPartitionEntryBox *ptr = (FDPartitionEntryBox *)s;
if (ptr == NULL) return;
if (ptr->blocks_and_symbols) gf_isom_box_del((GF_Box*)ptr->blocks_and_symbols);
if (ptr->FEC_symbol_locations) gf_isom_box_del((GF_Box*)ptr->FEC_symbol_locations);
if (ptr->File_symbol_locations) gf_isom_box_del((GF_Box*)ptr->File_symbol_locations);
gf_free(ptr);
}
GF_Err paen_AddBox(GF_Box *s, GF_Box *a)
{
FDPartitionEntryBox *ptr = (FDPartitionEntryBox *)s;
switch(a->type) {
case GF_ISOM_BOX_TYPE_FPAR:
if (ptr->blocks_and_symbols) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->blocks_and_symbols = (FilePartitionBox *)a;
return GF_OK;
case GF_ISOM_BOX_TYPE_FECR:
if (ptr->FEC_symbol_locations) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->FEC_symbol_locations = (FECReservoirBox *)a;
return GF_OK;
case GF_ISOM_BOX_TYPE_FIRE:
if (ptr->File_symbol_locations) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->File_symbol_locations = (FileReservoirBox *)a;
return GF_OK;
default:
return gf_isom_box_add_default(s, a);
}
return GF_OK;
}
GF_Err paen_Read(GF_Box *s, GF_BitStream *bs)
{
return gf_isom_box_array_read(s, bs, fiin_AddBox);
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err paen_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
FDPartitionEntryBox *ptr = (FDPartitionEntryBox *) s;
if (!s) return GF_BAD_PARAM;
if (ptr->blocks_and_symbols) {
e = gf_isom_box_write((GF_Box *)ptr->blocks_and_symbols, bs);
if (e) return e;
}
if (ptr->FEC_symbol_locations) {
e = gf_isom_box_write((GF_Box *)ptr->FEC_symbol_locations, bs);
if (e) return e;
}
if (ptr->File_symbol_locations) {
e = gf_isom_box_write((GF_Box *)ptr->File_symbol_locations, bs);
if (e) return e;
}
return GF_OK;
}
GF_Err paen_Size(GF_Box *s)
{
GF_Err e;
FDPartitionEntryBox *ptr = (FDPartitionEntryBox *)s;
if (ptr->blocks_and_symbols) {
e = gf_isom_box_size((GF_Box *)ptr->blocks_and_symbols);
if (e) return e;
ptr->size += ptr->blocks_and_symbols->size;
}
if (ptr->FEC_symbol_locations) {
e = gf_isom_box_size((GF_Box *) ptr->FEC_symbol_locations);
if (e) return e;
ptr->size += ptr->FEC_symbol_locations->size;
}
if (ptr->File_symbol_locations) {
e = gf_isom_box_size((GF_Box *) ptr->File_symbol_locations);
if (e) return e;
ptr->size += ptr->File_symbol_locations->size;
}
return GF_OK;
}
#endif
GF_Box *fpar_New()
{
ISOM_DECL_BOX_ALLOC(FilePartitionBox, GF_ISOM_BOX_TYPE_FPAR);
return (GF_Box *)tmp;
}
void fpar_del(GF_Box *s)
{
FilePartitionBox *ptr = (FilePartitionBox *)s;
if (ptr == NULL) return;
if (ptr->scheme_specific_info) gf_free(ptr->scheme_specific_info);
if (ptr->entries) gf_free(ptr->entries);
gf_free(ptr);
}
GF_Err gf_isom_read_null_terminated_string(GF_Box *s, GF_BitStream *bs, u32 size, char **out_str)
{
u32 len=10;
u32 i=0;
*out_str = gf_malloc(sizeof(char)*len);
while (1) {
ISOM_DECREASE_SIZE(s, 1 );
(*out_str)[i] = gf_bs_read_u8(bs);
if (!(*out_str)[i]) break;
i++;
if (i==len) {
len += 10;
*out_str = gf_realloc(*out_str, sizeof(char)*len);
}
if (gf_bs_available(bs) == 0) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] missing null character in null terminated string\n"));
(*out_str)[i] = 0;
return GF_OK;
}
if (i >= size) {
GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] string bigger than container, probably missing null character\n"));
(*out_str)[i] = 0;
return GF_OK;
}
}
return GF_OK;
}
GF_Err fpar_Read(GF_Box *s, GF_BitStream *bs)
{
u32 i;
GF_Err e;
FilePartitionBox *ptr = (FilePartitionBox *)s;
ISOM_DECREASE_SIZE(ptr, ((ptr->version ? 4 : 2) + 12) );
ptr->itemID = gf_bs_read_int(bs, ptr->version ? 32 : 16);
ptr->packet_payload_size = gf_bs_read_u16(bs);
gf_bs_read_u8(bs);
ptr->FEC_encoding_ID = gf_bs_read_u8(bs);
ptr->FEC_instance_ID = gf_bs_read_u16(bs);
ptr->max_source_block_length = gf_bs_read_u16(bs);
ptr->encoding_symbol_length = gf_bs_read_u16(bs);
ptr->max_number_of_encoding_symbols = gf_bs_read_u16(bs);
e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->scheme_specific_info);
if (e) return e;
ISOM_DECREASE_SIZE(ptr, (ptr->version ? 4 : 2) );
ptr->nb_entries = gf_bs_read_int(bs, ptr->version ? 32 : 16);
ISOM_DECREASE_SIZE(ptr, ptr->nb_entries * 6 );
GF_SAFE_ALLOC_N(ptr->entries, ptr->nb_entries, FilePartitionEntry);
for (i=0;i < ptr->nb_entries; i++) {
ptr->entries[i].block_count = gf_bs_read_u16(bs);
ptr->entries[i].block_size = gf_bs_read_u32(bs);
}
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err fpar_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
FilePartitionBox *ptr = (FilePartitionBox *) s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_int(bs, ptr->itemID, ptr->version ? 32 : 16);
gf_bs_write_u16(bs, ptr->packet_payload_size);
gf_bs_write_u8(bs, 0);
gf_bs_write_u8(bs, ptr->FEC_encoding_ID);
gf_bs_write_u16(bs, ptr->FEC_instance_ID);
gf_bs_write_u16(bs, ptr->max_source_block_length);
gf_bs_write_u16(bs, ptr->encoding_symbol_length);
gf_bs_write_u16(bs, ptr->max_number_of_encoding_symbols);
if (ptr->scheme_specific_info) {
gf_bs_write_data(bs, ptr->scheme_specific_info, (u32)strlen(ptr->scheme_specific_info) );
}
gf_bs_write_u8(bs, 0);
gf_bs_write_int(bs, ptr->nb_entries, ptr->version ? 32 : 16);
for (i=0;i < ptr->nb_entries; i++) {
gf_bs_write_u16(bs, ptr->entries[i].block_count);
gf_bs_write_u32(bs, ptr->entries[i].block_size);
}
return GF_OK;
}
GF_Err fpar_Size(GF_Box *s)
{
FilePartitionBox *ptr = (FilePartitionBox *)s;
ptr->size+= 13 + ptr->version ? 8 : 4;
if (ptr->scheme_specific_info)
ptr->size += strlen(ptr->scheme_specific_info);
ptr->size+= ptr->nb_entries * 6;
return GF_OK;
}
#endif
GF_Box *fecr_New()
{
ISOM_DECL_BOX_ALLOC(FECReservoirBox, GF_ISOM_BOX_TYPE_FECR);
return (GF_Box *)tmp;
}
void fecr_del(GF_Box *s)
{
FECReservoirBox *ptr = (FECReservoirBox *)s;
if (ptr == NULL) return;
if (ptr->entries) gf_free(ptr->entries);
gf_free(ptr);
}
GF_Err fecr_Read(GF_Box *s, GF_BitStream *bs)
{
u32 i;
FECReservoirBox *ptr = (FECReservoirBox *)s;
ISOM_DECREASE_SIZE(ptr, (ptr->version ? 4 : 2) );
ptr->nb_entries = gf_bs_read_int(bs, ptr->version ? 32 : 16);
ISOM_DECREASE_SIZE(ptr, ptr->nb_entries * (ptr->version ? 8 : 6) );
GF_SAFE_ALLOC_N(ptr->entries, ptr->nb_entries, FECReservoirEntry);
for (i=0; i<ptr->nb_entries; i++) {
ptr->entries[i].item_id = gf_bs_read_int(bs, ptr->version ? 32 : 16);
ptr->entries[i].symbol_count = gf_bs_read_u32(bs);
}
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err fecr_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
FECReservoirBox *ptr = (FECReservoirBox *) s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_int(bs, ptr->nb_entries, ptr->version ? 32 : 16);
for (i=0; i<ptr->nb_entries; i++) {
gf_bs_write_int(bs, ptr->entries[i].item_id, ptr->version ? 32 : 16);
gf_bs_write_u32(bs, ptr->entries[i].symbol_count);
}
return GF_OK;
}
GF_Err fecr_Size(GF_Box *s)
{
FECReservoirBox *ptr = (FECReservoirBox *)s;
ptr->size += (ptr->version ? 4 : 2) + ptr->nb_entries * (ptr->version ? 8 : 6);
return GF_OK;
}
#endif
GF_Box *segr_New()
{
ISOM_DECL_BOX_ALLOC(FDSessionGroupBox, GF_ISOM_BOX_TYPE_SEGR);
return (GF_Box *)tmp;
}
void segr_del(GF_Box *s)
{
u32 i;
FDSessionGroupBox *ptr = (FDSessionGroupBox *)s;
if (ptr == NULL) return;
for (i=0; i<ptr->num_session_groups; i++) {
if (ptr->session_groups[i].group_ids) gf_free(ptr->session_groups[i].group_ids);
if (ptr->session_groups[i].channels) gf_free(ptr->session_groups[i].channels);
}
if (ptr->session_groups) gf_free(ptr->session_groups);
gf_free(ptr);
}
GF_Err segr_Read(GF_Box *s, GF_BitStream *bs)
{
u32 i, k;
FDSessionGroupBox *ptr = (FDSessionGroupBox *)s;
ISOM_DECREASE_SIZE(ptr, 2);
ptr->num_session_groups = gf_bs_read_u16(bs);
if (ptr->num_session_groups*3>ptr->size) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in segr\n", ptr->num_session_groups));
return GF_ISOM_INVALID_FILE;
}
GF_SAFE_ALLOC_N(ptr->session_groups, ptr->num_session_groups, SessionGroupEntry);
for (i=0; i<ptr->num_session_groups; i++) {
ptr->session_groups[i].nb_groups = gf_bs_read_u8(bs);
ISOM_DECREASE_SIZE(ptr, 1);
GF_SAFE_ALLOC_N(ptr->session_groups[i].group_ids, ptr->session_groups[i].nb_groups, u32);
for (k=0; k<ptr->session_groups[i].nb_groups; k++) {
ISOM_DECREASE_SIZE(ptr, 4);
ptr->session_groups[i].group_ids[k] = gf_bs_read_u32(bs);
}
ptr->session_groups[i].nb_channels = gf_bs_read_u16(bs);
GF_SAFE_ALLOC_N(ptr->session_groups[i].channels, ptr->session_groups[i].nb_channels, u32);
for (k=0; k<ptr->session_groups[i].nb_channels; k++) {
ISOM_DECREASE_SIZE(ptr, 4);
ptr->session_groups[i].channels[k] = gf_bs_read_u32(bs);
}
}
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err segr_Write(GF_Box *s, GF_BitStream *bs)
{
u32 i, k;
FDSessionGroupBox *ptr = (FDSessionGroupBox *) s;
if (!s) return GF_BAD_PARAM;
gf_bs_write_u16(bs, ptr->num_session_groups);
for (i=0; i<ptr->num_session_groups; i++) {
gf_bs_write_u8(bs, ptr->session_groups[i].nb_groups);
for (k=0; k<ptr->session_groups[i].nb_groups; k++) {
gf_bs_write_u32(bs, ptr->session_groups[i].group_ids[k]);
}
gf_bs_write_u16(bs, ptr->session_groups[i].nb_channels);
for (k=0; k<ptr->session_groups[i].nb_channels; k++) {
gf_bs_write_u32(bs, ptr->session_groups[i].channels[k]);
}
}
return GF_OK;
}
GF_Err segr_Size(GF_Box *s)
{
u32 i;
FDSessionGroupBox *ptr = (FDSessionGroupBox *)s;
ptr->size += 2;
for (i=0; i<ptr->num_session_groups; i++) {
ptr->size += 1 + 4*ptr->session_groups[i].nb_groups;
ptr->size += 2 + 4*ptr->session_groups[i].nb_channels;
}
return GF_OK;
}
#endif
GF_Box *gitn_New()
{
ISOM_DECL_BOX_ALLOC(GroupIdToNameBox, GF_ISOM_BOX_TYPE_GITN);
return (GF_Box *)tmp;
}
void gitn_del(GF_Box *s)
{
u32 i;
GroupIdToNameBox *ptr = (GroupIdToNameBox *)s;
if (ptr == NULL) return;
for (i=0; i<ptr->nb_entries; i++) {
if (ptr->entries[i].name) gf_free(ptr->entries[i].name);
}
if (ptr->entries) gf_free(ptr->entries);
gf_free(ptr);
}
GF_Err gitn_Read(GF_Box *s, GF_BitStream *bs)
{
u32 i;
GF_Err e;
GroupIdToNameBox *ptr = (GroupIdToNameBox *)s;
ISOM_DECREASE_SIZE(ptr, 2);
ptr->nb_entries = gf_bs_read_u16(bs);
GF_SAFE_ALLOC_N(ptr->entries, ptr->nb_entries, GroupIdNameEntry);
for (i=0; i<ptr->nb_entries; i++) {
ISOM_DECREASE_SIZE(ptr, 4);
ptr->entries[i].group_id = gf_bs_read_u32(bs);
e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->entries[i].name);
if (e) return e;
}
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err gitn_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GroupIdToNameBox *ptr = (GroupIdToNameBox *) s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u16(bs, ptr->nb_entries);
for (i=0; i<ptr->nb_entries; i++) {
gf_bs_write_u32(bs, ptr->entries[i].group_id);
if (ptr->entries[i].name) gf_bs_write_data(bs, ptr->entries[i].name, (u32)strlen(ptr->entries[i].name) );
gf_bs_write_u8(bs, 0);
}
return GF_OK;
}
GF_Err gitn_Size(GF_Box *s)
{
u32 i;
GroupIdToNameBox *ptr = (GroupIdToNameBox *)s;
ptr->size += 2;
for (i=0; i<ptr->nb_entries; i++) {
ptr->size += 5;
if (ptr->entries[i].name) ptr->size += strlen(ptr->entries[i].name);
}
return GF_OK;
}
#endif
#ifndef GPAC_DISABLE_ISOM_HINTING
GF_Box *fdpa_New()
{
ISOM_DECL_BOX_ALLOC(GF_FDpacketBox, GF_ISOM_BOX_TYPE_FDPA);
return (GF_Box *)tmp;
}
void fdpa_del(GF_Box *s)
{
u32 i;
GF_FDpacketBox *ptr = (GF_FDpacketBox *)s;
if (ptr == NULL) return;
if (ptr->headers) {
for (i=0; i<ptr->header_ext_count; i++) {
if (ptr->headers[i].data) gf_free(ptr->headers[i].data);
}
gf_free(ptr->headers);
}
gf_free(ptr);
}
GF_Err fdpa_Read(GF_Box *s, GF_BitStream *bs)
{
u32 i;
GF_FDpacketBox *ptr = (GF_FDpacketBox *)s;
ISOM_DECREASE_SIZE(ptr, 3);
ptr->info.sender_current_time_present = gf_bs_read_int(bs, 1);
ptr->info.expected_residual_time_present = gf_bs_read_int(bs, 1);
ptr->info.session_close_bit = gf_bs_read_int(bs, 1);
ptr->info.object_close_bit = gf_bs_read_int(bs, 1);
gf_bs_read_int(bs, 4);
ptr->info.transport_object_identifier = gf_bs_read_u16(bs);
ISOM_DECREASE_SIZE(ptr, 2);
ptr->header_ext_count = gf_bs_read_u16(bs);
if (ptr->header_ext_count*2>ptr->size) {
GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in fdpa\n", ptr->header_ext_count));
return GF_ISOM_INVALID_FILE;
}
GF_SAFE_ALLOC_N(ptr->headers, ptr->header_ext_count, GF_LCTheaderExtension);
for (i=0; i<ptr->header_ext_count; i++) {
ptr->headers[i].header_extension_type = gf_bs_read_u8(bs);
ISOM_DECREASE_SIZE(ptr, 1);
if (ptr->headers[i].header_extension_type > 127) {
gf_bs_read_data(bs, (char *) ptr->headers[i].content, 3);
} else {
ISOM_DECREASE_SIZE(ptr, 1);
ptr->headers[i].data_length = gf_bs_read_u8(bs);
if (ptr->headers[i].data_length) {
ptr->headers[i].data_length = 4*ptr->headers[i].data_length - 2;
ptr->headers[i].data = gf_malloc(sizeof(char) * ptr->headers[i].data_length);
gf_bs_read_data(bs, ptr->headers[i].data, ptr->headers[i].data_length);
}
}
}
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err fdpa_Write(GF_Box *s, GF_BitStream *bs)
{
u32 i;
GF_FDpacketBox *ptr = (GF_FDpacketBox *) s;
if (!s) return GF_BAD_PARAM;
gf_bs_write_int(bs, ptr->info.sender_current_time_present, 1);
gf_bs_write_int(bs, ptr->info.expected_residual_time_present, 1);
gf_bs_write_int(bs, ptr->info.session_close_bit, 1);
gf_bs_write_int(bs, ptr->info.object_close_bit, 1);
gf_bs_write_int(bs, 0, 4);
ptr->info.transport_object_identifier = gf_bs_read_u16(bs);
gf_bs_write_u16(bs, ptr->header_ext_count);
for (i=0; i<ptr->header_ext_count; i++) {
gf_bs_write_u8(bs, ptr->headers[i].header_extension_type);
if (ptr->headers[i].header_extension_type > 127) {
gf_bs_write_data(bs, (const char *) ptr->headers[i].content, 3);
} else {
gf_bs_write_u8(bs, ptr->headers[i].data_length ? (ptr->headers[i].data_length+2)/4 : 0);
if (ptr->headers[i].data_length) {
gf_bs_write_data(bs, ptr->headers[i].data, ptr->headers[i].data_length);
}
}
}
return GF_OK;
}
GF_Err fdpa_Size(GF_Box *s)
{
u32 i;
GF_FDpacketBox *ptr = (GF_FDpacketBox *)s;
ptr->size += 5;
for (i=0; i<ptr->header_ext_count; i++) {
ptr->size += 1;
if (ptr->headers[i].header_extension_type > 127) {
ptr->size += 3;
} else {
ptr->size += 1 + ptr->headers[i].data_length;
}
}
return GF_OK;
}
#endif
GF_Box *extr_New()
{
ISOM_DECL_BOX_ALLOC(GF_ExtraDataBox, GF_ISOM_BOX_TYPE_EXTR);
return (GF_Box *)tmp;
}
void extr_del(GF_Box *s)
{
GF_ExtraDataBox *ptr = (GF_ExtraDataBox *)s;
if (ptr == NULL) return;
if (ptr->feci) gf_isom_box_del((GF_Box*)ptr->feci);
if (ptr->data) gf_free(ptr->data);
gf_free(ptr);
}
GF_Err extr_Read(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_ExtraDataBox *ptr = (GF_ExtraDataBox *)s;
e = gf_isom_box_parse((GF_Box**) &ptr->feci, bs);
if (e) return e;
if (ptr->feci->size>ptr->size) return GF_ISOM_INVALID_MEDIA;
ptr->data_length = (u32) (ptr->size - ptr->feci->size);
ptr->data = gf_malloc(sizeof(char)*ptr->data_length);
gf_bs_read_data(bs, ptr->data, ptr->data_length);
return GF_OK;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err extr_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_ExtraDataBox *ptr = (GF_ExtraDataBox *) s;
if (!s) return GF_BAD_PARAM;
if (ptr->feci) {
e = gf_isom_box_write((GF_Box *)ptr->feci, bs);
if (e) return e;
}
gf_bs_write_data(bs, ptr->data, ptr->data_length);
return GF_OK;
}
GF_Err extr_Size(GF_Box *s)
{
GF_Err e;
GF_ExtraDataBox *ptr = (GF_ExtraDataBox *) s;
if (ptr->feci) {
e = gf_isom_box_size((GF_Box *)ptr->feci);
if (e) return e;
ptr->size += ptr->feci->size;
}
ptr->size += ptr->data_length;
return GF_OK;
}
#endif
GF_Box *fdsa_New()
{
ISOM_DECL_BOX_ALLOC(GF_HintSample, GF_ISOM_BOX_TYPE_FDSA);
if (!tmp) return NULL;
tmp->packetTable = gf_list_new();
tmp->hint_subtype = GF_ISOM_BOX_TYPE_FDP_STSD;
return (GF_Box*)tmp;
}
void fdsa_del(GF_Box *s)
{
GF_HintSample *ptr = (GF_HintSample *)s;
gf_isom_box_array_del(ptr->packetTable);
if (ptr->extra_data) gf_isom_box_del((GF_Box*)ptr->extra_data);
gf_free(ptr);
}
GF_Err fdsa_AddBox(GF_Box *s, GF_Box *a)
{
GF_HintSample *ptr = (GF_HintSample *)s;
switch(a->type) {
case GF_ISOM_BOX_TYPE_FDPA:
gf_list_add(ptr->packetTable, a);
break;
case GF_ISOM_BOX_TYPE_EXTR:
if (ptr->extra_data) ERROR_ON_DUPLICATED_BOX(a, ptr)
ptr->extra_data = (GF_ExtraDataBox*)a;
break;
default:
return gf_isom_box_add_default(s, a);
}
return GF_OK;
}
GF_Err fdsa_Read(GF_Box *s, GF_BitStream *bs)
{
return gf_isom_box_array_read(s, bs, fdsa_AddBox);
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err fdsa_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_HintSample *ptr = (GF_HintSample *) s;
if (!s) return GF_BAD_PARAM;
e = gf_isom_box_array_write(s, ptr->packetTable, bs);
if (e) return e;
if (ptr->extra_data) {
e = gf_isom_box_write((GF_Box *)ptr->extra_data, bs);
if (e) return e;
}
return GF_OK;
}
GF_Err fdsa_Size(GF_Box *s)
{
GF_HintSample *ptr = (GF_HintSample*)s;
GF_Err e;
if (ptr->extra_data) {
e = gf_isom_box_size((GF_Box *)ptr->extra_data);
if (e) return e;
ptr->size += ptr->extra_data->size;
}
return gf_isom_box_array_size(s, ptr->packetTable);
}
#endif
#endif
void trik_del(GF_Box *s)
{
GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s;
if (ptr == NULL) return;
if (ptr->entries) gf_free(ptr->entries);
gf_free(ptr);
}
GF_Err trik_Read(GF_Box *s,GF_BitStream *bs)
{
u32 i;
GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s;
ptr->entry_count = (u32) ptr->size;
ptr->entries = (GF_TrickPlayBoxEntry *) gf_malloc(ptr->entry_count * sizeof(GF_TrickPlayBoxEntry) );
if (ptr->entries == NULL) return GF_OUT_OF_MEM;
for (i=0; i< ptr->entry_count; i++) {
ptr->entries[i].pic_type = gf_bs_read_int(bs, 2);
ptr->entries[i].dependency_level = gf_bs_read_int(bs, 6);
}
return GF_OK;
}
GF_Box *trik_New()
{
ISOM_DECL_BOX_ALLOC(GF_TrickPlayBox, GF_ISOM_BOX_TYPE_TRIK);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err trik_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
for (i=0; i < ptr->entry_count; i++ ) {
gf_bs_write_int(bs, ptr->entries[i].pic_type, 2);
gf_bs_write_int(bs, ptr->entries[i].dependency_level, 6);
}
return GF_OK;
}
GF_Err trik_Size(GF_Box *s)
{
GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s;
ptr->size += 8 * ptr->entry_count;
return GF_OK;
}
#endif
void bloc_del(GF_Box *s)
{
gf_free(s);
}
GF_Err bloc_Read(GF_Box *s,GF_BitStream *bs)
{
GF_BaseLocationBox *ptr = (GF_BaseLocationBox *) s;
ISOM_DECREASE_SIZE(s, 256)
gf_bs_read_data(bs, (char *) ptr->baseLocation, 256);
ISOM_DECREASE_SIZE(s, 256)
gf_bs_read_data(bs, (char *) ptr->basePurlLocation, 256);
ISOM_DECREASE_SIZE(s, 512)
gf_bs_skip_bytes(bs, 512);
return GF_OK;
}
GF_Box *bloc_New()
{
ISOM_DECL_BOX_ALLOC(GF_BaseLocationBox, GF_ISOM_BOX_TYPE_TRIK);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err bloc_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
u32 i;
GF_BaseLocationBox *ptr = (GF_BaseLocationBox *) s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_data(bs, (const char *) ptr->baseLocation, 256);
gf_bs_write_data(bs, (const char *) ptr->basePurlLocation, 256);
for (i=0; i < 64; i++ ) {
gf_bs_write_u64(bs, 0);
}
return GF_OK;
}
GF_Err bloc_Size(GF_Box *s)
{
s->size += 1024;
return GF_OK;
}
#endif
void ainf_del(GF_Box *s)
{
GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s;
if (ptr->APID) gf_free(ptr->APID);
gf_free(s);
}
GF_Err ainf_Read(GF_Box *s,GF_BitStream *bs)
{
GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s;
ISOM_DECREASE_SIZE(s, 4)
ptr->profile_version = gf_bs_read_u32(bs);
return gf_isom_read_null_terminated_string(s, bs, s->size, &ptr->APID);
}
GF_Box *ainf_New()
{
ISOM_DECL_BOX_ALLOC(GF_AssetInformationBox, GF_ISOM_BOX_TYPE_AINF);
return (GF_Box *)tmp;
}
#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err ainf_Write(GF_Box *s, GF_BitStream *bs)
{
GF_Err e;
GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s;
e = gf_isom_full_box_write(s, bs);
if (e) return e;
gf_bs_write_u32(bs, ptr->profile_version);
gf_bs_write_data(bs, ptr->APID, (u32) strlen(ptr->APID) + 1);
return GF_OK;
}
GF_Err ainf_Size(GF_Box *s)
{
GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s;
s->size += 4 + strlen(ptr->APID) + 1;
return GF_OK;
}
#endif
#endif