GF_EXPORT void gf_oci_event_del(OCIEvent *event) { GF_Descriptor *desc; if (!event) return; while (gf_list_count(event->OCIDescriptors)) { desc = (GF_Descriptor *)gf_list_get(event->OCIDescriptors, 0); gf_list_rem(event->OCIDescriptors, 0); gf_odf_delete_descriptor(desc); } gf_list_del(event->OCIDescriptors); gf_free(event); }
GF_Err gf_odf_delete_descriptor_list(GF_List *descList) { GF_Err e; GF_Descriptor*tmp; u32 i; //no error if NULL chain... if (! descList) return GF_OK; i=0; while ((tmp = (GF_Descriptor*)gf_list_enum(descList, &i))) { e = gf_odf_delete_descriptor(tmp); if (e) return e; } gf_list_del(descList); return GF_OK; }
GF_Err gf_odf_del_ipmp_update(GF_IPMPUpdate *IPMPDUpdate) { GF_Err e; if (!IPMPDUpdate) return GF_BAD_PARAM; while (gf_list_count(IPMPDUpdate->IPMPDescList)) { GF_Descriptor *tmp = (GF_Descriptor*)gf_list_get(IPMPDUpdate->IPMPDescList, 0); e = gf_odf_delete_descriptor(tmp); if (e) return e; e = gf_list_rem(IPMPDUpdate->IPMPDescList, 0); if (e) return e; } gf_list_del(IPMPDUpdate->IPMPDescList); gf_free(IPMPDUpdate); return GF_OK; }
GF_Err AddToESDUpdate(GF_ESDUpdate *esdUp, GF_Descriptor *desc) { if (!esdUp) return GF_BAD_PARAM; if (!desc) return GF_OK; switch (desc->tag) { case GF_ODF_ESD_TAG: case GF_ODF_ESD_REF_TAG: return gf_list_add(esdUp->ESDescriptors, desc); default: gf_odf_delete_descriptor(desc); return GF_OK; } }
GF_Err gf_odf_del_esd_update(GF_ESDUpdate *ESDUpdate) { GF_Err e; if (!ESDUpdate) return GF_BAD_PARAM; while (gf_list_count(ESDUpdate->ESDescriptors)) { GF_Descriptor *tmp = (GF_Descriptor*)gf_list_get(ESDUpdate->ESDescriptors, 0); e = gf_odf_delete_descriptor(tmp); if (e) return e; e = gf_list_rem(ESDUpdate->ESDescriptors, 0); if (e) return e; } gf_list_del(ESDUpdate->ESDescriptors); gf_free(ESDUpdate); return GF_OK; }
GF_Err gf_odf_del_od_update(GF_ODUpdate *ODUpdate) { GF_Err e; if (!ODUpdate) return GF_BAD_PARAM; while (gf_list_count(ODUpdate->objectDescriptors)) { GF_Descriptor *tmp = (GF_Descriptor*)gf_list_get(ODUpdate->objectDescriptors, 0); e = gf_odf_delete_descriptor(tmp); if (e) return e; e = gf_list_rem(ODUpdate->objectDescriptors, 0); if (e) return e; } gf_list_del(ODUpdate->objectDescriptors); gf_free(ODUpdate); return GF_OK; }
//this functions will destroy the descriptors in a list but not the list GF_EXPORT GF_Err gf_odf_desc_list_del(GF_List *descList) { GF_Err e; GF_Descriptor *tmp; if (!descList) return GF_BAD_PARAM; while (gf_list_count(descList)) { tmp = (GF_Descriptor*)gf_list_get(descList, 0); gf_list_rem(descList, 0); e = gf_odf_delete_descriptor(tmp); if (e) return e; } return GF_OK; }
GF_Err AddToODUpdate(GF_ODUpdate *odUp, GF_Descriptor *desc) { if (!odUp) return GF_BAD_PARAM; if (!desc) return GF_OK; switch (desc->tag) { case GF_ODF_OD_TAG: case GF_ODF_IOD_TAG: case GF_ODF_ISOM_IOD_TAG: case GF_ODF_ISOM_OD_TAG: return gf_list_add(odUp->objectDescriptors, desc); default: gf_odf_delete_descriptor(desc); return GF_OK; } }
// ... and to delete it GF_EXPORT void gf_odf_desc_del(GF_Descriptor *desc) { if (desc) gf_odf_delete_descriptor(desc); }
GF_EXPORT GF_Err gf_oci_codec_decode(OCICodec *codec, char *au, u32 au_length) { OCIEvent *ev; GF_BitStream *bs; u32 size, hdrS, desc_size, tot_size, tmp_size, val; GF_Descriptor *tmp; GF_Err e; //must be decoder if (!codec || codec->Mode || !au) return GF_BAD_PARAM; bs = gf_bs_new(au, au_length, GF_BITSTREAM_READ); ev = 0; tot_size = 0; while (tot_size < au_length) { //create an event ev = gf_oci_event_new(0); if (!ev) { e = GF_OUT_OF_MEM; goto err_exit; } //FIX IM1 gf_bs_read_int(bs, 8); size = 0; //get its size hdrS = 0; do { val = gf_bs_read_int(bs, 8); hdrS += 1; size <<= 7; size |= val & 0x7F; } while ( val & 0x80 ); //parse event vars ev->EventID = gf_bs_read_int(bs, 15); ev->AbsoluteTimeFlag = gf_bs_read_int(bs, 1); gf_bs_read_data(bs, ev->StartingTime, 4); gf_bs_read_data(bs, ev->duration, 4); desc_size = 0; //parse descriptor list while (desc_size < size - 10) { e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size); //RE-FIX IM1 if (e || !tmp) goto err_exit; if (!OCI_IsOCIDesc(tmp)) { gf_odf_delete_descriptor(tmp); e = GF_ODF_INVALID_DESCRIPTOR; goto err_exit; } gf_list_add(ev->OCIDescriptors, tmp); desc_size += tmp_size + gf_odf_size_field_size(tmp_size); } if (desc_size != size - 10) { e = GF_CORRUPTED_DATA; goto err_exit; } gf_list_add(codec->OCIEvents, ev); //FIX IM1 size += 1; tot_size += size + hdrS; ev = NULL; } if (tot_size != au_length) { e = GF_CORRUPTED_DATA; goto err_exit; } gf_bs_del(bs); return GF_OK; err_exit: gf_bs_del(bs); if (ev) gf_oci_event_del(ev); //delete everything while (gf_list_count(codec->OCIEvents)) { ev = (OCIEvent *)gf_list_get(codec->OCIEvents, 0); gf_list_rem(codec->OCIEvents, 0); gf_oci_event_del(ev); } return e; }
GF_EXPORT GF_Err gf_odf_parse_descriptor(GF_BitStream *bs, GF_Descriptor **desc, u32 *desc_size) { u32 val, size, sizeHeader; u8 tag; GF_Err err; GF_Descriptor *newDesc; if (!bs) return GF_BAD_PARAM; *desc_size = 0; //tag tag = (u8) gf_bs_read_int(bs, 8); sizeHeader = 1; //size size = 0; do { val = gf_bs_read_int(bs, 8); sizeHeader++; size <<= 7; size |= val & 0x7F; } while ( val & 0x80); *desc_size = size; GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[ODF] Reading descriptor (tag %d size %d)\n", tag, size )); newDesc = gf_odf_create_descriptor(tag); if (! newDesc) { *desc = NULL; *desc_size = sizeHeader; if ( (tag >= GF_ODF_ISO_RES_BEGIN_TAG) && (tag <= GF_ODF_ISO_RES_END_TAG) ) { return GF_ODF_FORBIDDEN_DESCRIPTOR; } else if (!tag || (tag == 0xFF)) { return GF_ODF_INVALID_DESCRIPTOR; } #ifndef GPAC_MINIMAL_ODF return GF_OUT_OF_MEM; #else gf_bs_skip_bytes(bs, size); *desc_size = size + sizeHeader - gf_odf_size_field_size(*desc_size); return GF_OK; #endif } newDesc->tag = tag; err = gf_odf_read_descriptor(bs, newDesc, *desc_size); /*FFMPEG fix*/ if ((tag==GF_ODF_SLC_TAG) && (((GF_SLConfig*)newDesc)->predefined==2)) { if (*desc_size==3) { *desc_size = 1; err = GF_OK; } } //little trick to handle lazy bitstreams that encode //SizeOfInstance on a fix number of bytes //This nb of bytes is added in Read methods *desc_size += sizeHeader - gf_odf_size_field_size(*desc_size); *desc = newDesc; if (err) { GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[ODF] Error reading descriptor (tag %d size %d): %s\n", tag, size, gf_error_to_string(err) )); gf_odf_delete_descriptor(newDesc); *desc = NULL; } return err; }