int mxf_find_singular_set_by_key(MXFHeaderMetadata* headerMetadata, const mxfKey* key, MXFMetadataSet** set) { MXFList* setList = NULL; if (!mxf_find_set_by_key(headerMetadata, key, &setList)) { return 0; } CHK_OFAIL(mxf_get_list_length(setList) == 1); *set = (MXFMetadataSet*)mxf_get_first_list_element(setList); mxf_free_list(&setList); return 1; fail: mxf_free_list(&setList); return 0; }
int archive_mxf_get_info(MXFHeaderMetadata* headerMetadata, ArchiveMXFInfo* info) { MXFList* list = NULL; MXFListIterator iter; MXFArrayItemIterator arrayIter; uint8_t* arrayElement; uint32_t arrayElementLen; mxfUL dataDef; uint32_t count; mxfUTF16Char* tempWString = NULL; int haveSourceInfaxData = 0; MXFList* nameList = NULL; MXFList* valueList = NULL; MXFMetadataSet* identSet; MXFMetadataSet* fileSourcePackageSet; MXFMetadataSet* sourcePackageSet; MXFMetadataSet* sourcePackageTrackSet; MXFMetadataSet* sequenceSet; MXFMetadataSet* dmSet; MXFMetadataSet* dmFrameworkSet; MXFMetadataSet* descriptorSet; MXFMetadataSet* locatorSet; MXFMetadataSet* materialPackageSet; /* if metadata only then only try reading infax user comments */ if (is_metadata_only_file(headerMetadata, &materialPackageSet)) { if (mxf_avid_read_string_user_comments(materialPackageSet, &nameList, &valueList)) { haveSourceInfaxData = parse_infax_user_comments(nameList, valueList, &info->sourceInfaxData); mxf_free_list(&nameList); mxf_free_list(&valueList); } return 1; } /* Creation timestamp identification info */ CHK_OFAIL(mxf_find_set_by_key(headerMetadata, &MXF_SET_K(Identification), &list)); mxf_initialise_list_iter(&iter, list); if (mxf_next_list_iter_element(&iter)) { identSet = (MXFMetadataSet*)mxf_get_iter_element(&iter); CHK_OFAIL(mxf_get_timestamp_item(identSet, &MXF_ITEM_K(Identification, ModificationDate), &info->creationDate)); } mxf_free_list(&list); /* LTO Infax data */ CHK_OFAIL(mxf_uu_get_top_file_package(headerMetadata, &fileSourcePackageSet)); CHK_OFAIL(mxf_uu_get_package_tracks(fileSourcePackageSet, &arrayIter)); while (mxf_uu_next_track(headerMetadata, &arrayIter, &sourcePackageTrackSet)) { CHK_OFAIL(mxf_uu_get_track_datadef(sourcePackageTrackSet, &dataDef)); if (mxf_is_descriptive_metadata(&dataDef)) { /* get to the single DMSegment */ CHK_OFAIL(mxf_get_strongref_item(sourcePackageTrackSet, &MXF_ITEM_K(GenericTrack, Sequence), &sequenceSet)); if (mxf_is_subclass_of(headerMetadata->dataModel, &sequenceSet->key, &MXF_SET_K(Sequence))) { CHK_OFAIL(mxf_get_array_item_count(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), &count)); if (count != 1) { /* Sequence of length 1 is expected for the DMS track */ continue; } CHK_OFAIL(mxf_get_array_item_element(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), 0, &arrayElement)); CHK_OFAIL(mxf_get_strongref(headerMetadata, arrayElement, &dmSet)); } else { dmSet = sequenceSet; } /* if it is a DMSegment with a DMFramework reference then we have the DMS track */ if (mxf_is_subclass_of(headerMetadata->dataModel, &dmSet->key, &MXF_SET_K(DMSegment))) { if (mxf_have_item(dmSet, &MXF_ITEM_K(DMSegment, DMFramework))) { CHK_OFAIL(mxf_get_strongref_item(dmSet, &MXF_ITEM_K(DMSegment, DMFramework), &dmFrameworkSet)); /* if it is a APP_InfaxFramework then it is the Infax data */ if (mxf_is_subclass_of(headerMetadata->dataModel, &dmFrameworkSet->key, &MXF_SET_K(APP_InfaxFramework))) { CHK_OFAIL(get_infax_data(dmFrameworkSet, &info->ltoInfaxData)); break; } } } } } /* original filename */ CHK_OFAIL(mxf_get_strongref_item(fileSourcePackageSet, &MXF_ITEM_K(SourcePackage, Descriptor), &descriptorSet)); if (mxf_have_item(descriptorSet, &MXF_ITEM_K(GenericDescriptor, Locators))) { CHK_OFAIL(mxf_initialise_array_item_iterator(descriptorSet, &MXF_ITEM_K(GenericDescriptor, Locators), &arrayIter)); while (mxf_next_array_item_element(&arrayIter, &arrayElement, &arrayElementLen)) { CHK_OFAIL(mxf_get_strongref(headerMetadata, arrayElement, &locatorSet)); if (mxf_is_subclass_of(headerMetadata->dataModel, &locatorSet->key, &MXF_SET_K(NetworkLocator))) { CHK_OFAIL(mxf_uu_get_utf16string_item(locatorSet, &MXF_ITEM_K(NetworkLocator, URLString), &tempWString)); CHK_OFAIL(wcstombs(info->filename, tempWString, sizeof(info->filename)) != (size_t)(-1)); info->filename[sizeof(info->filename) - 1] = '\0'; SAFE_FREE(&tempWString); break; } } } /* source Infax data */ CHK_OFAIL(mxf_find_set_by_key(headerMetadata, &MXF_SET_K(SourcePackage), &list)); mxf_initialise_list_iter(&iter, list); while (mxf_next_list_iter_element(&iter)) { sourcePackageSet = (MXFMetadataSet*)(mxf_get_iter_element(&iter)); /* it is the tape SourcePackage if it has a TapeDescriptor */ CHK_OFAIL(mxf_get_strongref_item(sourcePackageSet, &MXF_ITEM_K(SourcePackage, Descriptor), &descriptorSet)); if (mxf_is_subclass_of(headerMetadata->dataModel, &descriptorSet->key, &MXF_SET_K(TapeDescriptor))) { /* go through the tracks and find the DMS track */ CHK_OFAIL(mxf_uu_get_package_tracks(sourcePackageSet, &arrayIter)); while (mxf_uu_next_track(headerMetadata, &arrayIter, &sourcePackageTrackSet)) { CHK_OFAIL(mxf_uu_get_track_datadef(sourcePackageTrackSet, &dataDef)); if (mxf_is_descriptive_metadata(&dataDef)) { /* get to the single DMSegment */ CHK_OFAIL(mxf_get_strongref_item(sourcePackageTrackSet, &MXF_ITEM_K(GenericTrack, Sequence), &sequenceSet)); if (mxf_is_subclass_of(headerMetadata->dataModel, &sequenceSet->key, &MXF_SET_K(Sequence))) { CHK_OFAIL(mxf_get_array_item_count(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), &count)); if (count != 1) { /* Sequence of length 1 is expected for the DMS track */ continue; } CHK_OFAIL(mxf_get_array_item_element(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), 0, &arrayElement)); CHK_OFAIL(mxf_get_strongref(headerMetadata, arrayElement, &dmSet)); } else { dmSet = sequenceSet; } /* if it is a DMSegment with a DMFramework reference then we have the DMS track */ if (mxf_is_subclass_of(headerMetadata->dataModel, &dmSet->key, &MXF_SET_K(DMSegment))) { if (mxf_have_item(dmSet, &MXF_ITEM_K(DMSegment, DMFramework))) { CHK_OFAIL(mxf_get_strongref_item(dmSet, &MXF_ITEM_K(DMSegment, DMFramework), &dmFrameworkSet)); /* if it is a APP_InfaxFramework then it is the Infax data */ if (mxf_is_subclass_of(headerMetadata->dataModel, &dmFrameworkSet->key, &MXF_SET_K(APP_InfaxFramework))) { CHK_OFAIL(get_infax_data(dmFrameworkSet, &info->sourceInfaxData)); haveSourceInfaxData = 1; break; } } } } } break; } } mxf_free_list(&list); /* try reading Infax data from UserComments attached to the MaterialPackage if no data was found elsewhere */ if (!haveSourceInfaxData) { CHK_OFAIL(mxf_find_singular_set_by_key(headerMetadata, &MXF_SET_K(MaterialPackage), &materialPackageSet)); if (mxf_avid_read_string_user_comments(materialPackageSet, &nameList, &valueList)) { haveSourceInfaxData = parse_infax_user_comments(nameList, valueList, &info->sourceInfaxData); mxf_free_list(&nameList); mxf_free_list(&valueList); } } return haveSourceInfaxData; fail: SAFE_FREE(&tempWString); mxf_free_list(&list); mxf_free_list(&nameList); mxf_free_list(&valueList); return 0; }
int mxf_app_get_info(MXFHeaderMetadata *headerMetadata, ArchiveMXFInfo *info) { MXFList *list = NULL; MXFListIterator iter; MXFArrayItemIterator arrayIter; uint8_t *arrayElement; uint32_t arrayElementLen; mxfUTF16Char *tempWString = NULL; MXFList *nameList = NULL; MXFList *valueList = NULL; MXFMetadataSet *identSet; MXFMetadataSet *fileSourcePackageSet; MXFMetadataSet *sourcePackageSet; MXFMetadataSet *descriptorSet; MXFMetadataSet *locatorSet; MXFMetadataSet *materialPackageSet; MXFMetadataSet *prefaceSet; memset(info, 0, sizeof(*info)); /* read event counts in Preface */ CHK_ORET(mxf_find_singular_set_by_key(headerMetadata, &MXF_SET_K(Preface), &prefaceSet)); #define GET_EVENT_COUNT(name, var) \ if (mxf_have_item(prefaceSet, &MXF_ITEM_K(Preface, name))) \ CHK_ORET(mxf_get_uint32_item(prefaceSet, &MXF_ITEM_K(Preface, name), &var)); GET_EVENT_COUNT(APP_VTRErrorCount, info->vtrErrorCount) GET_EVENT_COUNT(APP_PSEFailureCount, info->pseFailureCount) GET_EVENT_COUNT(APP_DigiBetaDropoutCount, info->digibetaDropoutCount) GET_EVENT_COUNT(APP_TimecodeBreakCount, info->timecodeBreakCount) /* if metadata only then only try reading infax user comments */ if (is_metadata_only_file(headerMetadata, &materialPackageSet)) { if (mxf_avid_read_string_user_comments(materialPackageSet, &nameList, &valueList)) { info->haveSourceInfaxData = parse_infax_user_comments(nameList, valueList, &info->sourceInfaxData); mxf_free_list(&nameList); mxf_free_list(&valueList); } return 1; } /* Creation timestamp identification info */ CHK_OFAIL(mxf_find_set_by_key(headerMetadata, &MXF_SET_K(Identification), &list)); mxf_initialise_list_iter(&iter, list); if (mxf_next_list_iter_element(&iter)) { identSet = (MXFMetadataSet*)mxf_get_iter_element(&iter); CHK_OFAIL(mxf_get_timestamp_item(identSet, &MXF_ITEM_K(Identification, ModificationDate), &info->creationDate)); } mxf_free_list(&list); /* LTO Infax data */ CHK_OFAIL(mxf_uu_get_top_file_package(headerMetadata, &fileSourcePackageSet)); info->haveLTOInfaxData = archive_mxf_get_package_infax_data(headerMetadata, fileSourcePackageSet, &info->ltoInfaxData); /* original filename */ CHK_OFAIL(mxf_get_strongref_item(fileSourcePackageSet, &MXF_ITEM_K(SourcePackage, Descriptor), &descriptorSet)); if (mxf_have_item(descriptorSet, &MXF_ITEM_K(GenericDescriptor, Locators))) { CHK_OFAIL(mxf_initialise_array_item_iterator(descriptorSet, &MXF_ITEM_K(GenericDescriptor, Locators), &arrayIter)); while (mxf_next_array_item_element(&arrayIter, &arrayElement, &arrayElementLen)) { CHK_OFAIL(mxf_get_strongref(headerMetadata, arrayElement, &locatorSet)); if (mxf_is_subclass_of(headerMetadata->dataModel, &locatorSet->key, &MXF_SET_K(NetworkLocator))) { CHK_OFAIL(mxf_uu_get_utf16string_item(locatorSet, &MXF_ITEM_K(NetworkLocator, URLString), &tempWString)); CHK_OFAIL(mxf_utf16_to_utf8(info->filename, tempWString, sizeof(info->filename)) != (size_t)(-1)); info->filename[sizeof(info->filename) - 1] = '\0'; SAFE_FREE(tempWString); break; } } } /* source Infax data */ CHK_OFAIL(mxf_find_set_by_key(headerMetadata, &MXF_SET_K(SourcePackage), &list)); mxf_initialise_list_iter(&iter, list); while (mxf_next_list_iter_element(&iter)) { sourcePackageSet = (MXFMetadataSet*)(mxf_get_iter_element(&iter)); /* it is the tape SourcePackage if it has a TapeDescriptor */ CHK_OFAIL(mxf_get_strongref_item(sourcePackageSet, &MXF_ITEM_K(SourcePackage, Descriptor), &descriptorSet)); if (mxf_is_subclass_of(headerMetadata->dataModel, &descriptorSet->key, &MXF_SET_K(TapeDescriptor))) { info->haveSourceInfaxData = archive_mxf_get_package_infax_data(headerMetadata, sourcePackageSet, &info->sourceInfaxData); break; } } mxf_free_list(&list); /* try alternative locations for source Infax data */ if (!info->haveSourceInfaxData) { /* framework in the material package */ CHK_OFAIL(mxf_find_singular_set_by_key(headerMetadata, &MXF_SET_K(MaterialPackage), &materialPackageSet)); info->haveSourceInfaxData = archive_mxf_get_package_infax_data(headerMetadata, materialPackageSet, &info->sourceInfaxData); /* UserComments in the MaterialPackage */ if (!info->haveSourceInfaxData) { if (mxf_avid_read_string_user_comments(materialPackageSet, &nameList, &valueList)) { info->haveSourceInfaxData = parse_infax_user_comments(nameList, valueList, &info->sourceInfaxData); mxf_free_list(&nameList); mxf_free_list(&valueList); } } } return info->haveSourceInfaxData; fail: SAFE_FREE(tempWString); mxf_free_list(&list); mxf_free_list(&nameList); mxf_free_list(&valueList); return 0; }