From 81b8b8d2e6c548fe0cac006b6551945f5c1d77a9 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 7 May 2017 23:19:05 +0100 Subject: [PATCH] Pull ActiveSubtitles code out to a class. --- src/lib/active_subtitles.cc | 115 ++++++++++++++++++++++++++++++++++++ src/lib/active_subtitles.h | 58 ++++++++++++++++++ src/lib/player.cc | 83 +++++++------------------- src/lib/player.h | 19 +----- src/lib/wscript | 1 + 5 files changed, 196 insertions(+), 80 deletions(-) create mode 100644 src/lib/active_subtitles.cc create mode 100644 src/lib/active_subtitles.h diff --git a/src/lib/active_subtitles.cc b/src/lib/active_subtitles.cc new file mode 100644 index 000000000..457f09643 --- /dev/null +++ b/src/lib/active_subtitles.cc @@ -0,0 +1,115 @@ +/* + Copyright (C) 2017 Carl Hetherington + + This file is part of DCP-o-matic. + + DCP-o-matic is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DCP-o-matic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DCP-o-matic. If not, see . + +*/ + +#include "active_subtitles.h" +#include "piece.h" +#include "subtitle_content.h" +#include +#include + +using std::list; +using std::pair; +using std::make_pair; +using boost::weak_ptr; +using boost::shared_ptr; + +list +ActiveSubtitles::get (DCPTime time, bool always_burn_subtitles) const +{ + list ps; + + for (Map::const_iterator i = _data.begin(); i != _data.end(); ++i) { + + shared_ptr piece = i->first.lock (); + if (!piece) { + continue; + } + + if (!piece->content->subtitle->use() || (!always_burn_subtitles && !piece->content->subtitle->burn())) { + continue; + } + + BOOST_FOREACH (Period j, i->second) { + if (j.from <= time && (!j.to || j.to.get() > time)) { + ps.push_back (j.subs); + } + } + } + + return ps; +} + +void +ActiveSubtitles::clear_before (DCPTime time) +{ + Map updated; + for (Map::const_iterator i = _data.begin(); i != _data.end(); ++i) { + list as; + BOOST_FOREACH (Period j, i->second) { + if (!j.to || j.to.get() >= time) { + as.push_back (j); + } + } + if (!as.empty ()) { + updated[i->first] = as; + } + } + _data = updated; +} + +void +ActiveSubtitles::add_from (weak_ptr piece, PlayerSubtitles ps, DCPTime from) +{ + if (_data.find(piece) == _data.end()) { + _data[piece] = list(); + } + _data[piece].push_back (Period (ps, from)); +} + +pair +ActiveSubtitles::add_to (weak_ptr piece, DCPTime to) +{ + DCPOMATIC_ASSERT (_data.find(piece) != _data.end()); + + _data[piece].back().to = to; + + BOOST_FOREACH (SubtitleString& i, _data[piece].back().subs.text) { + i.set_out (dcp::Time(to.seconds(), 1000)); + } + + return make_pair (_data[piece].back().subs, _data[piece].back().from); +} + +bool +ActiveSubtitles::have (weak_ptr piece) const +{ + Map::const_iterator i = _data.find(piece); + if (i == _data.end()) { + return false; + } + + return !i->second.empty(); +} + +void +ActiveSubtitles::clear () +{ + _data.clear (); +} diff --git a/src/lib/active_subtitles.h b/src/lib/active_subtitles.h new file mode 100644 index 000000000..aa57c5b7a --- /dev/null +++ b/src/lib/active_subtitles.h @@ -0,0 +1,58 @@ +/* + Copyright (C) 2017 Carl Hetherington + + This file is part of DCP-o-matic. + + DCP-o-matic is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DCP-o-matic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DCP-o-matic. If not, see . + +*/ + +#include "dcpomatic_time.h" +#include "player_subtitles.h" +#include +#include +#include + +class Piece; + +class ActiveSubtitles : public boost::noncopyable +{ +public: + std::list get (DCPTime time, bool always_burn_subtitles) const; + void clear_before (DCPTime time); + void clear (); + void add_from (boost::weak_ptr piece, PlayerSubtitles ps, DCPTime from); + std::pair add_to (boost::weak_ptr piece, DCPTime to); + bool have (boost::weak_ptr piece) const; + +private: + class Period + { + public: + Period () {} + + Period (PlayerSubtitles s, DCPTime f) + : subs (s) + , from (f) + {} + + PlayerSubtitles subs; + DCPTime from; + boost::optional to; + }; + + typedef std::map, std::list > Map; + + Map _data; +}; diff --git a/src/lib/player.cc b/src/lib/player.cc index 1110b41b0..06f11c617 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -586,46 +586,26 @@ Player::pass () optional Player::subtitles_for_frame (DCPTime time) const { - /* Get any subtitles */ + list subtitles; - optional subtitles; + BOOST_FOREACH (PlayerSubtitles i, _active_subtitles.get(time, _always_burn_subtitles)) { - for (ActiveSubtitlesMap::const_iterator i = _active_subtitles.begin(); i != _active_subtitles.end(); ++i) { + /* Image subtitles */ + list c = transform_image_subtitles (i.image); + copy (c.begin(), c.end(), back_inserter (subtitles)); - shared_ptr sub_piece = i->first.lock (); - if (!sub_piece) { - continue; - } - - if (!sub_piece->content->subtitle->use() || (!_always_burn_subtitles && !sub_piece->content->subtitle->burn())) { - continue; + /* Text subtitles (rendered to an image) */ + if (!i.text.empty ()) { + list s = render_subtitles (i.text, i.fonts, _video_container_size, time); + copy (s.begin(), s.end(), back_inserter (subtitles)); } + } - BOOST_FOREACH (ActiveSubtitles j, i->second) { - - if (j.from > time || (j.to && j.to.get() <= time)) { - continue; - } - - list sub_images; - - /* Image subtitles */ - list c = transform_image_subtitles (j.subs.image); - copy (c.begin(), c.end(), back_inserter (sub_images)); - - /* Text subtitles (rendered to an image) */ - if (!j.subs.text.empty ()) { - list s = render_subtitles (j.subs.text, j.subs.fonts, _video_container_size, time); - copy (s.begin (), s.end (), back_inserter (sub_images)); - } - - if (!sub_images.empty ()) { - subtitles = merge (sub_images); - } - } + if (subtitles.empty ()) { + return optional (); } - return subtitles; + return merge (subtitles); } void @@ -681,20 +661,7 @@ Player::video (weak_ptr wp, ContentVideo video) _last_video_time = time + one_video_frame (); - /* Clear any finished _active_subtitles */ - ActiveSubtitlesMap updated; - for (ActiveSubtitlesMap::const_iterator i = _active_subtitles.begin(); i != _active_subtitles.end(); ++i) { - list as; - BOOST_FOREACH (ActiveSubtitles j, i->second) { - if (!j.to || j.to.get() >= time) { - as.push_back (j); - } - } - if (!as.empty ()) { - updated[i->first] = as; - } - } - _active_subtitles = updated; + _active_subtitles.clear_before (time); } void @@ -847,10 +814,7 @@ Player::image_subtitle_start (weak_ptr wp, ContentImageSubtitle subtitle) ps.image.push_back (subtitle.sub); DCPTime from (content_time_to_dcp (piece, subtitle.from())); - if (_active_subtitles.find(wp) == _active_subtitles.end()) { - _active_subtitles[wp] = list(); - } - _active_subtitles[wp].push_back (ActiveSubtitles (ps, from)); + _active_subtitles.add_from (wp, ps, from); } void @@ -889,16 +853,13 @@ Player::text_subtitle_start (weak_ptr wp, ContentTextSubtitle subtitle) ps.add_fonts (piece->content->subtitle->fonts ()); } - if (_active_subtitles.find(wp) == _active_subtitles.end()) { - _active_subtitles[wp] = list (); - } - _active_subtitles[wp].push_back (ActiveSubtitles (ps, from)); + _active_subtitles.add_from (wp, ps, from); } void Player::subtitle_stop (weak_ptr wp, ContentTime to) { - if (_active_subtitles.find (wp) == _active_subtitles.end ()) { + if (!_active_subtitles.have (wp)) { return; } @@ -909,14 +870,10 @@ Player::subtitle_stop (weak_ptr wp, ContentTime to) DCPTime const dcp_to = content_time_to_dcp (piece, to); - if (piece->content->subtitle->use() && !_always_burn_subtitles && !piece->content->subtitle->burn()) { - Subtitle (_active_subtitles[wp].back().subs, DCPTimePeriod (_active_subtitles[wp].back().from, dcp_to)); - } - - _active_subtitles[wp].back().to = dcp_to; + pair from = _active_subtitles.add_to (wp, dcp_to); - BOOST_FOREACH (SubtitleString& i, _active_subtitles[wp].back().subs.text) { - i.set_out (dcp::Time(dcp_to.seconds(), 1000)); + if (piece->content->subtitle->use() && !_always_burn_subtitles && !piece->content->subtitle->burn()) { + Subtitle (from.first, DCPTimePeriod (from.second, dcp_to)); } } diff --git a/src/lib/player.h b/src/lib/player.h index 48dcd8892..760b54a60 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -22,6 +22,7 @@ #define DCPOMATIC_PLAYER_H #include "player_subtitles.h" +#include "active_subtitles.h" #include "film.h" #include "content.h" #include "position_image.h" @@ -170,23 +171,7 @@ private: std::list _no_video; std::list _no_audio; - class ActiveSubtitles - { - public: - ActiveSubtitles () {} - - ActiveSubtitles (PlayerSubtitles s, DCPTime f) - : subs (s) - , from (f) - {} - - PlayerSubtitles subs; - DCPTime from; - boost::optional to; - }; - typedef std::map, std::list > ActiveSubtitlesMap; - ActiveSubtitlesMap _active_subtitles; - + ActiveSubtitles _active_subtitles; boost::shared_ptr _audio_processor; typedef std::map, AudioStreamPtr>, boost::shared_ptr > ResamplerMap; ResamplerMap _resamplers; diff --git a/src/lib/wscript b/src/lib/wscript index 7b19108f5..765ee60a3 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -21,6 +21,7 @@ import os import i18n sources = """ + active_subtitles.cc analyse_audio_job.cc atmos_mxf_content.cc audio_analysis.cc -- 2.30.2