diff options
| author | Carl Hetherington <cth@carlh.net> | 2014-07-10 11:27:26 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2014-07-10 11:27:26 +0100 |
| commit | bde76c3341775bd02da59932d285e14eade64ae0 (patch) | |
| tree | 7f0922faf1e64e74c029037afe8857c63f25e51a /src/lib | |
| parent | c7b68d663ac3db10dcf2bfcc11009dce46f820dc (diff) | |
Basics of DCP subtitle import.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/content_factory.cc | 5 | ||||
| -rw-r--r-- | src/lib/dcp_content.cc | 6 | ||||
| -rw-r--r-- | src/lib/dcp_content.h | 1 | ||||
| -rw-r--r-- | src/lib/dcp_subtitle_content.cc | 87 | ||||
| -rw-r--r-- | src/lib/dcp_subtitle_content.h | 37 | ||||
| -rw-r--r-- | src/lib/dcp_subtitle_decoder.cc | 82 | ||||
| -rw-r--r-- | src/lib/dcp_subtitle_decoder.h | 38 | ||||
| -rw-r--r-- | src/lib/player.cc | 9 | ||||
| -rw-r--r-- | src/lib/subrip_content.cc | 14 | ||||
| -rw-r--r-- | src/lib/subrip_content.h | 1 | ||||
| -rw-r--r-- | src/lib/subrip_decoder.cc | 2 | ||||
| -rw-r--r-- | src/lib/subtitle_content.cc | 13 | ||||
| -rw-r--r-- | src/lib/subtitle_content.h | 1 | ||||
| -rw-r--r-- | src/lib/wscript | 2 |
14 files changed, 283 insertions, 15 deletions
diff --git a/src/lib/content_factory.cc b/src/lib/content_factory.cc index 73e333816..16340adb4 100644 --- a/src/lib/content_factory.cc +++ b/src/lib/content_factory.cc @@ -27,6 +27,7 @@ #include "sndfile_content.h" #include "subrip_content.h" #include "dcp_content.h" +#include "dcp_subtitle_content.h" #include "util.h" using std::string; @@ -57,6 +58,8 @@ content_factory (shared_ptr<const Film> film, cxml::NodePtr node, int version, l content.reset (new SubRipContent (film, node, version)); } else if (type == "DCP") { content.reset (new DCPContent (film, node, version)); + } else if (type == "DCPSubtitle") { + content.reset (new DCPSubtitleContent (film, node, version)); } return content; @@ -81,6 +84,8 @@ content_factory (shared_ptr<const Film> film, boost::filesystem::path path) content.reset (new SndfileContent (film, path)); } else if (ext == ".srt") { content.reset (new SubRipContent (film, path)); + } else if (ext == ".xml") { + content.reset (new DCPSubtitleContent (film, path)); } else { content.reset (new FFmpegContent (film, path)); } diff --git a/src/lib/dcp_content.cc b/src/lib/dcp_content.cc index 8ecd52f24..b1d0d9a37 100644 --- a/src/lib/dcp_content.cc +++ b/src/lib/dcp_content.cc @@ -110,3 +110,9 @@ DCPContent::full_length () const assert (film); return DCPTime (video_length (), FrameRateChange (video_frame_rate (), film->video_frame_rate ())); } + +string +DCPContent::identifier () const +{ + return SubtitleContent::identifier (); +} diff --git a/src/lib/dcp_content.h b/src/lib/dcp_content.h index a6ef97400..7ead80ecb 100644 --- a/src/lib/dcp_content.h +++ b/src/lib/dcp_content.h @@ -38,6 +38,7 @@ public: std::string summary () const; std::string technical_summary () const; void as_xml (xmlpp::Node *) const; + std::string identifier () const; boost::filesystem::path directory () const { boost::mutex::scoped_lock lm (_mutex); diff --git a/src/lib/dcp_subtitle_content.cc b/src/lib/dcp_subtitle_content.cc new file mode 100644 index 000000000..e9998dd2a --- /dev/null +++ b/src/lib/dcp_subtitle_content.cc @@ -0,0 +1,87 @@ +/* + Copyright (C) 2014 Carl Hetherington <cth@carlh.net> + + This program 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. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include <dcp/subtitle_content.h> +#include <dcp/raw_convert.h> +#include "dcp_subtitle_content.h" + +#include "i18n.h" + +using std::string; +using boost::shared_ptr; +using dcp::raw_convert; + +DCPSubtitleContent::DCPSubtitleContent (shared_ptr<const Film> film, boost::filesystem::path path) + : Content (film, path) + , SubtitleContent (film, path) +{ + +} + +DCPSubtitleContent::DCPSubtitleContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version) + : Content (film, node) + , SubtitleContent (film, node, version) + , _length (node->number_child<DCPTime::Type> ("Length")) +{ + +} + +void +DCPSubtitleContent::examine (shared_ptr<Job> job) +{ + Content::examine (job); + dcp::SubtitleContent sc (path (0), false); + _length = DCPTime::from_frames (sc.intrinsic_duration(), sc.edit_rate().as_float ()); +} + +DCPTime +DCPSubtitleContent::full_length () const +{ + /* XXX: this assumes that the timing of the subtitle file is appropriate + for the DCP's frame rate. + */ + return _length; +} + +string +DCPSubtitleContent::summary () const +{ + return path_summary() + " " + _("[subtitles]"); +} + +string +DCPSubtitleContent::technical_summary () const +{ + return Content::technical_summary() + " - " + _("DCP XML subtitles"); +} + +string +DCPSubtitleContent::information () const +{ + +} + +void +DCPSubtitleContent::as_xml (xmlpp::Node* node) const +{ + node->add_child("Type")->add_child_text ("DCPSubtitle"); + Content::as_xml (node); + SubtitleContent::as_xml (node); + node->add_child("Length")->add_child_text (raw_convert<string> (_length.get ())); +} diff --git a/src/lib/dcp_subtitle_content.h b/src/lib/dcp_subtitle_content.h new file mode 100644 index 000000000..79338c1af --- /dev/null +++ b/src/lib/dcp_subtitle_content.h @@ -0,0 +1,37 @@ +/* + Copyright (C) 2014 Carl Hetherington <cth@carlh.net> + + This program 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. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "subtitle_content.h" + +class DCPSubtitleContent : public SubtitleContent +{ +public: + DCPSubtitleContent (boost::shared_ptr<const Film>, boost::filesystem::path); + DCPSubtitleContent (boost::shared_ptr<const Film>, cxml::ConstNodePtr, int); + + void examine (boost::shared_ptr<Job>); + std::string summary () const; + std::string technical_summary () const; + std::string information () const; + void as_xml (xmlpp::Node *) const; + DCPTime full_length () const; + +private: + DCPTime _length; +}; diff --git a/src/lib/dcp_subtitle_decoder.cc b/src/lib/dcp_subtitle_decoder.cc new file mode 100644 index 000000000..c1f0ab500 --- /dev/null +++ b/src/lib/dcp_subtitle_decoder.cc @@ -0,0 +1,82 @@ +/* + Copyright (C) 2014 Carl Hetherington <cth@carlh.net> + + This program 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. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include <dcp/subtitle_content.h> +#include "dcp_subtitle_decoder.h" +#include "dcp_subtitle_content.h" + +using std::list; +using boost::shared_ptr; + +DCPSubtitleDecoder::DCPSubtitleDecoder (shared_ptr<const DCPSubtitleContent> content) + : SubtitleDecoder (content) +{ + dcp::SubtitleContent c (content->path (0), false); + _subtitles = c.subtitles (); + _next = _subtitles.begin (); +} + +void +DCPSubtitleDecoder::seek (ContentTime time, bool accurate) +{ + SubtitleDecoder::seek (time, accurate); + + _next = _subtitles.begin (); + list<dcp::SubtitleString>::const_iterator i = _subtitles.begin (); + while (i != _subtitles.end() && ContentTime::from_seconds (_next->in().to_seconds()) < time) { + ++i; + } +} + +bool +DCPSubtitleDecoder::pass () +{ + if (_next == _subtitles.end ()) { + return true; + } + + list<dcp::SubtitleString> s; + s.push_back (*_next); + text_subtitle (s); + ++_next; + + return false; +} + +list<ContentTimePeriod> +DCPSubtitleDecoder::subtitles_during (ContentTimePeriod p, bool starting) const +{ + /* XXX: inefficient */ + + list<ContentTimePeriod> d; + + for (list<dcp::SubtitleString>::const_iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) { + ContentTimePeriod period ( + ContentTime::from_seconds (i->in().to_seconds ()), + ContentTime::from_seconds (i->out().to_seconds ()) + ); + + if ((starting && p.contains (period.from)) || (!starting && p.overlaps (period))) { + d.push_back (period); + } + } + + return d; +} + diff --git a/src/lib/dcp_subtitle_decoder.h b/src/lib/dcp_subtitle_decoder.h new file mode 100644 index 000000000..070562458 --- /dev/null +++ b/src/lib/dcp_subtitle_decoder.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2014 Carl Hetherington <cth@carlh.net> + + This program 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. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "subtitle_decoder.h" + +class DCPSubtitleContent; + +class DCPSubtitleDecoder : public SubtitleDecoder +{ +public: + DCPSubtitleDecoder (boost::shared_ptr<const DCPSubtitleContent>); + +protected: + void seek (ContentTime time, bool accurate); + bool pass (); + +private: + std::list<ContentTimePeriod> subtitles_during (ContentTimePeriod, bool starting) const; + + std::list<dcp::SubtitleString> _subtitles; + std::list<dcp::SubtitleString>::const_iterator _next; +}; diff --git a/src/lib/player.cc b/src/lib/player.cc index c855471b4..9e14b65b3 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -45,6 +45,8 @@ #include "frame_rate_change.h" #include "dcp_content.h" #include "dcp_decoder.h" +#include "dcp_subtitle_content.h" +#include "dcp_subtitle_decoder.h" #define LOG_GENERAL(...) _film->log()->log (String::compose (__VA_ARGS__), Log::TYPE_GENERAL); @@ -160,6 +162,13 @@ Player::setup_pieces () frc = best_overlap_frc; } + /* DCPSubtitleContent */ + shared_ptr<const DCPSubtitleContent> dsc = dynamic_pointer_cast<const DCPSubtitleContent> (*i); + if (dsc) { + decoder.reset (new DCPSubtitleDecoder (dsc)); + frc = best_overlap_frc; + } + _pieces.push_back (shared_ptr<Piece> (new Piece (*i, decoder, frc.get ()))); } diff --git a/src/lib/subrip_content.cc b/src/lib/subrip_content.cc index 455bd1e8f..c60b05d50 100644 --- a/src/lib/subrip_content.cc +++ b/src/lib/subrip_content.cc @@ -77,7 +77,7 @@ SubRipContent::technical_summary () const string SubRipContent::information () const { - + } void @@ -97,15 +97,3 @@ SubRipContent::full_length () const */ return _length; } - -string -SubRipContent::identifier () const -{ - stringstream s; - s << Content::identifier() - << "_" << raw_convert<string> (subtitle_scale()) - << "_" << raw_convert<string> (subtitle_x_offset()) - << "_" << raw_convert<string> (subtitle_y_offset()); - - return s.str (); -} diff --git a/src/lib/subrip_content.h b/src/lib/subrip_content.h index 5688f81d5..7da6e71f7 100644 --- a/src/lib/subrip_content.h +++ b/src/lib/subrip_content.h @@ -35,7 +35,6 @@ public: std::string information () const; void as_xml (xmlpp::Node *) const; DCPTime full_length () const; - std::string identifier () const; private: DCPTime _length; diff --git a/src/lib/subrip_decoder.cc b/src/lib/subrip_decoder.cc index 4bdf06e7c..e2bdc347b 100644 --- a/src/lib/subrip_decoder.cc +++ b/src/lib/subrip_decoder.cc @@ -75,7 +75,7 @@ SubRipDecoder::pass () } text_subtitle (out); - _next++; + ++_next; return false; } diff --git a/src/lib/subtitle_content.cc b/src/lib/subtitle_content.cc index 88e48b420..8c94a94b9 100644 --- a/src/lib/subtitle_content.cc +++ b/src/lib/subtitle_content.cc @@ -26,6 +26,7 @@ #include "i18n.h" using std::string; +using std::stringstream; using std::vector; using std::cout; using boost::shared_ptr; @@ -155,3 +156,15 @@ SubtitleContent::set_subtitle_scale (double s) } signal_changed (SubtitleContentProperty::SUBTITLE_SCALE); } + +string +SubtitleContent::identifier () const +{ + stringstream s; + s << Content::identifier() + << "_" << raw_convert<string> (subtitle_scale()) + << "_" << raw_convert<string> (subtitle_x_offset()) + << "_" << raw_convert<string> (subtitle_y_offset()); + + return s.str (); +} diff --git a/src/lib/subtitle_content.h b/src/lib/subtitle_content.h index f46a87c15..1425c33cd 100644 --- a/src/lib/subtitle_content.h +++ b/src/lib/subtitle_content.h @@ -40,6 +40,7 @@ public: SubtitleContent (boost::shared_ptr<const Film>, std::vector<boost::shared_ptr<Content> >); void as_xml (xmlpp::Node *) const; + std::string identifier () const; void set_subtitle_use (bool); void set_subtitle_x_offset (double); diff --git a/src/lib/wscript b/src/lib/wscript index ae6e0b800..d96bb7f96 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -19,6 +19,8 @@ sources = """ dcp_content_type.cc dcp_decoder.cc dcp_examiner.cc + dcp_subtitle_content.cc + dcp_subtitle_decoder.cc dcp_video.cc dcpomatic_time.cc dolby_cp750.cc |
