Pull ActiveSubtitles code out to a class.
authorCarl Hetherington <cth@carlh.net>
Sun, 7 May 2017 22:19:05 +0000 (23:19 +0100)
committerCarl Hetherington <cth@carlh.net>
Sun, 7 May 2017 23:35:55 +0000 (00:35 +0100)
src/lib/active_subtitles.cc [new file with mode: 0644]
src/lib/active_subtitles.h [new file with mode: 0644]
src/lib/player.cc
src/lib/player.h
src/lib/wscript

diff --git a/src/lib/active_subtitles.cc b/src/lib/active_subtitles.cc
new file mode 100644 (file)
index 0000000..457f096
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+    Copyright (C) 2017 Carl Hetherington <cth@carlh.net>
+
+    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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "active_subtitles.h"
+#include "piece.h"
+#include "subtitle_content.h"
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+
+using std::list;
+using std::pair;
+using std::make_pair;
+using boost::weak_ptr;
+using boost::shared_ptr;
+
+list<PlayerSubtitles>
+ActiveSubtitles::get (DCPTime time, bool always_burn_subtitles) const
+{
+       list<PlayerSubtitles> ps;
+
+       for (Map::const_iterator i = _data.begin(); i != _data.end(); ++i) {
+
+               shared_ptr<Piece> 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<Period> 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> piece, PlayerSubtitles ps, DCPTime from)
+{
+       if (_data.find(piece) == _data.end()) {
+               _data[piece] = list<Period>();
+       }
+       _data[piece].push_back (Period (ps, from));
+}
+
+pair<PlayerSubtitles, DCPTime>
+ActiveSubtitles::add_to (weak_ptr<Piece> 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> 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 (file)
index 0000000..aa57c5b
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+    Copyright (C) 2017 Carl Hetherington <cth@carlh.net>
+
+    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 <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "dcpomatic_time.h"
+#include "player_subtitles.h"
+#include <boost/noncopyable.hpp>
+#include <list>
+#include <map>
+
+class Piece;
+
+class ActiveSubtitles : public boost::noncopyable
+{
+public:
+       std::list<PlayerSubtitles> get (DCPTime time, bool always_burn_subtitles) const;
+       void clear_before (DCPTime time);
+       void clear ();
+       void add_from (boost::weak_ptr<Piece> piece, PlayerSubtitles ps, DCPTime from);
+       std::pair<PlayerSubtitles, DCPTime> add_to (boost::weak_ptr<Piece> piece, DCPTime to);
+       bool have (boost::weak_ptr<Piece> piece) const;
+
+private:
+       class Period
+       {
+       public:
+               Period () {}
+
+               Period (PlayerSubtitles s, DCPTime f)
+                       : subs (s)
+                       , from (f)
+               {}
+
+               PlayerSubtitles subs;
+               DCPTime from;
+               boost::optional<DCPTime> to;
+       };
+
+       typedef std::map<boost::weak_ptr<Piece>, std::list<Period> > Map;
+
+       Map _data;
+};
index 1110b41b0bea325af567d2e7277d64e7a67d4bb0..06f11c617efdfcfedf3477e6e490fd0f678dcd1f 100644 (file)
@@ -586,46 +586,26 @@ Player::pass ()
 optional<PositionImage>
 Player::subtitles_for_frame (DCPTime time) const
 {
-       /* Get any subtitles */
+       list<PositionImage> subtitles;
 
-       optional<PositionImage> 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<PositionImage> c = transform_image_subtitles (i.image);
+               copy (c.begin(), c.end(), back_inserter (subtitles));
 
-               shared_ptr<Piece> 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<PositionImage> 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<PositionImage> sub_images;
-
-                       /* Image subtitles */
-                       list<PositionImage> 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<PositionImage> 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<PositionImage> ();
        }
 
-       return subtitles;
+       return merge (subtitles);
 }
 
 void
@@ -681,20 +661,7 @@ Player::video (weak_ptr<Piece> 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<ActiveSubtitles> 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<Piece> 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<ActiveSubtitles>();
-       }
-       _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<Piece> wp, ContentTextSubtitle subtitle)
                ps.add_fonts (piece->content->subtitle->fonts ());
        }
 
-       if (_active_subtitles.find(wp) == _active_subtitles.end()) {
-               _active_subtitles[wp] = list<ActiveSubtitles> ();
-       }
-       _active_subtitles[wp].push_back (ActiveSubtitles (ps, from));
+       _active_subtitles.add_from (wp, ps, from);
 }
 
 void
 Player::subtitle_stop (weak_ptr<Piece> 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<Piece> 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<PlayerSubtitles, DCPTime> 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));
        }
 }
 
index 48dcd8892c6891761b96979551477bb272107102..760b54a605f3e1eee868875749ddf8d2d581c187 100644 (file)
@@ -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<DCPTimePeriod> _no_video;
        std::list<DCPTimePeriod> _no_audio;
 
-       class ActiveSubtitles
-       {
-       public:
-               ActiveSubtitles () {}
-
-               ActiveSubtitles (PlayerSubtitles s, DCPTime f)
-                       : subs (s)
-                       , from (f)
-               {}
-
-               PlayerSubtitles subs;
-               DCPTime from;
-               boost::optional<DCPTime> to;
-       };
-       typedef std::map<boost::weak_ptr<Piece>, std::list<ActiveSubtitles> > ActiveSubtitlesMap;
-       ActiveSubtitlesMap _active_subtitles;
-
+       ActiveSubtitles _active_subtitles;
        boost::shared_ptr<AudioProcessor> _audio_processor;
        typedef std::map<std::pair<boost::shared_ptr<const AudioContent>, AudioStreamPtr>, boost::shared_ptr<Resampler> > ResamplerMap;
        ResamplerMap _resamplers;
index 7b19108f591cca0c0053f55eb0d10c396f19717d..765ee60a34bab30163fb106f4ea08c02f722934c 100644 (file)
@@ -21,6 +21,7 @@ import os
 import i18n
 
 sources = """
+          active_subtitles.cc
           analyse_audio_job.cc
           atmos_mxf_content.cc
           audio_analysis.cc