summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2021-09-15 01:00:33 +0200
committerCarl Hetherington <cth@carlh.net>2021-09-27 13:41:46 +0200
commit9bfa07293928c371d59db2091ba2b7e715ce5994 (patch)
treef73bc4c69e13d19c934b0ee798ebfa4a68e46597 /src/lib
parentc59981ce92898f6be6987f10ebb29161e36e6766 (diff)
Various alignment adjustments.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/encoder.cc2
-rw-r--r--src/lib/ffmpeg_decoder.cc2
-rw-r--r--src/lib/ffmpeg_image_proxy.cc4
-rw-r--r--src/lib/ffmpeg_image_proxy.h1
-rw-r--r--src/lib/hints.cc2
-rw-r--r--src/lib/image.cc16
-rw-r--r--src/lib/image.h6
-rw-r--r--src/lib/image_examiner.cc2
-rw-r--r--src/lib/image_proxy.h3
-rw-r--r--src/lib/j2k_image_proxy.cc12
-rw-r--r--src/lib/j2k_image_proxy.h3
-rw-r--r--src/lib/player.cc5
-rw-r--r--src/lib/player.h5
-rw-r--r--src/lib/player_video.cc10
-rw-r--r--src/lib/raw_image_proxy.cc7
-rw-r--r--src/lib/raw_image_proxy.h1
-rw-r--r--src/lib/util.cc2
-rw-r--r--src/lib/video_filter_graph.cc4
18 files changed, 49 insertions, 38 deletions
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<const Film> film, std::weak_ptr<Job> 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<const Film> film, shared_ptr<const FFmp
video = make_shared<VideoDecoder>(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<Image>(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<dcp::Size>) const
+FFmpegImageProxy::image (bool aligned, optional<dcp::Size>) const
{
auto constexpr name_for_errors = "FFmpegImageProxy::image";
@@ -205,7 +205,7 @@ FFmpegImageProxy::image (optional<dcp::Size>) const
throw DecodeError (N_("avcodec_receive_frame"), name_for_errors, r, *_path);
}
- _image = make_shared<Image>(frame);
+ _image = make_shared<Image>(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> socket);
Result image (
+ bool aligned,
boost::optional<dcp::Size> size = boost::optional<dcp::Size> ()
) 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<Player>(film);
+ auto player = make_shared<Player>(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<AVPixelFormat>(frame->format))
- , _aligned (true)
+ , _aligned (aligned)
{
DCPOMATIC_ASSERT (_pixel_format != AV_PIX_FMT_NONE);
@@ -1139,7 +1139,7 @@ Image::aligned () const
PositionImage
-merge (list<PositionImage> images)
+merge (list<PositionImage> images, bool aligned)
{
if (images.empty ()) {
return {};
@@ -1154,7 +1154,7 @@ merge (list<PositionImage> images)
all.extend (dcpomatic::Rect<int>(i.position, i.image->size().width, i.image->size().height));
}
- auto merged = make_shared<Image>(images.front().image->pixel_format(), dcp::Size(all.width, all.height), false);
+ auto merged = make_shared<Image>(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<const Image>
-Image::ensure_aligned (shared_ptr<const Image> image)
+Image::ensure_aligned (shared_ptr<const Image> image, bool aligned)
{
- if (image->aligned()) {
+ if (image->aligned() == aligned) {
return image;
}
- return make_shared<Image>(image, true);
+ return make_shared<Image>(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<Image>
{
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<const Image>, bool);
Image& operator= (Image const &);
@@ -94,7 +94,7 @@ public:
void png_error (char const * message);
- static std::shared_ptr<const Image> ensure_aligned (std::shared_ptr<const Image> image);
+ static std::shared_ptr<const Image> ensure_aligned (std::shared_ptr<const Image> image, bool aligned);
private:
friend struct pixel_formats_test;
@@ -115,7 +115,7 @@ private:
bool _aligned;
};
-extern PositionImage merge (std::list<PositionImage> images);
+extern PositionImage merge (std::list<PositionImage> 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<const Film> film, shared_ptr<const Imag
delete[] buffer;
} else {
FFmpegImageProxy proxy(content->path(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<dcp::Size> size = boost::optional<dcp::Size> ()
) 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<dcp::Size> = boost::optional<dcp::Size>()) const { return 0; }
+ virtual int prepare (bool, boost::optional<dcp::Size> = boost::optional<dcp::Size>()) 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<cxml::Node> xml, shared_ptr<Socket> soc
if (xml->optional_number_child<int>("Eye")) {
_eye = static_cast<dcp::Eye>(xml->number_child<int>("Eye"));
}
- shared_ptr<ArrayData> data(new ArrayData(xml->number_child<int>("Size")));
+ auto data = make_shared<ArrayData>(xml->number_child<int>("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<cxml::Node> xml, shared_ptr<Socket> soc
int
-J2KImageProxy::prepare (optional<dcp::Size> target_size) const
+J2KImageProxy::prepare (bool aligned, optional<dcp::Size> target_size) const
{
boost::mutex::scoped_lock lm (_mutex);
@@ -145,7 +145,7 @@ J2KImageProxy::prepare (optional<dcp::Size> target_size) const
try {
/* XXX: should check that potentially trashing _data here doesn't matter */
auto decompressed = dcp::decompress_j2k (const_cast<uint8_t*>(_data->data()), _data->size(), reduce);
- _image.reset (new Image (_pixel_format, decompressed->size(), false));
+ _image = make_shared<Image>(_pixel_format, decompressed->size(), aligned);
int const shift = 16 - decompressed->precision (0);
@@ -169,7 +169,7 @@ J2KImageProxy::prepare (optional<dcp::Size> target_size) const
}
}
} catch (dcp::J2KDecompressionError& e) {
- _image = make_shared<Image>(_pixel_format, _size, true);
+ _image = make_shared<Image>(_pixel_format, _size, aligned);
_image->make_black ();
_error = true;
}
@@ -182,9 +182,9 @@ J2KImageProxy::prepare (optional<dcp::Size> target_size) const
ImageProxy::Result
-J2KImageProxy::image (optional<dcp::Size> target_size) const
+J2KImageProxy::image (bool aligned, optional<dcp::Size> 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<dcp::Size> size = boost::optional<dcp::Size> ()
) const;
@@ -64,7 +65,7 @@ public:
void write_to_socket (std::shared_ptr<Socket>) const;
/** @return true if our image is definitely the same as another, false if it is probably not */
bool same (std::shared_ptr<const ImageProxy>) const;
- int prepare (boost::optional<dcp::Size> = boost::optional<dcp::Size>()) const;
+ int prepare (bool aligned, boost::optional<dcp::Size> = boost::optional<dcp::Size>()) const;
std::shared_ptr<const dcp::Data> 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<const Film> film)
+Player::Player (shared_ptr<const Film> 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<Player>
{
public:
- Player (std::shared_ptr<const Film>);
+ Player (std::shared_ptr<const Film>, bool aligned_subtitles);
Player (std::shared_ptr<const Film>, std::shared_ptr<const Playlist> 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<AVPixelFormat (AVPixelFormat)> pixel_format, VideoR
}
-shared_ptr<Image>
+shared_ptr<const Image>
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<AVPixelFormat (AVPixelFormat)> 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<AVPixelFormat (AVPixelFormat)> 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<AVPixelFormat (AVPixelFormat)> 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<cxml::Node> xml, shared_ptr<Socket> soc
ImageProxy::Result
-RawImageProxy::image (optional<dcp::Size>) const
+RawImageProxy::image (bool aligned, optional<dcp::Size>) 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<const ImageProxy> 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<cxml::Node> xml, std::shared_ptr<Socket> socket);
Result image (
+ bool aligned,
boost::optional<dcp::Size> size = boost::optional<dcp::Size> ()
) 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<double> 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<pair<shared_ptr<Image>, int64_t>> images;
if (_copy) {
- images.push_back (make_pair(make_shared<Image>(frame), frame->best_effort_timestamp));
+ images.push_back (make_pair(make_shared<Image>(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<Image>(_frame), frame->best_effort_timestamp));
+ images.push_back (make_pair(make_shared<Image>(_frame, true), frame->best_effort_timestamp));
av_frame_unref (_frame);
}
}