From 9bfa07293928c371d59db2091ba2b7e715ce5994 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 15 Sep 2021 01:00:33 +0200 Subject: Various alignment adjustments. --- src/lib/encoder.cc | 2 +- src/lib/ffmpeg_decoder.cc | 2 +- src/lib/ffmpeg_image_proxy.cc | 4 ++-- src/lib/ffmpeg_image_proxy.h | 1 + src/lib/hints.cc | 2 +- src/lib/image.cc | 16 +++++++++------- src/lib/image.h | 6 +++--- src/lib/image_examiner.cc | 2 +- src/lib/image_proxy.h | 3 ++- src/lib/j2k_image_proxy.cc | 12 ++++++------ src/lib/j2k_image_proxy.h | 3 ++- src/lib/player.cc | 5 +++-- src/lib/player.h | 5 ++++- src/lib/player_video.cc | 10 +++++----- src/lib/raw_image_proxy.cc | 7 ++++--- src/lib/raw_image_proxy.h | 1 + src/lib/util.cc | 2 +- src/lib/video_filter_graph.cc | 4 ++-- 18 files changed, 49 insertions(+), 38 deletions(-) (limited to 'src/lib') diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index fe27cb7dd..0b7c241d8 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -41,7 +41,7 @@ Encoder::Encoder (std::shared_ptr film, std::weak_ptr job) : _film (film) , _job (job) - , _player (new Player(film)) + , _player (new Player(film, true)) { } diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 72372fca8..70f9b0545 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -86,7 +86,7 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr film, shared_ptr(this, c); _pts_offset = pts_offset (c->ffmpeg_audio_streams(), c->first_video(), c->active_video_frame_rate(film)); /* It doesn't matter what size or pixel format this is, it just needs to be black */ - _black_image.reset (new Image (AV_PIX_FMT_RGB24, dcp::Size (128, 128), true)); + _black_image = make_shared(AV_PIX_FMT_RGB24, dcp::Size (128, 128), true); _black_image->make_black (); } else { _pts_offset = {}; diff --git a/src/lib/ffmpeg_image_proxy.cc b/src/lib/ffmpeg_image_proxy.cc index e7d5b424d..dd2f80e0e 100644 --- a/src/lib/ffmpeg_image_proxy.cc +++ b/src/lib/ffmpeg_image_proxy.cc @@ -122,7 +122,7 @@ FFmpegImageProxy::avio_seek (int64_t const pos, int whence) ImageProxy::Result -FFmpegImageProxy::image (optional) const +FFmpegImageProxy::image (bool aligned, optional) const { auto constexpr name_for_errors = "FFmpegImageProxy::image"; @@ -205,7 +205,7 @@ FFmpegImageProxy::image (optional) const throw DecodeError (N_("avcodec_receive_frame"), name_for_errors, r, *_path); } - _image = make_shared(frame); + _image = make_shared(frame, aligned); av_packet_unref (&packet); av_frame_free (&frame); diff --git a/src/lib/ffmpeg_image_proxy.h b/src/lib/ffmpeg_image_proxy.h index 21109c9d6..f4e5bf66c 100644 --- a/src/lib/ffmpeg_image_proxy.h +++ b/src/lib/ffmpeg_image_proxy.h @@ -32,6 +32,7 @@ public: FFmpegImageProxy (std::shared_ptr socket); Result image ( + bool aligned, boost::optional size = boost::optional () ) const; diff --git a/src/lib/hints.cc b/src/lib/hints.cc index 64122db8d..f21c51db9 100644 --- a/src/lib/hints.cc +++ b/src/lib/hints.cc @@ -408,7 +408,7 @@ try emit (bind(boost::ref(Progress), _("Examining audio, subtitles and closed captions"))); } - auto player = make_shared(film); + auto player = make_shared(film, false); player->set_ignore_video (); if (check_loudness_done) { /* We don't need to analyse audio because we already loaded a suitable analysis */ diff --git a/src/lib/image.cc b/src/lib/image.cc index d2f8fbbfd..ce3f5817d 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -1027,10 +1027,10 @@ Image::Image (Image const & other) } } -Image::Image (AVFrame const * frame) +Image::Image (AVFrame const * frame, bool aligned) : _size (frame->width, frame->height) , _pixel_format (static_cast(frame->format)) - , _aligned (true) + , _aligned (aligned) { DCPOMATIC_ASSERT (_pixel_format != AV_PIX_FMT_NONE); @@ -1139,7 +1139,7 @@ Image::aligned () const PositionImage -merge (list images) +merge (list images, bool aligned) { if (images.empty ()) { return {}; @@ -1154,7 +1154,7 @@ merge (list images) all.extend (dcpomatic::Rect(i.position, i.image->size().width, i.image->size().height)); } - auto merged = make_shared(images.front().image->pixel_format(), dcp::Size(all.width, all.height), false); + auto merged = make_shared(images.front().image->pixel_format(), dcp::Size(all.width, all.height), aligned); merged->make_transparent (); for (auto const& i: images) { merged->alpha_blend (i.image, i.position - all.position()); @@ -1312,16 +1312,18 @@ Image::fade (float f) } } + shared_ptr -Image::ensure_aligned (shared_ptr image) +Image::ensure_aligned (shared_ptr image, bool aligned) { - if (image->aligned()) { + if (image->aligned() == aligned) { return image; } - return make_shared(image, true); + return make_shared(image, aligned); } + size_t Image::memory_used () const { diff --git a/src/lib/image.h b/src/lib/image.h index cb8f11ffc..3cba8f7e5 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -41,7 +41,7 @@ class Image : public std::enable_shared_from_this { public: Image (AVPixelFormat p, dcp::Size s, bool aligned); - explicit Image (AVFrame const *); + explicit Image (AVFrame const *, bool aligned); explicit Image (Image const &); Image (std::shared_ptr, bool); Image& operator= (Image const &); @@ -94,7 +94,7 @@ public: void png_error (char const * message); - static std::shared_ptr ensure_aligned (std::shared_ptr image); + static std::shared_ptr ensure_aligned (std::shared_ptr image, bool aligned); private: friend struct pixel_formats_test; @@ -115,7 +115,7 @@ private: bool _aligned; }; -extern PositionImage merge (std::list images); +extern PositionImage merge (std::list images, bool aligned); extern bool operator== (Image const & a, Image const & b); #endif diff --git a/src/lib/image_examiner.cc b/src/lib/image_examiner.cc index 89d1517ce..8b2096214 100644 --- a/src/lib/image_examiner.cc +++ b/src/lib/image_examiner.cc @@ -67,7 +67,7 @@ ImageExaminer::ImageExaminer (shared_ptr film, shared_ptrpath(0)); - _video_size = proxy.image().image->size(); + _video_size = proxy.image(false).image->size(); } if (content->still ()) { diff --git a/src/lib/image_proxy.h b/src/lib/image_proxy.h index cf1fb9a2d..8817845d9 100644 --- a/src/lib/image_proxy.h +++ b/src/lib/image_proxy.h @@ -91,6 +91,7 @@ public: * can be used as an optimisation. */ virtual Result image ( + bool aligned, boost::optional size = boost::optional () ) const = 0; @@ -102,7 +103,7 @@ public: * This method may be called in a different thread to image(). * @return log2 of any scaling down that will be applied to the image. */ - virtual int prepare (boost::optional = boost::optional()) const { return 0; } + virtual int prepare (bool, boost::optional = boost::optional()) const { return 0; } virtual size_t memory_used () const = 0; }; diff --git a/src/lib/j2k_image_proxy.cc b/src/lib/j2k_image_proxy.cc index c98273ad2..21507ca15 100644 --- a/src/lib/j2k_image_proxy.cc +++ b/src/lib/j2k_image_proxy.cc @@ -108,7 +108,7 @@ J2KImageProxy::J2KImageProxy (shared_ptr xml, shared_ptr soc if (xml->optional_number_child("Eye")) { _eye = static_cast(xml->number_child("Eye")); } - shared_ptr data(new ArrayData(xml->number_child("Size"))); + auto data = make_shared(xml->number_child("Size")); /* This only matters when we are using J2KImageProxy for the preview, which will never use this constructor (which is only used for passing data to encode servers). So we can put anything in here. It's a bit of a hack. @@ -120,7 +120,7 @@ J2KImageProxy::J2KImageProxy (shared_ptr xml, shared_ptr soc int -J2KImageProxy::prepare (optional target_size) const +J2KImageProxy::prepare (bool aligned, optional target_size) const { boost::mutex::scoped_lock lm (_mutex); @@ -145,7 +145,7 @@ J2KImageProxy::prepare (optional target_size) const try { /* XXX: should check that potentially trashing _data here doesn't matter */ auto decompressed = dcp::decompress_j2k (const_cast(_data->data()), _data->size(), reduce); - _image.reset (new Image (_pixel_format, decompressed->size(), false)); + _image = make_shared(_pixel_format, decompressed->size(), aligned); int const shift = 16 - decompressed->precision (0); @@ -169,7 +169,7 @@ J2KImageProxy::prepare (optional target_size) const } } } catch (dcp::J2KDecompressionError& e) { - _image = make_shared(_pixel_format, _size, true); + _image = make_shared(_pixel_format, _size, aligned); _image->make_black (); _error = true; } @@ -182,9 +182,9 @@ J2KImageProxy::prepare (optional target_size) const ImageProxy::Result -J2KImageProxy::image (optional target_size) const +J2KImageProxy::image (bool aligned, optional target_size) const { - int const r = prepare (target_size); + int const r = prepare (aligned, target_size); /* I think this is safe without a lock on mutex. _image is guaranteed to be set up when prepare() has happened. diff --git a/src/lib/j2k_image_proxy.h b/src/lib/j2k_image_proxy.h index 5235d8e42..a23ec6d98 100644 --- a/src/lib/j2k_image_proxy.h +++ b/src/lib/j2k_image_proxy.h @@ -57,6 +57,7 @@ public: J2KImageProxy (dcp::ArrayData data, dcp::Size size, AVPixelFormat pixel_format); Result image ( + bool aligned, boost::optional size = boost::optional () ) const; @@ -64,7 +65,7 @@ public: void write_to_socket (std::shared_ptr) const; /** @return true if our image is definitely the same as another, false if it is probably not */ bool same (std::shared_ptr) const; - int prepare (boost::optional = boost::optional()) const; + int prepare (bool aligned, boost::optional = boost::optional()) const; std::shared_ptr j2k () const { return _data; diff --git a/src/lib/player.cc b/src/lib/player.cc index 5de089ba9..810d949d9 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -95,11 +95,12 @@ int const PlayerProperty::DCP_DECODE_REDUCTION = 704; int const PlayerProperty::PLAYBACK_LENGTH = 705; -Player::Player (shared_ptr film) +Player::Player (shared_ptr film, bool aligned) : _film (film) , _suspended (0) , _tolerant (film->tolerant()) , _audio_merger (_film->audio_frame_rate()) + , _aligned_subtitles (aligned) { construct (); } @@ -827,7 +828,7 @@ Player::open_subtitles_for_frame (DCPTime time) const return {}; } - return merge (captions); + return merge (captions, _aligned_subtitles); } diff --git a/src/lib/player.h b/src/lib/player.h index 6cefbe232..767218379 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -76,7 +76,7 @@ public: class Player : public std::enable_shared_from_this { public: - Player (std::shared_ptr); + Player (std::shared_ptr, bool aligned_subtitles); Player (std::shared_ptr, std::shared_ptr playlist); Player (Player const& Player) = delete; @@ -233,6 +233,9 @@ private: dcpomatic::DCPTime _playback_length; + /** aligned flag for subtitle images that we create */ + bool _aligned_subtitles = true; + boost::signals2::scoped_connection _film_changed_connection; boost::signals2::scoped_connection _playlist_change_connection; boost::signals2::scoped_connection _playlist_content_change_connection; diff --git a/src/lib/player_video.cc b/src/lib/player_video.cc index 0a6ce0d99..a687e7ea5 100644 --- a/src/lib/player_video.cc +++ b/src/lib/player_video.cc @@ -122,10 +122,10 @@ PlayerVideo::image (function pixel_format, VideoR } -shared_ptr +shared_ptr PlayerVideo::raw_image () const { - return _in->image(_inter_size).image; + return _in->image(false, _inter_size).image; } @@ -144,7 +144,7 @@ PlayerVideo::make_image (function pixel_format, V _image_out_size = _out_size; _image_fade = _fade; - auto prox = _in->image (_inter_size); + auto prox = _in->image (true, _inter_size); _error = prox.error; auto total_crop = _crop; @@ -184,7 +184,7 @@ PlayerVideo::make_image (function pixel_format, V ); if (_text) { - _image->alpha_blend (Image::ensure_aligned (_text->image), _text->position); + _image->alpha_blend (Image::ensure_aligned(_text->image, true), _text->position); } if (_fade) { @@ -300,7 +300,7 @@ PlayerVideo::keep_xyz_or_rgb (AVPixelFormat p) void PlayerVideo::prepare (function pixel_format, VideoRange video_range, bool aligned, bool fast, bool proxy_only) { - _in->prepare (_inter_size); + _in->prepare (aligned, _inter_size); boost::mutex::scoped_lock lm (_mutex); if (!_image && !proxy_only) { make_image (pixel_format, video_range, aligned, fast); diff --git a/src/lib/raw_image_proxy.cc b/src/lib/raw_image_proxy.cc index fed40c45e..ac8ff0763 100644 --- a/src/lib/raw_image_proxy.cc +++ b/src/lib/raw_image_proxy.cc @@ -64,9 +64,10 @@ RawImageProxy::RawImageProxy (shared_ptr xml, shared_ptr soc ImageProxy::Result -RawImageProxy::image (optional) const +RawImageProxy::image (bool aligned, optional) const { - return Result (_image, 0); + /* This ensure_aligned could be wasteful */ + return Result (Image::ensure_aligned(_image, aligned), 0); } @@ -95,7 +96,7 @@ RawImageProxy::same (shared_ptr other) const return false; } - return (*_image.get()) == (*rp->image().image.get()); + return (*_image.get()) == (*rp->image(_image->aligned()).image.get()); } diff --git a/src/lib/raw_image_proxy.h b/src/lib/raw_image_proxy.h index ec30f5a29..7e0861104 100644 --- a/src/lib/raw_image_proxy.h +++ b/src/lib/raw_image_proxy.h @@ -33,6 +33,7 @@ public: RawImageProxy (std::shared_ptr xml, std::shared_ptr socket); Result image ( + bool aligned, boost::optional size = boost::optional () ) const; diff --git a/src/lib/util.cc b/src/lib/util.cc index 0646a4787..c65b2bc85 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -956,7 +956,7 @@ emit_subtitle_image (ContentTimePeriod period, dcp::SubtitleImage sub, dcp::Size { /* XXX: this is rather inefficient; decoding the image just to get its size */ FFmpegImageProxy proxy (sub.png_image()); - auto image = proxy.image().image; + auto image = proxy.image(false).image; /* set up rect with height and width */ dcpomatic::Rect rect(0, 0, image->size().width / double(size.width), image->size().height / double(size.height)); diff --git a/src/lib/video_filter_graph.cc b/src/lib/video_filter_graph.cc index a61da6773..b4198da72 100644 --- a/src/lib/video_filter_graph.cc +++ b/src/lib/video_filter_graph.cc @@ -59,7 +59,7 @@ VideoFilterGraph::process (AVFrame* frame) list, int64_t>> images; if (_copy) { - images.push_back (make_pair(make_shared(frame), frame->best_effort_timestamp)); + images.push_back (make_pair(make_shared(frame, true), frame->best_effort_timestamp)); } else { int r = av_buffersrc_write_frame (_buffer_src_context, frame); if (r < 0) { @@ -71,7 +71,7 @@ VideoFilterGraph::process (AVFrame* frame) break; } - images.push_back (make_pair(make_shared(_frame), frame->best_effort_timestamp)); + images.push_back (make_pair(make_shared(_frame, true), frame->best_effort_timestamp)); av_frame_unref (_frame); } } -- cgit v1.2.3