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; }
static int archive_mxf_get_package_timecode_breaks(MXFHeaderMetadata* headerMetadata, MXFMetadataSet* packageSet, TimecodeBreak** timecodeBreaks, long* numTimecodeBreaks) { MXFArrayItemIterator arrayIter; MXFArrayItemIterator arrayIter2; uint8_t* arrayElement; uint32_t arrayElementLen; mxfUL dataDef; uint32_t count; MXFMetadataSet* packageTrackSet; MXFMetadataSet* sequenceSet; MXFMetadataSet* dmSet; MXFMetadataSet* dmFrameworkSet; MXFListIterator setsIter; TimecodeBreak* newTimecodeBreaks = NULL; long totalBreaks = 0; TimecodeBreak* tmp; CHK_OFAIL(mxf_uu_get_package_tracks(packageSet, &arrayIter)); while (mxf_uu_next_track(headerMetadata, &arrayIter, &packageTrackSet)) { CHK_OFAIL(mxf_uu_get_track_datadef(packageTrackSet, &dataDef)); if (mxf_is_descriptive_metadata(&dataDef)) { /* get to the sequence */ CHK_OFAIL(mxf_get_strongref_item(packageTrackSet, &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 == 0) { 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)); /* check whether the DMFrameworkSet is a APP_TimecodeBreakFramework */ if (mxf_is_subclass_of(headerMetadata->dataModel, &dmFrameworkSet->key, &MXF_SET_K(APP_TimecodeBreakFramework))) { /* go back to the sequence and extract the timecode breaks */ CHK_OFAIL(mxf_get_array_item_count(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), &count)); if (newTimecodeBreaks == NULL) { CHK_OFAIL((tmp = malloc(sizeof(TimecodeBreak) * (totalBreaks + count))) != NULL); } else { /* multiple tracks with timecode breaks - reallocate the array */ CHK_OFAIL((tmp = realloc(newTimecodeBreaks, sizeof(TimecodeBreak) * (totalBreaks + count))) != NULL); } newTimecodeBreaks = tmp; /* extract the digibeta dropouts */ initialise_sets_iter(headerMetadata, &setsIter); mxf_initialise_array_item_iterator(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), &arrayIter2); while (mxf_next_array_item_element(&arrayIter2, &arrayElement, &arrayElementLen)) { TimecodeBreak* timecodeBreak = &newTimecodeBreaks[totalBreaks]; CHK_OFAIL(mxf_get_strongref_s(headerMetadata, &setsIter, arrayElement, &dmSet)); CHK_OFAIL(mxf_get_position_item(dmSet, &MXF_ITEM_K(DMSegment, EventStartPosition), &timecodeBreak->position)); CHK_OFAIL(mxf_get_strongref_item_s(&setsIter, dmSet, &MXF_ITEM_K(DMSegment, DMFramework), &dmFrameworkSet)); CHK_OFAIL(mxf_get_uint16_item(dmFrameworkSet, &MXF_ITEM_K(APP_TimecodeBreakFramework, APP_TimecodeType), &timecodeBreak->timecodeType)); totalBreaks++; } } } } } } *timecodeBreaks = newTimecodeBreaks; *numTimecodeBreaks = totalBreaks; return 1; fail: SAFE_FREE(&newTimecodeBreaks); return 0; }
static int archive_mxf_get_package_pse_failures(MXFHeaderMetadata* headerMetadata, MXFMetadataSet* packageSet, PSEFailure** failures, long* numFailures) { MXFArrayItemIterator arrayIter; MXFArrayItemIterator arrayIter2; uint8_t* arrayElement; uint32_t arrayElementLen; mxfUL dataDef; uint32_t count; MXFMetadataSet* packageTrackSet; MXFMetadataSet* sequenceSet; MXFMetadataSet* dmSet; MXFMetadataSet* dmFrameworkSet; MXFListIterator setsIter; PSEFailure* newFailures = NULL; long countedPSEFailures = 0; PSEFailure* tmp; int32_t i; CHK_OFAIL(mxf_uu_get_package_tracks(packageSet, &arrayIter)); while (mxf_uu_next_track(headerMetadata, &arrayIter, &packageTrackSet)) { CHK_OFAIL(mxf_uu_get_track_datadef(packageTrackSet, &dataDef)); if (mxf_is_descriptive_metadata(&dataDef)) { /* get to the sequence */ CHK_OFAIL(mxf_get_strongref_item(packageTrackSet, &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 == 0) { 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)); /* check whether the DMFrameworkSet is a APP_PSEAnalysisFramework */ if (mxf_is_subclass_of(headerMetadata->dataModel, &dmFrameworkSet->key, &MXF_SET_K(APP_PSEAnalysisFramework))) { /* go back to the sequence and extract the PSE failures */ CHK_OFAIL(mxf_get_array_item_count(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), &count)); countedPSEFailures += count; if (newFailures == NULL) { CHK_OFAIL((tmp = malloc(sizeof(PSEFailure) * countedPSEFailures)) != NULL); } else { /* multiple tracks with PSE failures - reallocate the array */ CHK_OFAIL((tmp = realloc(newFailures, sizeof(PSEFailure) * countedPSEFailures)) != NULL); } newFailures = tmp; /* extract the PSE failures */ initialise_sets_iter(headerMetadata, &setsIter); i = 0; mxf_initialise_array_item_iterator(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), &arrayIter2); while (mxf_next_array_item_element(&arrayIter2, &arrayElement, &arrayElementLen)) { PSEFailure* pseFailure = &newFailures[i]; CHK_OFAIL(mxf_get_strongref_s(headerMetadata, &setsIter, arrayElement, &dmSet)); CHK_OFAIL(mxf_get_position_item(dmSet, &MXF_ITEM_K(DMSegment, EventStartPosition), &pseFailure->position)); CHK_OFAIL(mxf_get_strongref_item_s(&setsIter, dmSet, &MXF_ITEM_K(DMSegment, DMFramework), &dmFrameworkSet)); CHK_OFAIL(mxf_get_int16_item(dmFrameworkSet, &MXF_ITEM_K(APP_PSEAnalysisFramework, APP_RedFlash), &pseFailure->redFlash)); CHK_OFAIL(mxf_get_int16_item(dmFrameworkSet, &MXF_ITEM_K(APP_PSEAnalysisFramework, APP_SpatialPattern), &pseFailure->spatialPattern)); CHK_OFAIL(mxf_get_int16_item(dmFrameworkSet, &MXF_ITEM_K(APP_PSEAnalysisFramework, APP_LuminanceFlash), &pseFailure->luminanceFlash)); CHK_OFAIL(mxf_get_boolean_item(dmFrameworkSet, &MXF_ITEM_K(APP_PSEAnalysisFramework, APP_ExtendedFailure), &pseFailure->extendedFailure)); i++; } break; } } } } } *failures = newFailures; *numFailures = countedPSEFailures; return 1; fail: SAFE_FREE(&newFailures); return 0; }
static int archive_mxf_get_package_vtr_errors(MXFHeaderMetadata *headerMetadata, MXFMetadataSet *packageSet, VTRErrorAtPos **errors, size_t *numErrors) { MXFArrayItemIterator arrayIter; MXFArrayItemIterator arrayIter2; uint8_t *arrayElement; uint32_t arrayElementLen; mxfUL dataDef; uint32_t count; MXFMetadataSet *packageTrackSet; MXFMetadataSet *sequenceSet; MXFMetadataSet *dmSet; MXFMetadataSet *dmFrameworkSet; MXFListIterator setsIter; VTRErrorAtPos *newErrors = NULL; size_t totalErrors = 0; VTRErrorAtPos *tmp; CHK_OFAIL(mxf_uu_get_package_tracks(packageSet, &arrayIter)); while (mxf_uu_next_track(headerMetadata, &arrayIter, &packageTrackSet)) { CHK_OFAIL(mxf_uu_get_track_datadef(packageTrackSet, &dataDef)); if (mxf_is_descriptive_metadata(&dataDef)) { /* get to the sequence */ CHK_OFAIL(mxf_get_strongref_item(packageTrackSet, &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 == 0) { 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)); /* check whether the DMFrameworkSet is a APP_VTRReplayErrorFramework */ if (mxf_is_subclass_of(headerMetadata->dataModel, &dmFrameworkSet->key, &MXF_SET_K(APP_VTRReplayErrorFramework))) { /* go back to the sequence and extract the VTR errors */ CHK_OFAIL(mxf_get_array_item_count(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), &count)); if (newErrors == NULL) { CHK_OFAIL((tmp = malloc(sizeof(VTRErrorAtPos) * (totalErrors + count))) != NULL); } else { /* multiple tracks with VTR errors - reallocate the array */ CHK_OFAIL((tmp = realloc(newErrors, sizeof(VTRErrorAtPos) * (totalErrors + count))) != NULL); } newErrors = tmp; /* extract the VTR errors */ mxf_initialise_sets_iter(headerMetadata, &setsIter); mxf_initialise_array_item_iterator(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), &arrayIter2); while (mxf_next_array_item_element(&arrayIter2, &arrayElement, &arrayElementLen)) { VTRErrorAtPos *vtrError = &newErrors[totalErrors]; CHK_OFAIL(mxf_get_strongref_s(headerMetadata, &setsIter, arrayElement, &dmSet)); CHK_OFAIL(mxf_get_position_item(dmSet, &MXF_ITEM_K(DMSegment, EventStartPosition), &vtrError->position)); CHK_OFAIL(mxf_get_strongref_item_s(&setsIter, dmSet, &MXF_ITEM_K(DMSegment, DMFramework), &dmFrameworkSet)); CHK_OFAIL(mxf_get_uint8_item(dmFrameworkSet, &MXF_ITEM_K(APP_VTRReplayErrorFramework, APP_VTRErrorCode), &vtrError->errorCode)); totalErrors++; } } } } } } *errors = newErrors; *numErrors = totalErrors; return 1; fail: SAFE_FREE(newErrors); return 0; }
static int archive_mxf_get_package_infax_data(MXFHeaderMetadata *headerMetadata, MXFMetadataSet *packageSet, InfaxData *infaxData) { MXFArrayItemIterator arrayIter; uint8_t *arrayElement; mxfUL dataDef; uint32_t count; MXFMetadataSet *trackSet; MXFMetadataSet *sequenceSet; MXFMetadataSet *dmSet; MXFMetadataSet *dmFrameworkSet; int haveInfaxData = 0; /* go through the tracks and find the DM track */ CHK_ORET(mxf_uu_get_package_tracks(packageSet, &arrayIter)); while (mxf_uu_next_track(headerMetadata, &arrayIter, &trackSet)) { CHK_ORET(mxf_uu_get_track_datadef(trackSet, &dataDef)); if (!mxf_is_descriptive_metadata(&dataDef)) { continue; } /* get to the single DMSegment */ CHK_ORET(mxf_get_strongref_item(trackSet, &MXF_ITEM_K(GenericTrack, Sequence), &sequenceSet)); if (mxf_is_subclass_of(headerMetadata->dataModel, &sequenceSet->key, &MXF_SET_K(Sequence))) { CHK_ORET(mxf_get_array_item_count(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), &count)); if (count != 1) { /* more than one segment */ continue; } CHK_ORET(mxf_get_array_item_element(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), 0, &arrayElement)); if (!mxf_get_strongref(headerMetadata, arrayElement, &dmSet)) { /* unknown DMSegment sub-class */ continue; } } 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))) { /* if it is an APP_InfaxFramework then it is the Infax data */ if (mxf_get_strongref_item(dmSet, &MXF_ITEM_K(DMSegment, DMFramework), &dmFrameworkSet) && mxf_is_subclass_of(headerMetadata->dataModel, &dmFrameworkSet->key, &MXF_SET_K(APP_InfaxFramework))) { CHK_ORET(get_infax_data(dmFrameworkSet, infaxData)); haveInfaxData = 1; break; } } } } return haveInfaxData; }
static int process_metadata(MXFReader *reader, MXFPartition *partition) { MXFFile *mxfFile = reader->mxfFile; EssenceReader *essenceReader = reader->essenceReader; EssenceReaderData *data = essenceReader->data; mxfKey key; uint8_t llen; uint64_t len; MXFMetadataSet *essContainerDataSet; MXFMetadataSet *sourcePackageSet; MXFMetadataSet *sourcePackageTrackSet; MXFMetadataSet *materialPackageSet; MXFMetadataSet *materialPackageTrackSet; MXFMetadataSet *descriptorSet; MXFArrayItemIterator arrayIter; mxfUL dataDefUL; MXFTrack *track; EssenceTrack *essenceTrack; MXFList wrappedTracks; MXFList sortedWrappedTracks; WrappedTrack *newWrappedTrack = NULL; WrappedTrack *wrappedTrack; WrappedTrack *sortedWrappedTrack; WrappedTrack *prevSortedWrappedTrack; WrappedTrack *firstSortedWrappedTrack; MXFListIterator listIter; MXFListIterator sortedListIter; int wasInserted; int haveZeroTrackNumber; uint32_t trackID; mxf_initialise_list(&wrappedTracks, free); mxf_initialise_list(&sortedWrappedTracks, NULL); /* create and read the header metadata */ CHK_OFAIL(mxf_read_next_nonfiller_kl(mxfFile, &key, &llen, &len)); CHK_OFAIL(mxf_is_header_metadata(&key)); CHK_OFAIL(mxf_create_header_metadata(&data->headerMetadata, reader->dataModel)); CHK_OFAIL(mxf_read_header_metadata(mxfFile, data->headerMetadata, partition->headerByteCount, &key, llen, len)); /* check for metadata only files */ if (!mxf_find_singular_set_by_key(data->headerMetadata, &MXF_SET_K(EssenceContainerData), &essContainerDataSet)) { reader->isMetadataOnly = 1; return 1; } /* get the body and index SID from the (single essence container; external essence not supported) */ CHK_OFAIL(mxf_get_uint32_item(essContainerDataSet, &MXF_ITEM_K(EssenceContainerData, BodySID), &data->bodySID)); if (mxf_have_item(essContainerDataSet, &MXF_ITEM_K(EssenceContainerData, IndexSID))) { CHK_OFAIL(mxf_get_uint32_item(essContainerDataSet, &MXF_ITEM_K(EssenceContainerData, IndexSID), &data->indexSID)); } else { data->indexSID = 0; } /* get the clip duration */ CHK_OFAIL(get_clip_duration(data->headerMetadata, &reader->clip, 0)); /* get the tracks from the (single) material package */ haveZeroTrackNumber = 0; CHK_OFAIL(mxf_find_singular_set_by_key(data->headerMetadata, &MXF_SET_K(MaterialPackage), &materialPackageSet)); CHK_OFAIL(mxf_uu_get_package_tracks(materialPackageSet, &arrayIter)); while (mxf_uu_next_track(data->headerMetadata, &arrayIter, &materialPackageTrackSet)) { /* CHK_OFAIL(mxf_uu_get_track_datadef(materialPackageTrackSet, &dataDefUL)); */ /* NOTE: not failing because files from Omneon were found to have a missing DataDefinition item in the Sequence and DMSourceClip referenced by a static DM Track */ if (!mxf_uu_get_track_datadef(materialPackageTrackSet, &dataDefUL)) { continue; } if (mxf_is_picture(&dataDefUL) || mxf_is_sound(&dataDefUL)) { CHK_MALLOC_OFAIL(newWrappedTrack, WrappedTrack); memset(newWrappedTrack, 0, sizeof(WrappedTrack)); CHK_OFAIL(mxf_append_list_element(&wrappedTracks, newWrappedTrack)); wrappedTrack = newWrappedTrack; newWrappedTrack = NULL; /* assigned to list so set to NULL so not free'ed in fail */ CHK_OFAIL(add_track(reader, &track)); wrappedTrack->track = track; if (mxf_have_item(materialPackageTrackSet, &MXF_ITEM_K(GenericTrack, TrackNumber))) { CHK_OFAIL(mxf_get_uint32_item(materialPackageTrackSet, &MXF_ITEM_K(GenericTrack, TrackNumber), &wrappedTrack->trackNumber)); } else { wrappedTrack->trackNumber = 0; } CHK_OFAIL(mxf_get_uint32_item(materialPackageTrackSet, &MXF_ITEM_K(GenericTrack, TrackID), &wrappedTrack->trackID)); CHK_OFAIL(mxf_get_rational_item(materialPackageTrackSet, &MXF_ITEM_K(Track, EditRate), &wrappedTrack->editRate)); CHK_OFAIL(mxf_uu_get_track_duration(materialPackageTrackSet, &wrappedTrack->duration)); CHK_OFAIL(mxf_uu_get_track_reference(materialPackageTrackSet, &wrappedTrack->sourcePackageUID, &wrappedTrack->sourceTrackID)); wrappedTrack->isVideo = mxf_is_picture(&dataDefUL); track->isVideo = wrappedTrack->isVideo; track->materialTrackID = wrappedTrack->trackID; track->materialTrackNumber = wrappedTrack->trackNumber; if (wrappedTrack->isVideo) { track->video.frameRate = wrappedTrack->editRate; } if (wrappedTrack->trackNumber == 0) { haveZeroTrackNumber = 1; } } } /* sort the tracks; use trackNumber if != 0 else use the trackID; video track is always first */ mxf_initialise_list_iter(&listIter, &wrappedTracks); while (mxf_next_list_iter_element(&listIter)) { wrappedTrack = (WrappedTrack*)mxf_get_iter_element(&listIter); wasInserted = 0; mxf_initialise_list_iter(&sortedListIter, &sortedWrappedTracks); while (mxf_next_list_iter_element(&sortedListIter)) { sortedWrappedTrack = (WrappedTrack*)mxf_get_iter_element(&sortedListIter); if ((wrappedTrack->track->isVideo && !sortedWrappedTrack->track->isVideo) || (wrappedTrack->track->isVideo == sortedWrappedTrack->track->isVideo && ((!haveZeroTrackNumber && wrappedTrack->trackNumber < sortedWrappedTrack->trackNumber) || (haveZeroTrackNumber && wrappedTrack->trackID < sortedWrappedTrack->trackID)))) { CHK_OFAIL(mxf_insert_list_element(&sortedWrappedTracks, mxf_get_list_iter_index(&sortedListIter), 1, wrappedTrack)); wasInserted = 1; break; } } if (!wasInserted) { CHK_OFAIL(mxf_append_list_element(&sortedWrappedTracks, wrappedTrack)); } } /* set the MXFTracks to the same order */ prevSortedWrappedTrack = NULL; firstSortedWrappedTrack = NULL; mxf_initialise_list_iter(&sortedListIter, &sortedWrappedTracks); while (mxf_next_list_iter_element(&sortedListIter)) { sortedWrappedTrack = (WrappedTrack*)mxf_get_iter_element(&sortedListIter); if (firstSortedWrappedTrack == NULL) { firstSortedWrappedTrack = sortedWrappedTrack; } if (prevSortedWrappedTrack != NULL) { prevSortedWrappedTrack->track->next = sortedWrappedTrack->track; } prevSortedWrappedTrack = sortedWrappedTrack; } if (prevSortedWrappedTrack != NULL) { prevSortedWrappedTrack->track->next = NULL; } if (firstSortedWrappedTrack != NULL) { reader->clip.tracks = firstSortedWrappedTrack->track; } /* process source package tracks and linked descriptors */ mxf_initialise_list_iter(&sortedListIter, &sortedWrappedTracks); while (mxf_next_list_iter_element(&sortedListIter)) { sortedWrappedTrack = (WrappedTrack*)mxf_get_iter_element(&sortedListIter); CHK_OFAIL(mxf_uu_get_referenced_track(data->headerMetadata, &sortedWrappedTrack->sourcePackageUID, sortedWrappedTrack->sourceTrackID, &sourcePackageTrackSet)); CHK_OFAIL(add_essence_track(essenceReader, &essenceTrack)); essenceTrack->isVideo = sortedWrappedTrack->isVideo; if (mxf_have_item(sourcePackageTrackSet, &MXF_ITEM_K(GenericTrack, TrackNumber))) { CHK_OFAIL(mxf_get_uint32_item(sourcePackageTrackSet, &MXF_ITEM_K(GenericTrack, TrackNumber), &essenceTrack->trackNumber)); } else { essenceTrack->trackNumber = 0; } CHK_OFAIL(mxf_get_uint32_item(sourcePackageTrackSet, &MXF_ITEM_K(GenericTrack, TrackID), &trackID)); essenceTrack->frameRate = reader->clip.frameRate; essenceTrack->playoutDuration = reader->clip.duration; essenceTrack->indexSID = data->indexSID; essenceTrack->bodySID = data->bodySID; /* process the descriptor */ CHK_OFAIL(mxf_uu_get_referenced_package(data->headerMetadata, &sortedWrappedTrack->sourcePackageUID, &sourcePackageSet)); CHK_OFAIL(mxf_uu_get_track_descriptor(sourcePackageSet, trackID, &descriptorSet)); if (mxf_is_subclass_of(data->headerMetadata->dataModel, &descriptorSet->key, &MXF_SET_K(CDCIEssenceDescriptor))) { CHK_OFAIL(process_cdci_descriptor(descriptorSet, sortedWrappedTrack->track, essenceTrack)); } else if (mxf_is_subclass_of(data->headerMetadata->dataModel, &descriptorSet->key, &MXF_SET_K(WaveAudioDescriptor))) { CHK_OFAIL(process_wav_descriptor(descriptorSet, sortedWrappedTrack->track, essenceTrack)); } else if (mxf_is_subclass_of(data->headerMetadata->dataModel, &descriptorSet->key, &MXF_SET_K(GenericSoundEssenceDescriptor))) { CHK_OFAIL(process_sound_descriptor(descriptorSet, track, essenceTrack)); } else { mxf_log_error("Unsupported file descriptor" LOG_LOC_FORMAT, LOG_LOC_PARAMS); return 0; } } /* initialise the playout timecode */ if (!initialise_playout_timecode(reader, materialPackageSet)) { CHK_ORET(initialise_default_playout_timecode(reader)); } /* initialise the source timecodes */ initialise_source_timecodes(reader, sourcePackageSet); mxf_clear_list(&wrappedTracks); mxf_clear_list(&sortedWrappedTracks); return 1; fail: SAFE_FREE(newWrappedTrack); mxf_clear_list(&wrappedTracks); mxf_clear_list(&sortedWrappedTracks); return 0; }