X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fffmpeg_content.cc;h=e843e1e168c3fbb71e561279b9babe2debf6b376;hb=c3da7c64f01420447dbab7f5c2ea42ff1b911cc5;hp=487325d71b152245af66534e19537812bae950bd;hpb=f09070bbc5e4e46f80f2897c5baf5934b1514b99;p=dcpomatic.git diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 487325d71..e843e1e16 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -26,6 +26,7 @@ #include "filter.h" #include "film.h" #include "log.h" +#include "exceptions.h" #include "i18n.h" @@ -34,8 +35,10 @@ using std::stringstream; using std::vector; using std::list; using std::cout; +using std::pair; using boost::shared_ptr; using boost::lexical_cast; +using boost::dynamic_pointer_cast; int const FFmpegContentProperty::SUBTITLE_STREAMS = 100; int const FFmpegContentProperty::SUBTITLE_STREAM = 101; @@ -58,8 +61,8 @@ FFmpegContent::FFmpegContent (shared_ptr f, shared_ptr > c = node->node_children ("SubtitleStream"); - for (list >::const_iterator i = c.begin(); i != c.end(); ++i) { + 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))); if ((*i)->optional_number_child ("Selected")) { _subtitle_stream = _subtitle_streams.back (); @@ -67,7 +70,7 @@ FFmpegContent::FFmpegContent (shared_ptr f, shared_ptrnode_children ("AudioStream"); - for (list >::const_iterator i = c.begin(); i != c.end(); ++i) { + for (list::const_iterator i = c.begin(); i != c.end(); ++i) { _audio_streams.push_back (shared_ptr (new FFmpegAudioStream (*i))); if ((*i)->optional_number_child ("Selected")) { _audio_stream = _audio_streams.back (); @@ -75,24 +78,38 @@ FFmpegContent::FFmpegContent (shared_ptr f, shared_ptrnode_children ("Filter"); - for (list >::iterator i = c.begin(); i != c.end(); ++i) { + for (list::iterator i = c.begin(); i != c.end(); ++i) { _filters.push_back (Filter::from_id ((*i)->content ())); } _first_video = node->optional_number_child ("FirstVideo"); } -FFmpegContent::FFmpegContent (FFmpegContent const & o) - : Content (o) - , VideoContent (o) - , AudioContent (o) - , SubtitleContent (o) - , _subtitle_streams (o._subtitle_streams) - , _subtitle_stream (o._subtitle_stream) - , _audio_streams (o._audio_streams) - , _audio_stream (o._audio_stream) +FFmpegContent::FFmpegContent (shared_ptr f, vector > c) + : Content (f, c) + , VideoContent (f, c) + , AudioContent (f, c) + , SubtitleContent (f, c) { + shared_ptr ref = dynamic_pointer_cast (c[0]); + assert (ref); + + for (size_t i = 0; i < c.size(); ++i) { + shared_ptr fc = dynamic_pointer_cast (c[i]); + if (*(fc->_subtitle_stream.get()) != *(ref->_subtitle_stream.get())) { + throw JoinError (_("Content to be joined must use the same subtitle stream.")); + } + if (*(fc->_audio_stream.get()) != *(ref->_audio_stream.get())) { + throw JoinError (_("Content to be joined must use the same audio stream.")); + } + } + + _subtitle_streams = ref->subtitle_streams (); + _subtitle_stream = ref->subtitle_stream (); + _audio_streams = ref->audio_streams (); + _audio_stream = ref->audio_stream (); + _first_video = ref->_first_video; } void @@ -178,7 +195,31 @@ FFmpegContent::examine (shared_ptr job) string FFmpegContent::summary () const { - return String::compose (_("Movie: %1"), file().filename().string()); + /* Get the string() here so that the name does not have quotes around it */ + return String::compose (_("%1 [movie]"), path_summary ()); +} + +string +FFmpegContent::technical_summary () const +{ + string as = "none"; + if (_audio_stream) { + as = String::compose ("id %1", _audio_stream->id); + } + + string ss = "none"; + if (_subtitle_stream) { + ss = String::compose ("id %1", _subtitle_stream->id); + } + + pair filt = Filter::ffmpeg_strings (_filters); + + return Content::technical_summary() + " - " + + VideoContent::technical_summary() + " - " + + AudioContent::technical_summary() + " - " + + String::compose ( + "ffmpeg: audio %1, subtitle %2, filters %3 %4", as, ss, filt.first, filt.second + ); } string @@ -266,7 +307,7 @@ FFmpegContent::output_audio_frame_rate () const /* Resample to a DCI-approved sample rate */ double t = dcp_audio_frame_rate (content_audio_frame_rate ()); - FrameRateConversion frc (video_frame_rate(), film->dcp_video_frame_rate()); + FrameRateConversion frc (video_frame_rate(), film->video_frame_rate()); /* Compensate if the DCP is being run at a different frame rate to the source; that is, if the video is run such that it will @@ -275,7 +316,7 @@ FFmpegContent::output_audio_frame_rate () const */ if (frc.change_speed) { - t *= video_frame_rate() * frc.factor() / film->dcp_video_frame_rate(); + t *= video_frame_rate() * frc.factor() / film->video_frame_rate(); } return rint (t); @@ -287,19 +328,31 @@ operator== (FFmpegSubtitleStream const & a, FFmpegSubtitleStream const & b) return a.id == b.id; } +bool +operator!= (FFmpegSubtitleStream const & a, FFmpegSubtitleStream const & b) +{ + return a.id != b.id; +} + bool operator== (FFmpegAudioStream const & a, FFmpegAudioStream const & b) { return a.id == b.id; } +bool +operator!= (FFmpegAudioStream const & a, FFmpegAudioStream const & b) +{ + return a.id != b.id; +} + FFmpegAudioStream::FFmpegAudioStream (shared_ptr node) + : mapping (node->node_child ("Mapping")) { name = node->string_child ("Name"); id = node->number_child ("Id"); frame_rate = node->number_child ("FrameRate"); channels = node->number_child ("Channels"); - mapping = AudioMapping (node->node_child ("Mapping")); first_audio = node->optional_number_child ("FirstAudio"); } @@ -333,20 +386,14 @@ FFmpegSubtitleStream::as_xml (xmlpp::Node* root) const root->add_child("Id")->add_child_text (lexical_cast (id)); } -shared_ptr -FFmpegContent::clone () const -{ - return shared_ptr (new FFmpegContent (*this)); -} - Time -FFmpegContent::length () const +FFmpegContent::full_length () const { shared_ptr film = _film.lock (); assert (film); - FrameRateConversion frc (video_frame_rate (), film->dcp_video_frame_rate ()); - return video_length() * frc.factor() * TIME_HZ / film->dcp_video_frame_rate (); + FrameRateConversion frc (video_frame_rate (), film->video_frame_rate ()); + return video_length() * frc.factor() * TIME_HZ / film->video_frame_rate (); } AudioMapping @@ -398,3 +445,4 @@ FFmpegContent::identifier () const return s.str (); } +