示例#1
0
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);
		}
	}
}
示例#3
0
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);
                }
            }
        }
    }
}
示例#4
0
文件: AvidInfo.cpp 项目: hdsdi3g/bmx
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));
    }
}
示例#5
0
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);
        }
    }
}
示例#6
0
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;
    }
}
示例#7
0
文件: OP1AFile.cpp 项目: hdsdi3g/bmx
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);
}