void AvidClip::CreateMinimalHeaderMetadata() { mDataModel = new DataModel(); mHeaderMetadata = new AvidHeaderMetadata(mDataModel); // Preface Preface *preface = new Preface(mHeaderMetadata); // Preface - ContentStorage mContentStorage = new ContentStorage(mHeaderMetadata); preface->setContentStorage(mContentStorage); }
void AppendDMSLabel(HeaderMetadata *header_metadata, mxfUL scheme_label) { BMX_ASSERT(header_metadata); Preface *preface = header_metadata->getPreface(); std::vector<mxfUL> dm_schemes = preface->getDMSchemes(); size_t i; for (i = 0; i < dm_schemes.size(); i++) { if (mxf_equals_ul(&dm_schemes[i], &scheme_label)) break; } try { if (i >= dm_schemes.size()) preface->appendDMSchemes(scheme_label); } catch (const MXFException &ex) { // oops, cannot append, maybe something wrong with the array as read from the file // try and create a new DMSchemes array if empty now if (dm_schemes.size() == 0) { preface->setDMSchemes(std::vector<mxfUL>()); preface->appendDMSchemes(scheme_label); } } }
void AvidClip::UpdateTrackDurations(AvidTrack *avid_track, Track *track, mxfRational edit_rate, int64_t duration) { int64_t track_duration = convert_duration(edit_rate, duration, track->getEditRate(), ROUND_AUTO); Sequence *sequence = dynamic_cast<Sequence*>(track->getSequence()); BMX_ASSERT(sequence); if (sequence->getDuration() >= 0) { if (sequence->getDuration() < track_duration) log_warn("Existing track duration is less than the essence duration\n"); return; } sequence->setDuration(track_duration); Preface *preface = avid_track->GetHeaderMetadata()->getPreface(); vector<StructuralComponent*> components = sequence->getStructuralComponents(); BMX_CHECK(components.size() == 1); components[0]->setDuration(track_duration); // update duration further down the reference chain SourceClip *source_clip = dynamic_cast<SourceClip*>(components[0]); if (source_clip) { mxfUMID source_package_id = source_clip->getSourcePackageID(); if (source_package_id != g_Null_UMID) { GenericPackage *ref_package = preface->findPackage(source_package_id); if (ref_package) { GenericTrack *ref_gen_track = ref_package->findTrack(source_clip->getSourceTrackID()); if (ref_gen_track) { Track *ref_track = dynamic_cast<Track*>(ref_gen_track); BMX_CHECK(ref_track); UpdateTrackDurations(avid_track, ref_track, track->getEditRate(), source_clip->getStartPosition() + track_duration); } } } } }
void AvidInfo::ReadInfo(HeaderMetadata *header_metadata) { Reset(); MaterialPackage *mp = header_metadata->getPreface()->findMaterialPackage(); if (!mp) { log_warn("No material package found\n"); return; } GetMaterialPackageAttrs(mp); GetUserComments(mp); GetLocators(mp); GetPhysicalPackageInfo(header_metadata); Preface *preface = header_metadata->getPreface(); if (preface->haveItem(&MXF_ITEM_K(Preface, ProjectName))) { project_name = preface->getStringItem(&MXF_ITEM_K(Preface, ProjectName)); } else { size_t i; for (i = 0; i < material_package_attrs.size(); i++) { if (material_package_attrs[i]->name == "_PJ") { project_name = material_package_attrs[i]->value; break; } } } vector<SourcePackage*> file_source_packages = header_metadata->getPreface()->findFileSourcePackages(); if (file_source_packages.size() == 1) { FileDescriptor *file_desc = dynamic_cast<FileDescriptor*>(file_source_packages[0]->getDescriptorLight()); if (file_desc && file_desc->haveItem(&MXF_ITEM_K(GenericPictureEssenceDescriptor, ResolutionID))) resolution_id = file_desc->getInt32Item(&MXF_ITEM_K(GenericPictureEssenceDescriptor, ResolutionID)); } }
void AS02Track::CreateHeaderMetadata() { // Preface Preface *preface = new Preface(mHeaderMetadata); preface->setLastModifiedDate(mClip->mCreationDate); preface->setVersion(MXF_PREFACE_VER(1, 3)); preface->setOperationalPattern(MXF_OP_L(1a, UniTrack_Stream_Internal)); preface->appendEssenceContainers(GetEssenceContainerUL()); preface->setDMSchemes(vector<mxfUL>()); // Preface - Identification Identification *ident = new Identification(mHeaderMetadata); preface->appendIdentifications(ident); ident->initialise(mClip->mCompanyName, mClip->mProductName, mClip->mVersionString, mClip->mProductUID); if (mClip->mProductVersion.major != 0 || mClip->mProductVersion.minor != 0 || mClip->mProductVersion.patch != 0 || mClip->mProductVersion.build != 0 || mClip->mProductVersion.release != 0) { ident->setProductVersion(mClip->mProductVersion); } ident->setModificationDate(mClip->mCreationDate); ident->setThisGenerationUID(mClip->mGenerationUID); // Preface - ContentStorage ContentStorage* content_storage = new ContentStorage(mHeaderMetadata); preface->setContentStorage(content_storage); // Preface - ContentStorage - EssenceContainerData EssenceContainerData *ess_container_data = new EssenceContainerData(mHeaderMetadata); content_storage->appendEssenceContainerData(ess_container_data); ess_container_data->setLinkedPackageUID(mFileSourcePackageUID); ess_container_data->setIndexSID(mIndexSID); ess_container_data->setBodySID(mBodySID); // Preface - ContentStorage - MaterialPackage mMaterialPackage = new MaterialPackage(mHeaderMetadata); content_storage->appendPackages(mMaterialPackage); mMaterialPackage->setPackageUID(mMaterialPackageUID); mMaterialPackage->setPackageCreationDate(mClip->mCreationDate); mMaterialPackage->setPackageModifiedDate(mClip->mCreationDate); if (!mClip->mClipName.empty()) mMaterialPackage->setName(get_track_clip_name(mClip->mClipName, mIsPicture, mOutputTrackNumber)); // Preface - ContentStorage - MaterialPackage - Timecode Track Track *timecode_track = new Track(mHeaderMetadata); mMaterialPackage->appendTracks(timecode_track); timecode_track->setTrackName(TIMECODE_TRACK_NAME); timecode_track->setTrackID(TIMECODE_TRACK_ID); timecode_track->setTrackNumber(0); timecode_track->setEditRate(GetSampleRate()); timecode_track->setOrigin(0); // Preface - ContentStorage - MaterialPackage - Timecode Track - Sequence Sequence *sequence = new Sequence(mHeaderMetadata); timecode_track->setSequence(sequence); sequence->setDataDefinition(MXF_DDEF_L(Timecode)); sequence->setDuration(-1); // updated when writing completed // Preface - ContentStorage - MaterialPackage - Timecode Track - TimecodeComponent TimecodeComponent *timecode_component = new TimecodeComponent(mHeaderMetadata); sequence->appendStructuralComponents(timecode_component); timecode_component->setDataDefinition(MXF_DDEF_L(Timecode)); timecode_component->setDuration(-1); // updated when writing completed timecode_component->setRoundedTimecodeBase(mClip->mStartTimecode.GetRoundedTCBase()); timecode_component->setDropFrame(mClip->mStartTimecode.IsDropFrame()); timecode_component->setStartTimecode(mClip->mStartTimecode.GetOffset()); // Preface - ContentStorage - MaterialPackage - Timeline Track Track *track = new Track(mHeaderMetadata); mMaterialPackage->appendTracks(track); track->setTrackName(mIsPicture ? VIDEO_TRACK_NAME : AUDIO_TRACK_NAME); track->setTrackID(mIsPicture ? VIDEO_TRACK_ID : AUDIO_TRACK_ID); track->setTrackNumber(0); track->setEditRate(GetSampleRate()); track->setOrigin(0); // Preface - ContentStorage - MaterialPackage - Timeline Track - Sequence sequence = new Sequence(mHeaderMetadata); track->setSequence(sequence); sequence->setDataDefinition(mIsPicture ? MXF_DDEF_L(Picture) : MXF_DDEF_L(Sound)); sequence->setDuration(-1); // updated when writing completed // Preface - ContentStorage - MaterialPackage - Timeline Track - Sequence - SourceClip SourceClip *source_clip = new SourceClip(mHeaderMetadata); sequence->appendStructuralComponents(source_clip); source_clip->setDataDefinition(mIsPicture ? MXF_DDEF_L(Picture) : MXF_DDEF_L(Sound)); source_clip->setDuration(-1); // updated when writing completed source_clip->setStartPosition(0); source_clip->setSourceTrackID(mIsPicture ? VIDEO_TRACK_ID : AUDIO_TRACK_ID); source_clip->setSourcePackageID(mFileSourcePackageUID); // Preface - ContentStorage - SourcePackage mFileSourcePackage = new SourcePackage(mHeaderMetadata); content_storage->appendPackages(mFileSourcePackage); mFileSourcePackage->setPackageUID(mFileSourcePackageUID); mFileSourcePackage->setPackageCreationDate(mClip->mCreationDate); mFileSourcePackage->setPackageModifiedDate(mClip->mCreationDate); preface->setPrimaryPackage(mFileSourcePackage); // Preface - ContentStorage - SourcePackage - Timecode Track timecode_track = new Track(mHeaderMetadata); mFileSourcePackage->appendTracks(timecode_track); timecode_track->setTrackName(TIMECODE_TRACK_NAME); timecode_track->setTrackID(TIMECODE_TRACK_ID); timecode_track->setTrackNumber(0); timecode_track->setEditRate(GetSampleRate()); timecode_track->setOrigin(0); // could be updated when writing completed // Preface - ContentStorage - SourcePackage - Timecode Track - Sequence sequence = new Sequence(mHeaderMetadata); timecode_track->setSequence(sequence); sequence->setDataDefinition(MXF_DDEF_L(Timecode)); sequence->setDuration(-1); // updated when writing completed // Preface - ContentStorage - SourcePackage - Timecode Track - TimecodeComponent timecode_component = new TimecodeComponent(mHeaderMetadata); sequence->appendStructuralComponents(timecode_component); timecode_component->setDataDefinition(MXF_DDEF_L(Timecode)); timecode_component->setDuration(-1); // updated when writing completed Timecode sp_start_timecode = mClip->mStartTimecode; sp_start_timecode.AddOffset(- mOutputStartOffset, GetSampleRate()); timecode_component->setRoundedTimecodeBase(sp_start_timecode.GetRoundedTCBase()); timecode_component->setDropFrame(sp_start_timecode.IsDropFrame()); timecode_component->setStartTimecode(sp_start_timecode.GetOffset()); // Preface - ContentStorage - SourcePackage - Timeline Track track = new Track(mHeaderMetadata); mFileSourcePackage->appendTracks(track); track->setTrackName(mIsPicture ? VIDEO_TRACK_NAME : AUDIO_TRACK_NAME); track->setTrackID(mIsPicture ? VIDEO_TRACK_ID : AUDIO_TRACK_ID); track->setTrackNumber(mTrackNumber); track->setEditRate(GetSampleRate()); track->setOrigin(0); // could be updated when writing completed // Preface - ContentStorage - SourcePackage - Timeline Track - Sequence sequence = new Sequence(mHeaderMetadata); track->setSequence(sequence); sequence->setDataDefinition(mIsPicture ? MXF_DDEF_L(Picture) : MXF_DDEF_L(Sound)); sequence->setDuration(-1); // updated when writing completed // Preface - ContentStorage - SourcePackage - Timeline Track - Sequence - SourceClip source_clip = new SourceClip(mHeaderMetadata); sequence->appendStructuralComponents(source_clip); source_clip->setDataDefinition(mIsPicture ? MXF_DDEF_L(Picture) : MXF_DDEF_L(Sound)); source_clip->setDuration(-1); // updated when writing completed source_clip->setStartPosition(0); if (mHaveLowerLevelSourcePackage) { source_clip->setSourcePackageID(mLowerLevelSourcePackageUID); source_clip->setSourceTrackID(mLowerLevelTrackId); } else { source_clip->setSourceTrackID(0); source_clip->setSourcePackageID(g_Null_UMID); } // Preface - ContentStorage - SourcePackage - FileDescriptor FileDescriptor *descriptor = mDescriptorHelper->CreateFileDescriptor(mHeaderMetadata); mFileSourcePackage->setDescriptor(descriptor); descriptor->setLinkedTrackID(mIsPicture ? VIDEO_TRACK_ID : AUDIO_TRACK_ID); // Preface - ContentStorage - (lower-level) SourcePackage if (mLowerLevelSourcePackage) { content_storage->appendPackages(mLowerLevelSourcePackage); if (!mLowerLevelURI.empty()) { NetworkLocator *network_locator = new NetworkLocator(mHeaderMetadata); mLowerLevelSourcePackage->getDescriptor()->appendLocators(network_locator); network_locator->setURLString(mLowerLevelURI); } } }
OPAtomTrackReader::OPAtomTrackReader(string filename, File *file, Partition *header_partition) { mFilename = filename; mTrackId = 0; mDurationInMetadata = -1; mIsPicture = true; DataModel *data_model = 0; AvidHeaderMetadata *header_metadata = 0; FrameOffsetIndexTableSegment *index_table = 0; try { int64_t essence_length = 0; mxfUL essence_label = g_Null_UL; mxfRational edit_rate = (mxfRational){0, 1}; FileDescriptor *file_descriptor = 0; uint32_t frame_size = 0; mxfKey key; uint8_t llen; uint64_t len; // get essence container label vector<mxfUL> container_labels = header_partition->getEssenceContainers(); MXFPP_CHECK(container_labels.size() == 1); essence_label = container_labels[0]; // read the header metadata data_model = new DataModel(); header_metadata = new AvidHeaderMetadata(data_model); TaggedValue::registerObjectFactory(header_metadata); file->readNextNonFillerKL(&key, &llen, &len); if (!mxf_is_header_metadata(&key)) throw OP_ATOM_FAIL; header_metadata->read(file, header_partition, &key, llen, len); Preface *preface = header_metadata->getPreface(); ContentStorage *content = preface->getContentStorage(); vector<GenericPackage*> packages = content->getPackages(); // get the file source package and descriptor SourcePackage *fsp; size_t i; for (i = 0; i < packages.size(); i++) { fsp = dynamic_cast<SourcePackage*>(packages[i]); if (!fsp || !fsp->haveDescriptor()) continue; file_descriptor = dynamic_cast<FileDescriptor*>(fsp->getDescriptor()); if (file_descriptor) break; } if (!file_descriptor) throw OP_ATOM_NO_FILE_PACKAGE; // get the material track info Track *mp_track = 0; for (i = 0; i < packages.size(); i++) { MaterialPackage *mp = dynamic_cast<MaterialPackage*>(packages[i]); if (!mp) continue; vector<GenericTrack*> tracks = mp->getTracks(); size_t j; for (j = 0; j < tracks.size(); j++) { Track *track = dynamic_cast<Track*>(tracks[j]); if (!track) continue; StructuralComponent *track_sequence = track->getSequence(); Sequence *sequence = dynamic_cast<Sequence*>(track_sequence); SourceClip *source_clip = dynamic_cast<SourceClip*>(track_sequence); if (sequence) { vector<StructuralComponent*> components = sequence->getStructuralComponents(); if (components.size() != 1) continue; source_clip = dynamic_cast<SourceClip*>(components[0]); } if (!source_clip) continue; mxfUMID fsp_umid = fsp->getPackageUID(); mxfUMID sc_umid = source_clip->getSourcePackageID(); if (memcmp(&fsp_umid, &sc_umid, sizeof(fsp_umid)) == 0) { mp_track = track; edit_rate = mp_track->getEditRate(); mTrackId = mp_track->getTrackID(); mDurationInMetadata = source_clip->getDuration(); break; } } if (mp_track) break; } if (!mp_track) throw OP_ATOM_HEADER_ERROR; // read the index table if present and complete int64_t file_pos = file->tell(); try { file->readNextNonFillerKL(&key, &llen, &len); while (!IndexTableSegment::isIndexTableSegment(&key)) { file->skip(len); file->readNextNonFillerKL(&key, &llen, &len); } if (IndexTableSegment::isIndexTableSegment(&key)) { index_table = FrameOffsetIndexTableSegment::read(file, len); mxfRational index_edit_rate = index_table->getIndexEditRate(); if (memcmp(&index_edit_rate, &edit_rate, sizeof(index_edit_rate)) == 0) frame_size = index_table->getEditUnitByteCount(); } } catch (...) { mxf_log_warn("Ignore errors - failed to find or read the index table segment\n"); // do nothing } file->seek(file_pos, SEEK_SET); // position the file at the start of the essence data try { file->readNextNonFillerKL(&key, &llen, &len); while (!mxf_is_gc_essence_element(&key) && !mxf_avid_is_essence_element(&key)) { file->skip(len); file->readNextNonFillerKL(&key, &llen, &len); } } catch (...) { throw OP_ATOM_ESSENCE_DATA_NOT_FOUND; } essence_length = len; mEssenceParser = RawEssenceParser::Create(file, essence_length, essence_label, file_descriptor, edit_rate, frame_size, index_table); if (!mEssenceParser) throw MXFException("Failed to create essence parser"); mDataModel = data_model; mHeaderMetadata = header_metadata; mIndexTable = index_table; } catch (...) { delete data_model; delete header_metadata; delete index_table; throw; } }
void OP1AFile::CreateHeaderMetadata() { BMX_ASSERT(!mHeaderMetadata); int64_t material_track_duration = -1; // unknown - could be updated if not writing in a single pass int64_t source_track_duration = -1; // unknown - could be updated if not writing in a single pass int64_t source_track_origin = 0; // could be updated if not writing in a single pass if (mSupportCompleteSinglePass) { // values are known and will not be updated material_track_duration = mInputDuration - mOutputStartOffset + mOutputEndOffset; if (material_track_duration < 0) material_track_duration = 0; source_track_duration = mInputDuration + mOutputEndOffset; source_track_origin = mOutputStartOffset; } // create the header metadata mDataModel = new DataModel(); mHeaderMetadata = new HeaderMetadata(mDataModel); // Preface Preface *preface = new Preface(mHeaderMetadata); preface->setLastModifiedDate(mCreationDate); preface->setVersion((mFlavour & OP1A_377_2004_FLAVOUR) ? MXF_PREFACE_VER(1, 2) : MXF_PREFACE_VER(1, 3)); if (mTracks.size() <= 1) preface->setOperationalPattern(MXF_OP_L(1a, UniTrack_Stream_Internal)); else preface->setOperationalPattern(MXF_OP_L(1a, MultiTrack_Stream_Internal)); set<mxfUL>::const_iterator iter; for (iter = mEssenceContainerULs.begin(); iter != mEssenceContainerULs.end(); iter++) preface->appendEssenceContainers(*iter); preface->setDMSchemes(vector<mxfUL>()); if ((mFlavour & OP1A_ARD_ZDF_HDF_PROFILE_FLAVOUR)) preface->setIsRIPPresent(true); // Preface - Identification Identification *ident = new Identification(mHeaderMetadata); preface->appendIdentifications(ident); ident->initialise(mCompanyName, mProductName, mVersionString, mProductUID); if (mProductVersion.major != 0 || mProductVersion.minor != 0 || mProductVersion.patch != 0 || mProductVersion.build != 0 || mProductVersion.release != 0) { ident->setProductVersion(mProductVersion); } ident->setModificationDate(mCreationDate); ident->setThisGenerationUID(mGenerationUID); // Preface - ContentStorage ContentStorage* content_storage = new ContentStorage(mHeaderMetadata); preface->setContentStorage(content_storage); // Preface - ContentStorage - EssenceContainerData EssenceContainerData *ess_container_data = new EssenceContainerData(mHeaderMetadata); content_storage->appendEssenceContainerData(ess_container_data); ess_container_data->setLinkedPackageUID(mFileSourcePackageUID); ess_container_data->setIndexSID(INDEX_SID); ess_container_data->setBodySID(BODY_SID); // Preface - ContentStorage - MaterialPackage mMaterialPackage = new MaterialPackage(mHeaderMetadata); content_storage->appendPackages(mMaterialPackage); mMaterialPackage->setPackageUID(mMaterialPackageUID); mMaterialPackage->setPackageCreationDate(mCreationDate); mMaterialPackage->setPackageModifiedDate(mCreationDate); if (!mClipName.empty()) mMaterialPackage->setName(mClipName); // Preface - ContentStorage - MaterialPackage - Timecode Track Track *timecode_track = new Track(mHeaderMetadata); mMaterialPackage->appendTracks(timecode_track); timecode_track->setTrackName(TIMECODE_TRACK_NAME); timecode_track->setTrackID(TIMECODE_TRACK_ID); timecode_track->setTrackNumber(0); timecode_track->setEditRate(mEditRate); timecode_track->setOrigin(0); // Preface - ContentStorage - MaterialPackage - Timecode Track - Sequence Sequence *sequence = new Sequence(mHeaderMetadata); timecode_track->setSequence(sequence); sequence->setDataDefinition(MXF_DDEF_L(Timecode)); sequence->setDuration(material_track_duration); // Preface - ContentStorage - MaterialPackage - Timecode Track - TimecodeComponent TimecodeComponent *timecode_component = new TimecodeComponent(mHeaderMetadata); sequence->appendStructuralComponents(timecode_component); timecode_component->setDataDefinition(MXF_DDEF_L(Timecode)); timecode_component->setDuration(material_track_duration); timecode_component->setRoundedTimecodeBase(mStartTimecode.GetRoundedTCBase()); timecode_component->setDropFrame(mStartTimecode.IsDropFrame()); timecode_component->setStartTimecode(mStartTimecode.GetOffset()); // Preface - ContentStorage - SourcePackage mFileSourcePackage = new SourcePackage(mHeaderMetadata); content_storage->appendPackages(mFileSourcePackage); mFileSourcePackage->setPackageUID(mFileSourcePackageUID); mFileSourcePackage->setPackageCreationDate(mCreationDate); mFileSourcePackage->setPackageModifiedDate(mCreationDate); // Preface - ContentStorage - SourcePackage - Timecode Track timecode_track = new Track(mHeaderMetadata); mFileSourcePackage->appendTracks(timecode_track); timecode_track->setTrackName(TIMECODE_TRACK_NAME); timecode_track->setTrackID(TIMECODE_TRACK_ID); timecode_track->setTrackNumber(0); timecode_track->setEditRate(mEditRate); timecode_track->setOrigin(source_track_origin); // Preface - ContentStorage - SourcePackage - Timecode Track - Sequence sequence = new Sequence(mHeaderMetadata); timecode_track->setSequence(sequence); sequence->setDataDefinition(MXF_DDEF_L(Timecode)); sequence->setDuration(source_track_duration); // Preface - ContentStorage - SourcePackage - Timecode Track - TimecodeComponent timecode_component = new TimecodeComponent(mHeaderMetadata); sequence->appendStructuralComponents(timecode_component); timecode_component->setDataDefinition(MXF_DDEF_L(Timecode)); timecode_component->setDuration(source_track_duration); Timecode sp_start_timecode = mStartTimecode; sp_start_timecode.AddOffset(- mOutputStartOffset, mFrameRate); timecode_component->setRoundedTimecodeBase(sp_start_timecode.GetRoundedTCBase()); timecode_component->setDropFrame(sp_start_timecode.IsDropFrame()); timecode_component->setStartTimecode(sp_start_timecode.GetOffset()); // Preface - ContentStorage - SourcePackage - (Multiple) File Descriptor if (mTracks.size() > 1) { MultipleDescriptor *mult_descriptor = new MultipleDescriptor(mHeaderMetadata); mFileSourcePackage->setDescriptor(mult_descriptor); mult_descriptor->setSampleRate(mEditRate); mult_descriptor->setEssenceContainer(MXF_EC_L(MultipleWrappings)); if (mSupportCompleteSinglePass) mult_descriptor->setContainerDuration(mInputDuration); } // MaterialPackage and file SourcePackage Tracks and FileDescriptor size_t i; for (i = 0; i < mTracks.size(); i++) mTracks[i]->AddHeaderMetadata(mHeaderMetadata, mMaterialPackage, mFileSourcePackage); }