+c8926dcc6cb327ddf4796bf2bfe17d65c75940e5
+0ee1e8c65e2977638375a8f96dbea201210aac98
+f2851b7066d0e12102b0f3aabc2b827a261206a9
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
+#include <boost/foreach.hpp>
#include <unistd.h>
#include <stdexcept>
#include <iostream>
using std::endl;
using std::cout;
using std::list;
+using std::set;
using boost::shared_ptr;
using boost::weak_ptr;
using boost::dynamic_pointer_cast;
available = double (s.available) / 1073741824.0f;
return (available - required) > 1;
}
+
+string
+Film::subtitle_language () const
+{
+ set<string> languages;
+
+ ContentList cl = content ();
+ BOOST_FOREACH (shared_ptr<Content>& c, cl) {
+ shared_ptr<SubtitleContent> sc = dynamic_pointer_cast<SubtitleContent> (c);
+ if (sc) {
+ languages.insert (sc->subtitle_language ());
+ }
+ }
+
+ string all;
+ BOOST_FOREACH (string s, languages) {
+ if (!all.empty ()) {
+ all += "/" + s;
+ } else {
+ all += s;
+ }
+ }
+
+ return all;
+}
return _state_version;
}
+ std::string subtitle_language () const;
+
/** Identifiers for the parts of our state;
used for signalling changes.
*/
Font::Font (cxml::NodePtr node)
{
- id = node->optional_string_child ("Id");
+ id = node->string_child ("Id");
file = node->optional_string_child ("File");
}
void
Font::as_xml (xmlpp::Node* node)
{
- if (id) {
- node->add_child("Id")->add_child_text (id.get ());
- }
-
+ node->add_child("Id")->add_child_text (id);
if (file) {
node->add_child("File")->add_child_text (file.get().string ());
}
class Font
{
public:
- Font () {}
-
Font (std::string id_)
: id (id_) {}
void as_xml (xmlpp::Node* node);
- /** Font ID, or empty for the default font */
- boost::optional<std::string> id;
+ /** Font ID */
+ std::string id;
boost::optional<boost::filesystem::path> file;
};
continue;
}
- /* XXX: this will break down if we have multiple subtitle content */
- ps.language = subtitle_content->subtitle_language();
- if (ps.language.empty ()) {
- ps.language = _("Unknown");
- }
-
shared_ptr<SubtitleDecoder> subtitle_decoder = dynamic_pointer_cast<SubtitleDecoder> ((*j)->decoder);
ContentTime const from = dcp_to_content_subtitle (*j, time);
/* XXX: this video_frame_rate() should be the rate that the subtitle content has been prepared for */
return ps;
}
+
+list<shared_ptr<Font> >
+Player::get_subtitle_fonts ()
+{
+ if (!_have_valid_pieces) {
+ setup_pieces ();
+ }
+
+ list<shared_ptr<Font> > fonts;
+ BOOST_FOREACH (shared_ptr<Piece>& p, _pieces) {
+ shared_ptr<SubtitleContent> sc = dynamic_pointer_cast<SubtitleContent> (p->content);
+ if (sc) {
+ /* XXX: things may go wrong if there are duplicate font IDs
+ with different font files.
+ */
+ list<shared_ptr<Font> > f = sc->fonts ();
+ copy (f.begin(), f.end(), back_inserter (fonts));
+ }
+ }
+
+ return fonts;
+}
std::list<boost::shared_ptr<PlayerVideo> > get_video (DCPTime time, bool accurate);
boost::shared_ptr<AudioBuffers> get_audio (DCPTime time, DCPTime length, bool accurate);
PlayerSubtitles get_subtitles (DCPTime time, DCPTime length, bool starting);
+ std::list<boost::shared_ptr<Font> > get_subtitle_fonts ();
void set_video_container_size (dcp::Size);
void set_approximate_size ();
/** ImageSubtitles, with their rectangles transformed as specified by their content */
std::list<ImageSubtitle> image;
std::list<dcp::SubtitleString> text;
-
- std::string language;
};
#endif
using boost::shared_ptr;
using boost::lexical_cast;
+std::string const SubRipContent::font_id = "font";
+
SubRipContent::SubRipContent (shared_ptr<const Film> film, boost::filesystem::path path)
: Content (film, path)
, SubtitleContent (film, path)
boost::mutex::scoped_lock lm (_mutex);
_length = len;
- _fonts.push_back (shared_ptr<Font> (new Font ()));
+ _fonts.push_back (shared_ptr<Font> (new Font (font_id)));
}
string
return true;
}
+ static std::string const font_id;
+
private:
DCPTime _length;
};
for (list<sub::Block>::const_iterator j = i->blocks.begin(); j != i->blocks.end(); ++j) {
out.push_back (
dcp::SubtitleString (
- optional<string> (),
+ SubRipContent::font_id,
j->italic,
dcp::Color (255, 255, 255),
/* .srt files don't specify size, so this is an arbitrary value */
DCPTime const frame = DCPTime::from_frames (1, _film->video_frame_rate ());
DCPTime const length = _film->length ();
+
+ if (!_film->burn_subtitles ()) {
+ _writer->write (_player->get_subtitle_fonts ());
+ }
+
for (DCPTime t; t < length; t += frame) {
list<shared_ptr<PlayerVideo> > v = _player->get_video (t, true);
for (list<shared_ptr<PlayerVideo> >::const_iterator i = v.begin(); i != v.end(); ++i) {
#include "md5_digester.h"
#include "encoded_data.h"
#include "version.h"
+#include "font.h"
#include <dcp/mono_picture_mxf.h>
#include <dcp/stereo_picture_mxf.h>
#include <dcp/sound_mxf.h>
}
if (!_subtitle_content) {
- _subtitle_content.reset (new dcp::InteropSubtitleContent (_film->name(), subs.language));
+ _subtitle_content.reset (new dcp::InteropSubtitleContent (_film->name(), _film->subtitle_language ()));
}
for (list<dcp::SubtitleString>::const_iterator i = subs.text.begin(); i != subs.text.end(); ++i) {
}
}
+void
+Writer::write (list<shared_ptr<Font> > fonts)
+{
+ if (!_subtitle_content) {
+ _subtitle_content.reset (new dcp::InteropSubtitleContent (_film->name(), _film->subtitle_language ()));
+ }
+
+ for (list<shared_ptr<Font> >::const_iterator i = fonts.begin(); i != fonts.end(); ++i) {
+ /* XXX: this LiberationSans-Regular needs to be a path to a DCP-o-matic-distributed copy */
+ _subtitle_content->add_font ((*i)->id, (*i)->file.get_value_or ("LiberationSans-Regular.ttf").leaf().string ());
+ }
+}
+
bool
operator< (QueueItem const & a, QueueItem const & b)
{
#include "exceptions.h"
#include "types.h"
#include "player_subtitles.h"
-#include <dcp/subtitle_content.h>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/thread.hpp>
class EncodedData;
class AudioBuffers;
class Job;
+class Font;
namespace dcp {
class MonoPictureMXF;
class PictureMXFWriter;
class SoundMXF;
class SoundMXFWriter;
+ class InteropSubtitleContent;
}
struct QueueItem
void fake_write (int, Eyes);
void write (boost::shared_ptr<const AudioBuffers>);
void write (PlayerSubtitles subs);
+ void write (std::list<boost::shared_ptr<Font> > fonts);
void repeat (int f, Eyes);
void finish ();
boost::shared_ptr<dcp::PictureMXFWriter> _picture_mxf_writer;
boost::shared_ptr<dcp::SoundMXF> _sound_mxf;
boost::shared_ptr<dcp::SoundMXFWriter> _sound_mxf_writer;
- boost::shared_ptr<dcp::SubtitleContent> _subtitle_content;
+ boost::shared_ptr<dcp::InteropSubtitleContent> _subtitle_content;
};
wxListItem item;
item.SetId (n);
_fonts->InsertItem (item);
- _fonts->SetItem (n, 0, (*i)->id.get_value_or (wx_to_std (_("[Default]"))));
+ _fonts->SetItem (n, 0, std_to_wx ((*i)->id));
if ((*i)->file) {
_fonts->SetItem (n, 1, (*i)->file.get().leaf().string ());
}
using std::cout;
using boost::shared_ptr;
-/** Test load of very simple DCP subtitle file */
+/** Test pass-through of a very simple DCP subtitle file */
BOOST_AUTO_TEST_CASE (dcp_subtitle_test)
{
shared_ptr<Film> film = new_test_film ("dcp_subtitle_test");
film->set_container (Ratio::from_id ("185"));
film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
film->set_name ("frobozz");
+ film->set_burn_subtitles (false);
shared_ptr<DCPSubtitleContent> content (new DCPSubtitleContent (film, "test/data/dcp_sub.xml"));
film->examine_and_add_content (content, true);
wait_for_jobs ();
BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (2));
+
+ content->set_use_subtitles (true);
+ film->make_dcp ();
+ wait_for_jobs ();
+
+ check_dcp ("test/data/dcp_subtitle_test", film->dir (film->dcp_name ()));
}