📄 media_odf.c
字号:
} //then find the OD reference, and create it if none e = Track_FindRef(mdia->mediaTrack, GF_ISOM_BOX_TYPE_MPOD, &mpod); if (e) return e; if (!mpod) { mpod = (GF_TrackReferenceTypeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MPOD); e = tref_AddBox((GF_Box*)tref, (GF_Box *)mpod); if (e) return e; } //OK, create our codecs ODencode = gf_odf_codec_new(); if (!ODencode) return GF_OUT_OF_MEM; ODdecode = gf_odf_codec_new(); if (!ODdecode) return GF_OUT_OF_MEM; e = gf_odf_codec_set_au(ODdecode, sample->data, sample->dataLength); if (e) goto err_exit; e = gf_odf_codec_decode(ODdecode); if (e) goto err_exit; while (1) { com = gf_odf_codec_get_com(ODdecode); if (!com) break; //check our commands switch (com->tag) { //Rewrite OD Update case GF_ODF_OD_UPDATE_TAG: //duplicate our command odU = (GF_ODUpdate *) com; odU2 = (GF_ODUpdate *) gf_odf_com_new(GF_ODF_OD_UPDATE_TAG); i=0; while ((desc = (GF_Descriptor*)gf_list_enum(odU->objectDescriptors, &i))) { //both OD and IODs are accepted switch (desc->tag) { case GF_ODF_OD_TAG: case GF_ODF_IOD_TAG: break; default: e = GF_ODF_INVALID_DESCRIPTOR; goto err_exit; } //get the esd e = gf_odf_desc_copy(desc, (GF_Descriptor **)&od); if (e) goto err_exit; if (desc->tag == GF_ODF_OD_TAG) { isom_od = (GF_IsomObjectDescriptor *) malloc(sizeof(GF_IsomObjectDescriptor)); isom_od->tag = GF_ODF_ISOM_OD_TAG; } else { isom_od = (GF_IsomObjectDescriptor *) malloc(sizeof(GF_IsomInitialObjectDescriptor)); isom_od->tag = GF_ODF_ISOM_IOD_TAG; //copy PL ((GF_IsomInitialObjectDescriptor *)isom_od)->inlineProfileFlag = ((GF_InitialObjectDescriptor *)od)->inlineProfileFlag; ((GF_IsomInitialObjectDescriptor *)isom_od)->graphics_profileAndLevel = ((GF_InitialObjectDescriptor *)od)->graphics_profileAndLevel; ((GF_IsomInitialObjectDescriptor *)isom_od)->audio_profileAndLevel = ((GF_InitialObjectDescriptor *)od)->audio_profileAndLevel; ((GF_IsomInitialObjectDescriptor *)isom_od)->OD_profileAndLevel = ((GF_InitialObjectDescriptor *)od)->OD_profileAndLevel; ((GF_IsomInitialObjectDescriptor *)isom_od)->scene_profileAndLevel = ((GF_InitialObjectDescriptor *)od)->scene_profileAndLevel; ((GF_IsomInitialObjectDescriptor *)isom_od)->visual_profileAndLevel = ((GF_InitialObjectDescriptor *)od)->visual_profileAndLevel; ((GF_IsomInitialObjectDescriptor *)isom_od)->IPMPToolList = ((GF_InitialObjectDescriptor *)od)->IPMPToolList; ((GF_InitialObjectDescriptor *)od)->IPMPToolList = NULL; } //in OD stream only ref desc are accepted isom_od->ES_ID_RefDescriptors = gf_list_new(); isom_od->ES_ID_IncDescriptors = NULL; //TO DO: check that a given sampleDescription exists isom_od->extensionDescriptors = od->extensionDescriptors; od->extensionDescriptors = NULL; isom_od->IPMP_Descriptors = od->IPMP_Descriptors; od->IPMP_Descriptors = NULL; isom_od->OCIDescriptors = od->OCIDescriptors; od->OCIDescriptors = NULL; isom_od->URLString = od->URLString; od->URLString = NULL; isom_od->objectDescriptorID = od->objectDescriptorID; j=0; while ((esd = (GF_ESD*)gf_list_enum(od->ESDescriptors, &j))) { ref = (GF_ES_ID_Ref *) gf_odf_desc_new(GF_ODF_ESD_REF_TAG); //1 to 1 mapping trackID and ESID. Add this track to MPOD //if track does not exist, this will be remove while reading the OD stream e = reftype_AddRefTrack(mpod, esd->ESID, &ref->trackRef); e = gf_odf_desc_add_desc((GF_Descriptor *)isom_od, (GF_Descriptor *)ref); if (e) goto err_exit; } //delete our desc gf_odf_desc_del((GF_Descriptor *)od); //and add the new one to our command gf_list_add(odU2->objectDescriptors, isom_od); } //delete the command gf_odf_com_del((GF_ODCom **)&odU); //and add the new one to the codec gf_odf_codec_add_com(ODencode, (GF_ODCom *)odU2); break; //Rewrite ESD Update case GF_ODF_ESD_UPDATE_TAG: esdU = (GF_ESDUpdate *) com; esdU2 = (GF_ESDUpdate *) gf_odf_com_new(GF_ODF_ESD_UPDATE_TAG); esdU2->ODID = esdU->ODID; i=0; while ((esd = (GF_ESD*)gf_list_enum(esdU->ESDescriptors, &i))) { ref = (GF_ES_ID_Ref *) gf_odf_desc_new(GF_ODF_ESD_REF_TAG); //1 to 1 mapping trackID and ESID e = reftype_AddRefTrack(mpod, esd->ESID, &ref->trackRef); e = gf_list_add(esdU2->ESDescriptors, ref); if (e) goto err_exit; } gf_odf_com_del((GF_ODCom **)&esdU); gf_odf_codec_add_com(ODencode, (GF_ODCom *)esdU2); break; //Brand new case: the ESRemove has to be rewritten too according to the specs... case GF_ODF_ESD_REMOVE_TAG: esdR = (GF_ESDRemove *) com; esdR2 = (GF_ESDRemove *) gf_odf_com_new(GF_ODF_ESD_REMOVE_TAG); //change the tag for the file format esdR2->tag = GF_ODF_ESD_REMOVE_REF_TAG; esdR2->ODID = esdR->ODID; esdR2->NbESDs = esdR->NbESDs; if (esdR->NbESDs) { //alloc our stuff esdR2->ES_ID = (unsigned short*)malloc(sizeof(u32) * esdR->NbESDs); if (!esdR2->ES_ID) { e = GF_OUT_OF_MEM; goto err_exit; } for (i = 0; i < esdR->NbESDs; i++) { //1 to 1 mapping trackID and ESID e = reftype_AddRefTrack(mpod, esdR->ES_ID[i], &esdR2->ES_ID[i]); if (e) goto err_exit; } } gf_odf_com_del(&com); gf_odf_codec_add_com(ODencode, (GF_ODCom *)esdR2); break; //Add the command as is default: e = gf_odf_codec_add_com(ODencode, com); if (e) goto err_exit; } } //encode our new AU e = gf_odf_codec_encode(ODencode, 1); if (e) goto err_exit; //and set the buffer in the sample free(sample->data); sample->data = NULL; sample->dataLength = 0; e = gf_odf_codec_get_au(ODencode, &sample->data, &sample->dataLength);err_exit: gf_odf_codec_del(ODencode); gf_odf_codec_del(ODdecode); return e;}// Rewrite the good dependancies when an OD AU is extracted from the filestatic u32 Media_FindOD_ID(GF_MediaBox *mdia, GF_ISOSample *sample, u32 track_id){ GF_Err e; GF_ODCodec *ODdecode; GF_ODCom *com; u32 the_od_id; GF_ODUpdate *odU; GF_ESD *esd; GF_Descriptor *desc; GF_TrackReferenceTypeBox *mpod; u32 i, j; if (!mdia || !sample || !sample->data || !sample->dataLength) return 0; mpod = NULL; e = Track_FindRef(mdia->mediaTrack, GF_ISOM_BOX_TYPE_MPOD, &mpod); if (e) return 0; //no references, nothing to do... if (!mpod) return 0; the_od_id = 0; ODdecode = gf_odf_codec_new(); if (!ODdecode) return 0; e = gf_odf_codec_set_au(ODdecode, sample->data, sample->dataLength); if (e) goto err_exit; e = gf_odf_codec_decode(ODdecode); if (e) goto err_exit; while (1) { GF_List *esd_list = NULL; com = gf_odf_codec_get_com(ODdecode); if (!com) break; if (com->tag != GF_ODF_OD_UPDATE_TAG) continue; odU = (GF_ODUpdate *) com; i=0; while ((desc = (GF_Descriptor*)gf_list_enum(odU->objectDescriptors, &i))) { switch (desc->tag) { case GF_ODF_OD_TAG: case GF_ODF_IOD_TAG: esd_list = ((GF_ObjectDescriptor *)desc)->ESDescriptors; break; default: continue; } j=0; while ((esd = (GF_ESD*)gf_list_enum( esd_list, &j))){ if (esd->ESID==track_id) { the_od_id = ((GF_IsomObjectDescriptor*)desc)->objectDescriptorID; break; } } if (the_od_id) break; } gf_odf_com_del((GF_ODCom **)&odU); if (the_od_id) break; }err_exit: gf_odf_codec_del(ODdecode); if (e) return 0; return the_od_id;}GF_EXPORTu32 gf_isom_find_od_for_track(GF_ISOFile *file, u32 track){ u32 i, j, di, the_od_id; GF_TrackBox *od_tk; GF_TrackBox *tk = gf_isom_get_track_from_file(file, track); if (!tk) return 0; the_od_id = 0; i=0; while ( (od_tk = (GF_TrackBox*)gf_list_enum(file->moov->trackList, &i))) { if (od_tk->Media->handler->handlerType != GF_ISOM_MEDIA_OD) continue; for (j=0; j<od_tk->Media->information->sampleTable->SampleSize->sampleCount; j++) { GF_ISOSample *samp = gf_isom_get_sample(file, i, j+1, &di); the_od_id = Media_FindOD_ID(od_tk->Media, samp, tk->Header->trackID); gf_isom_sample_del(&samp); if (the_od_id) return the_od_id; } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -