diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dcp.cc | 8 | ||||
| -rw-r--r-- | src/mxf_asset.cc | 11 | ||||
| -rw-r--r-- | src/mxf_asset.h | 2 | ||||
| -rw-r--r-- | src/picture_asset.cc | 14 | ||||
| -rw-r--r-- | src/picture_asset.h | 12 | ||||
| -rw-r--r-- | src/sound_asset.cc | 112 | ||||
| -rw-r--r-- | src/sound_asset.h | 39 |
7 files changed, 176 insertions, 22 deletions
@@ -361,9 +361,7 @@ CPL::CPL (string directory, string file, shared_ptr<const AssetMap> asset_map, b try { picture.reset (new MonoPictureAsset ( _directory, - asset_map->asset_from_id (p->id)->chunks.front()->path, - _fps, - (*i)->asset_list->main_picture->duration + asset_map->asset_from_id (p->id)->chunks.front()->path ) ); @@ -400,9 +398,7 @@ CPL::CPL (string directory, string file, shared_ptr<const AssetMap> asset_map, b try { sound.reset (new SoundAsset ( _directory, - asset_map->asset_from_id ((*i)->asset_list->main_sound->id)->chunks.front()->path, - _fps, - (*i)->asset_list->main_sound->duration + asset_map->asset_from_id ((*i)->asset_list->main_sound->id)->chunks.front()->path ) ); diff --git a/src/mxf_asset.cc b/src/mxf_asset.cc index af3c74dc..7c75cb27 100644 --- a/src/mxf_asset.cc +++ b/src/mxf_asset.cc @@ -36,6 +36,17 @@ using boost::shared_ptr; using boost::dynamic_pointer_cast; using namespace libdcp; +MXFAsset::MXFAsset (string directory, string file_name) + : Asset (directory, file_name) + , _progress (0) + , _fps (0) + , _entry_point (0) + , _intrinsic_duration (0) + , _duration (0) +{ + +} + MXFAsset::MXFAsset (string directory, string file_name, boost::signals2::signal<void (float)>* progress, int fps, int intrinsic_duration) : Asset (directory, file_name) , _progress (progress) diff --git a/src/mxf_asset.h b/src/mxf_asset.h index fd786cc6..ff43fecb 100644 --- a/src/mxf_asset.h +++ b/src/mxf_asset.h @@ -30,6 +30,8 @@ namespace libdcp class MXFAsset : public Asset { public: + MXFAsset (std::string directory, std::string file_name); + /** Construct an MXFAsset. * @param directory Directory where MXF file is. * @param file_name Name of MXF file. diff --git a/src/picture_asset.cc b/src/picture_asset.cc index f3d52396..a7d5243a 100644 --- a/src/picture_asset.cc +++ b/src/picture_asset.cc @@ -53,6 +53,12 @@ PictureAsset::PictureAsset (string directory, string mxf_name, boost::signals2:: } +PictureAsset::PictureAsset (string directory, string mxf_name) + : MXFAsset (directory, mxf_name) +{ + +} + void PictureAsset::write_to_cpl (ostream& s) const { @@ -161,8 +167,8 @@ MonoPictureAsset::MonoPictureAsset (string directory, string mxf_name, int fps, } -MonoPictureAsset::MonoPictureAsset (string directory, string mxf_name, int fps, int intrinsic_duration) - : PictureAsset (directory, mxf_name, 0, fps, intrinsic_duration, Size (0, 0)) +MonoPictureAsset::MonoPictureAsset (string directory, string mxf_name) + : PictureAsset (directory, mxf_name) { ASDCP::JP2K::MXFReader reader; if (ASDCP_FAILURE (reader.OpenRead (path().string().c_str()))) { @@ -176,6 +182,9 @@ MonoPictureAsset::MonoPictureAsset (string directory, string mxf_name, int fps, _size.width = desc.StoredWidth; _size.height = desc.StoredHeight; + _fps = desc.EditRate.Numerator; + assert (desc.EditRate.Denominator == 1); + _intrinsic_duration = desc.ContainerDuration; } void @@ -434,6 +443,7 @@ MonoPictureAssetWriter::finalize () _finalized = true; _asset->set_intrinsic_duration (_frames_written); + _asset->set_duration (_frames_written); } MonoPictureAssetWriter::~MonoPictureAssetWriter () diff --git a/src/picture_asset.h b/src/picture_asset.h index 059e5926..dd69e352 100644 --- a/src/picture_asset.h +++ b/src/picture_asset.h @@ -36,6 +36,7 @@ class StereoPictureFrame; class PictureAsset : public MXFAsset { public: + PictureAsset (std::string directory, std::string mxf_name); PictureAsset (std::string directory, std::string mxf_name, boost::signals2::signal<void (float)>* progress, int fps, int intrinsic_duration, Size size); /** Write details of this asset to a CPL stream. @@ -129,17 +130,12 @@ public: Size size ); - MonoPictureAsset ( - std::string directory, - std::string mxf_name, - int fps, - Size size - ); + MonoPictureAsset (std::string directory, std::string mxf_name); + + MonoPictureAsset (std::string directory, std::string mxf_name, int fps, Size size); boost::shared_ptr<MonoPictureAssetWriter> start_write (); - MonoPictureAsset (std::string directory, std::string mxf_name, int fps, int intrinsic_duration); - boost::shared_ptr<const MonoPictureFrame> get_frame (int n) const; bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, std::list<std::string>& notes) const; diff --git a/src/sound_asset.cc b/src/sound_asset.cc index 04ca88da..89132f26 100644 --- a/src/sound_asset.cc +++ b/src/sound_asset.cc @@ -75,8 +75,8 @@ SoundAsset::SoundAsset ( construct (get_path); } -SoundAsset::SoundAsset (string directory, string mxf_name, int fps, int intrinsic_duration) - : MXFAsset (directory, mxf_name, 0, fps, intrinsic_duration) +SoundAsset::SoundAsset (string directory, string mxf_name) + : MXFAsset (directory, mxf_name) , _channels (0) , _start_frame (0) { @@ -85,7 +85,6 @@ SoundAsset::SoundAsset (string directory, string mxf_name, int fps, int intrinsi throw MXFFileError ("could not open MXF file for reading", path().string()); } - ASDCP::PCM::AudioDescriptor desc; if (ASDCP_FAILURE (reader.FillAudioDescriptor (desc))) { throw DCPReadError ("could not read audio MXF information"); @@ -93,6 +92,18 @@ SoundAsset::SoundAsset (string directory, string mxf_name, int fps, int intrinsi _sampling_rate = desc.AudioSamplingRate.Numerator / desc.AudioSamplingRate.Denominator; _channels = desc.ChannelCount; + _fps = desc.EditRate.Numerator; + assert (desc.EditRate.Denominator == 1); + _intrinsic_duration = desc.ContainerDuration; +} + +SoundAsset::SoundAsset (string directory, string mxf_name, int fps, int channels, int sampling_rate) + : MXFAsset (directory, mxf_name, 0, fps, 0) + , _channels (channels) + , _sampling_rate (sampling_rate) + , _start_frame (0) +{ + } string @@ -157,7 +168,7 @@ SoundAsset::construct (boost::function<string (Channel)> get_path) frame_buffer.Size (ASDCP::PCM::CalcFrameBufferSize (audio_desc)); ASDCP::WriterInfo writer_info; - fill_writer_info (&writer_info, _uuid); + MXFAsset::fill_writer_info (&writer_info, _uuid); ASDCP::PCM::MXFWriter mxf_writer; if (ASDCP_FAILURE (mxf_writer.OpenWrite (path().string().c_str(), writer_info, audio_desc))) { @@ -302,3 +313,96 @@ SoundAsset::get_frame (int n) const { return shared_ptr<const SoundFrame> (new SoundFrame (path().string(), n + _entry_point)); } + +shared_ptr<SoundAssetWriter> +SoundAsset::start_write () +{ + /* XXX: can't we use a shared_ptr here? */ + return shared_ptr<SoundAssetWriter> (new SoundAssetWriter (this)); +} + +SoundAssetWriter::SoundAssetWriter (SoundAsset* a) + : _asset (a) + , _finalized (false) + , _frames_written (0) + , _frame_buffer_offset (0) +{ + /* Derived from ASDCP::Wav::SimpleWaveHeader::FillADesc */ + _audio_desc.EditRate = ASDCP::Rational (_asset->frames_per_second(), 1); + _audio_desc.AudioSamplingRate = ASDCP::Rational (_asset->sampling_rate(), 0); + _audio_desc.Locked = 0; + _audio_desc.ChannelCount = _asset->channels (); + _audio_desc.QuantizationBits = 24; + _audio_desc.BlockAlign = 3 * _asset->channels(); + _audio_desc.AvgBps = _asset->sampling_rate() * _audio_desc.BlockAlign; + _audio_desc.LinkedTrackID = 0; + _audio_desc.ChannelFormat = ASDCP::PCM::CF_NONE; + + _frame_buffer.Capacity (ASDCP::PCM::CalcFrameBufferSize (_audio_desc)); + _frame_buffer.Size (ASDCP::PCM::CalcFrameBufferSize (_audio_desc)); + memset (_frame_buffer.Data(), 0, _frame_buffer.Capacity()); + + MXFAsset::fill_writer_info (&_writer_info, _asset->uuid ()); + + if (ASDCP_FAILURE (_mxf_writer.OpenWrite (_asset->path().c_str(), _writer_info, _audio_desc))) { + throw FileError ("could not open audio MXF for writing", _asset->path().string()); + } +} + +void +SoundAssetWriter::write (float const * const * data, int frames) +{ + for (int i = 0; i < frames; ++i) { + + byte_t* out = _frame_buffer.Data() + _frame_buffer_offset; + + /* Write one sample per channel */ + for (int j = 0; j < _asset->channels(); ++j) { + int32_t const s = data[j][i] * (1 << 23); + *out++ = (s & 0xff); + *out++ = (s & 0xff00) >> 8; + *out++ = (s & 0xff0000) >> 16; + } + _frame_buffer_offset += 3 * _asset->channels(); + + assert (_frame_buffer_offset <= int (_frame_buffer.Capacity())); + + /* Finish the MXF frame if required */ + if (_frame_buffer_offset == int (_frame_buffer.Capacity())) { + write_current_frame (); + _frame_buffer_offset = 0; + memset (_frame_buffer.Data(), 0, _frame_buffer.Capacity()); + } + } +} + +void +SoundAssetWriter::write_current_frame () +{ + if (ASDCP_FAILURE (_mxf_writer.WriteFrame (_frame_buffer, 0, 0))) { + throw MiscError ("could not write audio MXF frame"); + } + + ++_frames_written; +} + +void +SoundAssetWriter::finalize () +{ + if (_frame_buffer_offset > 0) { + write_current_frame (); + } + + if (ASDCP_FAILURE (_mxf_writer.Finalize())) { + throw MiscError ("could not finalise audio MXF"); + } + + _finalized = true; + _asset->set_intrinsic_duration (_frames_written); + _asset->set_duration (_frames_written); +} + +SoundAssetWriter::~SoundAssetWriter () +{ + assert (_finalized); +} diff --git a/src/sound_asset.h b/src/sound_asset.h index 569bb305..17767b3a 100644 --- a/src/sound_asset.h +++ b/src/sound_asset.h @@ -24,13 +24,40 @@ * @brief An asset made up of PCM audio data files */ +#include "AS_DCP.h" #include "mxf_asset.h" #include "types.h" namespace libdcp { -class SoundFrame; +class SoundFrame; + +class SoundAsset; + +class SoundAssetWriter +{ +public: + ~SoundAssetWriter (); + + void write (float const * const *, int); + void finalize (); + +private: + friend class SoundAsset; + + SoundAssetWriter (SoundAsset *); + void write_current_frame (); + + SoundAsset* _asset; + bool _finalized; + int _frames_written; + int _frame_buffer_offset; + ASDCP::PCM::MXFWriter _mxf_writer; + ASDCP::PCM::FrameBuffer _frame_buffer; + ASDCP::WriterInfo _writer_info; + ASDCP::PCM::AudioDescriptor _audio_desc; +}; /** @brief An asset made up of WAV files */ class SoundAsset : public MXFAsset @@ -82,10 +109,18 @@ public: SoundAsset ( std::string directory, + std::string mxf_name + ); + + SoundAsset ( + std::string directory, std::string mxf_name, int fps, - int intrinsic_duration + int channels, + int sampling_rate ); + + boost::shared_ptr<SoundAssetWriter> start_write (); /** Write details of this asset to a CPL stream. * @param s Stream. |
