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; }
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; } }