diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-12-04 21:55:06 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-12-04 21:55:06 +0000 |
| commit | a3241f40b061480a0907699a5857075388216643 (patch) | |
| tree | 4e1d80bbe66c093d6844024c4ea62e9ff61643d0 /src/lib | |
| parent | 98060a4e6f02b418f30b4b736e5880a357454c40 (diff) | |
Suspend scale / crop / window / subtitle overlay until we decide that a frame is going to be used.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/encoder.cc | 5 | ||||
| -rw-r--r-- | src/lib/encoder.h | 3 | ||||
| -rw-r--r-- | src/lib/player.cc | 79 | ||||
| -rw-r--r-- | src/lib/player.h | 26 | ||||
| -rw-r--r-- | src/lib/transcoder.cc | 2 |
5 files changed, 98 insertions, 17 deletions
diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 059c4014c..f8a597191 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -34,6 +34,7 @@ #include "cross.h" #include "writer.h" #include "server_finder.h" +#include "player.h" #include "i18n.h" @@ -181,7 +182,7 @@ Encoder::frame_done () } void -Encoder::process_video (shared_ptr<const Image> image, Eyes eyes, ColourConversion conversion, bool same) +Encoder::process_video (shared_ptr<PlayerImage> image, Eyes eyes, ColourConversion conversion, bool same) { boost::mutex::scoped_lock lock (_mutex); @@ -215,7 +216,7 @@ Encoder::process_video (shared_ptr<const Image> image, Eyes eyes, ColourConversi TIMING ("adding to queue of %1", _queue.size ()); _queue.push_back (shared_ptr<DCPVideoFrame> ( new DCPVideoFrame ( - image, _video_frames_out, eyes, conversion, _film->video_frame_rate(), + image->image(), _video_frames_out, eyes, conversion, _film->video_frame_rate(), _film->j2k_bandwidth(), _film->log() ) )); diff --git a/src/lib/encoder.h b/src/lib/encoder.h index 686aaa2f2..d43e4e1d3 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -47,6 +47,7 @@ class EncodedData; class Writer; class Job; class ServerFinder; +class PlayerImage; /** @class Encoder * @brief Encoder to J2K and WAV for DCP. @@ -68,7 +69,7 @@ public: * @param i Video frame image. * @param same true if i is the same as the last time we were called. */ - void process_video (boost::shared_ptr<const Image> i, Eyes eyes, ColourConversion, bool same); + void process_video (boost::shared_ptr<PlayerImage> i, Eyes eyes, ColourConversion, bool same); /** Call with some audio data */ void process_audio (boost::shared_ptr<const AudioBuffers>); diff --git a/src/lib/player.cc b/src/lib/player.cc index 978db035f..f4e181daf 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -273,23 +273,32 @@ Player::process_video (weak_ptr<Piece> weak_piece, shared_ptr<const Image> image Time const time = content->position() + relative_time + extra - content->trim_start (); float const ratio = content->ratio() ? content->ratio()->ratio() : content->video_size_after_crop().ratio(); libdcp::Size const image_size = fit_ratio_within (ratio, _video_container_size); - - shared_ptr<Image> work_image = image->crop_scale_window (content->crop(), image_size, _video_container_size, _film->scaler(), PIX_FMT_RGB24, false); - Position<int> const container_offset ( - (_video_container_size.width - image_size.width) / 2, - (_video_container_size.height - image_size.width) / 2 + shared_ptr<PlayerImage> pi ( + new PlayerImage ( + image, + content->crop(), + image_size, + _video_container_size, + _film->scaler() + ) ); - + if (_film->with_subtitles () && _out_subtitle.image && time >= _out_subtitle.from && time <= _out_subtitle.to) { - work_image->alpha_blend (_out_subtitle.image, _out_subtitle.position + container_offset); - } + Position<int> const container_offset ( + (_video_container_size.width - image_size.width) / 2, + (_video_container_size.height - image_size.width) / 2 + ); + + pi->set_subtitle (_out_subtitle.image, _out_subtitle.position + container_offset); + } + #ifdef DCPOMATIC_DEBUG _last_video = piece->content; #endif - Video (work_image, eyes, content->colour_conversion(), same, time); + Video (pi, eyes, content->colour_conversion(), same, time); _last_emit_was_black = false; _video_position = piece->video_position = (time + TIME_HZ / _film->video_frame_rate()); @@ -530,8 +539,19 @@ void Player::set_video_container_size (libdcp::Size s) { _video_container_size = s; - _black_frame.reset (new Image (PIX_FMT_RGB24, _video_container_size, true)); - _black_frame->make_black (); + + shared_ptr<Image> im (new Image (PIX_FMT_RGB24, _video_container_size, true)); + im->make_black (); + + _black_frame.reset ( + new PlayerImage ( + im, + Crop(), + _video_container_size, + _video_container_size, + Scaler::from_id ("bicubic") + ) + ); } shared_ptr<Resampler> @@ -679,3 +699,40 @@ Player::repeat_last_video () return true; } + +PlayerImage::PlayerImage ( + shared_ptr<const Image> in, + Crop crop, + libdcp::Size inter_size, + libdcp::Size out_size, + Scaler const * scaler + ) + : _in (in) + , _crop (crop) + , _inter_size (inter_size) + , _out_size (out_size) + , _scaler (scaler) +{ + +} + +void +PlayerImage::set_subtitle (shared_ptr<const Image> image, Position<int> pos) +{ + _subtitle_image = image; + _subtitle_position = pos; +} + +shared_ptr<Image> +PlayerImage::image () +{ + shared_ptr<Image> out = _in->crop_scale_window (_crop, _inter_size, _out_size, _scaler, PIX_FMT_RGB24, false); + + Position<int> const container_offset ((_out_size.width - _inter_size.width) / 2, (_out_size.height - _inter_size.width) / 2); + + if (_subtitle_image) { + out->alpha_blend (_subtitle_image, _subtitle_position); + } + + return out; +} diff --git a/src/lib/player.h b/src/lib/player.h index 5f7c2e369..11cc99e77 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -52,6 +52,28 @@ public: VideoContent::Frame frame; Time extra; }; + +/** A wrapper for an Image which contains some pending operations; these may + * not be necessary if the receiver of the PlayerImage throws it away. + */ +class PlayerImage +{ +public: + PlayerImage (boost::shared_ptr<const Image>, Crop, libdcp::Size, libdcp::Size, Scaler const *); + + void set_subtitle (boost::shared_ptr<const Image>, Position<int>); + + boost::shared_ptr<Image> image (); + +private: + boost::shared_ptr<const Image> _in; + Crop _crop; + libdcp::Size _inter_size; + libdcp::Size _out_size; + Scaler const * _scaler; + boost::shared_ptr<const Image> _subtitle_image; + Position<int> _subtitle_position; +}; class Player : public boost::enable_shared_from_this<Player>, public boost::noncopyable { @@ -79,7 +101,7 @@ public: * Fourth parameter is true if the image is the same as the last one that was emitted. * Fifth parameter is the time. */ - boost::signals2::signal<void (boost::shared_ptr<const Image>, Eyes, ColourConversion, bool, Time)> Video; + boost::signals2::signal<void (boost::shared_ptr<PlayerImage>, Eyes, ColourConversion, bool, Time)> Video; /** Emitted when some audio data is ready */ boost::signals2::signal<void (boost::shared_ptr<const AudioBuffers>, Time)> Audio; @@ -128,7 +150,7 @@ private: AudioMerger<Time, AudioContent::Frame> _audio_merger; libdcp::Size _video_container_size; - boost::shared_ptr<Image> _black_frame; + boost::shared_ptr<PlayerImage> _black_frame; std::map<boost::shared_ptr<AudioContent>, boost::shared_ptr<Resampler> > _resamplers; struct { diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 826cba4fc..1c8f7e3eb 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -40,7 +40,7 @@ using boost::weak_ptr; using boost::dynamic_pointer_cast; static void -video_proxy (weak_ptr<Encoder> encoder, shared_ptr<const Image> image, Eyes eyes, ColourConversion conversion, bool same) +video_proxy (weak_ptr<Encoder> encoder, shared_ptr<PlayerImage> image, Eyes eyes, ColourConversion conversion, bool same) { shared_ptr<Encoder> e = encoder.lock (); if (e) { |
