Use new libdcp reader interface.
authorCarl Hetherington <cth@carlh.net>
Wed, 1 Jun 2016 22:58:47 +0000 (23:58 +0100)
committerCarl Hetherington <cth@carlh.net>
Wed, 1 Jun 2016 22:58:47 +0000 (23:58 +0100)
cscript
src/lib/dcp_decoder.cc
src/lib/dcp_decoder.h
src/lib/dcp_examiner.cc
src/lib/video_mxf_decoder.cc
src/lib/video_mxf_decoder.h
test/audio_delay_test.cc
test/ffmpeg_audio_test.cc
test/silence_padding_test.cc

diff --git a/cscript b/cscript
index 7f25420e3829042767870b517e7e927f3c78c799..c3a17aa114750e8167996572535daf4b2153f305 100644 (file)
--- a/cscript
+++ b/cscript
@@ -237,7 +237,7 @@ def dependencies(target):
         ffmpeg_options = {}
 
     return (('ffmpeg-cdist', 'aab2fb1', ffmpeg_options),
-            ('libdcp', 'f028e8a'),
+            ('libdcp', 'a641fdc'),
             ('libsub', '3d8c3bc'))
 
 def configure_options(target):
index 18cbda84cb69b592ca964272a4645cfd574e97ed..e7e88d3191e9bf2a3ecfaa0f0f8108b1cf7e4613 100644 (file)
 #include <dcp/cpl.h>
 #include <dcp/reel.h>
 #include <dcp/mono_picture_asset.h>
+#include <dcp/mono_picture_asset_reader.h>
 #include <dcp/stereo_picture_asset.h>
+#include <dcp/stereo_picture_asset_reader.h>
 #include <dcp/reel_picture_asset.h>
 #include <dcp/reel_sound_asset.h>
 #include <dcp/reel_subtitle_asset.h>
 #include <dcp/mono_picture_frame.h>
 #include <dcp/stereo_picture_frame.h>
 #include <dcp/sound_frame.h>
+#include <dcp/sound_asset_reader.h>
 #include <boost/foreach.hpp>
 #include <iostream>
 
@@ -72,6 +75,7 @@ DCPDecoder::DCPDecoder (shared_ptr<const DCPContent> c, shared_ptr<Log> log, boo
 
        _reel = _reels.begin ();
        _offset = 0;
+       get_readers ();
 }
 
 bool
@@ -86,29 +90,27 @@ DCPDecoder::pass (PassReason reason, bool)
        /* Frame within the (played part of the) reel that is coming up next */
        int64_t const frame = _next.frames_round (vfr);
 
-       if ((*_reel)->main_picture () && reason != PASS_REASON_SUBTITLE) {
+       if ((_mono_reader || _stereo_reader) && reason != PASS_REASON_SUBTITLE) {
                shared_ptr<dcp::PictureAsset> asset = (*_reel)->main_picture()->asset ();
-               shared_ptr<dcp::MonoPictureAsset> mono = dynamic_pointer_cast<dcp::MonoPictureAsset> (asset);
-               shared_ptr<dcp::StereoPictureAsset> stereo = dynamic_pointer_cast<dcp::StereoPictureAsset> (asset);
                int64_t const entry_point = (*_reel)->main_picture()->entry_point ();
-               if (mono) {
-                       video->give (shared_ptr<ImageProxy> (new J2KImageProxy (mono->get_frame (entry_point + frame), asset->size())), _offset + frame);
+               if (_mono_reader) {
+                       video->give (shared_ptr<ImageProxy> (new J2KImageProxy (_mono_reader->get_frame (entry_point + frame), asset->size())), _offset + frame);
                } else {
                        video->give (
-                               shared_ptr<ImageProxy> (new J2KImageProxy (stereo->get_frame (entry_point + frame), asset->size(), dcp::EYE_LEFT)),
+                               shared_ptr<ImageProxy> (new J2KImageProxy (_stereo_reader->get_frame (entry_point + frame), asset->size(), dcp::EYE_LEFT)),
                                _offset + frame
                                );
 
                        video->give (
-                               shared_ptr<ImageProxy> (new J2KImageProxy (stereo->get_frame (entry_point + frame), asset->size(), dcp::EYE_RIGHT)),
+                               shared_ptr<ImageProxy> (new J2KImageProxy (_stereo_reader->get_frame (entry_point + frame), asset->size(), dcp::EYE_RIGHT)),
                                _offset + frame
                                );
                }
        }
 
-       if ((*_reel)->main_sound () && reason != PASS_REASON_SUBTITLE) {
+       if (_sound_reader && reason != PASS_REASON_SUBTITLE) {
                int64_t const entry_point = (*_reel)->main_sound()->entry_point ();
-               shared_ptr<const dcp::SoundFrame> sf = (*_reel)->main_sound()->asset()->get_frame (entry_point + frame);
+               shared_ptr<const dcp::SoundFrame> sf = _sound_reader->get_frame (entry_point + frame);
                uint8_t const * from = sf->data ();
 
                int const channels = _dcp_content->audio->stream()->channels ();
@@ -161,6 +163,41 @@ DCPDecoder::next_reel ()
 {
        _offset += (*_reel)->main_picture()->duration();
        ++_reel;
+       get_readers ();
+}
+
+void
+DCPDecoder::get_readers ()
+{
+       if (_reel == _reels.end()) {
+               _mono_reader.reset ();
+               _stereo_reader.reset ();
+               _sound_reader.reset ();
+               return;
+       }
+
+       if ((*_reel)->main_picture()) {
+               shared_ptr<dcp::PictureAsset> asset = (*_reel)->main_picture()->asset ();
+               shared_ptr<dcp::MonoPictureAsset> mono = dynamic_pointer_cast<dcp::MonoPictureAsset> (asset);
+               shared_ptr<dcp::StereoPictureAsset> stereo = dynamic_pointer_cast<dcp::StereoPictureAsset> (asset);
+               DCPOMATIC_ASSERT (mono || stereo);
+               if (mono) {
+                       _mono_reader = mono->start_read ();
+                       _stereo_reader.reset ();
+               } else {
+                       _stereo_reader = stereo->start_read ();
+                       _mono_reader.reset ();
+               }
+       } else {
+               _mono_reader.reset ();
+               _stereo_reader.reset ();
+       }
+
+       if ((*_reel)->main_sound()) {
+               _sound_reader = (*_reel)->main_sound()->asset()->start_read ();
+       } else {
+               _sound_reader.reset ();
+       }
 }
 
 void
index b7141f91643d645e76a034e2a0e7d7b1e91bf050..7ad6fcbf7c53eff44193f4c5c289e424fd94c2b3 100644 (file)
@@ -26,6 +26,9 @@
 
 namespace dcp {
        class Reel;
+       class MonoPictureAssetReader;
+       class StereoPictureAssetReader;
+       class SoundAssetReader;
 }
 
 class DCPContent;
@@ -47,15 +50,23 @@ private:
        bool pass (PassReason, bool accurate);
        void seek (ContentTime t, bool accurate);
        void next_reel ();
+       void get_readers ();
 
        std::list<ContentTimePeriod> image_subtitles_during (ContentTimePeriod, bool starting) const;
        std::list<ContentTimePeriod> text_subtitles_during (ContentTimePeriod, bool starting) const;
 
+       boost::shared_ptr<const DCPContent> _dcp_content;
        /** Time of next thing to return from pass relative to the start of _reel */
        ContentTime _next;
        std::list<boost::shared_ptr<dcp::Reel> > _reels;
+
        std::list<boost::shared_ptr<dcp::Reel> >::iterator _reel;
        /** Offset of _reel from the start of the content in frames */
        int64_t _offset;
-       boost::shared_ptr<const DCPContent> _dcp_content;
+       /** Reader for current mono picture asset, if applicable */
+       boost::shared_ptr<dcp::MonoPictureAssetReader> _mono_reader;
+       /** Reader for current stereo picture asset, if applicable */
+       boost::shared_ptr<dcp::StereoPictureAssetReader> _stereo_reader;
+       /** Reader for current sound asset, if applicable */
+       boost::shared_ptr<dcp::SoundAssetReader> _sound_reader;
 };
index 92f0d15c87c7847a085e0a13bc71e53cb9fd0664..fa05f6e64f5574030b0790d01b1ea1839bb9e7f6 100644 (file)
 #include <dcp/reel_picture_asset.h>
 #include <dcp/reel_sound_asset.h>
 #include <dcp/mono_picture_asset.h>
+#include <dcp/mono_picture_asset_reader.h>
 #include <dcp/mono_picture_frame.h>
 #include <dcp/stereo_picture_asset.h>
+#include <dcp/stereo_picture_asset_reader.h>
 #include <dcp/stereo_picture_frame.h>
 #include <dcp/sound_asset.h>
 #include <iostream>
@@ -122,9 +124,9 @@ DCPExaminer::DCPExaminer (shared_ptr<const DCPContent> content)
                        shared_ptr<dcp::StereoPictureAsset> stereo = dynamic_pointer_cast<dcp::StereoPictureAsset> (asset);
 
                        if (mono) {
-                               mono->get_frame(0)->xyz_image ();
+                               mono->start_read()->get_frame(0)->xyz_image ();
                        } else {
-                               stereo->get_frame(0)->xyz_image (dcp::EYE_LEFT);
+                               stereo->start_read()->get_frame(0)->xyz_image (dcp::EYE_LEFT);
                        }
 
                }
index 70c884699fe523b81fdbe568adc85402ca22539a..938d7deaf5c540668e0316b3a45cb99bf5b31501 100644 (file)
@@ -23,7 +23,9 @@
 #include "video_mxf_content.h"
 #include "j2k_image_proxy.h"
 #include <dcp/mono_picture_asset.h>
+#include <dcp/mono_picture_asset_reader.h>
 #include <dcp/stereo_picture_asset.h>
+#include <dcp/stereo_picture_asset_reader.h>
 #include <dcp/exceptions.h>
 
 using boost::shared_ptr;
@@ -32,17 +34,6 @@ VideoMXFDecoder::VideoMXFDecoder (shared_ptr<const VideoMXFContent> content, sha
        : _content (content)
 {
        video.reset (new VideoDecoder (this, content, log));
-}
-
-bool
-VideoMXFDecoder::pass (PassReason, bool)
-{
-       double const vfr = _content->active_video_frame_rate ();
-       int64_t const frame = _next.frames_round (vfr);
-
-       if (frame >= _content->video->length()) {
-               return true;
-       }
 
        shared_ptr<dcp::MonoPictureAsset> mono;
        try {
@@ -67,10 +58,29 @@ VideoMXFDecoder::pass (PassReason, bool)
        }
 
        if (mono) {
-               video->give (shared_ptr<ImageProxy> (new J2KImageProxy (mono->get_frame(frame), mono->size())), frame);
+               _mono_reader = mono->start_read ();
+               _size = mono->size ();
+       } else {
+               _stereo_reader = stereo->start_read ();
+               _size = stereo->size ();
+       }
+}
+
+bool
+VideoMXFDecoder::pass (PassReason, bool)
+{
+       double const vfr = _content->active_video_frame_rate ();
+       int64_t const frame = _next.frames_round (vfr);
+
+       if (frame >= _content->video->length()) {
+               return true;
+       }
+
+       if (_mono_reader) {
+               video->give (shared_ptr<ImageProxy> (new J2KImageProxy (_mono_reader->get_frame(frame), _size)), frame);
        } else {
-               video->give (shared_ptr<ImageProxy> (new J2KImageProxy (stereo->get_frame(frame), stereo->size(), dcp::EYE_LEFT)), frame);
-               video->give (shared_ptr<ImageProxy> (new J2KImageProxy (stereo->get_frame(frame), stereo->size(), dcp::EYE_RIGHT)), frame);
+               video->give (shared_ptr<ImageProxy> (new J2KImageProxy (_stereo_reader->get_frame(frame), _size, dcp::EYE_LEFT)), frame);
+               video->give (shared_ptr<ImageProxy> (new J2KImageProxy (_stereo_reader->get_frame(frame), _size, dcp::EYE_RIGHT)), frame);
        }
 
        _next += ContentTime::from_frames (1, vfr);
index 0432ad885e0ad9554bfd3082b94979a32050836c..34388ac82ce46d0d2e0ef89e3bab67b4e8037d0e 100644 (file)
 
 #include "decoder.h"
 
+namespace dcp {
+       class MonoPictureAssetReader;
+       class StereoPictureAssetReader;
+}
+
 class VideoMXFContent;
 class Log;
 
@@ -35,4 +40,8 @@ private:
        boost::shared_ptr<const VideoMXFContent> _content;
        /** Time of next thing to return from pass */
        ContentTime _next;
+
+       boost::shared_ptr<dcp::MonoPictureAssetReader> _mono_reader;
+       boost::shared_ptr<dcp::StereoPictureAssetReader> _stereo_reader;
+       dcp::Size _size;
 };
index b46cfeb2ca606dfeece78715c11bbd1446e688d8..1d2d171dbdf4c3669147bcd13b4ad296d6699b71 100644 (file)
@@ -29,6 +29,7 @@
 #include <dcp/cpl.h>
 #include <dcp/reel.h>
 #include <dcp/sound_asset.h>
+#include <dcp/sound_asset_reader.h>
 #include <dcp/reel_sound_asset.h>
 #include "lib/ffmpeg_content.h"
 #include "lib/dcp_content_type.h"
@@ -79,7 +80,7 @@ void test_audio_delay (int delay_in_ms)
        int const delay_in_frames = delay_in_ms * 48000 / 1000;
 
        while (n < sound_asset->asset()->intrinsic_duration()) {
-               shared_ptr<const dcp::SoundFrame> sound_frame = sound_asset->asset()->get_frame (frame++);
+               shared_ptr<const dcp::SoundFrame> sound_frame = sound_asset->asset()->start_read()->get_frame (frame++);
                uint8_t const * d = sound_frame->data ();
 
                for (int i = 0; i < sound_frame->size(); i += (3 * sound_asset->asset()->channels())) {
index ae3a65a679f01eb417917d29244c7acc3fe2f902..cfbaf46c30aaa8d064458551ce1ea1d551b7ccfb 100644 (file)
  *  @brief A simple test of reading audio from an FFmpeg file.
  */
 
-#include <boost/test/unit_test.hpp>
-#include <dcp/cpl.h>
-#include <dcp/dcp.h>
-#include <dcp/sound_asset.h>
-#include <dcp/sound_frame.h>
-#include <dcp/reel_sound_asset.h>
-#include <dcp/reel.h>
 #include "lib/ffmpeg_content.h"
 #include "lib/film.h"
 #include "lib/dcp_content_type.h"
 #include "lib/ratio.h"
 #include "lib/ffmpeg_content.h"
 #include "test.h"
+#include <dcp/cpl.h>
+#include <dcp/dcp.h>
+#include <dcp/sound_asset.h>
+#include <dcp/sound_frame.h>
+#include <dcp/reel_sound_asset.h>
+#include <dcp/sound_asset_reader.h>
+#include <dcp/reel.h>
+#include <boost/test/unit_test.hpp>
 
 using std::string;
 using boost::shared_ptr;
@@ -75,7 +76,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_audio_test)
        int frame = 0;
 
        while (n < sound_asset->asset()->intrinsic_duration()) {
-               shared_ptr<const dcp::SoundFrame> sound_frame = sound_asset->asset()->get_frame (frame++);
+               shared_ptr<const dcp::SoundFrame> sound_frame = sound_asset->asset()->start_read()->get_frame (frame++);
                uint8_t const * d = sound_frame->data ();
 
                for (int i = 0; i < sound_frame->size(); i += (3 * sound_asset->asset()->channels())) {
index 53c5021c39fb4ddf6e9fb7a61e63f67fe3b95eb7..9791b71722e3bd92b430d27b13916780074330fe 100644 (file)
  *  @brief Test the padding (with silence) of a mono source to a 6-channel DCP.
  */
 
-#include <boost/test/unit_test.hpp>
+#include "lib/ffmpeg_content.h"
+#include "lib/film.h"
+#include "lib/dcp_content_type.h"
+#include "lib/ratio.h"
+#include "test.h"
 #include <dcp/cpl.h>
 #include <dcp/dcp.h>
 #include <dcp/sound_asset.h>
 #include <dcp/sound_frame.h>
 #include <dcp/reel.h>
 #include <dcp/reel_sound_asset.h>
-#include "lib/ffmpeg_content.h"
-#include "lib/film.h"
-#include "lib/dcp_content_type.h"
-#include "lib/ratio.h"
-#include "test.h"
+#include <dcp/sound_asset_reader.h>
+#include <boost/test/unit_test.hpp>
 
 using std::string;
 using boost::lexical_cast;
@@ -72,7 +73,7 @@ test_silence_padding (int channels)
        int frame = 0;
 
        while (n < sound_asset->asset()->intrinsic_duration()) {
-               shared_ptr<const dcp::SoundFrame> sound_frame = sound_asset->asset()->get_frame (frame++);
+               shared_ptr<const dcp::SoundFrame> sound_frame = sound_asset->asset()->start_read()->get_frame (frame++);
                uint8_t const * d = sound_frame->data ();
 
                for (int i = 0; i < sound_frame->size(); i += (3 * sound_asset->asset()->channels())) {