#include "sndfile_content.h"
#include "subrip_content.h"
#include "dcp_content.h"
+#include "dcp_subtitle_content.h"
#include "util.h"
using std::string;
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;
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));
}
assert (film);
return DCPTime (video_length (), FrameRateChange (video_frame_rate (), film->video_frame_rate ()));
}
+
+string
+DCPContent::identifier () const
+{
+ return SubtitleContent::identifier ();
+}
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);
--- /dev/null
+/*
+ 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 ()));
+}
--- /dev/null
+/*
+ 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;
+};
--- /dev/null
+/*
+ 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;
+}
+
--- /dev/null
+/*
+ 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;
+};
#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);
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 ())));
}
string
SubRipContent::information () const
{
-
+
}
void
*/
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 ();
-}
std::string information () const;
void as_xml (xmlpp::Node *) const;
DCPTime full_length () const;
- std::string identifier () const;
private:
DCPTime _length;
}
text_subtitle (out);
- _next++;
+ ++_next;
return false;
}
#include "i18n.h"
using std::string;
+using std::stringstream;
using std::vector;
using std::cout;
using boost::shared_ptr;
}
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 ();
+}
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);
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
#include "lib/ffmpeg_content.h"
#include "lib/subrip_content.h"
#include "lib/ffmpeg_subtitle_stream.h"
+#include "lib/dcp_subtitle_content.h"
+#include "lib/subrip_decoder.h"
+#include "lib/dcp_subtitle_decoder.h"
#include "subtitle_panel.h"
#include "film_editor.h"
#include "wx_util.h"
{
int any_subs = 0;
int ffmpeg_subs = 0;
- int subrip_subs = 0;
+ int subrip_or_dcp_subs = 0;
SubtitleContentList c = _editor->selected_subtitle_content ();
for (SubtitleContentList::const_iterator i = c.begin(); i != c.end(); ++i) {
shared_ptr<const FFmpegContent> fc = boost::dynamic_pointer_cast<const FFmpegContent> (*i);
shared_ptr<const SubRipContent> sc = boost::dynamic_pointer_cast<const SubRipContent> (*i);
+ shared_ptr<const DCPSubtitleContent> dsc = boost::dynamic_pointer_cast<const DCPSubtitleContent> (*i);
if (fc) {
if (!fc->subtitle_streams().empty ()) {
++ffmpeg_subs;
++any_subs;
}
- } else if (sc) {
- ++subrip_subs;
+ } else if (sc || dsc) {
+ ++subrip_or_dcp_subs;
++any_subs;
} else {
++any_subs;
_y_offset->Enable (any_subs > 0 && use);
_scale->Enable (any_subs > 0 && use);
_stream->Enable (ffmpeg_subs == 1);
- _view_button->Enable (subrip_subs == 1);
+ _view_button->Enable (subrip_or_dcp_subs == 1);
}
void
SubtitleContentList c = _editor->selected_subtitle_content ();
assert (c.size() == 1);
+
+ shared_ptr<SubtitleDecoder> decoder;
+
shared_ptr<SubRipContent> sr = dynamic_pointer_cast<SubRipContent> (c.front ());
if (sr) {
- _view = new SubtitleView (this, _editor->film(), sr);
+ decoder.reset (new SubRipDecoder (sr));
+ }
+
+ shared_ptr<DCPSubtitleContent> dc = dynamic_pointer_cast<DCPSubtitleContent> (c.front ());
+ if (dc) {
+ decoder.reset (new DCPSubtitleDecoder (dc));
+ }
+
+ if (decoder) {
+ _view = new SubtitleView (this, _editor->film(), decoder, c.front()->position ());
_view->Show ();
}
}
using boost::shared_ptr;
using boost::dynamic_pointer_cast;
-SubtitleView::SubtitleView (wxWindow* parent, shared_ptr<Film> film, shared_ptr<SubRipContent> content)
+SubtitleView::SubtitleView (wxWindow* parent, shared_ptr<Film> film, shared_ptr<SubtitleDecoder> decoder, DCPTime position)
: wxDialog (parent, wxID_ANY, _("Subtitles"))
{
_list = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL);
sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
}
- shared_ptr<SubRipDecoder> decoder (new SubRipDecoder (content));
list<ContentTextSubtitle> subs = decoder->get_text_subtitles (ContentTimePeriod (ContentTime(), ContentTime::max ()), true);
- FrameRateChange const frc = film->active_frame_rate_change (content->position ());
+ FrameRateChange const frc = film->active_frame_rate_change (position);
int n = 0;
for (list<ContentTextSubtitle>::const_iterator i = subs.begin(); i != subs.end(); ++i) {
for (list<dcp::SubtitleString>::const_iterator j = i->subs.begin(); j != i->subs.end(); ++j) {
#include <wx/wx.h>
#include <wx/listctrl.h>
-class SubRipContent;
+class SubtitleDecoder;
class SubtitleView : public wxDialog
{
public:
- SubtitleView (wxWindow *, boost::shared_ptr<Film>, boost::shared_ptr<SubRipContent>);
+ SubtitleView (wxWindow *, boost::shared_ptr<Film>, boost::shared_ptr<SubtitleDecoder>, DCPTime position);
private:
wxListCtrl* _list;