Tidying up; comments; fps in assets -> edit rate.
authorCarl Hetherington <cth@carlh.net>
Fri, 18 Jan 2013 22:15:51 +0000 (22:15 +0000)
committerCarl Hetherington <cth@carlh.net>
Fri, 18 Jan 2013 22:15:51 +0000 (22:15 +0000)
src/mxf_asset.cc
src/mxf_asset.h
src/picture_asset.cc
src/picture_asset.h
src/sound_asset.cc

index 7c75cb278bb2025f09cab08e1c26dd2b8e663d21..9b4cbf745625bab25d85ad8752240b764c5e35f7 100644 (file)
@@ -39,7 +39,7 @@ using namespace libdcp;
 MXFAsset::MXFAsset (string directory, string file_name)
        : Asset (directory, file_name)
        , _progress (0)
-       , _fps (0)
+       , _edit_rate (0)
        , _entry_point (0)
        , _intrinsic_duration (0)
        , _duration (0)
@@ -47,29 +47,16 @@ MXFAsset::MXFAsset (string directory, string file_name)
 
 }
 
-MXFAsset::MXFAsset (string directory, string file_name, boost::signals2::signal<void (float)>* progress, int fps, int intrinsic_duration)
+MXFAsset::MXFAsset (string directory, string file_name, boost::signals2::signal<void (float)>* progress, int edit_rate, int intrinsic_duration)
        : Asset (directory, file_name)
        , _progress (progress)
-       , _fps (fps)
+       , _edit_rate (edit_rate)
        , _entry_point (0)
        , _intrinsic_duration (intrinsic_duration)
        , _duration (intrinsic_duration)
 {
        
 }
-
-void
-MXFAsset::set_entry_point (int e)
-{
-       _entry_point = e;
-}
-
-void
-MXFAsset::set_duration (int d)
-{
-       _duration = d;
-}
-
 void
 MXFAsset::fill_writer_info (ASDCP::WriterInfo* writer_info, string uuid)
 {
@@ -97,8 +84,8 @@ MXFAsset::equals (shared_ptr<const Asset> other, EqualityOptions, list<string>&
                return false;
        }
 
-       if (_fps != other_mxf->_fps) {
-               notes.push_back ("MXF frames per second differ");
+       if (_edit_rate != other_mxf->_edit_rate) {
+               notes.push_back ("MXF edit rates differ");
                return false;
        }
        
@@ -114,9 +101,3 @@ MXFAsset::equals (shared_ptr<const Asset> other, EqualityOptions, list<string>&
        
        return true;
 }
-
-int
-MXFAsset::intrinsic_duration () const
-{
-       return _intrinsic_duration;
-}
index ff43fecb60a224ab59bfabcd079e1b229c5bdb66..430e915771803e05bb717cc64568572dc437ca35 100644 (file)
@@ -30,31 +30,47 @@ namespace libdcp
 class MXFAsset : public Asset
 {
 public:
+       /** Construct an MXFAsset.
+        *  This class will not write anything to disk in this constructor, but subclasses may.
+        *
+        *  @param directory Directory where MXF file is.
+        *  @param file_name Name of MXF file.
+        */
        MXFAsset (std::string directory, std::string file_name);
        
        /** Construct an MXFAsset.
+        *  This class will not write anything to disk in this constructor, but subclasses may.
+        *
         *  @param directory Directory where MXF file is.
         *  @param file_name Name of MXF file.
-        *  @param progress Signal to inform of progress.
-        *  @param fps Frames per second.
+        *  @param progress Signal to use to inform of progress, or 0.
+        *  @param edit_rate Edit rate in frames per second (usually equal to the video frame rate).
         *  @param intrinsic_duration Duration of the whole asset in frames.
         */
-       MXFAsset (std::string directory, std::string file_name, boost::signals2::signal<void (float)>* progress, int fps, int intrinsic_duration);
+       MXFAsset (std::string directory, std::string file_name, boost::signals2::signal<void (float)>* progress, int edit_rate, int intrinsic_duration);
 
-       void set_entry_point (int e);
-       void set_duration (int d);
-
-       virtual bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, std::list<std::string>& notes) const;
+       void set_entry_point (int e) {
+               _entry_point = e;
+       }
        
-       int intrinsic_duration () const;
-       int frames_per_second () const {
-               return _fps;
+       void set_duration (int d) {
+               _duration = d;
        }
 
        void set_intrinsic_duration (int d) {
                _intrinsic_duration = d;
        }
 
+       virtual bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, std::list<std::string>& notes) const;
+       
+       int intrinsic_duration () const {
+               return _intrinsic_duration;
+       }
+       
+       int edit_rate () const {
+               return _edit_rate;
+       }
+
        /** Fill in a ADSCP::WriteInfo struct.
         *  @param w struct to fill in.
         *  @param uuid uuid to use.
@@ -63,10 +79,10 @@ public:
 
 protected:
 
-       /** Signal to emit to report progress */
+       /** Signal to emit to report progress, or 0 */
        boost::signals2::signal<void (float)>* _progress;
-       /** Frames per second */
-       int _fps;
+       /** The edit rate; this is normally equal to the number of video frames per second */
+       int _edit_rate;
        /** Start point to present in frames */
        int _entry_point;
        /** Total length in frames */
index a7d5243a5df04efabdbc7d72cc3feca9faf480bf..a2f6b584a154d97496be7e9f4ccf9c613c2feeb8 100644 (file)
@@ -65,11 +65,11 @@ PictureAsset::write_to_cpl (ostream& s) const
        s << "        <MainPicture>\n"
          << "          <Id>urn:uuid:" << _uuid << "</Id>\n"
          << "          <AnnotationText>" << _file_name << "</AnnotationText>\n"
-         << "          <EditRate>" << _fps << " 1</EditRate>\n"
+         << "          <EditRate>" << _edit_rate << " 1</EditRate>\n"
          << "          <IntrinsicDuration>" << _intrinsic_duration << "</IntrinsicDuration>\n"
          << "          <EntryPoint>" << _entry_point << "</EntryPoint>\n"
          << "          <Duration>" << _duration << "</Duration>\n"
-         << "          <FrameRate>" << _fps << " 1</FrameRate>\n"
+         << "          <FrameRate>" << _edit_rate << " 1</FrameRate>\n"
          << "          <ScreenAspectRatio>" << _size.width << " " << _size.height << "</ScreenAspectRatio>\n"
          << "        </MainPicture>\n";
 }
@@ -182,7 +182,7 @@ MonoPictureAsset::MonoPictureAsset (string directory, string mxf_name)
 
        _size.width = desc.StoredWidth;
        _size.height = desc.StoredHeight;
-       _fps = desc.EditRate.Numerator;
+       _edit_rate = desc.EditRate.Numerator;
        assert (desc.EditRate.Denominator == 1);
        _intrinsic_duration = desc.ContainerDuration;
 }
@@ -198,7 +198,7 @@ MonoPictureAsset::construct (boost::function<string (int)> get_path)
        
        ASDCP::JP2K::PictureDescriptor picture_desc;
        j2k_parser.FillPictureDescriptor (picture_desc);
-       picture_desc.EditRate = ASDCP::Rational (_fps, 1);
+       picture_desc.EditRate = ASDCP::Rational (_edit_rate, 1);
        
        ASDCP::WriterInfo writer_info;
        fill_writer_info (&writer_info, _uuid);
@@ -400,6 +400,9 @@ MonoPictureAsset::start_write ()
        return shared_ptr<MonoPictureAssetWriter> (new MonoPictureAssetWriter (this));
 }
 
+/** @param a Asset to write to.  `a' must not be deleted while
+ *  this writer class still exists, or bad things will happen.
+ */
 MonoPictureAssetWriter::MonoPictureAssetWriter (MonoPictureAsset* a)
        : _frame_buffer (4 * Kumu::Megabyte)
        , _asset (a)
@@ -412,13 +415,17 @@ MonoPictureAssetWriter::MonoPictureAssetWriter (MonoPictureAsset* a)
 void
 MonoPictureAssetWriter::write (uint8_t* data, int size)
 {
+       assert (!_finalized);
+       
        if (ASDCP_FAILURE (_j2k_parser.OpenReadFrame (data, size, _frame_buffer))) {
                throw MiscError ("could not parse J2K frame");
        }
 
        if (_frames_written == 0) {
+               /* This is our first frame; set up the writer */
+               
                _j2k_parser.FillPictureDescriptor (_picture_descriptor);
-               _picture_descriptor.EditRate = ASDCP::Rational (_asset->frames_per_second(), 1);
+               _picture_descriptor.EditRate = ASDCP::Rational (_asset->edit_rate(), 1);
        
                MXFAsset::fill_writer_info (&_writer_info, _asset->uuid());
                
index dd69e352f5ff7512416a84e12999ea328b087477..ea558e7d0c77781191000e56fa848d8d334e69ac 100644 (file)
@@ -36,7 +36,24 @@ class StereoPictureFrame;
 class PictureAsset : public MXFAsset
 {
 public:
+       /** Construct a PictureAsset.
+        *  This class will not write anything to disk in this constructor, but subclasses may.
+        *  
+        *  @param directory Directory where MXF file is.
+        *  @param mxf_name Name of MXF file.
+        */
        PictureAsset (std::string directory, std::string mxf_name);
+
+       /** Construct a PictureAsset.
+        *  This class will not write anything to disk in this constructor, but subclasses may.
+        *
+        *  @param directory Directory where MXF file is.
+        *  @param mxf_name Name of MXF file.
+        *  @param progress Signal to use to inform of progres, or 0.
+        *  @param fps Video Frames per second.
+        *  @param intrinsic_duration Duration of all the frames in the asset.
+        *  @param size Size of video frame images in pixels.
+        */
        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.
@@ -63,6 +80,16 @@ protected:
 
 class MonoPictureAsset;
 
+/** A helper class for writing to MonoPictureAssets progressively (i.e. writing frame-by-frame,
+ *  rather than giving libdcp all the frames in one go).
+ *
+ *  Objects of this class can only be created with MonoPictureAsset::start_write().
+ *
+ *  Frames can be written to the MonoPictureAsset by calling write() with a JPEG2000 image
+ *  (a verbatim .j2 file).  finalize() must be called after the last frame has been written.
+ *  The action of finalize() can't be done in MonoPictureAssetWriter's destructor as it may
+ *  throw an exception.
+ */
 class MonoPictureAssetWriter
 {
 public:
@@ -82,7 +109,9 @@ private:
        ASDCP::WriterInfo _writer_info;
        ASDCP::JP2K::PictureDescriptor _picture_descriptor;
        MonoPictureAsset* _asset;
+       /** Number of picture frames written to the asset so far */
        int _frames_written;
+       /** true if finalize() has been called */
        bool _finalized;
 };
 
@@ -90,13 +119,14 @@ private:
 class MonoPictureAsset : public PictureAsset
 {
 public:
-       /** Construct a PictureAsset, generating the MXF from the JPEG2000 files.
+       /** Construct a MonoPictureAsset, generating the MXF from the JPEG2000 files.
         *  This may take some time; progress is indicated by emission of the Progress signal.
+        *
         *  @param files Pathnames of JPEG2000 files, in frame order.
         *  @param directory Directory in which to create MXF file.
         *  @param mxf_name Name of MXF file to create.
         *  @param progress Signal to inform of progress.
-        *  @param fps Frames per second.
+        *  @param fps Video frames per second.
         *  @param intrinsic_duration Length of the whole asset in frames.
         *  @param size Size of images in pixels.
         */
@@ -110,13 +140,14 @@ public:
                Size size
                );
 
-       /** Construct a PictureAsset, generating the MXF from the JPEG2000 files.
+       /** Construct a MonoPictureAsset, generating the MXF from the JPEG2000 files.
         *  This may take some time; progress is indicated by emission of the Progress signal.
+        *
         *  @param get_path Functor which returns a JPEG2000 file path for a given frame (frames counted from 0).
         *  @param directory Directory in which to create MXF file.
         *  @param mxf_name Name of MXF file to create.
         *  @param progress Signal to inform of progress.
-        *  @param fps Frames per second.
+        *  @param fps Video frames per second.
         *  @param intrinsic_duration Length of the whole asset in frames.
         *  @param size Size of images in pixels.
         */
@@ -130,10 +161,23 @@ public:
                Size size
                );
 
+       /** Construct a MonoPictureAsset, reading the MXF from disk.
+        *  @param directory Directory that the MXF is in.
+        *  @param mxf_name The filename of the MXF within `directory'.
+        */
        MonoPictureAsset (std::string directory, std::string mxf_name);
-       
+
+       /** Construct a MonoPictureAsset for progressive writing using
+        *  start_write() and a MonoPictureAssetWriter.
+        *
+        *  @param directory Directory to put the MXF in.
+        *  @param mxf_name Filename of the MXF within this directory.
+        *  @param fps Video frames per second.
+        *  @param size Size in pixels that the picture frames will be.
+        */
        MonoPictureAsset (std::string directory, std::string mxf_name, int fps, Size size);
 
+       /** Start a progressive write to a MonoPictureAsset */
        boost::shared_ptr<MonoPictureAssetWriter> start_write ();
 
        boost::shared_ptr<const MonoPictureFrame> get_frame (int n) const;
index 89132f2628d20ab5d4bbc4f907228ed61a3d59e2..499f41122209219ff0dc54b58b1564baee9b2e85 100644 (file)
@@ -92,7 +92,7 @@ SoundAsset::SoundAsset (string directory, string mxf_name)
 
        _sampling_rate = desc.AudioSamplingRate.Numerator / desc.AudioSamplingRate.Denominator;
        _channels = desc.ChannelCount;
-       _fps = desc.EditRate.Numerator;
+       _edit_rate = desc.EditRate.Numerator;
        assert (desc.EditRate.Denominator == 1);
        _intrinsic_duration = desc.ContainerDuration;
 }
@@ -117,10 +117,10 @@ SoundAsset::path_from_channel (Channel channel, vector<string> const & files)
 void
 SoundAsset::construct (boost::function<string (Channel)> get_path)
 {
-       ASDCP::Rational asdcp_fps (_fps, 1);
+       ASDCP::Rational asdcp_edit_rate (_edit_rate, 1);
 
        ASDCP::PCM::WAVParser pcm_parser_channel[_channels];
-       if (pcm_parser_channel[0].OpenRead (get_path(LEFT).c_str(), asdcp_fps)) {
+       if (pcm_parser_channel[0].OpenRead (get_path(LEFT).c_str(), asdcp_edit_rate)) {
                throw FileError ("could not open WAV file for reading", get_path(LEFT));
        }
        
@@ -128,7 +128,7 @@ SoundAsset::construct (boost::function<string (Channel)> get_path)
        pcm_parser_channel[0].FillAudioDescriptor (audio_desc);
        audio_desc.ChannelCount = 0;
        audio_desc.BlockAlign = 0;
-       audio_desc.EditRate = asdcp_fps;
+       audio_desc.EditRate = asdcp_edit_rate;
        audio_desc.AvgBps = audio_desc.AvgBps * _channels;
 
        Channel channels[] = {
@@ -152,7 +152,7 @@ SoundAsset::construct (boost::function<string (Channel)> get_path)
 
                string const path = get_path (channels[i]);
                
-               if (ASDCP_FAILURE (pcm_parser_channel[i].OpenRead (path.c_str(), asdcp_fps))) {
+               if (ASDCP_FAILURE (pcm_parser_channel[i].OpenRead (path.c_str(), asdcp_edit_rate))) {
                        throw FileError ("could not open WAV file for reading", path);
                }
 
@@ -227,7 +227,7 @@ SoundAsset::write_to_cpl (ostream& s) const
        s << "        <MainSound>\n"
          << "          <Id>urn:uuid:" << _uuid << "</Id>\n"
          << "          <AnnotationText>" << _file_name << "</AnnotationText>\n"
-         << "          <EditRate>" << _fps << " 1</EditRate>\n"
+         << "          <EditRate>" << _edit_rate << " 1</EditRate>\n"
          << "          <IntrinsicDuration>" << _intrinsic_duration << "</IntrinsicDuration>\n"
          << "          <EntryPoint>" << _entry_point << "</EntryPoint>\n"
          << "          <Duration>" << _duration << "</Duration>\n"
@@ -328,7 +328,7 @@ SoundAssetWriter::SoundAssetWriter (SoundAsset* a)
        , _frame_buffer_offset (0)
 {
        /* Derived from ASDCP::Wav::SimpleWaveHeader::FillADesc */
-       _audio_desc.EditRate = ASDCP::Rational (_asset->frames_per_second(), 1);
+       _audio_desc.EditRate = ASDCP::Rational (_asset->edit_rate(), 1);
        _audio_desc.AudioSamplingRate = ASDCP::Rational (_asset->sampling_rate(), 0);
        _audio_desc.Locked = 0;
        _audio_desc.ChannelCount = _asset->channels ();