diff options
| author | Carl Hetherington <cth@carlh.net> | 2017-08-03 17:54:06 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2017-08-14 21:07:49 +0100 |
| commit | 0253b4e45c71a1c2e2a8bffaf1c3cb84a0a3e41a (patch) | |
| tree | 85ca9af20c85ca04a221ca9023c0d2980ffeeca7 /src/lib | |
| parent | e952a7b0681d1ad2fc6ebcd0cd7231bf59bbe043 (diff) | |
Basics of forced reduction of JPEG2000 decode resolution.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/dcp_decoder.cc | 32 | ||||
| -rw-r--r-- | src/lib/dcp_decoder.h | 2 | ||||
| -rw-r--r-- | src/lib/j2k_image_proxy.cc | 30 | ||||
| -rw-r--r-- | src/lib/j2k_image_proxy.h | 19 | ||||
| -rw-r--r-- | src/lib/player.cc | 21 | ||||
| -rw-r--r-- | src/lib/player.h | 3 | ||||
| -rw-r--r-- | src/lib/video_mxf_decoder.cc | 18 |
7 files changed, 109 insertions, 16 deletions
diff --git a/src/lib/dcp_decoder.cc b/src/lib/dcp_decoder.cc index c7294bda7..ef40f2ec7 100644 --- a/src/lib/dcp_decoder.cc +++ b/src/lib/dcp_decoder.cc @@ -48,6 +48,7 @@ using std::list; using std::cout; using boost::shared_ptr; using boost::dynamic_pointer_cast; +using boost::optional; DCPDecoder::DCPDecoder (shared_ptr<const DCPContent> c, shared_ptr<Log> log) : DCP (c) @@ -100,20 +101,39 @@ DCPDecoder::pass () if (_mono_reader) { video->emit ( shared_ptr<ImageProxy> ( - new J2KImageProxy (_mono_reader->get_frame (entry_point + frame), asset->size(), AV_PIX_FMT_XYZ12LE) + new J2KImageProxy ( + _mono_reader->get_frame (entry_point + frame), + asset->size(), + AV_PIX_FMT_XYZ12LE, + _forced_reduction + ) ), _offset + frame ); } else { video->emit ( shared_ptr<ImageProxy> ( - new J2KImageProxy (_stereo_reader->get_frame (entry_point + frame), asset->size(), dcp::EYE_LEFT, AV_PIX_FMT_XYZ12LE)), + new J2KImageProxy ( + _stereo_reader->get_frame (entry_point + frame), + asset->size(), + dcp::EYE_LEFT, + AV_PIX_FMT_XYZ12LE, + _forced_reduction + ) + ), _offset + frame ); video->emit ( shared_ptr<ImageProxy> ( - new J2KImageProxy (_stereo_reader->get_frame (entry_point + frame), asset->size(), dcp::EYE_RIGHT, AV_PIX_FMT_XYZ12LE)), + new J2KImageProxy ( + _stereo_reader->get_frame (entry_point + frame), + asset->size(), + dcp::EYE_RIGHT, + AV_PIX_FMT_XYZ12LE, + _forced_reduction + ) + ), _offset + frame ); } @@ -234,3 +254,9 @@ DCPDecoder::set_decode_referenced () { _decode_referenced = true; } + +void +DCPDecoder::set_forced_reduction (optional<int> reduction) +{ + _forced_reduction = reduction; +} diff --git a/src/lib/dcp_decoder.h b/src/lib/dcp_decoder.h index 71687ad15..aa76b83d6 100644 --- a/src/lib/dcp_decoder.h +++ b/src/lib/dcp_decoder.h @@ -46,6 +46,7 @@ public: } void set_decode_referenced (); + void set_forced_reduction (boost::optional<int> reduction); bool pass (); void seek (ContentTime t, bool accurate); @@ -71,4 +72,5 @@ private: boost::shared_ptr<dcp::SoundAssetReader> _sound_reader; bool _decode_referenced; + boost::optional<int> _forced_reduction; }; diff --git a/src/lib/j2k_image_proxy.cc b/src/lib/j2k_image_proxy.cc index 9e68951e9..a60af1eb2 100644 --- a/src/lib/j2k_image_proxy.cc +++ b/src/lib/j2k_image_proxy.cc @@ -53,18 +53,31 @@ J2KImageProxy::J2KImageProxy (boost::filesystem::path path, dcp::Size size, AVPi } -J2KImageProxy::J2KImageProxy (shared_ptr<const dcp::MonoPictureFrame> frame, dcp::Size size, AVPixelFormat pixel_format) +J2KImageProxy::J2KImageProxy ( + shared_ptr<const dcp::MonoPictureFrame> frame, + dcp::Size size, + AVPixelFormat pixel_format, + optional<int> forced_reduction + ) : _data (frame->j2k_size ()) , _size (size) , _pixel_format (pixel_format) + , _forced_reduction (forced_reduction) { memcpy (_data.data().get(), frame->j2k_data(), _data.size ()); } -J2KImageProxy::J2KImageProxy (shared_ptr<const dcp::StereoPictureFrame> frame, dcp::Size size, dcp::Eye eye, AVPixelFormat pixel_format) +J2KImageProxy::J2KImageProxy ( + shared_ptr<const dcp::StereoPictureFrame> frame, + dcp::Size size, + dcp::Eye eye, + AVPixelFormat pixel_format, + optional<int> forced_reduction + ) : _size (size) , _eye (eye) , _pixel_format (pixel_format) + , _forced_reduction (forced_reduction) { switch (eye) { case dcp::EYE_LEFT: @@ -104,12 +117,17 @@ J2KImageProxy::prepare (optional<dcp::Size> target_size) const int reduce = 0; - while (target_size && (_size.width / pow(2, reduce)) > target_size->width && (_size.height / pow(2, reduce)) > target_size->height) { - ++reduce; + if (_forced_reduction) { + reduce = *_forced_reduction; + } else { + while (target_size && (_size.width / pow(2, reduce)) > target_size->width && (_size.height / pow(2, reduce)) > target_size->height) { + ++reduce; + } + + --reduce; + reduce = max (0, reduce); } - --reduce; - reduce = max (0, reduce); _decompressed = dcp::decompress_j2k (const_cast<uint8_t*> (_data.data().get()), _data.size (), reduce); if (_decompressed->precision(0) < 12) { diff --git a/src/lib/j2k_image_proxy.h b/src/lib/j2k_image_proxy.h index 3133aac20..c20d89340 100644 --- a/src/lib/j2k_image_proxy.h +++ b/src/lib/j2k_image_proxy.h @@ -32,8 +32,22 @@ class J2KImageProxy : public ImageProxy { public: J2KImageProxy (boost::filesystem::path path, dcp::Size, AVPixelFormat pixel_format); - J2KImageProxy (boost::shared_ptr<const dcp::MonoPictureFrame> frame, dcp::Size, AVPixelFormat pixel_format); - J2KImageProxy (boost::shared_ptr<const dcp::StereoPictureFrame> frame, dcp::Size, dcp::Eye, AVPixelFormat pixel_format); + + J2KImageProxy ( + boost::shared_ptr<const dcp::MonoPictureFrame> frame, + dcp::Size, + AVPixelFormat pixel_format, + boost::optional<int> forced_reduction + ); + + J2KImageProxy ( + boost::shared_ptr<const dcp::StereoPictureFrame> frame, + dcp::Size, + dcp::Eye, + AVPixelFormat pixel_format, + boost::optional<int> forced_reduction + ); + J2KImageProxy (boost::shared_ptr<cxml::Node> xml, boost::shared_ptr<Socket> socket); boost::shared_ptr<Image> image ( @@ -71,4 +85,5 @@ private: mutable boost::optional<dcp::Size> _target_size; AVPixelFormat _pixel_format; mutable boost::mutex _mutex; + boost::optional<int> _forced_reduction; }; diff --git a/src/lib/player.cc b/src/lib/player.cc index 3d191a302..7e21ef937 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -127,7 +127,10 @@ Player::setup_pieces () shared_ptr<DCPDecoder> dcp = dynamic_pointer_cast<DCPDecoder> (decoder); if (dcp && _play_referenced) { - dcp->set_decode_referenced (); + if (_play_referenced) { + dcp->set_decode_referenced (); + } + dcp->set_forced_reduction (_dcp_decode_reduction); } shared_ptr<Piece> piece (new Piece (i, decoder, frc)); @@ -850,6 +853,10 @@ Player::subtitle_stop (weak_ptr<Piece> wp, ContentTime to) void Player::seek (DCPTime time, bool accurate) { + if (!_have_valid_pieces) { + setup_pieces (); + } + if (_audio_processor) { _audio_processor->flush (); } @@ -950,3 +957,15 @@ Player::discard_audio (shared_ptr<const AudioBuffers> audio, DCPTime time, DCPTi cut->copy_from (audio.get(), remaining_frames, discard_frames, 0); return make_pair(cut, time + discard_time); } + +void +Player::set_dcp_decode_reduction (optional<int> reduction) +{ + if (reduction == _dcp_decode_reduction) { + return; + } + + _dcp_decode_reduction = reduction; + _have_valid_pieces = false; + Changed (false); +} diff --git a/src/lib/player.h b/src/lib/player.h index ee7f89aaa..9dd5afd26 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -67,6 +67,7 @@ public: void set_always_burn_subtitles (bool burn); void set_fast (); void set_play_referenced (); + void set_dcp_decode_reduction (boost::optional<int> reduction); /** Emitted when something has changed such that if we went back and emitted * the last frame again it would look different. This is not emitted after @@ -147,6 +148,8 @@ private: /** Time just after the last audio frame we emitted, or the time of the last accurate seek */ boost::optional<DCPTime> _last_audio_time; + boost::optional<int> _dcp_decode_reduction; + typedef std::map<boost::weak_ptr<Piece>, boost::shared_ptr<PlayerVideo> > LastVideoMap; LastVideoMap _last_video; diff --git a/src/lib/video_mxf_decoder.cc b/src/lib/video_mxf_decoder.cc index 216721375..194830c63 100644 --- a/src/lib/video_mxf_decoder.cc +++ b/src/lib/video_mxf_decoder.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2016 Carl Hetherington <cth@carlh.net> + Copyright (C) 2016-2017 Carl Hetherington <cth@carlh.net> This file is part of DCP-o-matic. @@ -29,6 +29,7 @@ #include <dcp/exceptions.h> using boost::shared_ptr; +using boost::optional; VideoMXFDecoder::VideoMXFDecoder (shared_ptr<const VideoMXFContent> content, shared_ptr<Log> log) : _content (content) @@ -78,14 +79,23 @@ VideoMXFDecoder::pass () if (_mono_reader) { video->emit ( - shared_ptr<ImageProxy> (new J2KImageProxy (_mono_reader->get_frame(frame), _size, AV_PIX_FMT_XYZ12LE)), frame + shared_ptr<ImageProxy> ( + new J2KImageProxy (_mono_reader->get_frame(frame), _size, AV_PIX_FMT_XYZ12LE, optional<int>()) + ), + frame ); } else { video->emit ( - shared_ptr<ImageProxy> (new J2KImageProxy (_stereo_reader->get_frame(frame), _size, dcp::EYE_LEFT, AV_PIX_FMT_XYZ12LE)), frame + shared_ptr<ImageProxy> ( + new J2KImageProxy (_stereo_reader->get_frame(frame), _size, dcp::EYE_LEFT, AV_PIX_FMT_XYZ12LE, optional<int>()) + ), + frame ); video->emit ( - shared_ptr<ImageProxy> (new J2KImageProxy (_stereo_reader->get_frame(frame), _size, dcp::EYE_RIGHT, AV_PIX_FMT_XYZ12LE)), frame + shared_ptr<ImageProxy> ( + new J2KImageProxy (_stereo_reader->get_frame(frame), _size, dcp::EYE_RIGHT, AV_PIX_FMT_XYZ12LE, optional<int>()) + ), + frame ); } |
