A possibly-better approach to seeking.
[dcpomatic.git] / src / lib / video_mxf_decoder.cc
index e8b787d8d45019a346b82bca55a9fe2d3c76d370..84aec869a2a2292c6883e97a9590622524072c5b 100644 (file)
@@ -1,19 +1,20 @@
 /*
     Copyright (C) 2016 Carl Hetherington <cth@carlh.net>
 
-    This program is free software; you can redistribute it and/or modify
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.
 
-    This program is distributed in the hope that it will be useful,
+    DCP-o-matic is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
 
     You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
 
 */
 
@@ -22,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;
@@ -31,11 +34,7 @@ VideoMXFDecoder::VideoMXFDecoder (shared_ptr<const VideoMXFContent> content, sha
        : _content (content)
 {
        video.reset (new VideoDecoder (this, content, log));
-}
 
-bool
-VideoMXFDecoder::pass (PassReason reason, bool)
-{
        shared_ptr<dcp::MonoPictureAsset> mono;
        try {
                mono.reset (new dcp::MonoPictureAsset (_content->path(0)));
@@ -58,17 +57,41 @@ VideoMXFDecoder::pass (PassReason reason, bool)
                }
        }
 
+       if (mono) {
+               _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 (mono) {
-               video->give (shared_ptr<ImageProxy> (new J2KImageProxy (mono->get_frame(frame), mono->size())), frame);
+       if (frame >= _content->video->length()) {
+               return true;
+       }
+
+       if (_mono_reader) {
+               video->give (
+                       shared_ptr<ImageProxy> (new J2KImageProxy (_mono_reader->get_frame(frame), _size, AV_PIX_FMT_XYZ12LE)), 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, AV_PIX_FMT_XYZ12LE)), frame
+                       );
+               video->give (
+                       shared_ptr<ImageProxy> (new J2KImageProxy (_stereo_reader->get_frame(frame), _size, dcp::EYE_RIGHT, AV_PIX_FMT_XYZ12LE)), frame
+                       );
        }
 
+       _position = _next;
        _next += ContentTime::from_frames (1, vfr);
+       return false;
 }
 
 void