Basics of direct write of J2K data without encode/decode.
authorCarl Hetherington <cth@carlh.net>
Thu, 10 Jul 2014 08:40:56 +0000 (09:40 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 10 Jul 2014 08:40:56 +0000 (09:40 +0100)
src/lib/dcp_decoder.cc
src/lib/encoded_data.cc
src/lib/encoded_data.h
src/lib/encoder.cc
src/lib/j2k_image_proxy.cc
src/lib/j2k_image_proxy.h
src/lib/player_video.cc
src/lib/player_video.h

index 6e59f6cde244d0051276c72ae5f8a6884aa98908..e9c1101083c69fc15e3ea5d9bb83478630e22bed 100644 (file)
@@ -85,7 +85,7 @@ DCPDecoder::pass ()
        _next += ContentTime::from_frames (1, vfr);
 
        if ((*_reel)->main_picture ()) {
-               if ((*_reel)->main_picture()->duration() >= _next.frames (vfr)) {
+               if (_next.frames (vfr) >= (*_reel)->main_picture()->duration()) {
                        ++_reel;
                }
        }
index fffc4d91f0b51d5c016d6a4e6f472a09d471b35f..61d2644daf324dd251861dbfe686ff93e514dc31 100644 (file)
@@ -33,6 +33,13 @@ EncodedData::EncodedData (int s)
 
 }
 
+EncodedData::EncodedData (uint8_t const * d, int s)
+       : _data (new uint8_t[s])
+       , _size (s)
+{
+       memcpy (_data, d, s);
+}
+
 EncodedData::EncodedData (boost::filesystem::path file)
 {
        _size = boost::filesystem::file_size (file);
index 9064cc9292f351c98b028685db9c3873a4fb591b..232ed6e8a4aaedc0871f7d3a1f6318129b80d7f4 100644 (file)
@@ -33,6 +33,7 @@ class EncodedData : public boost::noncopyable
 public:
        /** @param s Size of data, in bytes */
        EncodedData (int s);
+       EncodedData (uint8_t const * d, int s);
 
        EncodedData (boost::filesystem::path);
 
index 7b21296a2b81c96f3108115d79096a886eaa68d8..e8ab5452bd404ec8a5c10cdb49ee761a8ad29f20 100644 (file)
@@ -207,6 +207,8 @@ Encoder::enqueue (shared_ptr<PlayerVideo> pvf)
        if (_writer->can_fake_write (_video_frames_out)) {
                _writer->fake_write (_video_frames_out, pvf->eyes ());
                frame_done ();
+       } else if (pvf->has_j2k ()) {
+               _writer->write (pvf->j2k(), _video_frames_out, pvf->eyes ());
        } else {
                /* Queue this new frame for encoding */
                LOG_TIMING ("adding to queue of %1", _queue.size ());
index db1a2b53f53497e738d06d88aa9ffc517ef15417..6924fad795bd1ddbdcab067036a96917110560ed 100644 (file)
@@ -24,6 +24,7 @@
 #include "j2k_image_proxy.h"
 #include "util.h"
 #include "image.h"
+#include "encoded_data.h"
 
 #include "i18n.h"
 
@@ -106,3 +107,17 @@ J2KImageProxy::send_binary (shared_ptr<Socket> socket) const
                socket->write (_stereo->right_j2k_data(), _stereo->right_j2k_size ());
        }
 }
+
+shared_ptr<EncodedData>
+J2KImageProxy::j2k () const
+{
+       if (_mono) {
+               return shared_ptr<EncodedData> (new EncodedData (_mono->j2k_data(), _mono->j2k_size()));
+       } else {
+               if (_eye == dcp::EYE_LEFT) {
+                       return shared_ptr<EncodedData> (new EncodedData (_stereo->left_j2k_data(), _stereo->left_j2k_size()));
+               } else {
+                       return shared_ptr<EncodedData> (new EncodedData (_stereo->right_j2k_data(), _stereo->right_j2k_size()));
+               }
+       }
+}
index 1c283180201c37a18d8b04b256c8e445f5c29d1d..d7b5c83fc443d36e2c79b98b641067fea695c924 100644 (file)
@@ -20,6 +20,8 @@
 #include <dcp/util.h>
 #include "image_proxy.h"
 
+class EncodedData;
+
 class J2KImageProxy : public ImageProxy
 {
 public:
@@ -31,6 +33,11 @@ public:
        void add_metadata (xmlpp::Node *) const;
        void send_binary (boost::shared_ptr<Socket>) const;
 
+       boost::shared_ptr<EncodedData> j2k () const;
+       dcp::Size size () const {
+               return _size;
+       }
+       
 private:
        boost::shared_ptr<const dcp::MonoPictureFrame> _mono;
        boost::shared_ptr<const dcp::StereoPictureFrame> _stereo;
index d1b394933b67dc6e9fe70c278d06d6a8be9d5610..a44264ceddd23bcad2c3e5dea92512e6e8d0c9ec 100644 (file)
 #include "player_video.h"
 #include "image.h"
 #include "image_proxy.h"
+#include "j2k_image_proxy.h"
 #include "scaler.h"
 
 using std::string;
 using std::cout;
-using boost::shared_ptr;
 using dcp::raw_convert;
+using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
 
 PlayerVideo::PlayerVideo (
        shared_ptr<const ImageProxy> in,
@@ -148,3 +150,24 @@ PlayerVideo::send_binary (shared_ptr<Socket> socket, bool send_subtitles) const
                _subtitle.image->write_to_socket (socket);
        }
 }
+
+bool
+PlayerVideo::has_j2k () const
+{
+       /* XXX: burnt-in subtitle; maybe other things */
+       
+       shared_ptr<const J2KImageProxy> j2k = dynamic_pointer_cast<const J2KImageProxy> (_in);
+       if (!j2k) {
+               return false;
+       }
+       
+       return _crop == Crop () && _inter_size == j2k->size();
+}
+
+shared_ptr<EncodedData>
+PlayerVideo::j2k () const
+{
+       shared_ptr<const J2KImageProxy> j2k = dynamic_pointer_cast<const J2KImageProxy> (_in);
+       assert (j2k);
+       return j2k->j2k ();
+}
index e06e5f45e183f1cad603a7b14f4fc38e03c4cae7..4fe8712d489735c9e546c65bc304c8f2b2ad959f 100644 (file)
@@ -28,6 +28,7 @@ class ImageProxy;
 class Scaler;
 class Socket;
 class Log;
+class EncodedData;
 
 /** Everything needed to describe a video frame coming out of the player, but with the
  *  bits still their raw form.  We may want to combine the bits on a remote machine,
@@ -46,6 +47,9 @@ public:
        void add_metadata (xmlpp::Node* node, bool send_subtitles) const;
        void send_binary (boost::shared_ptr<Socket> socket, bool send_subtitles) const;
 
+       bool has_j2k () const;
+       boost::shared_ptr<EncodedData> j2k () const;
+
        DCPTime time () const {
                return _time;
        }