Exemple #1
0
void AvidClip::SetPhysicalSourceStartTimecode()
{
    // set start position in file source package source clips that reference a physical source package
    size_t i;
    for (i = 0; i < mTracks.size(); i++) {
        SourcePackage *ref_source_package = mTracks[i]->GetRefSourcePackage();
        if (!ref_source_package ||
            !ref_source_package->haveDescriptor() ||
            !mTracks[i]->GetDataModel()->isSubclassOf(ref_source_package->getDescriptor(), &MXF_SET_K(PhysicalDescriptor)))
        {
            continue;
        }

        // get physical package start timecode
        Timecode phys_start_timecode;
        if (!GetStartTimecode(ref_source_package, &phys_start_timecode))
            continue;

        // convert to a offset at clip frame rate
        uint16_t rounded_clip_tc_base = get_rounded_tc_base(mClipFrameRate);
        int64_t phys_tc_start_offset = convert_position(phys_start_timecode.GetOffset(),
                                                        rounded_clip_tc_base,
                                                        phys_start_timecode.GetRoundedTCBase(),
                                                        ROUND_AUTO);
        int64_t clip_tc_start_offset = convert_position(mStartTimecode.GetOffset(),
                                                        rounded_clip_tc_base,
                                                        mStartTimecode.GetRoundedTCBase(),
                                                        ROUND_AUTO);
        int64_t start_position = clip_tc_start_offset - phys_tc_start_offset;
        if (start_position < 0) {
            // physical source's start timecode was > start timecode
            log_warn("Not setting start timecode in file source package because start position was negative\n");
            continue;
        }

        // set the start position
        vector<GenericTrack*> tracks = mTracks[i]->GetFileSourcePackage()->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();
            mxfUL data_def = track_sequence->getDataDefinition();
            if (!mxf_is_picture(&data_def) && !mxf_is_sound(&data_def))
                continue;

            Sequence *sequence = dynamic_cast<Sequence*>(track_sequence);
            BMX_ASSERT(sequence);
            vector<StructuralComponent*> components = sequence->getStructuralComponents();
            BMX_ASSERT(components.size() == 1);
            SourceClip *source_clip = dynamic_cast<SourceClip*>(components[0]);
            BMX_ASSERT(source_clip);

            source_clip->setStartPosition(convert_position(mClipFrameRate, start_position, track->getEditRate(), ROUND_AUTO));
            break;
        }
    }
}
Exemple #2
0
void OP1AFile::UpdateTrackMetadata(GenericPackage *package, int64_t origin, int64_t duration)
{
    vector<GenericTrack*> tracks = package->getTracks();
    size_t i;
    for (i = 0; i < tracks.size(); i++) {
        Track *track = dynamic_cast<Track*>(tracks[i]);
        if (!track)
            continue;

        track->setOrigin(origin);

        Sequence *sequence = dynamic_cast<Sequence*>(track->getSequence());
        BMX_ASSERT(sequence);
        vector<StructuralComponent*> components = sequence->getStructuralComponents();
        if (sequence->getDuration() < 0) {
            sequence->setDuration(duration);
            BMX_ASSERT(components.size() == 1);
            components[0]->setDuration(duration);
        }
        if (components.size() == 1) {
            TimecodeComponent *timecode_component = dynamic_cast<TimecodeComponent*>(components[0]);
            if (timecode_component) {
                Timecode start_timecode = mStartTimecode;
                start_timecode.AddOffset(- origin, mFrameRate);
                timecode_component->setRoundedTimecodeBase(start_timecode.GetRoundedTCBase());
                timecode_component->setDropFrame(start_timecode.IsDropFrame());
                timecode_component->setStartTimecode(start_timecode.GetOffset());
            }
        }
    }
}
    TextBasedDMFramework *FindTextBasedDMFramework(mxfpp::HeaderMetadata *header_metadata, mxfUL xml_metadata_scheme_id, mxfpp::StaticTrack **static_track) {

        MaterialPackage *mp = header_metadata->getPreface()->findMaterialPackage();

        if (!mp)
            return NULL;

        // expect to find Static DM Track -> Sequence -> DM Segment -> DM Framework (a TextBasedDMFramework)
        std::vector<GenericTrack*> tracks = mp->getTracks();
        size_t i;
        for (i = 0; i < tracks.size(); i++) {
            StaticTrack *st = dynamic_cast<StaticTrack*>(tracks[i]);
            if (!st)
                continue;

            StructuralComponent *sc = st->getSequence();
            if (!sc || sc->getDataDefinition() != MXF_DDEF_L(DescriptiveMetadata))
                continue;

            Sequence *seq = dynamic_cast<Sequence*>(sc);
            DMSegment *seg = dynamic_cast<DMSegment*>(sc);
            if (!seq && !seg)
                continue;

            if (seq) {
                std::vector<StructuralComponent*> scs = seq->getStructuralComponents();
                if (scs.size() != 1)
                    continue;

                seg = dynamic_cast<DMSegment*>(scs[0]);
                if (!seg)
                    continue;
            }

            if (!seg->haveDMFramework())
                continue;

            DMFramework *framework = seg->getDMFrameworkLight();
            if (framework) {

		        TextBasedDMFramework *fw = dynamic_cast<TextBasedDMFramework*>(framework);
                if (!fw)
                    continue;
                TextBasedObject *t = dynamic_cast<TextBasedObject*>(fw->getTextBasedObject());
                if (!t)
                    continue;

                mxfUL ul = t->getTextBasedMetadataPayloadSchemaID();
                if (mxf_equals_ul(&ul, &xml_metadata_scheme_id)) {
                    // this is a match!
                    if (static_track != NULL)
                        *static_track = st;
                    return fw;
                }
            }
        }

        return NULL;
    }
Exemple #4
0
void AS02Track::UpdatePackageMetadata(GenericPackage *package)
{
    SourcePackage *source_package = dynamic_cast<SourcePackage*>(package);
    FileDescriptor *file_descriptor = 0;
    if (source_package && source_package->haveDescriptor())
        file_descriptor = dynamic_cast<FileDescriptor*>(source_package->getDescriptor());

    vector<GenericTrack*> tracks = package->getTracks();

    // update track origin in file source package tracks and
    // duration in sequences, timecode components and source clips
    size_t i;
    for (i = 0; i < tracks.size(); i++) {
        Track *track = dynamic_cast<Track*>(tracks[i]);
        BMX_ASSERT(track);

        if (source_package)
            track->setOrigin(mOutputStartOffset);

        Sequence *sequence = dynamic_cast<Sequence*>(track->getSequence());
        BMX_ASSERT(sequence);
        vector<StructuralComponent*> components = sequence->getStructuralComponents();
        if (sequence->getDuration() < 0) {
            if (source_package)
                sequence->setDuration(GetDuration());
            else
                sequence->setDuration(GetOutputDuration(false));

            BMX_ASSERT(components.size() == 1);
            if (source_package)
                components[0]->setDuration(GetDuration());
            else
                components[0]->setDuration(GetOutputDuration(false));
        }
        if (source_package && components.size() == 1) {
            TimecodeComponent *timecode_component = dynamic_cast<TimecodeComponent*>(components[0]);
            if (timecode_component) {
                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());
            }
        }
    }

    // update the container duration in the file descriptor
    if (file_descriptor)
        file_descriptor->setContainerDuration(mContainerDuration);
}
Exemple #5
0
void AvidInfo::GetLocators(MaterialPackage *mp)
{
    // expect to find (DM) Event Track - (DM) Sequence - DMSegment
    vector<GenericTrack*> tracks = mp->getTracks();
    size_t i;
    for (i = 0; i < tracks.size(); i++) {
        EventTrack *et = dynamic_cast<EventTrack*>(tracks[i]);
        if (!et)
            continue;

        StructuralComponent *sc = et->getSequence();
        if (!sc || sc->getDataDefinition() != MXF_DDEF_L(DescriptiveMetadata))
            continue;

        Sequence *seq = dynamic_cast<Sequence*>(sc);
        if (!seq)
            continue;

        vector<StructuralComponent*> dm_segs = seq->getStructuralComponents();
        if (dm_segs.empty())
            continue;

        size_t j;
        for (j = 0; j < dm_segs.size(); j++) {
            DMSegment *seg = dynamic_cast<DMSegment*>(dm_segs[j]);
            if (!seg)
                break;

            AvidLocator locator;
            locator.position = seg->getEventStartPosition();
            if (seg->haveEventComment())
                locator.comment = seg->getEventComment();
            if (seg->haveItem(&MXF_ITEM_K(DMSegment, CommentMarkerColor))) {
                RGBColor rgb_color;
                BMX_CHECK(mxf_avid_get_rgb_color_item(seg->getCMetadataSet(),
                                                      &MXF_ITEM_K(DMSegment, CommentMarkerColor),
                                                      &rgb_color));
                locator.color = convert_rgb_color(&rgb_color);
            } else {
                locator.color = COLOR_BLACK;
            }
            locators.push_back(locator);
        }
        if (j < dm_segs.size())
            locators.clear();

        locators_edit_rate = et->getEventEditRate();
        break;
    }
}
std::vector<DMFramework*> GetStaticFrameworks(MaterialPackage *mp)
{
    std::vector<DMFramework*> frameworks;

    // expect to find Static DM Track -> Sequence -> DM Segment -> DM Framework

    std::vector<GenericTrack*> tracks = mp->getTracks();
    size_t i;
    for (i = 0; i < tracks.size(); i++) {
        StaticTrack *st = dynamic_cast<StaticTrack*>(tracks[i]);
        if (!st)
            continue;

        StructuralComponent *sc = st->getSequence();
        if (!sc || sc->getDataDefinition() != MXF_DDEF_L(DescriptiveMetadata))
            continue;

        Sequence *seq = dynamic_cast<Sequence*>(sc);
        DMSegment *seg = dynamic_cast<DMSegment*>(sc);
        if (!seq && !seg)
            continue;

        if (seq) {
            std::vector<StructuralComponent*> scs = seq->getStructuralComponents();
            if (scs.size() != 1)
                continue;

            seg = dynamic_cast<DMSegment*>(scs[0]);
            if (!seg)
                continue;
        }

        if (!seg->haveDMFramework())
            continue;

        DMFramework *framework = seg->getDMFrameworkLight();
        if (framework)
            frameworks.push_back(framework);
    }

    return frameworks;
}
Exemple #7
0
bool AvidClip::GetStartTimecode(GenericPackage *package, Timecode *timecode)
{
    // find the timecode component in this package
    TimecodeComponent *tc_component = 0;
    vector<GenericTrack*> tracks = package->getTracks();
    size_t i;
    for (i = 0; i < tracks.size(); i++) {
        Track *track = dynamic_cast<Track*>(tracks[i]);
        if (!track)
            continue;

        StructuralComponent *track_sequence = track->getSequence();
        mxfUL data_def = track_sequence->getDataDefinition();
        if (!mxf_is_timecode(&data_def))
            continue;

        Sequence *sequence = dynamic_cast<Sequence*>(track_sequence);
        tc_component = dynamic_cast<TimecodeComponent*>(track_sequence);
        if (sequence) {
            vector<StructuralComponent*> components = sequence->getStructuralComponents();
            size_t j;
            for (j = 0; j < components.size(); j++) {
                tc_component = dynamic_cast<TimecodeComponent*>(components[j]);
                if (tc_component)
                    break;
            }
        }
        if (tc_component)
            break;
    }
    if (!tc_component)
        return false;


    timecode->Init(tc_component->getRoundedTimecodeBase(),
                   tc_component->getDropFrame(),
                   tc_component->getStartTimecode());
    return true;
}
Exemple #8
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);
                }
            }
        }
    }
}
Exemple #9
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;
    }
}