From: Philip de N. <ph...@us...> - 2010-02-17 16:04:32
|
Update of /cvsroot/ingex/ingex/libMXF++/examples/D10MXFOP1AWriter In directory sfp-cvsdas-1.v30.ch3.sourceforge.com:/tmp/cvs-serv14361/examples/D10MXFOP1AWriter Modified Files: D10ContentPackage.cpp D10ContentPackage.h D10MXFOP1AWriter.cpp D10MXFOP1AWriter.h test_d10mxfop1awriter.cpp Log Message: Declare File::write method read-only parameter as const Added DynamicByteArray::getAllocatedSize method Add missing default aspect ratio assignment to test_d10mxfop1awriter.cpp Allow D10MXFOP1AWriter clients to set the material and file source package uids Changed D10MXFOP1AWriter::GenerateUserTimecode method to return the timecode (and not set user timecode) to allow scenarios where the user timecode is required for externally managed content packages Index: D10MXFOP1AWriter.h =================================================================== RCS file: /cvsroot/ingex/ingex/libMXF++/examples/D10MXFOP1AWriter/D10MXFOP1AWriter.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** D10MXFOP1AWriter.h 12 Feb 2010 13:52:49 -0000 1.1 --- D10MXFOP1AWriter.h 17 Feb 2010 16:04:24 -0000 1.2 *************** *** 56,78 **** public: ! D10MXFOP1AWriter(std::string filename); ~D10MXFOP1AWriter(); ! // prepare ! void SetSampleRate(D10SampleRate sample_rate); // default D10_SAMPLE_RATE_625_50I ! void SetAudioChannelCount(uint32_t count); // default is 4 ! void SetAudioQuantizationBits(uint32_t bits); // default is 24; alternative is 16 ! void SetAspectRatio(mxfRational aspect_ratio); // default is 16:9; alternative is 4:3 ! void SetStartTimecode(int64_t count, bool drop_frame); // default 0, false ! void SetBitRate(D10BitRate rate, uint32_t encoded_picture_size); // default D10_BIT_RATE_50, 250000 ! void PrepareFile(); // write content package data ! // LTC timecode written to the system item in the essence container ! void SetTimecode(Timecode ltc); ! // SetTimecode using a timecode calculated from the start timecode and duration ! void GenerateTimecode(); // MPEG video data --- 56,83 ---- public: ! D10MXFOP1AWriter(); ~D10MXFOP1AWriter(); ! // configure and create file ! ! void SetSampleRate(D10SampleRate sample_rate); // default D10_SAMPLE_RATE_625_50I ! void SetAudioChannelCount(uint32_t count); // default is 4 ! void SetAudioQuantizationBits(uint32_t bits); // default is 24; alternative is 16 ! void SetAspectRatio(mxfRational aspect_ratio); // default is 16:9; alternative is 4:3 ! void SetStartTimecode(int64_t count, bool drop_frame); // default 0, false ! void SetBitRate(D10BitRate rate, uint32_t encoded_picture_size); // default D10_BIT_RATE_50, 250000 ! void SetMaterialPackageUID(mxfUMID uid); // default generated ! void SetFileSourcePackageUID(mxfUMID uid); // default generated ! ! bool CreateFile(std::string filename); ! bool CreateFile(mxfpp::File **file); // write content package data ! // user timecode written to the system item in the essence container ! void SetUserTimecode(Timecode user_timecode); ! // timecode calculated from the start timecode and duration ! Timecode GenerateUserTimecode(); // MPEG video data *************** *** 87,90 **** --- 92,104 ---- void WriteContentPackage(); + void WriteContentPackage(const D10ContentPackage *content_package); + + + // file info + int64_t GetDuration() const { return mDuration; } + int64_t GetFileSize() const; + mxfUMID GetMaterialPackageUID() const { return mMaterialPackageUID; } + mxfUMID GetFileSourcePackageUID() const { return mFileSourcePackageUID; } + // complete writing file *************** *** 92,101 **** private: void CalculateStartPosition(); ! uint32_t WriteSystemItem(); ! uint32_t WriteAES3AudioElement(); private: - std::string mFilename; D10SampleRate mSampleRate; mxfRational mVideoSampleRate; --- 106,115 ---- private: + void CreateFile(); void CalculateStartPosition(); ! uint32_t WriteSystemItem(const D10ContentPackage *content_package); ! uint32_t WriteAES3AudioElement(const D10ContentPackage *content_package); private: D10SampleRate mSampleRate; mxfRational mVideoSampleRate; *************** *** 117,120 **** --- 131,137 ---- uint32_t mAudioItemSize; mxfUL mEssenceContainerUL; + + mxfUMID mMaterialPackageUID; + mxfUMID mFileSourcePackageUID; mxfpp::File *mMXFFile; *************** *** 126,130 **** std::vector<SetWithDuration*> mSetsWithDuration; ! D10ContentPackage mContentPackage; DynamicByteArray mAES3Block; uint32_t mAudioSequence[5]; --- 143,147 ---- std::vector<SetWithDuration*> mSetsWithDuration; ! D10ContentPackageInt mContentPackage; DynamicByteArray mAES3Block; uint32_t mAudioSequence[5]; Index: D10ContentPackage.cpp =================================================================== RCS file: /cvsroot/ingex/ingex/libMXF++/examples/D10MXFOP1AWriter/D10ContentPackage.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** D10ContentPackage.cpp 12 Feb 2010 13:52:49 -0000 1.1 --- D10ContentPackage.cpp 17 Feb 2010 16:04:23 -0000 1.2 *************** *** 30,53 **** #include "D10ContentPackage.h" - using namespace std; using namespace mxfpp; ! D10ContentPackage::D10ContentPackage() { Reset(); } ! D10ContentPackage::~D10ContentPackage() { } ! void D10ContentPackage::Reset() { ! mLTC.hour = 0; ! mLTC.min = 0; ! mLTC.sec = 0; ! mLTC.frame = 0; mVideoBytes.setSize(0); --- 30,52 ---- #include "D10ContentPackage.h" using namespace std; using namespace mxfpp; ! D10ContentPackageInt::D10ContentPackageInt() { Reset(); } ! D10ContentPackageInt::~D10ContentPackageInt() { } ! void D10ContentPackageInt::Reset() { ! mUserTimecode.hour = 0; ! mUserTimecode.min = 0; ! mUserTimecode.sec = 0; ! mUserTimecode.frame = 0; mVideoBytes.setSize(0); *************** *** 57,72 **** } ! bool D10ContentPackage::IsComplete(uint32_t num_audio_tracks) { if (mVideoBytes.getSize() == 0) return false; uint32_t i; ! for (i = 0; i < num_audio_tracks; i++) { if (mAudioBytes[i].getSize() == 0) ! return false; } ! return true; } --- 56,103 ---- } ! bool D10ContentPackageInt::IsComplete(uint32_t num_audio_tracks) const { if (mVideoBytes.getSize() == 0) return false; + return GetNumAudioTracks() >= num_audio_tracks; + } + + Timecode D10ContentPackageInt::GetUserTimecode() const + { + return mUserTimecode; + } + + const unsigned char* D10ContentPackageInt::GetVideo() const + { + return mVideoBytes.getBytes(); + } + + unsigned int D10ContentPackageInt::GetVideoSize() const + { + return mVideoBytes.getSize(); + } + + uint32_t D10ContentPackageInt::GetNumAudioTracks() const + { uint32_t i; ! for (i = 0; i < MAX_CP_AUDIO_TRACKS; i++) { if (mAudioBytes[i].getSize() == 0) ! break; } + + return i; + } + + const unsigned char* D10ContentPackageInt::GetAudio(int index) const + { + MXFPP_ASSERT(index >= 0 && index < MAX_CP_AUDIO_TRACKS); ! return mAudioBytes[index].getBytes(); ! } ! ! unsigned int D10ContentPackageInt::GetAudioSize() const ! { ! return mAudioBytes[0].getSize(); } Index: D10ContentPackage.h =================================================================== RCS file: /cvsroot/ingex/ingex/libMXF++/examples/D10MXFOP1AWriter/D10ContentPackage.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** D10ContentPackage.h 12 Feb 2010 13:52:49 -0000 1.1 --- D10ContentPackage.h 17 Feb 2010 16:04:24 -0000 1.2 *************** *** 34,48 **** class D10ContentPackage { public: ! D10ContentPackage(); ! ~D10ContentPackage(); void Reset(); ! bool IsComplete(uint32_t num_audio_tracks); public: ! Timecode mLTC; DynamicByteArray mVideoBytes; DynamicByteArray mAudioBytes[MAX_CP_AUDIO_TRACKS]; --- 34,72 ---- + class D10ContentPackage { public: ! virtual Timecode GetUserTimecode() const = 0; ! ! virtual const unsigned char* GetVideo() const = 0; ! virtual unsigned int GetVideoSize() const = 0; ! ! virtual uint32_t GetNumAudioTracks() const = 0; ! virtual const unsigned char* GetAudio(int index) const = 0; ! virtual unsigned int GetAudioSize() const = 0; ! }; ! ! ! class D10ContentPackageInt : public D10ContentPackage ! { ! public: ! D10ContentPackageInt(); ! ~D10ContentPackageInt(); void Reset(); ! bool IsComplete(uint32_t num_audio_tracks) const; public: ! // from D10ContentPackage ! virtual Timecode GetUserTimecode() const; ! virtual const unsigned char* GetVideo() const; ! virtual unsigned int GetVideoSize() const; ! virtual uint32_t GetNumAudioTracks() const; ! virtual const unsigned char* GetAudio(int index) const; ! virtual unsigned int GetAudioSize() const; ! ! public: ! Timecode mUserTimecode; DynamicByteArray mVideoBytes; DynamicByteArray mAudioBytes[MAX_CP_AUDIO_TRACKS]; Index: D10MXFOP1AWriter.cpp =================================================================== RCS file: /cvsroot/ingex/ingex/libMXF++/examples/D10MXFOP1AWriter/D10MXFOP1AWriter.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** D10MXFOP1AWriter.cpp 12 Feb 2010 13:52:49 -0000 1.1 --- D10MXFOP1AWriter.cpp 17 Feb 2010 16:04:24 -0000 1.2 *************** *** 52,56 **** ! static void convert_timecode_to_12m(Timecode *t, bool drop_frame, unsigned char *t12m) { // the format follows the specification of the TimecodeArray property --- 52,56 ---- ! static void convert_timecode_to_12m(Timecode tc, bool drop_frame, unsigned char *t12m) { // the format follows the specification of the TimecodeArray property *************** *** 61,68 **** if (drop_frame) t12m[0] = 0x40; // set drop-frame flag ! t12m[0] |= ((t->frame % 10) & 0x0f) | (((t->frame / 10) & 0x3) << 4); ! t12m[1] = ((t->sec % 10) & 0x0f) | (((t->sec / 10) & 0x7) << 4); ! t12m[2] = ((t->min % 10) & 0x0f) | (((t->min / 10) & 0x7) << 4); ! t12m[3] = ((t->hour % 10) & 0x0f) | (((t->hour / 10) & 0x3) << 4); } --- 61,68 ---- if (drop_frame) t12m[0] = 0x40; // set drop-frame flag ! t12m[0] |= ((tc.frame % 10) & 0x0f) | (((tc.frame / 10) & 0x3) << 4); ! t12m[1] = ((tc.sec % 10) & 0x0f) | (((tc.sec / 10) & 0x7) << 4); ! t12m[2] = ((tc.min % 10) & 0x0f) | (((tc.min / 10) & 0x7) << 4); ! t12m[3] = ((tc.hour % 10) & 0x0f) | (((tc.hour / 10) & 0x3) << 4); } *************** *** 140,146 **** ! D10MXFOP1AWriter::D10MXFOP1AWriter(string filename) { - mFilename = filename; SetSampleRate(D10_SAMPLE_RATE_625_50I); SetAudioChannelCount(4); --- 140,145 ---- ! D10MXFOP1AWriter::D10MXFOP1AWriter() { SetSampleRate(D10_SAMPLE_RATE_625_50I); SetAudioChannelCount(4); *************** *** 150,157 **** --- 149,159 ---- mStartPosition = 0; // calculated in PrepareFile() SetBitRate(D10_BIT_RATE_50, mMaxEncodedImageSize); + mxf_generate_umid(&mFileSourcePackageUID); + mxf_generate_umid(&mMaterialPackageUID); mSystemItemSize = 0; mVideoItemSize = 0; mAudioItemSize = 0; + memset(&mEssenceContainerUL, 0, sizeof(mEssenceContainerUL)); mMXFFile = 0; *************** *** 239,247 **** } ! void D10MXFOP1AWriter::PrepareFile() { mxfTimestamp now; - mxfUMID file_package_uid; - mxfUMID material_package_uid; mxfUUID uuid; mxfUL picture_essence_coding_ul = g_Null_UL; --- 241,438 ---- } ! void D10MXFOP1AWriter::SetMaterialPackageUID(mxfUMID uid) ! { ! mMaterialPackageUID = uid; ! } ! ! void D10MXFOP1AWriter::SetFileSourcePackageUID(mxfUMID uid) ! { ! mFileSourcePackageUID = uid; ! } ! ! bool D10MXFOP1AWriter::CreateFile(string filename) ! { ! try ! { ! mMXFFile = File::openNew(filename); ! CreateFile(); ! } ! catch (...) ! { ! return false; ! } ! ! return true; ! } ! ! bool D10MXFOP1AWriter::CreateFile(File **file) ! { ! try ! { ! mMXFFile = *file; ! CreateFile(); ! } ! catch (...) ! { ! mMXFFile = 0; ! return false; ! } ! ! *file = 0; ! return true; ! } ! ! void D10MXFOP1AWriter::SetUserTimecode(Timecode user_timecode) ! { ! MXFPP_ASSERT(mMXFFile); ! ! mContentPackage.mUserTimecode = user_timecode; ! } ! ! Timecode D10MXFOP1AWriter::GenerateUserTimecode() ! { ! MXFPP_ASSERT(mMXFFile); ! ! Timecode user_timecode; ! int64_t tc_count = mStartPosition + mDuration; ! ! if (mDropFrameTimecode && mSampleRate == D10MXFOP1AWriter::D10_SAMPLE_RATE_525_60I) { ! // first 2 frame numbers shall be omitted at the start of each minute, ! // except minutes 0, 10, 20, 30, 40 and 50 ! ! int hour, min; ! int64_t prev_skipped_count = -1; ! int64_t skipped_count = 0; ! while (prev_skipped_count != skipped_count) ! { ! prev_skipped_count = skipped_count; ! ! hour = (tc_count + skipped_count) / (60 * 60 * mRoundedTimecodeBase); ! min = ((tc_count + skipped_count) % (60 * 60 * mRoundedTimecodeBase)) / (60 * mRoundedTimecodeBase); ! ! // add frames skipped ! skipped_count = (60-6) * 2 * hour; // every whole hour ! skipped_count += (min / 10) * 9 * 2; // every whole 10 min ! skipped_count += (min % 10) * 2; // every whole min, except min 0 ! } ! ! tc_count += skipped_count; ! } ! ! user_timecode.hour = tc_count / (60 * 60 * mRoundedTimecodeBase); ! user_timecode.min = (tc_count % (60 * 60 * mRoundedTimecodeBase)) / (60 * mRoundedTimecodeBase); ! user_timecode.sec = ((tc_count % (60 * 60 * mRoundedTimecodeBase)) % (60 * mRoundedTimecodeBase)) / mRoundedTimecodeBase; ! user_timecode.frame = ((tc_count % (60 * 60 * mRoundedTimecodeBase)) % (60 * mRoundedTimecodeBase)) % mRoundedTimecodeBase; ! ! return user_timecode; ! } ! ! void D10MXFOP1AWriter::SetVideo(const unsigned char *data, uint32_t size) ! { ! MXFPP_ASSERT(mMXFFile); ! MXFPP_CHECK(size > 0 && size <= mEncodedImageSize); ! ! mContentPackage.mVideoBytes.setBytes(data, size); ! ! if (size < mEncodedImageSize) ! mContentPackage.mVideoBytes.appendZeros(mEncodedImageSize - size); ! } ! ! uint32_t D10MXFOP1AWriter::GetAudioSampleCount() ! { ! return mAudioSequence[mAudioSequenceIndex]; ! } ! ! void D10MXFOP1AWriter::SetAudio(uint32_t channel, const unsigned char *data, uint32_t size) ! { ! MXFPP_ASSERT(mMXFFile); ! MXFPP_ASSERT(channel < mChannelCount); ! MXFPP_CHECK(size == mAudioSequence[mAudioSequenceIndex] * mAudioBytesPerSample); ! ! mContentPackage.mAudioBytes[channel].setBytes(data, size); ! } ! ! void D10MXFOP1AWriter::WriteContentPackage() ! { ! MXFPP_CHECK(mContentPackage.IsComplete(mChannelCount)); ! ! WriteContentPackage(&mContentPackage); ! ! mContentPackage.Reset(); ! } ! ! void D10MXFOP1AWriter::WriteContentPackage(const D10ContentPackage *content_package) ! { ! MXFPP_ASSERT(mMXFFile); ! ! // write system item ! ! uint32_t element_size = WriteSystemItem(content_package); ! mMXFFile->writeFill(mSystemItemSize - element_size); ! ! ! // write video item ! ! mMXFFile->writeFixedKL(&VIDEO_ELEMENT_KEY, LLEN, content_package->GetVideoSize()); ! MXFPP_CHECK(mMXFFile->write(content_package->GetVideo(), content_package->GetVideoSize()) == ! content_package->GetVideoSize()); ! mMXFFile->writeFill(mVideoItemSize - mxfKey_extlen - LLEN - content_package->GetVideoSize()); ! ! ! // write audio item ! ! element_size = WriteAES3AudioElement(content_package); ! mMXFFile->writeFill(mAudioItemSize - element_size); ! ! ! mDuration++; ! mAudioSequenceIndex = (mAudioSequenceIndex + 1) % mAudioSequenceCount; ! } ! ! int64_t D10MXFOP1AWriter::GetFileSize() const ! { ! return mMXFFile->size(); ! } ! ! void D10MXFOP1AWriter::CompleteFile() ! { ! MXFPP_ASSERT(mMXFFile); ! ! // write the footer partition pack ! Partition &footer_partition = mMXFFile->createPartition(); ! footer_partition.setKey(&MXF_PP_K(ClosedComplete, Footer)); ! footer_partition.write(mMXFFile); ! footer_partition.fillToKag(mMXFFile); ! ! ! // update metadata sets and index with duration ! size_t i; ! for (i = 0; i < mSetsWithDuration.size(); i++) ! mSetsWithDuration[i]->UpdateDuration(mDuration); ! mIndexSegment->setIndexDuration(mDuration); ! ! ! // re-write the header metadata ! mMXFFile->seek(mHeaderMetadataStartPos, SEEK_SET); ! KAGFillerWriter kag_filler_writer(mHeaderPartition); ! mHeaderMetadata->write(mMXFFile, mHeaderPartition, &kag_filler_writer); ! ! ! // re-write the header index table segment ! mIndexSegment->write(mMXFFile, mHeaderPartition, &kag_filler_writer); ! ! ! // update the partition packs ! mMXFFile->updatePartitions(); ! ! ! // done with the file ! delete mMXFFile; ! mMXFFile = 0; ! } ! ! void D10MXFOP1AWriter::CreateFile() { mxfTimestamp now; mxfUUID uuid; mxfUL picture_essence_coding_ul = g_Null_UL; *************** *** 254,259 **** mxf_get_timestamp_now(&now); - mxf_generate_umid(&file_package_uid); - mxf_generate_umid(&material_package_uid); if (mSampleRate == D10_SAMPLE_RATE_625_50I) { switch (mD10BitRate) --- 445,448 ---- *************** *** 300,308 **** - // open file - - mMXFFile = File::openNew(mFilename); - - // set minimum llen --- 489,492 ---- *************** *** 347,351 **** EssenceContainerData *ess_container_data = new EssenceContainerData(mHeaderMetadata); content_storage->appendEssenceContainerData(ess_container_data); ! ess_container_data->setLinkedPackageUID(file_package_uid); ess_container_data->setBodySID(1); ess_container_data->setIndexSID(2); --- 531,535 ---- EssenceContainerData *ess_container_data = new EssenceContainerData(mHeaderMetadata); content_storage->appendEssenceContainerData(ess_container_data); ! ess_container_data->setLinkedPackageUID(mFileSourcePackageUID); ess_container_data->setBodySID(1); ess_container_data->setIndexSID(2); *************** *** 355,359 **** MaterialPackage *material_package = new MaterialPackage(mHeaderMetadata); content_storage->appendPackages(material_package); ! material_package->setPackageUID(material_package_uid); material_package->setPackageCreationDate(now); material_package->setPackageModifiedDate(now); --- 539,543 ---- MaterialPackage *material_package = new MaterialPackage(mHeaderMetadata); content_storage->appendPackages(material_package); ! material_package->setPackageUID(mMaterialPackageUID); material_package->setPackageCreationDate(now); material_package->setPackageModifiedDate(now); *************** *** 417,421 **** source_clip->setStartPosition(0); source_clip->setSourceTrackID(i + 2); ! source_clip->setSourcePackageID(file_package_uid); mSetsWithDuration.push_back(new StructComponentSet(source_clip)); } --- 601,605 ---- source_clip->setStartPosition(0); source_clip->setSourceTrackID(i + 2); ! source_clip->setSourcePackageID(mFileSourcePackageUID); mSetsWithDuration.push_back(new StructComponentSet(source_clip)); } *************** *** 425,429 **** SourcePackage *file_source_package = new SourcePackage(mHeaderMetadata); content_storage->appendPackages(file_source_package); ! file_source_package->setPackageUID(file_package_uid); file_source_package->setPackageCreationDate(now); file_source_package->setPackageModifiedDate(now); --- 609,613 ---- SourcePackage *file_source_package = new SourcePackage(mHeaderMetadata); content_storage->appendPackages(file_source_package); ! file_source_package->setPackageUID(mFileSourcePackageUID); file_source_package->setPackageCreationDate(now); file_source_package->setPackageModifiedDate(now); *************** *** 601,742 **** } - void D10MXFOP1AWriter::SetTimecode(Timecode ltc) - { - MXFPP_ASSERT(mMXFFile); - - mContentPackage.mLTC = ltc; - } - - void D10MXFOP1AWriter::GenerateTimecode() - { - MXFPP_ASSERT(mMXFFile); - - Timecode ltc; - int64_t tc_count = mStartPosition + mDuration; - - if (mDropFrameTimecode && mSampleRate == D10MXFOP1AWriter::D10_SAMPLE_RATE_525_60I) { - // first 2 frame numbers shall be omitted at the start of each minute, - // except minutes 0, 10, 20, 30, 40 and 50 - - int hour, min; - int64_t prev_skipped_count = -1; - int64_t skipped_count = 0; - while (prev_skipped_count != skipped_count) - { - prev_skipped_count = skipped_count; - - hour = (tc_count + skipped_count) / (60 * 60 * mRoundedTimecodeBase); - min = ((tc_count + skipped_count) % (60 * 60 * mRoundedTimecodeBase)) / (60 * mRoundedTimecodeBase); - - // add frames skipped - skipped_count = (60-6) * 2 * hour; // every whole hour - skipped_count += (min / 10) * 9 * 2; // every whole 10 min - skipped_count += (min % 10) * 2; // every whole min, except min 0 - } - - tc_count += skipped_count; - } - - ltc.hour = tc_count / (60 * 60 * mRoundedTimecodeBase); - ltc.min = (tc_count % (60 * 60 * mRoundedTimecodeBase)) / (60 * mRoundedTimecodeBase); - ltc.sec = ((tc_count % (60 * 60 * mRoundedTimecodeBase)) % (60 * mRoundedTimecodeBase)) / mRoundedTimecodeBase; - ltc.frame = ((tc_count % (60 * 60 * mRoundedTimecodeBase)) % (60 * mRoundedTimecodeBase)) % mRoundedTimecodeBase; - - SetTimecode(ltc); - } - - void D10MXFOP1AWriter::SetVideo(const unsigned char *data, uint32_t size) - { - MXFPP_ASSERT(mMXFFile); - MXFPP_CHECK(size > 0 && size <= mEncodedImageSize); - - mContentPackage.mVideoBytes.setBytes(data, size); - - if (size < mEncodedImageSize) - mContentPackage.mVideoBytes.appendZeros(mEncodedImageSize - size); - } - - uint32_t D10MXFOP1AWriter::GetAudioSampleCount() - { - return mAudioSequence[mAudioSequenceIndex]; - } - - void D10MXFOP1AWriter::SetAudio(uint32_t channel, const unsigned char *data, uint32_t size) - { - MXFPP_ASSERT(mMXFFile); - MXFPP_ASSERT(channel < mChannelCount); - MXFPP_CHECK(size == mAudioSequence[mAudioSequenceIndex] * mAudioBytesPerSample); - - mContentPackage.mAudioBytes[channel].setBytes(data, size); - } - - void D10MXFOP1AWriter::WriteContentPackage() - { - MXFPP_ASSERT(mMXFFile); - MXFPP_CHECK(mContentPackage.IsComplete(mChannelCount)); - - // write system item - - uint32_t element_size = WriteSystemItem(); - mMXFFile->writeFill(mSystemItemSize - element_size); - - - // write video item - - mMXFFile->writeFixedKL(&VIDEO_ELEMENT_KEY, LLEN, mContentPackage.mVideoBytes.getSize()); - MXFPP_CHECK(mMXFFile->write(mContentPackage.mVideoBytes.getBytes(), mContentPackage.mVideoBytes.getSize()) == - mContentPackage.mVideoBytes.getSize()); - mMXFFile->writeFill(mVideoItemSize - mxfKey_extlen - LLEN - mContentPackage.mVideoBytes.getSize()); - - - // write audio item - - element_size = WriteAES3AudioElement(); - mMXFFile->writeFill(mAudioItemSize - element_size); - - - mDuration++; - - mContentPackage.Reset(); - mAudioSequenceIndex = (mAudioSequenceIndex + 1) % mAudioSequenceCount; - } - - void D10MXFOP1AWriter::CompleteFile() - { - MXFPP_ASSERT(mMXFFile); - - // write the footer partition pack - Partition &footer_partition = mMXFFile->createPartition(); - footer_partition.setKey(&MXF_PP_K(ClosedComplete, Footer)); - footer_partition.write(mMXFFile); - footer_partition.fillToKag(mMXFFile); - - - // update metadata sets and index with duration - size_t i; - for (i = 0; i < mSetsWithDuration.size(); i++) - mSetsWithDuration[i]->UpdateDuration(mDuration); - mIndexSegment->setIndexDuration(mDuration); - - - // re-write the header metadata - mMXFFile->seek(mHeaderMetadataStartPos, SEEK_SET); - KAGFillerWriter kag_filler_writer(mHeaderPartition); - mHeaderMetadata->write(mMXFFile, mHeaderPartition, &kag_filler_writer); - - - // re-write the header index table segment - mIndexSegment->write(mMXFFile, mHeaderPartition, &kag_filler_writer); - - - // update the partition packs - mMXFFile->updatePartitions(); - - - // done with the file - delete mMXFFile; - mMXFFile = 0; - } - void D10MXFOP1AWriter::CalculateStartPosition() { --- 785,788 ---- *************** *** 758,762 **** } ! uint32_t D10MXFOP1AWriter::WriteSystemItem() { // System Metadata Pack --- 804,808 ---- } ! uint32_t D10MXFOP1AWriter::WriteSystemItem(const D10ContentPackage *content_package) { // System Metadata Pack *************** *** 783,789 **** MXFPP_CHECK(mMXFFile->write(bytes, sizeof(bytes)) == sizeof(bytes)); ! // User date / time stamp (LTC) bytes[0] = 0x81; // SMPTE 12-M timecode ! convert_timecode_to_12m(&mContentPackage.mLTC, mDropFrameTimecode, &bytes[1]); MXFPP_CHECK(mMXFFile->write(bytes, sizeof(bytes)) == sizeof(bytes)); --- 829,835 ---- MXFPP_CHECK(mMXFFile->write(bytes, sizeof(bytes)) == sizeof(bytes)); ! // User date / time stamp bytes[0] = 0x81; // SMPTE 12-M timecode ! convert_timecode_to_12m(content_package->GetUserTimecode(), mDropFrameTimecode, &bytes[1]); MXFPP_CHECK(mMXFFile->write(bytes, sizeof(bytes)) == sizeof(bytes)); *************** *** 796,800 **** } ! uint32_t D10MXFOP1AWriter::WriteAES3AudioElement() { uint32_t s, c; --- 842,846 ---- } ! uint32_t D10MXFOP1AWriter::WriteAES3AudioElement(const D10ContentPackage *content_package) { uint32_t s, c; *************** *** 817,835 **** if (mAudioBytesPerSample == 3) { // 24-bit ! bytes[0] |= (mContentPackage.mAudioBytes[c][s * mAudioBytesPerSample] << 4) & 0xf0; ! bytes[1] = ((mContentPackage.mAudioBytes[c][s * mAudioBytesPerSample] >> 4) & 0x0f) | ! ((mContentPackage.mAudioBytes[c][s * mAudioBytesPerSample + 1] << 4) & 0xf0); ! bytes[2] = ((mContentPackage.mAudioBytes[c][s * mAudioBytesPerSample + 1] >> 4) & 0x0f) | ! ((mContentPackage.mAudioBytes[c][s * mAudioBytesPerSample + 2] << 4) & 0xf0); ! bytes[3] = ((mContentPackage.mAudioBytes[c][s * mAudioBytesPerSample + 2] >> 4) & 0x0f); } else if (mAudioBytesPerSample == 2) { // 16-bit ! bytes[1] = ((mContentPackage.mAudioBytes[c][s * mAudioBytesPerSample] << 4) & 0xf0); ! bytes[2] = ((mContentPackage.mAudioBytes[c][s * mAudioBytesPerSample] >> 4) & 0x0f) | ! ((mContentPackage.mAudioBytes[c][s * mAudioBytesPerSample + 1] << 4) & 0xf0); ! bytes[3] = ((mContentPackage.mAudioBytes[c][s * mAudioBytesPerSample + 1] >> 4) & 0x0f); } else { // 8-bit bytes[1] = 0x00; ! bytes[2] = ((mContentPackage.mAudioBytes[c][s * mAudioBytesPerSample] << 4) & 0xf0); ! bytes[3] = ((mContentPackage.mAudioBytes[c][s * mAudioBytesPerSample] >> 4) & 0x0f); } --- 863,881 ---- if (mAudioBytesPerSample == 3) { // 24-bit ! bytes[0] |= (content_package->GetAudio(c)[s * mAudioBytesPerSample] << 4) & 0xf0; ! bytes[1] = ((content_package->GetAudio(c)[s * mAudioBytesPerSample] >> 4) & 0x0f) | ! ((content_package->GetAudio(c)[s * mAudioBytesPerSample + 1] << 4) & 0xf0); ! bytes[2] = ((content_package->GetAudio(c)[s * mAudioBytesPerSample + 1] >> 4) & 0x0f) | ! ((content_package->GetAudio(c)[s * mAudioBytesPerSample + 2] << 4) & 0xf0); ! bytes[3] = ((content_package->GetAudio(c)[s * mAudioBytesPerSample + 2] >> 4) & 0x0f); } else if (mAudioBytesPerSample == 2) { // 16-bit ! bytes[1] = ((content_package->GetAudio(c)[s * mAudioBytesPerSample] << 4) & 0xf0); ! bytes[2] = ((content_package->GetAudio(c)[s * mAudioBytesPerSample] >> 4) & 0x0f) | ! ((content_package->GetAudio(c)[s * mAudioBytesPerSample + 1] << 4) & 0xf0); ! bytes[3] = ((content_package->GetAudio(c)[s * mAudioBytesPerSample + 1] >> 4) & 0x0f); } else { // 8-bit bytes[1] = 0x00; ! bytes[2] = ((content_package->GetAudio(c)[s * mAudioBytesPerSample] << 4) & 0xf0); ! bytes[3] = ((content_package->GetAudio(c)[s * mAudioBytesPerSample] >> 4) & 0x0f); } Index: test_d10mxfop1awriter.cpp =================================================================== RCS file: /cvsroot/ingex/ingex/libMXF++/examples/D10MXFOP1AWriter/test_d10mxfop1awriter.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_d10mxfop1awriter.cpp 12 Feb 2010 13:52:49 -0000 1.1 --- test_d10mxfop1awriter.cpp 17 Feb 2010 16:04:24 -0000 1.2 *************** *** 99,103 **** const char *start_timecode_str = 0; bool drop_frame = false; ! mxfRational aspect_ratio; int value, num, den; int cmdln_index; --- 99,103 ---- const char *start_timecode_str = 0; bool drop_frame = false; ! mxfRational aspect_ratio = {16, 9}; int value, num, den; int cmdln_index; *************** *** 297,301 **** try { ! auto_ptr<D10MXFOP1AWriter> writer(new D10MXFOP1AWriter(out_filename)); writer->SetSampleRate(sample_rate); --- 297,301 ---- try { ! auto_ptr<D10MXFOP1AWriter> writer(new D10MXFOP1AWriter()); writer->SetSampleRate(sample_rate); *************** *** 305,309 **** writer->SetStartTimecode(start_timecode, drop_frame); writer->SetBitRate(video_bit_rate, video_frame_size); ! writer->PrepareFile(); unsigned char video[250000]; --- 305,310 ---- writer->SetStartTimecode(start_timecode, drop_frame); writer->SetBitRate(video_bit_rate, video_frame_size); ! if (!writer->CreateFile(out_filename)) ! throw MXFException("Failed to create file %s", out_filename); unsigned char video[250000]; *************** *** 313,317 **** int64_t frame_count = 0; while (true) { ! writer->GenerateTimecode(); if (fread(video, video_frame_size, 1, video_file) != 1) { --- 314,318 ---- int64_t frame_count = 0; while (true) { ! writer->SetUserTimecode(writer->GenerateUserTimecode()); if (fread(video, video_frame_size, 1, video_file) != 1) { |