Close assets on destruction even if finalize() is not called. v1.8.23
authorCarl Hetherington <cth@carlh.net>
Thu, 14 Jul 2022 21:51:21 +0000 (23:51 +0200)
committerCarl Hetherington <cth@carlh.net>
Thu, 14 Jul 2022 21:51:21 +0000 (23:51 +0200)
src/mono_picture_asset_writer.cc
src/mono_picture_asset_writer.h
src/sound_asset_writer.cc
src/sound_asset_writer.h
src/stereo_picture_asset_writer.cc
src/stereo_picture_asset_writer.h

index 1abdcccc3a83e2df5c6074426063823764863486..b2b829fab23a53aa5cd884469a76ff2d35af39ee 100644 (file)
@@ -74,6 +74,17 @@ MonoPictureAssetWriter::MonoPictureAssetWriter (PictureAsset* asset, boost::file
 }
 
 
+MonoPictureAssetWriter::~MonoPictureAssetWriter()
+{
+       try {
+               /* Last-resort finalization to close the file, at least */
+               if (_started) {
+                       _state->mxf_writer.Finalize();
+               }
+       } catch (...) {}
+}
+
+
 void
 MonoPictureAssetWriter::start (uint8_t const * data, int size)
 {
@@ -131,6 +142,7 @@ MonoPictureAssetWriter::finalize ()
                if (ASDCP_FAILURE(r)) {
                        boost::throw_exception (MXFFileError("error in finalizing video MXF", _file.string(), r));
                }
+               _started = false;
        }
 
        _picture_asset->_intrinsic_duration = _frames_written;
index 724e4ece357a28de5ead98572506a1ce287affee..551d8c804eaeb1dea966b7b58cff5bd493ddad09 100644 (file)
@@ -57,13 +57,15 @@ namespace dcp {
  *  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 .j2c 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.
+ *  (a verbatim .j2c file).  finalize() should be called after the last frame has been written,
+ *  but if it is not, it will be called by the destructor (though in that case any error
+ *  during finalization will be ignored).
  */
 class MonoPictureAssetWriter : public PictureAssetWriter
 {
 public:
+       ~MonoPictureAssetWriter();
+
        FrameInfo write (uint8_t const *, int) override;
        void fake_write (int size) override;
        bool finalize () override;
index 2842a1d56622cb6753311f72686ba7c2001977c4..40acf92491833cd97a78fa4bc9d8bd4c592282bb 100644 (file)
@@ -111,6 +111,17 @@ SoundAssetWriter::SoundAssetWriter (SoundAsset* asset, boost::filesystem::path f
 }
 
 
+SoundAssetWriter::~SoundAssetWriter()
+{
+       try {
+               /* Last-resort finalization to close the file, at least */
+               if (_started) {
+                       _state->mxf_writer.Finalize();
+               }
+       } catch (...) {}
+}
+
+
 void
 SoundAssetWriter::start ()
 {
@@ -265,6 +276,7 @@ SoundAssetWriter::finalize ()
                if (ASDCP_FAILURE(r)) {
                        boost::throw_exception (MiscError(String::compose ("could not finalise audio MXF (%1)", static_cast<int>(r))));
                }
+               _started = false;
        }
 
        _asset->_intrinsic_duration = _frames_written;
index fde56d95026715198d2f538aa93e41388fc6eca5..031af5c9937967487c02bbb866d09df0ebbc00b1 100644 (file)
@@ -67,6 +67,8 @@ class SoundAsset;
 class SoundAssetWriter : public AssetWriter
 {
 public:
+       ~SoundAssetWriter();
+
        /** @param data Pointer an array of float pointers, one for each channel.
         *  @param frames Number of frames i.e. number of floats that are given for each channel.
         */
index e02e83605de241592d7cabee94cdaadfb87588ec..f4ec7df0c2e383eb9654abee6da44f6a1da91f76 100644 (file)
@@ -68,6 +68,17 @@ StereoPictureAssetWriter::StereoPictureAssetWriter (PictureAsset* mxf, boost::fi
 }
 
 
+StereoPictureAssetWriter::~StereoPictureAssetWriter()
+{
+       try {
+               /* Last-resort finalization to close the file, at least */
+               if (_started) {
+                       _state->mxf_writer.Finalize();
+               }
+       } catch (...) {}
+}
+
+
 void
 StereoPictureAssetWriter::start (uint8_t const * data, int size)
 {
@@ -140,6 +151,7 @@ StereoPictureAssetWriter::finalize ()
                if (ASDCP_FAILURE(r)) {
                        boost::throw_exception (MXFFileError("error in finalizing video MXF", _file.string(), r));
                }
+               _started = false;
        }
 
        _picture_asset->_intrinsic_duration = _frames_written;
index 0a361e41f34d86976846d5b623c6bc461f21c221..287e7ecd786d87553ba76555a5a2e113b7986e4d 100644 (file)
@@ -53,13 +53,15 @@ namespace dcp {
  *  Objects of this class can only be created with StereoPictureAsset::start_write().
  *
  *  Frames can be written to the StereoPictureAsset by calling write() with a JPEG2000 image
- *  (a verbatim .j2c file).  finalize() must be called after the last frame has been written.
- *  The action of finalize() can't be done in StereoPictureAssetWriter's destructor as it may
- *  throw an exception.
+ *  (a verbatim .j2c file).  finalize() should be called after the last frame has been written,
+ *  but if it is not, it will be called by the destructor (though in that case any error
+ *  during finalization will be ignored).
  */
 class StereoPictureAssetWriter : public PictureAssetWriter
 {
 public:
+       ~StereoPictureAssetWriter();
+
        /** Write a frame for one eye.  Frames must be written left, then right, then left etc.
         *  @param data JPEG2000 data.
         *  @param size Size of data.