X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fffmpeg_content.cc;h=dfeb2a0ad249ed91d67ecdcbda4e58eabe5331c6;hb=150f708d27b25d5b5d4e486d03c5bc4078027997;hp=54e0b470aa15ded1acc1dc93e762eef27b008b4a;hpb=36774ee2b48f0bfde43b743592e5816ff58bb7d2;p=dcpomatic.git diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 54e0b470a..dfeb2a0ad 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -19,6 +19,7 @@ #include "ffmpeg_content.h" #include "video_content.h" +#include "audio_content.h" #include "ffmpeg_examiner.h" #include "ffmpeg_subtitle_stream.h" #include "ffmpeg_audio_stream.h" @@ -32,6 +33,7 @@ #include "frame_rate_change.h" #include "safe_stringstream.h" #include "raw_convert.h" +#include "subtitle_content.h" #include extern "C" { #include @@ -61,19 +63,21 @@ int const FFmpegContentProperty::FILTERS = 102; FFmpegContent::FFmpegContent (shared_ptr film, boost::filesystem::path p) : Content (film, p) - , AudioContent (film, p) - , SubtitleContent (film, p) - , video (new VideoContent (film)) { + video.reset (new VideoContent (this, film)); + audio.reset (new AudioContent (this, film)); + subtitle.reset (new SubtitleContent (this, film)); + set_default_colour_conversion (); } FFmpegContent::FFmpegContent (shared_ptr film, cxml::ConstNodePtr node, int version, list& notes) : Content (film, node) - , AudioContent (film, node) - , SubtitleContent (film, node, version) - , video (new VideoContent (film, node, version)) { + video.reset (new VideoContent (this, film, node, version)); + audio.reset (new AudioContent (this, film, node)); + subtitle.reset (new SubtitleContent (this, film, node, version)); + list c = node->node_children ("SubtitleStream"); for (list::const_iterator i = c.begin(); i != c.end(); ++i) { _subtitle_streams.push_back (shared_ptr (new FFmpegSubtitleStream (*i, version))); @@ -84,10 +88,11 @@ FFmpegContent::FFmpegContent (shared_ptr film, cxml::ConstNodePtr no c = node->node_children ("AudioStream"); for (list::const_iterator i = c.begin(); i != c.end(); ++i) { - _audio_streams.push_back (shared_ptr (new FFmpegAudioStream (*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 */ - _audio_streams.back()->set_mapping (AudioMapping (_audio_streams.back()->channels (), MAX_DCP_AUDIO_CHANNELS)); + as->set_mapping (AudioMapping (as->channels (), MAX_DCP_AUDIO_CHANNELS)); } } @@ -118,16 +123,17 @@ FFmpegContent::FFmpegContent (shared_ptr film, cxml::ConstNodePtr no FFmpegContent::FFmpegContent (shared_ptr film, vector > c) : Content (film, c) - , AudioContent (film, c) - , SubtitleContent (film, c) - , video (new VideoContent (film, c)) { + video.reset (new VideoContent (this, film, c)); + audio.reset (new AudioContent (this, film, c)); + subtitle.reset (new SubtitleContent (this, film, 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->use_subtitles() && *(fc->_subtitle_stream.get()) != *(ref->_subtitle_stream.get())) { + if (fc->subtitle->use() && *(fc->_subtitle_stream.get()) != *(ref->_subtitle_stream.get())) { throw JoinError (_("Content to be joined must use the same subtitle stream.")); } } @@ -136,7 +142,6 @@ FFmpegContent::FFmpegContent (shared_ptr film, vectorsubtitle_streams (); _subtitle_stream = ref->subtitle_stream (); - _audio_streams = ref->ffmpeg_audio_streams (); _first_video = ref->_first_video; _filters = ref->_filters; _color_range = ref->_color_range; @@ -152,8 +157,8 @@ FFmpegContent::as_xml (xmlpp::Node* node) const node->add_child("Type")->add_child_text ("FFmpeg"); Content::as_xml (node); video->as_xml (node); - AudioContent::as_xml (node); - SubtitleContent::as_xml (node); + audio->as_xml (node); + subtitle->as_xml (node); boost::mutex::scoped_lock lm (_mutex); @@ -165,8 +170,10 @@ FFmpegContent::as_xml (xmlpp::Node* node) const (*i)->as_xml (t); } - for (vector >::const_iterator i = _audio_streams.begin(); i != _audio_streams.end(); ++i) { - (*i)->as_xml (node->add_child("AudioStream")); + BOOST_FOREACH (AudioStreamPtr i, audio->streams ()) { + shared_ptr f = dynamic_pointer_cast (i); + DCPOMATIC_ASSERT (f); + f->as_xml (node->add_child("AudioStream")); } for (vector::const_iterator i = _filters.begin(); i != _filters.end(); ++i) { @@ -194,7 +201,7 @@ FFmpegContent::examine (shared_ptr job) Content::examine (job); shared_ptr examiner (new FFmpegExaminer (shared_from_this (), job)); - take_from_video_examiner (examiner); + video->take_from_examiner (examiner); set_default_colour_conversion (); { @@ -205,12 +212,15 @@ FFmpegContent::examine (shared_ptr job) _subtitle_stream = _subtitle_streams.front (); } - _audio_streams = examiner->audio_streams (); + BOOST_FOREACH (shared_ptr i, examiner->audio_streams ()) { + audio->add_stream (i); + } - if (!_audio_streams.empty ()) { - AudioMapping m = _audio_streams.front()->mapping (); + if (!audio->streams().empty ()) { + AudioStreamPtr as = audio->streams().front(); + AudioMapping m = as->mapping (); film()->make_audio_mapping_default (m); - _audio_streams.front()->set_mapping (m); + as->set_mapping (m); } _first_video = examiner->first_video (); @@ -224,7 +234,6 @@ FFmpegContent::examine (shared_ptr job) signal_changed (FFmpegContentProperty::SUBTITLE_STREAMS); signal_changed (FFmpegContentProperty::SUBTITLE_STREAM); - signal_changed (AudioContentProperty::AUDIO_STREAMS); } string @@ -255,7 +264,7 @@ FFmpegContent::technical_summary () const return Content::technical_summary() + " - " + video->technical_summary() + " - " - + AudioContent::technical_summary() + " - " + + audio->technical_summary() + " - " + String::compose ( "ffmpeg: audio %1 subtitle %2 filters %3", as, ss, filt ); @@ -287,8 +296,8 @@ operator!= (FFmpegStream const & a, FFmpegStream const & b) DCPTime FFmpegContent::full_length () const { - FrameRateChange const frc (video_frame_rate (), film()->video_frame_rate ()); - return DCPTime::from_frames (llrint (video_length_after_3d_combine() * frc.factor()), film()->video_frame_rate()); + FrameRateChange const frc (video->frame_rate (), film()->video_frame_rate ()); + return DCPTime::from_frames (llrint (video->length_after_3d_combine() * frc.factor()), film()->video_frame_rate()); } void @@ -309,7 +318,7 @@ FFmpegContent::identifier () const s << Content::identifier() << "_" << video->identifier() << "_" - << SubtitleContent::identifier(); + << subtitle->identifier(); boost::mutex::scoped_lock lm (_mutex); @@ -373,33 +382,23 @@ FFmpegContent::has_text_subtitles () const void FFmpegContent::set_default_colour_conversion () { - dcp::Size const s = video_size (); + dcp::Size const s = video->size (); boost::mutex::scoped_lock lm (_mutex); if (s.width < 1080) { - _colour_conversion = PresetColourConversion::from_id ("rec601").conversion; + video->set_colour_conversion (PresetColourConversion::from_id ("rec601").conversion); } else { - _colour_conversion = PresetColourConversion::from_id ("rec709").conversion; + video->set_colour_conversion (PresetColourConversion::from_id ("rec709").conversion); } } -vector -FFmpegContent::audio_streams () const -{ - boost::mutex::scoped_lock lm (_mutex); - - vector s; - copy (_audio_streams.begin(), _audio_streams.end(), back_inserter (s)); - return s; -} - void FFmpegContent::add_properties (list& p) const { Content::add_properties (p); video->add_properties (p); - AudioContent::add_properties (p); + audio->add_properties (p); if (_bits_per_pixel) { int const sub = 219 * pow (2, _bits_per_pixel.get() - 8); @@ -524,8 +523,20 @@ FFmpegContent::signal_subtitle_stream_changed () signal_changed (FFmpegContentProperty::SUBTITLE_STREAM); } -double -FFmpegContent::subtitle_video_frame_rate () const +void +FFmpegContent::changed (int property) { - return video->video_frame_rate (); + if (property == VideoContentProperty::FRAME_RATE && subtitle) { + subtitle->set_video_frame_rate (video->frame_rate ()); + } +} + +vector > +FFmpegContent::ffmpeg_audio_streams () const +{ + vector > fa; + BOOST_FOREACH (AudioStreamPtr i, audio->streams()) { + fa.push_back (dynamic_pointer_cast (i)); + } + return fa; }