/*
- Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2016 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
boost::signals2::signal<void (boost::weak_ptr<Content>, int, bool)> Changed;
boost::shared_ptr<VideoContent> video;
+ boost::shared_ptr<SubtitleContent> subtitle;
void signal_changed (int);
*/
+#ifndef DCPOMATIC_CONTENT_PART_H
+#define DCPOMATIC_CONTENT_PART_H
+
#include <boost/weak_ptr.hpp>
class Content;
boost::weak_ptr<const Film> _film;
mutable boost::mutex _mutex;
};
+
+#endif
#include "overlaps.h"
#include "compose.hpp"
#include "dcp_decoder.h"
+#include "subtitle_content.h"
#include <dcp/dcp.h>
#include <dcp/exceptions.h>
#include <dcp/reel_picture_asset.h>
DCPContent::DCPContent (shared_ptr<const Film> film, boost::filesystem::path p)
: Content (film)
, SingleStreamAudioContent (film)
- , SubtitleContent (film)
, _has_subtitles (false)
, _encrypted (false)
, _kdm_valid (false)
, _reference_subtitle (false)
{
video.reset (new VideoContent (this, film));
+ subtitle.reset (new SubtitleContent (this, film));
read_directory (p);
set_default_colour_conversion ();
DCPContent::DCPContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
: Content (film, node)
, SingleStreamAudioContent (film, node, version)
- , SubtitleContent (film, node, version)
{
video.reset (new VideoContent (this, film, node, version));
+ subtitle.reset (new SubtitleContent (this, film, node, version));
_name = node->string_child ("Name");
_has_subtitles = node->bool_child ("HasSubtitles");
Content::as_xml (node);
video->as_xml (node);
SingleStreamAudioContent::as_xml (node);
- SubtitleContent::as_xml (node);
+ subtitle->as_xml (node);
boost::mutex::scoped_lock lm (_mutex);
node->add_child("Name")->add_child_text (_name);
DCPContent::identifier () const
{
SafeStringStream s;
- s << Content::identifier() << "_" << video->identifier() << "_" << SubtitleContent::identifier () << " "
+ s << Content::identifier() << "_" << video->identifier() << "_" << subtitle->identifier () << " "
<< (_reference_video ? "1" : "0")
<< (_reference_subtitle ? "1" : "0");
return s.str ();
bool
DCPContent::can_reference_subtitle (list<string>& why_not) const
{
- DCPDecoder decoder (shared_from_this(), film()->log(), false);
- BOOST_FOREACH (shared_ptr<dcp::Reel> i, decoder.reels()) {
- if (!i->main_subtitle()) {
- why_not.push_back (_("The DCP does not have subtitles in all reels."));
- return false;
- }
- }
-
- return can_reference<SubtitleContent> (_("There is other subtitle content overlapping this DCP; remove it."), why_not);
+ /* XXX: this needs to be fixed */
+ return true;
}
double
*/
#include "single_stream_audio_content.h"
-#include "subtitle_content.h"
#include <libcxml/cxml.h>
#include <dcp/encrypted_kdm.h>
/** @class DCPContent
* @brief An existing DCP used as input.
*/
-class DCPContent : public SingleStreamAudioContent, public SubtitleContent
+class DCPContent : public SingleStreamAudioContent
{
public:
DCPContent (boost::shared_ptr<const Film>, boost::filesystem::path p);
DCPDecoder::DCPDecoder (shared_ptr<const DCPContent> c, shared_ptr<Log> log, bool fast)
: VideoDecoder (c->video, log)
, AudioDecoder (c, fast)
- , SubtitleDecoder (c)
+ , SubtitleDecoder (c->subtitle)
, _dcp_content (c)
{
dcp::DCP dcp (c->directory ());
#include "dcp_subtitle_content.h"
#include "raw_convert.h"
#include "film.h"
+#include "subtitle_content.h"
#include <dcp/interop_subtitle_asset.h>
#include <dcp/smpte_subtitle_asset.h>
#include <dcp/interop_load_font_node.h>
DCPSubtitleContent::DCPSubtitleContent (shared_ptr<const Film> film, boost::filesystem::path path)
: Content (film, path)
- , SubtitleContent (film, path)
{
-
+ subtitle.reset (new SubtitleContent (this, film));
}
DCPSubtitleContent::DCPSubtitleContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
: Content (film, node)
- , SubtitleContent (film, node, version)
, _length (node->number_child<ContentTime::Type> ("Length"))
, _frame_rate (node->optional_number_child<int>("SubtitleFrameRate"))
{
-
+ subtitle.reset (new SubtitleContent (this, film, node, version));
}
void
shared_ptr<dcp::SubtitleAsset> sc = load (path (0));
/* Default to turning these subtitles on */
- set_use_subtitles (true);
+ subtitle->set_use_subtitles (true);
boost::mutex::scoped_lock lm (_mutex);
shared_ptr<dcp::InteropSubtitleAsset> iop = dynamic_pointer_cast<dcp::InteropSubtitleAsset> (sc);
if (iop) {
- _subtitle_language = iop->language ();
+ subtitle->set_subtitle_language (iop->language ());
}
shared_ptr<dcp::SMPTESubtitleAsset> smpte = dynamic_pointer_cast<dcp::SMPTESubtitleAsset> (sc);
if (smpte) {
- _subtitle_language = smpte->language().get_value_or ("");
+ subtitle->set_subtitle_language (smpte->language().get_value_or (""));
_frame_rate = smpte->edit_rate().numerator;
}
_length = ContentTime::from_seconds (sc->latest_subtitle_out().as_seconds ());
BOOST_FOREACH (shared_ptr<dcp::LoadFontNode> i, sc->load_font_nodes ()) {
- add_font (shared_ptr<Font> (new Font (i->id)));
+ subtitle->add_font (shared_ptr<Font> (new Font (i->id)));
}
}
{
node->add_child("Type")->add_child_text ("DCPSubtitle");
Content::as_xml (node);
- SubtitleContent::as_xml (node);
+ subtitle->as_xml (node);
node->add_child("Length")->add_child_text (raw_convert<string> (_length.get ()));
}
/*
- Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2016 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
*/
-#include "subtitle_content.h"
#include "dcp_subtitle.h"
+#include "content.h"
-class DCPSubtitleContent : public SubtitleContent, public DCPSubtitle
+class DCPSubtitleContent : public DCPSubtitle, public Content
{
public:
DCPSubtitleContent (boost::shared_ptr<const Film>, boost::filesystem::path);
using boost::shared_ptr;
DCPSubtitleDecoder::DCPSubtitleDecoder (shared_ptr<const DCPSubtitleContent> content)
- : SubtitleDecoder (content)
+ : SubtitleDecoder (content->subtitle)
{
shared_ptr<dcp::SubtitleAsset> c (load (content->path (0)));
_subtitles = c->subtitles ();
#include "frame_rate_change.h"
#include "safe_stringstream.h"
#include "raw_convert.h"
+#include "subtitle_content.h"
#include <libcxml/cxml.h>
extern "C" {
#include <libavformat/avformat.h>
FFmpegContent::FFmpegContent (shared_ptr<const Film> film, boost::filesystem::path p)
: Content (film, p)
, AudioContent (film, p)
- , SubtitleContent (film, p)
{
video.reset (new VideoContent (this, film));
+ subtitle.reset (new SubtitleContent (this, film));
set_default_colour_conversion ();
}
FFmpegContent::FFmpegContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version, list<string>& notes)
: Content (film, node)
, AudioContent (film, node)
- , SubtitleContent (film, node, version)
{
video.reset (new VideoContent (this, film, node, version));
+ subtitle.reset (new SubtitleContent (this, film, node, version));
list<cxml::NodePtr> c = node->node_children ("SubtitleStream");
for (list<cxml::NodePtr>::const_iterator i = c.begin(); i != c.end(); ++i) {
FFmpegContent::FFmpegContent (shared_ptr<const Film> film, vector<boost::shared_ptr<Content> > c)
: Content (film, c)
, AudioContent (film, c)
- , SubtitleContent (film, c)
{
video.reset (new VideoContent (this, film, c));
+ subtitle.reset (new SubtitleContent (this, film, c));
shared_ptr<FFmpegContent> ref = dynamic_pointer_cast<FFmpegContent> (c[0]);
DCPOMATIC_ASSERT (ref);
for (size_t i = 0; i < c.size(); ++i) {
shared_ptr<FFmpegContent> fc = dynamic_pointer_cast<FFmpegContent> (c[i]);
- if (fc->use_subtitles() && *(fc->_subtitle_stream.get()) != *(ref->_subtitle_stream.get())) {
+ if (fc->subtitle->use_subtitles() && *(fc->_subtitle_stream.get()) != *(ref->_subtitle_stream.get())) {
throw JoinError (_("Content to be joined must use the same subtitle stream."));
}
}
Content::as_xml (node);
video->as_xml (node);
AudioContent::as_xml (node);
- SubtitleContent::as_xml (node);
+ subtitle->as_xml (node);
boost::mutex::scoped_lock lm (_mutex);
s << Content::identifier() << "_"
<< video->identifier() << "_"
- << SubtitleContent::identifier();
+ << subtitle->identifier();
boost::mutex::scoped_lock lm (_mutex);
#define DCPOMATIC_FFMPEG_CONTENT_H
#include "audio_content.h"
-#include "subtitle_content.h"
struct AVFormatContext;
struct AVStream;
static int const FILTERS;
};
-class FFmpegContent : public AudioContent, public SubtitleContent
+class FFmpegContent : public AudioContent
{
public:
FFmpegContent (boost::shared_ptr<const Film>, boost::filesystem::path);
FFmpegDecoder::FFmpegDecoder (shared_ptr<const FFmpegContent> c, shared_ptr<Log> log, bool fast)
: VideoDecoder (c->video, log)
, AudioDecoder (c, fast)
- , SubtitleDecoder (c)
+ , SubtitleDecoder (c->subtitle)
, FFmpeg (c)
, _log (log)
, _pts_offset (pts_offset (c->ffmpeg_audio_streams(), c->first_video(), c->video->video_frame_rate()))
{
-
}
void
PlayerSubtitles ps (time, length);
for (list<shared_ptr<Piece> >::const_iterator j = subs.begin(); j != subs.end(); ++j) {
- shared_ptr<SubtitleContent> subtitle_content = dynamic_pointer_cast<SubtitleContent> ((*j)->content);
- if (!subtitle_content->use_subtitles () || (!_always_burn_subtitles && (burnt != subtitle_content->burn_subtitles ()))) {
+ if (!(*j)->content->subtitle->use_subtitles () || (!_always_burn_subtitles && (burnt != (*j)->content->subtitle->burn_subtitles ()))) {
continue;
}
- shared_ptr<DCPContent> dcp_content = dynamic_pointer_cast<DCPContent> (subtitle_content);
+ shared_ptr<DCPContent> dcp_content = dynamic_pointer_cast<DCPContent> ((*j)->content);
if (dcp_content && dcp_content->reference_subtitle () && !_play_referenced) {
continue;
}
for (list<ContentImageSubtitle>::iterator i = image.begin(); i != image.end(); ++i) {
/* Apply content's subtitle offsets */
- i->sub.rectangle.x += subtitle_content->subtitle_x_offset ();
- i->sub.rectangle.y += subtitle_content->subtitle_y_offset ();
+ i->sub.rectangle.x += (*j)->content->subtitle->subtitle_x_offset ();
+ i->sub.rectangle.y += (*j)->content->subtitle->subtitle_y_offset ();
/* Apply content's subtitle scale */
- i->sub.rectangle.width *= subtitle_content->subtitle_x_scale ();
- i->sub.rectangle.height *= subtitle_content->subtitle_y_scale ();
+ i->sub.rectangle.width *= (*j)->content->subtitle->subtitle_x_scale ();
+ i->sub.rectangle.height *= (*j)->content->subtitle->subtitle_y_scale ();
/* Apply a corrective translation to keep the subtitle centred after that scale */
- i->sub.rectangle.x -= i->sub.rectangle.width * (subtitle_content->subtitle_x_scale() - 1);
- i->sub.rectangle.y -= i->sub.rectangle.height * (subtitle_content->subtitle_y_scale() - 1);
+ i->sub.rectangle.x -= i->sub.rectangle.width * ((*j)->content->subtitle->subtitle_x_scale() - 1);
+ i->sub.rectangle.y -= i->sub.rectangle.height * ((*j)->content->subtitle->subtitle_y_scale() - 1);
ps.image.push_back (i->sub);
}
list<ContentTextSubtitle> text = subtitle_decoder->get_text_subtitles (ContentTimePeriod (from, to), starting, accurate);
BOOST_FOREACH (ContentTextSubtitle& ts, text) {
BOOST_FOREACH (dcp::SubtitleString s, ts.subs) {
- s.set_h_position (s.h_position() + subtitle_content->subtitle_x_offset ());
- s.set_v_position (s.v_position() + subtitle_content->subtitle_y_offset ());
- float const xs = subtitle_content->subtitle_x_scale();
- float const ys = subtitle_content->subtitle_y_scale();
+ s.set_h_position (s.h_position() + (*j)->content->subtitle->subtitle_x_offset ());
+ s.set_v_position (s.v_position() + (*j)->content->subtitle->subtitle_y_offset ());
+ float const xs = (*j)->content->subtitle->subtitle_x_scale();
+ float const ys = (*j)->content->subtitle->subtitle_y_scale();
float size = s.size();
/* Adjust size to express the common part of the scaling;
s.set_in (dcp::Time(content_subtitle_to_dcp (*j, ts.period().from).seconds(), 1000));
s.set_out (dcp::Time(content_subtitle_to_dcp (*j, ts.period().to).seconds(), 1000));
ps.text.push_back (s);
- ps.add_fonts (subtitle_content->fonts ());
+ ps.add_fonts ((*j)->content->subtitle->fonts ());
}
}
}
#include "sndfile_content.h"
#include "sndfile_decoder.h"
#include "video_content.h"
+#include "subtitle_content.h"
#include "ffmpeg_decoder.h"
#include "ffmpeg_content.h"
#include "image_decoder.h"
DCPTime next;
BOOST_FOREACH (shared_ptr<Content> i, _content) {
- shared_ptr<SubtitleContent> sc = dynamic_pointer_cast<SubtitleContent> (i);
- if (!sc || !sc->has_subtitles() || find (placed.begin(), placed.end(), i) != placed.end()) {
+ if (!i->subtitle || !i->subtitle->has_subtitles() || find (placed.begin(), placed.end(), i) != placed.end()) {
continue;
}
- sc->set_position (next);
- next = sc->end();
+ i->set_position (next);
+ next = i->end();
}
/*
- Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2016 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
int const SubtitleContentProperty::FONTS = 507;
int const SubtitleContentProperty::SUBTITLE_VIDEO_FRAME_RATE = 508;
-SubtitleContent::SubtitleContent (shared_ptr<const Film> film)
- : Content (film)
+SubtitleContent::SubtitleContent (Content* parent, shared_ptr<const Film> film)
+ : ContentPart (parent, film)
, _use_subtitles (false)
, _burn_subtitles (false)
, _subtitle_x_offset (0)
}
-SubtitleContent::SubtitleContent (shared_ptr<const Film> film, boost::filesystem::path p)
- : Content (film, p)
- , _use_subtitles (false)
- , _burn_subtitles (false)
- , _subtitle_x_offset (0)
- , _subtitle_y_offset (0)
- , _subtitle_x_scale (1)
- , _subtitle_y_scale (1)
-{
-
-}
-
-SubtitleContent::SubtitleContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
- : Content (film, node)
+SubtitleContent::SubtitleContent (Content* parent, shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
+ : ContentParet (parent, film)
, _use_subtitles (false)
, _burn_subtitles (false)
, _subtitle_x_offset (0)
connect_to_fonts ();
}
-SubtitleContent::SubtitleContent (shared_ptr<const Film> film, vector<shared_ptr<Content> > c)
- : Content (film, c)
+SubtitleContent::SubtitleContent (Content* parent, shared_ptr<const Film> film, vector<shared_ptr<Content> > c)
+ : ContentPart (parent, film)
{
shared_ptr<SubtitleContent> ref = dynamic_pointer_cast<SubtitleContent> (c[0]);
DCPOMATIC_ASSERT (ref);
/*
- Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2016 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
#ifndef DCPOMATIC_SUBTITLE_CONTENT_H
#define DCPOMATIC_SUBTITLE_CONTENT_H
-#include "content.h"
+#include "content_part.h"
+#include <libcxml/cxml.h>
+#include <boost/signals2.hpp>
class Font;
static int const SUBTITLE_VIDEO_FRAME_RATE;
};
-/** @class SubtitleContent
- * @brief Parent for content which has the potential to include subtitles.
- *
- * Although inheriting from this class indicates that the content could
- * have subtitles, it may not. ::has_subtitles() will tell you.
- */
-class SubtitleContent : public virtual Content
+class SubtitleContent : public ContentPart
{
public:
- SubtitleContent (boost::shared_ptr<const Film>);
- SubtitleContent (boost::shared_ptr<const Film>, boost::filesystem::path);
- SubtitleContent (boost::shared_ptr<const Film>, cxml::ConstNodePtr, int version);
- SubtitleContent (boost::shared_ptr<const Film>, std::vector<boost::shared_ptr<Content> >);
+ SubtitleContent (Content* parent, boost::shared_ptr<const Film>);
+ SubtitleContent (Content* parent, boost::shared_ptr<const Film>, cxml::ConstNodePtr, int version);
+ SubtitleContent (Content* parent, boost::shared_ptr<const Film>, std::vector<boost::shared_ptr<Content> >);
void as_xml (xmlpp::Node *) const;
std::string identifier () const;
bool has_subtitles () const;
- virtual bool has_text_subtitles () const = 0;
- virtual bool has_image_subtitles () const = 0;
- virtual double subtitle_video_frame_rate () const = 0;
void add_font (boost::shared_ptr<Font> font);
#include "film.h"
#include "font.h"
#include "raw_convert.h"
+#include "subtitle_content.h"
#include <libxml++/libxml++.h>
#include <iostream>
TextSubtitleContent::TextSubtitleContent (shared_ptr<const Film> film, boost::filesystem::path path)
: Content (film, path)
- , SubtitleContent (film, path)
, _colour (255, 255, 255)
, _outline (false)
, _outline_colour (0, 0, 0)
{
-
+ subtitle.reset (new SubtitleContent (this, film, path));
}
TextSubtitleContent::TextSubtitleContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
: Content (film, node)
- , SubtitleContent (film, node, version)
, _length (node->number_child<ContentTime::Type> ("Length"))
, _frame_rate (node->optional_number_child<double>("SubtitleVideoFrameRate"))
, _colour (
node->optional_number_child<int>("OutlineBlue").get_value_or(255)
)
{
-
+ subtitle.reset (new SubtitleContent (this, film, node, version));
}
void
{
node->add_child("Type")->add_child_text ("TextSubtitle");
Content::as_xml (node);
- SubtitleContent::as_xml (node);
+ subtitle->as_xml (node);
node->add_child("Length")->add_child_text (raw_convert<string> (_length.get ()));
if (_frame_rate) {
node->add_child("SubtitleVideoFrameRate")->add_child_text (raw_convert<string> (_frame_rate.get()));
/*
- Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2016 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
*/
-#include "subtitle_content.h"
+#include "content.h"
+
+class Job;
class TextSubtitleContentProperty
{
/** @class TextSubtitleContent
* @brief SubRip or SSA subtitles.
*/
-class TextSubtitleContent : public SubtitleContent
+class TextSubtitleContent : public Content
{
public:
TextSubtitleContent (boost::shared_ptr<const Film>, boost::filesystem::path);
using boost::dynamic_pointer_cast;
TextSubtitleDecoder::TextSubtitleDecoder (shared_ptr<const TextSubtitleContent> content)
- : SubtitleDecoder (content)
+ : SubtitleDecoder (content->subtitle)
, TextSubtitle (content)
, _next (0)
{