X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fffmpeg_content.cc;h=9acc883fd0c306ebb01db70206b3693940e54f6a;hb=387304bc9147933b68eda2b38ba8cac0d250e87e;hp=9889d511cd45016c97b08746bce15856a953e265;hpb=3574212ee42b2bd924eb95d5c0f4f69ec9e0a2f0;p=dcpomatic.git diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 9889d511c..9acc883fd 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2014 Carl Hetherington + Copyright (C) 2013-2015 Carl Hetherington 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 @@ -17,11 +17,6 @@ */ -extern "C" { -#include -} -#include -#include #include "ffmpeg_content.h" #include "ffmpeg_examiner.h" #include "ffmpeg_subtitle_stream.h" @@ -33,20 +28,25 @@ extern "C" { #include "film.h" #include "log.h" #include "exceptions.h" +#include "frame_rate_change.h" +#include "safe_stringstream.h" +#include "raw_convert.h" +#include +extern "C" { +#include +} #include "i18n.h" #define LOG_GENERAL(...) film->log()->log (String::compose (__VA_ARGS__), Log::TYPE_GENERAL); using std::string; -using std::stringstream; using std::vector; using std::list; using std::cout; using std::pair; using boost::shared_ptr; using boost::dynamic_pointer_cast; -using dcp::raw_convert; int const FFmpegContentProperty::SUBTITLE_STREAMS = 100; int const FFmpegContentProperty::SUBTITLE_STREAM = 101; @@ -105,11 +105,11 @@ FFmpegContent::FFmpegContent (shared_ptr f, vector ref = dynamic_pointer_cast (c[0]); - assert (ref); + DCPOMATIC_ASSERT (ref); for (size_t i = 0; i < c.size(); ++i) { shared_ptr fc = dynamic_pointer_cast (c[i]); - if (f->with_subtitles() && *(fc->_subtitle_stream.get()) != *(ref->_subtitle_stream.get())) { + if (fc->use_subtitles() && *(fc->_subtitle_stream.get()) != *(ref->_subtitle_stream.get())) { throw JoinError (_("Content to be joined must use the same subtitle stream.")); } @@ -168,20 +168,15 @@ FFmpegContent::examine (shared_ptr job) Content::examine (job); - shared_ptr examiner (new FFmpegExaminer (shared_from_this ())); + shared_ptr examiner (new FFmpegExaminer (shared_from_this (), job)); take_from_video_examiner (examiner); - ContentTime video_length = examiner->video_length (); - shared_ptr film = _film.lock (); - assert (film); - LOG_GENERAL ("Video length obtained from header as %1 frames", video_length.frames (video_frame_rate ())); + DCPOMATIC_ASSERT (film); { boost::mutex::scoped_lock lm (_mutex); - _video_length = video_length; - _subtitle_streams = examiner->subtitle_streams (); if (!_subtitle_streams.empty ()) { _subtitle_stream = _subtitle_streams.front (); @@ -195,7 +190,6 @@ FFmpegContent::examine (shared_ptr job) _first_video = examiner->first_video (); } - signal_changed (ContentProperty::LENGTH); signal_changed (FFmpegContentProperty::SUBTITLE_STREAMS); signal_changed (FFmpegContentProperty::SUBTITLE_STREAM); signal_changed (FFmpegContentProperty::AUDIO_STREAMS); @@ -233,21 +227,6 @@ FFmpegContent::technical_summary () const ); } -string -FFmpegContent::information () const -{ - if (video_length() == ContentTime (0) || video_frame_rate() == 0) { - return ""; - } - - stringstream s; - - s << String::compose (_("%1 frames; %2 frames per second"), video_length_after_3d_combine().frames (video_frame_rate()), video_frame_rate()) << "\n"; - s << VideoContent::information (); - - return s.str (); -} - void FFmpegContent::set_subtitle_stream (shared_ptr s) { @@ -270,14 +249,18 @@ FFmpegContent::set_audio_stream (shared_ptr s) signal_changed (FFmpegContentProperty::AUDIO_STREAM); } -ContentTime +Frame FFmpegContent::audio_length () const { if (!audio_stream ()) { - return ContentTime (); + return 0; } - return video_length (); + /* We're talking about the content's audio length here, at the content's frame + rate. We assume it's the same as the video's length, and we can just convert + using the content's rates. + */ + return (video_length () / video_frame_rate ()) * audio_frame_rate (); } int @@ -289,7 +272,7 @@ FFmpegContent::audio_channels () const return 0; } - return _audio_stream->channels; + return _audio_stream->channels (); } int @@ -301,7 +284,7 @@ FFmpegContent::audio_frame_rate () const return 0; } - return _audio_stream->frame_rate; + return _audio_stream->frame_rate (); } bool @@ -320,8 +303,9 @@ DCPTime FFmpegContent::full_length () const { shared_ptr film = _film.lock (); - assert (film); - return DCPTime (video_length_after_3d_combine(), FrameRateChange (video_frame_rate (), film->video_frame_rate ())); + DCPOMATIC_ASSERT (film); + FrameRateChange const frc (video_frame_rate (), film->video_frame_rate ()); + return DCPTime::from_frames (rint (video_length_after_3d_combine() * frc.factor()), film->video_frame_rate()); } AudioMapping @@ -333,7 +317,7 @@ FFmpegContent::audio_mapping () const return AudioMapping (); } - return _audio_stream->mapping; + return _audio_stream->mapping (); } void @@ -350,14 +334,14 @@ FFmpegContent::set_filters (vector const & filters) void FFmpegContent::set_audio_mapping (AudioMapping m) { - audio_stream()->mapping = m; + audio_stream()->set_mapping (m); AudioContent::set_audio_mapping (m); } string FFmpegContent::identifier () const { - stringstream s; + SafeStringStream s; s << VideoContent::identifier(); @@ -386,26 +370,42 @@ FFmpegContent::audio_analysis_path () const analyses for each stream. */ - boost::filesystem::path p = film->audio_analysis_dir (); - string name = digest (); + boost::filesystem::path p = AudioContent::audio_analysis_path (); if (audio_stream ()) { - name += "_" + audio_stream()->identifier (); + p = p.string() + "_" + audio_stream()->identifier (); } - p /= name; return p; } -bool -FFmpegContent::has_subtitle_during (ContentTimePeriod period) const +list +FFmpegContent::subtitles_during (ContentTimePeriod period, bool starting) const { shared_ptr stream = subtitle_stream (); - - /* XXX: inefficient */ - for (vector::const_iterator i = stream->periods.begin(); i != stream->periods.end(); ++i) { - if (i->from <= period.to && i->to >= period.from) { - return true; - } + if (!stream) { + return list (); } - return false; + return stream->subtitles_during (period, starting); } + +bool +FFmpegContent::has_subtitles () const +{ + return !subtitle_streams().empty (); +} + +void +FFmpegContent::set_default_colour_conversion () +{ + dcp::Size const s = video_size (); + + boost::mutex::scoped_lock lm (_mutex); + + if (s.width < 1080) { + _colour_conversion = PresetColourConversion::from_id ("rec601").conversion; + } else { + _colour_conversion = PresetColourConversion::from_id ("rec709").conversion; + } +} + +