📄 odf_codec.c
字号:
{ GF_Err e; char *desc; u32 size; //warning: here we get some data allocated e = gf_odf_desc_write(inDesc, &desc, &size); if (e) return e; e = gf_odf_desc_read(desc, size, outDesc); free(desc); return e;}/************************************************************ Object Descriptors Edit Functions************************************************************///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 descGF_EXPORTGF_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: //tricky: the QoS doesnot accept a descriptor but a qualifier. //We have another function for that... 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; }}/************************************************************ QoSQualifiers Functions************************************************************/GF_EXPORTGF_QoS_Default *gf_odf_qos_new(u8 tag){ GF_QoS_Default *NewQoS(u8 tag); GF_QoS_Default *qos; qos = NewQoS(tag); return qos;}GF_EXPORTGF_Err gf_odf_qos_del(GF_QoS_Default **qos){ if (*qos) gf_odf_delete_qos_qual(*qos); *qos = NULL; return GF_OK;}//same function, but for QoS, as a Qualifier IS NOT a descriptorGF_EXPORTGF_Err gf_odf_qos_add_qualif(GF_QoS_Descriptor *desc, GF_QoS_Default *qualif){ u32 i; GF_QoS_Default *def; if (desc->tag != GF_ODF_QOS_TAG) return GF_BAD_PARAM; if (desc->predefined) return GF_ODF_FORBIDDEN_DESCRIPTOR; i=0; while ((def = (GF_QoS_Default *)gf_list_enum(desc->QoS_Qualifiers, &i))) { //if same Qualifier, not allowed... if (def->tag == qualif->tag) return GF_ODF_FORBIDDEN_DESCRIPTOR; } return gf_list_add(desc->QoS_Qualifiers, qualif);}/***************************************************************************************** Since IPMP V2, we introduce a new set of functions to read / write a list of descriptors that have no containers (a bit like an OD command, but for descriptors) This is usefull for IPMPv2 DecoderSpecificInfo which contains a set of IPMP_Declarators. As it could be used for other purposes we keep it generic You must create the list yourself, the functions just encode/decode from/to the list*****************************************************************************************/GF_EXPORTGF_Err gf_odf_desc_list_read(char *raw_list, u32 raw_size, GF_List *descList){ GF_BitStream *bs; u32 size, desc_size; GF_Descriptor *desc; GF_Err e = GF_OK; if (!descList || !raw_list || !raw_size) return GF_BAD_PARAM; bs = gf_bs_new(raw_list, raw_size, GF_BITSTREAM_READ); if (!bs) return GF_OUT_OF_MEM; size = 0; while (size < raw_size) { e = gf_odf_parse_descriptor(bs, &desc, &desc_size); if (e) goto exit; gf_list_add(descList, desc); size += desc_size + gf_odf_size_field_size(desc_size); }exit: //then delete our bitstream gf_bs_del(bs); if (size != raw_size) e = GF_ODF_INVALID_DESCRIPTOR; return e;}GF_EXPORTGF_Err gf_odf_desc_list_write(GF_List *descList, char **outEncList, u32 *outSize){ GF_BitStream *bs; GF_Err e; if (!descList || !outEncList || *outEncList || !outSize) return GF_BAD_PARAM; *outSize = 0; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); if (!bs) return GF_OUT_OF_MEM; e = gf_odf_write_descriptor_list(bs, descList); if (e) { gf_bs_del(bs); return e; } gf_bs_get_content(bs, outEncList, outSize); gf_bs_del(bs); return GF_OK;}GF_EXPORTGF_Err gf_odf_desc_list_size(GF_List *descList, u32 *outSize){ return gf_odf_size_descriptor_list(descList, outSize);}//this functions will destroy the descriptors in a list but not the listGF_EXPORTGF_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_EXPORTGF_ESD *gf_odf_desc_esd_new(u32 sl_predefined){ GF_ESD *esd; esd = (GF_ESD *) gf_odf_desc_new(GF_ODF_ESD_TAG); esd->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG); esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); esd->slConfig = (GF_SLConfig *) gf_odf_new_slc((u8) sl_predefined); return esd;}GF_Err gf_odf_codec_apply_com(GF_ODCodec *codec, GF_ODCom *command){ GF_ODCom *com; GF_ODUpdate *odU, *odU_o; u32 i, count; count = gf_list_count(codec->CommandList); switch (command->tag) { case GF_ODF_OD_REMOVE_TAG: for (i=0; i<count; i++) { com = (GF_ODCom *)gf_list_get(codec->CommandList, i); /*process OD updates*/ if (com->tag==GF_ODF_OD_UPDATE_TAG) { u32 count, j, k; GF_ODRemove *odR = (GF_ODRemove *) command; odU = (GF_ODUpdate *)com; count = gf_list_count(odU->objectDescriptors); /*remove all descs*/ for (k=0; k<count; k++) { GF_ObjectDescriptor *od = (GF_ObjectDescriptor *)gf_list_get(odU->objectDescriptors, k); for (j=0; j<odR->NbODs; j++) { if (od->objectDescriptorID==odR->OD_ID[j]) { gf_list_rem(odU->objectDescriptors, k); k--; count--; gf_odf_desc_del((GF_Descriptor *)od); break; } } } if (!gf_list_count(odU->objectDescriptors)) { gf_list_rem(codec->CommandList, i); i--; count--; } } /*process ESD updates*/ else if (com->tag==GF_ODF_ESD_UPDATE_TAG) { u32 j; GF_ODRemove *odR = (GF_ODRemove *) command; GF_ESDUpdate *esdU = (GF_ESDUpdate*)com; for (j=0; j<odR->NbODs; j++) { if (esdU->ODID==odR->OD_ID[j]) { gf_list_rem(codec->CommandList, i); i--; count--; gf_odf_com_del((GF_ODCom**)&esdU); break; } } } } return GF_OK; case GF_ODF_OD_UPDATE_TAG: odU_o = NULL; for (i=0; i<count; i++) { odU_o = (GF_ODUpdate*)gf_list_get(codec->CommandList, i); /*process OD updates*/ if (odU_o->tag==GF_ODF_OD_UPDATE_TAG) break; odU_o = NULL; } if (!odU_o) { odU_o = (GF_ODUpdate *)gf_odf_com_new(GF_ODF_OD_UPDATE_TAG); gf_list_add(codec->CommandList, odU_o); } odU = (GF_ODUpdate*)command; count = gf_list_count(odU->objectDescriptors); for (i=0; i<count; i++) { Bool found = 0; GF_ObjectDescriptor *od = (GF_ObjectDescriptor *)gf_list_get(odU->objectDescriptors, i); u32 j, count2 = gf_list_count(odU_o->objectDescriptors); for (j=0; j<count2; j++) { GF_ObjectDescriptor *od2 = (GF_ObjectDescriptor *)gf_list_get(odU_o->objectDescriptors, j); if (od2->objectDescriptorID==od->objectDescriptorID) { found = 1; break; } } if (!found) { GF_ObjectDescriptor *od_new; gf_odf_desc_copy((GF_Descriptor*)od, (GF_Descriptor**)&od_new); gf_list_add(odU_o->objectDescriptors, od_new); } } return GF_OK; } return GF_NOT_SUPPORTED;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -