summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2018-07-20 19:55:22 +0100
committerCarl Hetherington <cth@carlh.net>2018-07-20 19:55:22 +0100
commitad70feebe3a9a89865185b05e084b326637ff81e (patch)
treed440c1c5ab27cb5cde4333943654d57a40793684 /src/lib
parentf82bdaa6ffe1a9e62a010de405f8bbb7ea392f00 (diff)
Untested; allow viewing of subtitles or closed captions in the preview.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/active_captions.cc6
-rw-r--r--src/lib/active_captions.h2
-rw-r--r--src/lib/ffmpeg_encoder.cc2
-rw-r--r--src/lib/player.cc52
-rw-r--r--src/lib/player.h10
-rw-r--r--src/lib/player_video.cc36
-rw-r--r--src/lib/player_video.h4
7 files changed, 59 insertions, 53 deletions
diff --git a/src/lib/active_captions.cc b/src/lib/active_captions.cc
index d41270382..bb64f995d 100644
--- a/src/lib/active_captions.cc
+++ b/src/lib/active_captions.cc
@@ -33,10 +33,10 @@ using boost::optional;
/** Get the subtitles that should be burnt into a given period.
* @param period Period of interest.
- * @param always_burn_subtitles Always burn subtitles even if their content is not set to burn.
+ * @param always_burn_captions Always burn captions even if their content is not set to burn.
*/
list<PlayerCaption>
-ActiveCaptions::get_burnt (DCPTimePeriod period, bool always_burn_subtitles) const
+ActiveCaptions::get_burnt (DCPTimePeriod period, bool always_burn_captions) const
{
list<PlayerCaption> ps;
@@ -47,7 +47,7 @@ ActiveCaptions::get_burnt (DCPTimePeriod period, bool always_burn_subtitles) con
continue;
}
- if (!piece->content->caption->use() || (!always_burn_subtitles && !piece->content->caption->burn())) {
+ if (!piece->content->caption->use() || (!always_burn_captions && !piece->content->caption->burn())) {
/* Not burning this piece */
continue;
}
diff --git a/src/lib/active_captions.h b/src/lib/active_captions.h
index 718ba393e..e0e8acf8e 100644
--- a/src/lib/active_captions.h
+++ b/src/lib/active_captions.h
@@ -36,7 +36,7 @@ class Piece;
class ActiveCaptions : public boost::noncopyable
{
public:
- std::list<PlayerCaption> get_burnt (DCPTimePeriod period, bool always_burn_subtitles) const;
+ std::list<PlayerCaption> get_burnt (DCPTimePeriod period, bool always_burn_captions) const;
void clear_before (DCPTime time);
void clear ();
void add_from (boost::weak_ptr<Piece> piece, PlayerCaption ps, DCPTime from);
diff --git a/src/lib/ffmpeg_encoder.cc b/src/lib/ffmpeg_encoder.cc
index cc2591498..10d439f94 100644
--- a/src/lib/ffmpeg_encoder.cc
+++ b/src/lib/ffmpeg_encoder.cc
@@ -72,7 +72,7 @@ FFmpegEncoder::FFmpegEncoder (shared_ptr<const Film> film, weak_ptr<Job> job, bo
break;
}
- _player->set_always_burn_subtitles (true);
+ _player->set_always_burn_captions (CAPTION_OPEN);
_player->set_play_referenced ();
int const ch = film->audio_channels ();
diff --git a/src/lib/player.cc b/src/lib/player.cc
index 7040bd530..719e59acc 100644
--- a/src/lib/player.cc
+++ b/src/lib/player.cc
@@ -89,7 +89,6 @@ Player::Player (shared_ptr<const Film> film, shared_ptr<const Playlist> playlist
, _have_valid_pieces (false)
, _ignore_video (false)
, _ignore_subtitle (false)
- , _always_burn_subtitles (false)
, _fast (false)
, _play_referenced (false)
, _audio_merger (_film->audio_frame_rate())
@@ -431,14 +430,14 @@ Player::set_ignore_subtitle ()
_ignore_subtitle = true;
}
-/** Set whether or not this player should always burn text subtitles into the image,
+/** Set a type of caption that this player should always burn into the image,
* regardless of the content settings.
- * @param burn true to always burn subtitles, false to obey content settings.
+ * @param type type of captions to burn.
*/
void
-Player::set_always_burn_subtitles (bool burn)
+Player::set_always_burn_captions (CaptionType type)
{
- _always_burn_subtitles = burn;
+ _always_burn_captions = type;
}
/** Sets up the player to be faster, possibly at the expense of quality */
@@ -657,30 +656,36 @@ Player::pass ()
}
optional<PositionImage>
-Player::subtitles_for_frame (DCPTime time) const
+Player::captions_for_frame (DCPTime time) const
{
- list<PositionImage> subtitles;
+ list<PositionImage> captions;
int const vfr = _film->video_frame_rate();
- BOOST_FOREACH (PlayerCaption i, _active_captions[CAPTION_OPEN].get_burnt (DCPTimePeriod(time, time + DCPTime::from_frames(1, vfr)), _always_burn_subtitles)) {
-
- /* Image subtitles */
- list<PositionImage> c = transform_bitmap_captions (i.image);
- copy (c.begin(), c.end(), back_inserter (subtitles));
-
- /* Text subtitles (rendered to an image) */
- if (!i.text.empty ()) {
- list<PositionImage> s = render_text (i.text, i.fonts, _video_container_size, time, vfr);
- copy (s.begin(), s.end(), back_inserter (subtitles));
+ for (int i = 0; i < CAPTION_COUNT; ++i) {
+ bool const always = _always_burn_captions && *_always_burn_captions == i;
+ BOOST_FOREACH (
+ PlayerCaption j,
+ _active_captions[i].get_burnt(DCPTimePeriod(time, time + DCPTime::from_frames(1, vfr)), always)
+ ) {
+
+ /* Image subtitles */
+ list<PositionImage> c = transform_bitmap_captions (j.image);
+ copy (c.begin(), c.end(), back_inserter (captions));
+
+ /* Text subtitles (rendered to an image) */
+ if (!j.text.empty ()) {
+ list<PositionImage> s = render_text (j.text, j.fonts, _video_container_size, time, vfr);
+ copy (s.begin(), s.end(), back_inserter (captions));
+ }
}
}
- if (subtitles.empty ()) {
+ if (captions.empty ()) {
return optional<PositionImage> ();
}
- return merge (subtitles);
+ return merge (captions);
}
void
@@ -928,7 +933,8 @@ Player::subtitle_stop (weak_ptr<Piece> wp, ContentTime to, CaptionType type)
pair<PlayerCaption, DCPTime> from = _active_captions[type].add_to (wp, dcp_to);
- if (piece->content->caption->use() && !_always_burn_subtitles && !piece->content->caption->burn()) {
+ bool const always = _always_burn_captions && *_always_burn_captions == type;
+ if (piece->content->caption->use() && !always && !piece->content->caption->burn()) {
Caption (from.first, type, DCPTimePeriod (from.second, dcp_to));
}
}
@@ -1017,9 +1023,9 @@ Player::do_emit_video (shared_ptr<PlayerVideo> pv, DCPTime time)
}
}
- optional<PositionImage> subtitles = subtitles_for_frame (time);
- if (subtitles) {
- pv->set_subtitle (subtitles.get ());
+ optional<PositionImage> captions = captions_for_frame (time);
+ if (captions) {
+ pv->set_caption (captions.get ());
}
Video (pv, time);
diff --git a/src/lib/player.h b/src/lib/player.h
index 5b6a0b7b4..cbadb11f6 100644
--- a/src/lib/player.h
+++ b/src/lib/player.h
@@ -79,7 +79,7 @@ public:
void set_video_container_size (dcp::Size);
void set_ignore_video ();
void set_ignore_subtitle ();
- void set_always_burn_subtitles (bool burn);
+ void set_always_burn_captions (CaptionType type);
void set_fast ();
void set_play_referenced ();
void set_dcp_decode_reduction (boost::optional<int> reduction);
@@ -134,7 +134,7 @@ private:
std::pair<boost::shared_ptr<AudioBuffers>, DCPTime> discard_audio (
boost::shared_ptr<const AudioBuffers> audio, DCPTime time, DCPTime discard_to
) const;
- boost::optional<PositionImage> subtitles_for_frame (DCPTime time) const;
+ boost::optional<PositionImage> captions_for_frame (DCPTime time) const;
void emit_video (boost::shared_ptr<PlayerVideo> pv, DCPTime time);
void do_emit_video (boost::shared_ptr<PlayerVideo> pv, DCPTime time);
void emit_audio (boost::shared_ptr<AudioBuffers> data, DCPTime time);
@@ -154,10 +154,10 @@ private:
bool _ignore_video;
/** true if the player should ignore all audio; i.e. never produce any */
bool _ignore_subtitle;
- /** true if the player should always burn subtitles into the video regardless
- of content settings
+ /** Type of captions that the player should always burn into the video regardless
+ of content settings.
*/
- bool _always_burn_subtitles;
+ boost::optional<CaptionType> _always_burn_captions;
/** true if we should try to be fast rather than high quality */
bool _fast;
/** true if we should `play' (i.e output) referenced DCP data (e.g. for preview) */
diff --git a/src/lib/player_video.cc b/src/lib/player_video.cc
index a50b196a2..c8fb044aa 100644
--- a/src/lib/player_video.cc
+++ b/src/lib/player_video.cc
@@ -92,14 +92,14 @@ PlayerVideo::PlayerVideo (shared_ptr<cxml::Node> node, shared_ptr<Socket> socket
image->read_from_socket (socket);
- _subtitle = PositionImage (image, Position<int> (node->number_child<int> ("SubtitleX"), node->number_child<int> ("SubtitleY")));
+ _caption = PositionImage (image, Position<int> (node->number_child<int> ("SubtitleX"), node->number_child<int> ("SubtitleY")));
}
}
void
-PlayerVideo::set_subtitle (PositionImage image)
+PlayerVideo::set_caption (PositionImage image)
{
- _subtitle = image;
+ _caption = image;
}
/** Create an image for this frame.
@@ -153,8 +153,8 @@ PlayerVideo::image (dcp::NoteHandler note, function<AVPixelFormat (AVPixelFormat
total_crop, _inter_size, _out_size, yuv_to_rgb, pixel_format (_in->pixel_format()), aligned, fast
);
- if (_subtitle) {
- out->alpha_blend (Image::ensure_aligned (_subtitle->image), _subtitle->position);
+ if (_caption) {
+ out->alpha_blend (Image::ensure_aligned (_caption->image), _caption->position);
}
if (_fade) {
@@ -181,11 +181,11 @@ PlayerVideo::add_metadata (xmlpp::Node* node) const
if (_colour_conversion) {
_colour_conversion.get().as_xml (node);
}
- if (_subtitle) {
- node->add_child ("SubtitleWidth")->add_child_text (raw_convert<string> (_subtitle->image->size().width));
- node->add_child ("SubtitleHeight")->add_child_text (raw_convert<string> (_subtitle->image->size().height));
- node->add_child ("SubtitleX")->add_child_text (raw_convert<string> (_subtitle->position.x));
- node->add_child ("SubtitleY")->add_child_text (raw_convert<string> (_subtitle->position.y));
+ if (_caption) {
+ node->add_child ("SubtitleWidth")->add_child_text (raw_convert<string> (_caption->image->size().width));
+ node->add_child ("SubtitleHeight")->add_child_text (raw_convert<string> (_caption->image->size().height));
+ node->add_child ("SubtitleX")->add_child_text (raw_convert<string> (_caption->position.x));
+ node->add_child ("SubtitleY")->add_child_text (raw_convert<string> (_caption->position.y));
}
}
@@ -193,8 +193,8 @@ void
PlayerVideo::send_binary (shared_ptr<Socket> socket) const
{
_in->send_binary (socket);
- if (_subtitle) {
- _subtitle->image->write_to_socket (socket);
+ if (_caption) {
+ _caption->image->write_to_socket (socket);
}
}
@@ -208,7 +208,7 @@ PlayerVideo::has_j2k () const
return false;
}
- return _crop == Crop () && _out_size == j2k->size() && !_subtitle && !_fade && !_colour_conversion;
+ return _crop == Crop () && _out_size == j2k->size() && !_caption && !_fade && !_colour_conversion;
}
Data
@@ -239,13 +239,13 @@ PlayerVideo::same (shared_ptr<const PlayerVideo> other) const
return false;
}
- if ((!_subtitle && other->_subtitle) || (_subtitle && !other->_subtitle)) {
- /* One has a subtitle and the other doesn't */
+ if ((!_caption && other->_caption) || (_caption && !other->_caption)) {
+ /* One has a caption and the other doesn't */
return false;
}
- if (_subtitle && other->_subtitle && !_subtitle->same (other->_subtitle.get ())) {
- /* They both have subtitles but they are different */
+ if (_caption && other->_caption && !_caption->same (other->_caption.get ())) {
+ /* They both have captions but they are different */
return false;
}
@@ -278,7 +278,7 @@ PlayerVideo::memory_used () const
return _in->memory_used();
}
-/** @return Shallow copy of this; _in and _subtitle are shared between the original and the copy */
+/** @return Shallow copy of this; _in and _caption are shared between the original and the copy */
shared_ptr<PlayerVideo>
PlayerVideo::shallow_copy () const
{
diff --git a/src/lib/player_video.h b/src/lib/player_video.h
index f4bf2a471..96878e0bd 100644
--- a/src/lib/player_video.h
+++ b/src/lib/player_video.h
@@ -60,7 +60,7 @@ public:
boost::shared_ptr<PlayerVideo> shallow_copy () const;
- void set_subtitle (PositionImage);
+ void set_caption (PositionImage);
void prepare ();
boost::shared_ptr<Image> image (dcp::NoteHandler note, boost::function<AVPixelFormat (AVPixelFormat)> pixel_format, bool aligned, bool fast) const;
@@ -109,7 +109,7 @@ private:
Eyes _eyes;
Part _part;
boost::optional<ColourConversion> _colour_conversion;
- boost::optional<PositionImage> _subtitle;
+ boost::optional<PositionImage> _caption;
/** Content that we came from. This is so that reset_metadata() can work */
boost::weak_ptr<Content> _content;
/** Video frame that we came from. Again, this is for reset_metadata() */