// // Reader // M4Err ReadOD(BitStream *bs, ObjectDescriptor *od, u32 DescSize) { M4Err e; u32 reserved, urlflag; u32 tmpSize, nbBytes = 0; if (! od) return M4BadParam; od->objectDescriptorID = BS_ReadInt(bs, 10); urlflag = BS_ReadInt(bs, 1); reserved = BS_ReadInt(bs, 5); nbBytes += 2; if (urlflag) { e = OD_ReadString(bs, & od->URLString, 1); if (e) return e; nbBytes += strlen(od->URLString) + 1; } while (nbBytes < DescSize) { Descriptor *tmp = NULL; e = ParseDescriptor(bs, &tmp, &tmpSize); if (e) return e; if (!tmp) return M4ReadDescriptorFailed; e = AddDescriptorToOD(od, tmp); if (e) return e; nbBytes += tmpSize + GetSizeFieldSize(tmpSize); } if (nbBytes != DescSize) return M4ReadDescriptorFailed; return M4OK; }
//This functions handles internally what desc can be added to another desc //and adds it. NO DUPLICATION of the descriptor, so //once a desc is added to its parent, destroying the parent WILL destroy this desc GF_EXPORT GF_Err gf_odf_desc_add_desc(GF_Descriptor *parentDesc, GF_Descriptor *newDesc) { GF_DecoderConfig *dcd; //our ADD definition GF_Err AddDescriptorToOD(GF_ObjectDescriptor *od, GF_Descriptor *desc); GF_Err AddDescriptorToIOD(GF_InitialObjectDescriptor *iod, GF_Descriptor *desc); GF_Err AddDescriptorToESD(GF_ESD *esd, GF_Descriptor *desc); GF_Err AddDescriptorToIsomIOD(GF_IsomInitialObjectDescriptor *iod, GF_Descriptor *desc); GF_Err AddDescriptorToIsomOD(GF_IsomObjectDescriptor *od, GF_Descriptor *desc); if (!parentDesc || !newDesc) return GF_BAD_PARAM; switch (parentDesc->tag) { //these are container descriptors case GF_ODF_OD_TAG: return AddDescriptorToOD((GF_ObjectDescriptor *)parentDesc, newDesc); case GF_ODF_IOD_TAG: return AddDescriptorToIOD((GF_InitialObjectDescriptor *)parentDesc, newDesc); case GF_ODF_ESD_TAG: return AddDescriptorToESD((GF_ESD *)parentDesc, newDesc); case GF_ODF_DCD_TAG: dcd = (GF_DecoderConfig *)parentDesc; if ((newDesc->tag == GF_ODF_DSI_TAG) || (newDesc->tag == GF_ODF_BIFS_CFG_TAG) || (newDesc->tag == GF_ODF_UI_CFG_TAG) || (newDesc->tag == GF_ODF_TEXT_CFG_TAG) ) { if (dcd->decoderSpecificInfo) return GF_ODF_FORBIDDEN_DESCRIPTOR; dcd->decoderSpecificInfo = (GF_DefaultDescriptor *)newDesc; return GF_OK; } else if (newDesc->tag == GF_ODF_EXT_PL_TAG) { return gf_list_add(dcd->profileLevelIndicationIndexDescriptor, newDesc); } return GF_ODF_FORBIDDEN_DESCRIPTOR; case GF_ODF_TEXT_CFG_TAG: if (newDesc->tag != GF_ODF_TX3G_TAG) return GF_ODF_FORBIDDEN_DESCRIPTOR; return gf_list_add(((GF_TextConfig *)parentDesc)->sample_descriptions, newDesc); case GF_ODF_QOS_TAG: return GF_BAD_PARAM; //MP4 File Format tags case GF_ODF_ISOM_IOD_TAG: return AddDescriptorToIsomIOD((GF_IsomInitialObjectDescriptor *)parentDesc, newDesc); case GF_ODF_ISOM_OD_TAG: return AddDescriptorToIsomOD((GF_IsomObjectDescriptor *)parentDesc, newDesc); case GF_ODF_IPMP_TL_TAG: if (newDesc->tag != GF_ODF_IPMP_TOOL_TAG) return GF_BAD_PARAM; return gf_list_add(((GF_IPMP_ToolList *)parentDesc)->ipmp_tools, newDesc); case GF_ODF_BIFS_CFG_TAG: { GF_BIFSConfig *cfg = (GF_BIFSConfig *)parentDesc; if (newDesc->tag != GF_ODF_ELEM_MASK_TAG) return GF_BAD_PARAM; if (!cfg->elementaryMasks) cfg->elementaryMasks = gf_list_new(); return gf_list_add(cfg->elementaryMasks, newDesc); } default: return GF_ODF_FORBIDDEN_DESCRIPTOR; } }