X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fffmpeg_content.cc;h=44e1b2afb22363499a8b5d9c0b772ade907c1931;hb=de2af791bdfdcd653752cba970e59efc7bf810c7;hp=f3a4c4c4fc7893441267ea6d916f2fcadec98059;hpb=5a5324ed3a381a86dfe0a6e3932c1d58fdcd596f;p=dcpomatic.git diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index f3a4c4c4f..44e1b2afb 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -32,9 +32,8 @@ #include "log.h" #include "exceptions.h" #include "frame_rate_change.h" -#include "safe_stringstream.h" -#include "raw_convert.h" #include "subtitle_content.h" +#include #include extern "C" { #include @@ -42,7 +41,6 @@ extern "C" { } #include #include -#include #include #include "i18n.h" @@ -57,9 +55,9 @@ using std::pair; using std::make_pair; using std::max; using boost::shared_ptr; -using boost::make_shared; using boost::dynamic_pointer_cast; using boost::optional; +using dcp::raw_convert; int const FFmpegContentProperty::SUBTITLE_STREAMS = 100; int const FFmpegContentProperty::SUBTITLE_STREAM = 101; @@ -80,7 +78,7 @@ FFmpegContent::FFmpegContent (shared_ptr film, cxml::ConstNodePtr no list c = node->node_children ("SubtitleStream"); for (list::const_iterator i = c.begin(); i != c.end(); ++i) { - _subtitle_streams.push_back (make_shared (*i, version)); + _subtitle_streams.push_back (shared_ptr (new FFmpegSubtitleStream (*i, version))); if ((*i)->optional_number_child ("Selected")) { _subtitle_stream = _subtitle_streams.back (); } @@ -88,7 +86,7 @@ FFmpegContent::FFmpegContent (shared_ptr film, cxml::ConstNodePtr no c = node->node_children ("AudioStream"); for (list::const_iterator i = c.begin(); i != c.end(); ++i) { - shared_ptr as = make_shared (*i, version); + shared_ptr as (new FFmpegAudioStream (*i, version)); audio->add_stream (as); if (version < 11 && !(*i)->optional_node_child ("Selected")) { /* This is an old file and this stream is not selected, so un-map it */ @@ -121,22 +119,50 @@ FFmpegContent::FFmpegContent (shared_ptr film, cxml::ConstNodePtr no } -FFmpegContent::FFmpegContent (shared_ptr film, vector > c) +FFmpegContent::FFmpegContent (shared_ptr film, vector > c) : Content (film, c) { - /* XXX: this should look at c to decide which of video/audio/subtitle - get created. - */ - video.reset (new VideoContent (this, c)); - audio.reset (new AudioContent (this, c)); - subtitle.reset (new SubtitleContent (this, c)); + vector >::const_iterator i = c.begin (); + + bool need_video = false; + bool need_audio = false; + bool need_subtitle = false; + + if (i != c.end ()) { + need_video = static_cast ((*i)->video); + need_audio = static_cast ((*i)->audio); + need_subtitle = static_cast ((*i)->subtitle); + } + + while (i != c.end ()) { + if (need_video != static_cast ((*i)->video)) { + throw JoinError (_("Content to be joined must all have or not have video")); + } + if (need_audio != static_cast ((*i)->audio)) { + throw JoinError (_("Content to be joined must all have or not have audio")); + } + if (need_subtitle != static_cast ((*i)->subtitle)) { + throw JoinError (_("Content to be joined must all have or not have subtitles")); + } + ++i; + } + + if (need_video) { + video.reset (new VideoContent (this, c)); + } + if (need_audio) { + audio.reset (new AudioContent (this, c)); + } + if (need_subtitle) { + subtitle.reset (new SubtitleContent (this, c)); + } shared_ptr ref = dynamic_pointer_cast (c[0]); DCPOMATIC_ASSERT (ref); for (size_t i = 0; i < c.size(); ++i) { shared_ptr fc = dynamic_pointer_cast (c[i]); - if (fc->subtitle->use() && *(fc->_subtitle_stream.get()) != *(ref->_subtitle_stream.get())) { + if (fc->subtitle && fc->subtitle->use() && *(fc->_subtitle_stream.get()) != *(ref->_subtitle_stream.get())) { throw JoinError (_("Content to be joined must use the same subtitle stream.")); } } @@ -155,10 +181,10 @@ FFmpegContent::FFmpegContent (shared_ptr film, vectoradd_child("Type")->add_child_text ("FFmpeg"); - Content::as_xml (node); + Content::as_xml (node, with_paths); if (video) { video->as_xml (node); @@ -196,10 +222,10 @@ FFmpegContent::as_xml (xmlpp::Node* node) const node->add_child("FirstVideo")->add_child_text (raw_convert (_first_video.get().get())); } - node->add_child("ColorRange")->add_child_text (raw_convert (_color_range)); - node->add_child("ColorPrimaries")->add_child_text (raw_convert (_color_primaries)); - node->add_child("ColorTransferCharacteristic")->add_child_text (raw_convert (_color_trc)); - node->add_child("Colorspace")->add_child_text (raw_convert (_colorspace)); + node->add_child("ColorRange")->add_child_text (raw_convert (static_cast (_color_range))); + node->add_child("ColorPrimaries")->add_child_text (raw_convert (static_cast (_color_primaries))); + node->add_child("ColorTransferCharacteristic")->add_child_text (raw_convert (static_cast (_color_trc))); + node->add_child("Colorspace")->add_child_text (raw_convert (static_cast (_colorspace))); if (_bits_per_pixel) { node->add_child("BitsPerPixel")->add_child_text (raw_convert (_bits_per_pixel.get ())); } @@ -212,7 +238,7 @@ FFmpegContent::examine (shared_ptr job) Content::examine (job); - shared_ptr examiner = make_shared (shared_from_this (), job); + shared_ptr examiner (new FFmpegExaminer (shared_from_this (), job)); if (examiner->has_video ()) { video.reset (new VideoContent (this)); @@ -362,51 +388,27 @@ FFmpegContent::set_filters (vector const & filters) string FFmpegContent::identifier () const { - SafeStringStream s; - - s << Content::identifier(); + string s = Content::identifier(); if (video) { - s << "_" << video->identifier(); + s += "_" + video->identifier(); } if (subtitle) { - s << "_" << subtitle->identifier(); + s += "_" + subtitle->identifier(); } boost::mutex::scoped_lock lm (_mutex); if (_subtitle_stream) { - s << "_" << _subtitle_stream->identifier (); + s += "_" + _subtitle_stream->identifier (); } for (vector::const_iterator i = _filters.begin(); i != _filters.end(); ++i) { - s << "_" << (*i)->id (); - } - - return s.str (); -} - -list -FFmpegContent::image_subtitles_during (ContentTimePeriod period, bool starting) const -{ - shared_ptr stream = subtitle_stream (); - if (!stream) { - return list (); - } - - return stream->image_subtitles_during (period, starting); -} - -list -FFmpegContent::text_subtitles_during (ContentTimePeriod period, bool starting) const -{ - shared_ptr stream = subtitle_stream (); - if (!stream) { - return list (); + s += "_" + (*i)->id (); } - return stream->text_subtitles_during (period, starting); + return s; } void @@ -493,10 +495,12 @@ FFmpegContent::add_properties (list& p) const _("SMPTE 240M"), _("Film"), _("BT2020"), - _("SMPTE ST 428-1 (CIE 1931 XYZ)") + _("SMPTE ST 428-1 (CIE 1931 XYZ)"), + _("SMPTE ST 431-2 (2011)"), + _("SMPTE ST 432-1 D65 (2010)") }; - DCPOMATIC_ASSERT (AVCOL_PRI_NB <= 11); + DCPOMATIC_ASSERT (AVCOL_PRI_NB <= 13); p.push_back (UserProperty (UserProperty::VIDEO, _("Colour primaries"), primaries[_color_primaries])); char const * transfers[] = { @@ -517,10 +521,11 @@ FFmpegContent::add_properties (list& p) const _("BT2020 for a 10-bit system"), _("BT2020 for a 12-bit system"), _("SMPTE ST 2084 for 10, 12, 14 and 16 bit systems"), - _("SMPTE ST 428-1") + _("SMPTE ST 428-1"), + _("ARIB STD-B67 ('Hybrid log-gamma')") }; - DCPOMATIC_ASSERT (AVCOL_TRC_NB <= 18); + DCPOMATIC_ASSERT (AVCOL_TRC_NB <= 19); p.push_back (UserProperty (UserProperty::VIDEO, _("Colour transfer characteristic"), transfers[_color_trc])); char const * spaces[] = { @@ -535,13 +540,14 @@ FFmpegContent::add_properties (list& p) const _("YCOCG"), _("BT2020 non-constant luminance"), _("BT2020 constant luminance"), + _("SMPTE 2085, Y'D'zD'x"), }; - DCPOMATIC_ASSERT (AVCOL_SPC_NB == 11); + DCPOMATIC_ASSERT (AVCOL_SPC_NB == 12); p.push_back (UserProperty (UserProperty::VIDEO, _("Colourspace"), spaces[_colorspace])); if (_bits_per_pixel) { - p.push_back (UserProperty (UserProperty::VIDEO, _("Bits per pixel"), raw_convert (_bits_per_pixel.get ()))); + p.push_back (UserProperty (UserProperty::VIDEO, _("Bits per pixel"), _bits_per_pixel.get ())); } } @@ -574,3 +580,12 @@ FFmpegContent::ffmpeg_audio_streams () const return fa; } + +void +FFmpegContent::use_template (shared_ptr c) +{ + Content::use_template (c); + + shared_ptr fc = dynamic_pointer_cast (c); + _filters = fc->_filters; +}