diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-04-04 00:13:27 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-04-04 00:13:27 +0100 |
| commit | 190c074cc1508c0aa429452ea920f8f94ef0d0f2 (patch) | |
| tree | 88cfc25fdfc67837aaf84dc3980cce9ee98094bb /src/lib | |
| parent | 675e849d19812f5ed2d63b3bc0e34f142e6abb89 (diff) | |
More various bits.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/audio_source.cc | 12 | ||||
| -rw-r--r-- | src/lib/encoder.cc | 2 | ||||
| -rw-r--r-- | src/lib/encoder.h | 2 | ||||
| -rw-r--r-- | src/lib/ffmpeg_content.cc | 10 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 12 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.h | 10 | ||||
| -rw-r--r-- | src/lib/film.cc | 2 | ||||
| -rw-r--r-- | src/lib/playlist.cc | 25 | ||||
| -rw-r--r-- | src/lib/transcode_job.cc | 34 | ||||
| -rw-r--r-- | src/lib/transcode_job.h | 6 | ||||
| -rw-r--r-- | src/lib/transcoder.cc | 12 | ||||
| -rw-r--r-- | src/lib/transcoder.h | 3 | ||||
| -rw-r--r-- | src/lib/video_source.cc | 15 |
13 files changed, 113 insertions, 32 deletions
diff --git a/src/lib/audio_source.cc b/src/lib/audio_source.cc index 53b0dda15..99b59759d 100644 --- a/src/lib/audio_source.cc +++ b/src/lib/audio_source.cc @@ -21,10 +21,20 @@ #include "audio_sink.h" using boost::shared_ptr; +using boost::weak_ptr; using boost::bind; +static void +process_audio_proxy (weak_ptr<AudioSink> sink, shared_ptr<AudioBuffers> audio) +{ + shared_ptr<AudioSink> p = sink.lock (); + if (p) { + p->process_audio (audio); + } +} + void AudioSource::connect_audio (shared_ptr<AudioSink> s) { - Audio.connect (bind (&AudioSink::process_audio, s, _1)); + Audio.connect (bind (process_audio_proxy, weak_ptr<AudioSink> (s), _1)); } diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index 5c3e56709..a41ebec51 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -193,7 +193,7 @@ Encoder::process_end () * or 0 if not known. */ float -Encoder::current_frames_per_second () const +Encoder::current_encoding_rate () const { boost::mutex::scoped_lock lock (_history_mutex); if (int (_time_history.size()) < _history_size) { diff --git a/src/lib/encoder.h b/src/lib/encoder.h index 2cbd498e8..b85132b72 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -81,7 +81,7 @@ public: /** Called when a processing run has finished */ virtual void process_end (); - float current_frames_per_second () const; + float current_encoding_rate () const; int video_frames_out () const; private: diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index c6344d567..7834cb76e 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -111,12 +111,10 @@ FFmpegContent::as_xml (xmlpp::Node* node) const void FFmpegContent::examine (shared_ptr<Film> film, shared_ptr<Job> job, bool quick) { - job->descend (0.5); - Content::examine (film, job, quick); - job->ascend (); - job->set_progress_unknown (); + Content::examine (film, job, quick); + shared_ptr<FFmpegDecoder> decoder (new FFmpegDecoder (film, shared_from_this (), true, false, false, true)); ContentVideoFrame video_length = 0; @@ -166,6 +164,10 @@ FFmpegContent::summary () const string FFmpegContent::information () const { + if (video_length() == 0 || video_frame_rate() == 0) { + return ""; + } + stringstream s; s << String::compose (_("%1 frames; %2 frames per second"), video_length(), video_frame_rate()) << "\n"; diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 3a185bd6a..fdc5189a6 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -61,6 +61,8 @@ using boost::optional; using boost::dynamic_pointer_cast; using libdcp::Size; +boost::mutex FFmpegDecoder::_mutex; + FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> f, shared_ptr<const FFmpegContent> c, bool video, bool audio, bool subtitles, bool video_sync) : Decoder (f) , VideoDecoder (f) @@ -92,10 +94,12 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> f, shared_ptr<const FFmpegC FFmpegDecoder::~FFmpegDecoder () { + boost::mutex::scoped_lock lm (_mutex); + if (_audio_codec_context) { avcodec_close (_audio_codec_context); } - + if (_video_codec_context) { avcodec_close (_video_codec_context); } @@ -160,6 +164,8 @@ FFmpegDecoder::setup_general () void FFmpegDecoder::setup_video () { + boost::mutex::scoped_lock lm (_mutex); + _video_codec_context = _format_context->streams[_video_stream]->codec; _video_codec = avcodec_find_decoder (_video_codec_context->codec_id); @@ -175,6 +181,8 @@ FFmpegDecoder::setup_video () void FFmpegDecoder::setup_audio () { + boost::mutex::scoped_lock lm (_mutex); + if (!_ffmpeg_content->audio_stream ()) { return; } @@ -194,6 +202,8 @@ FFmpegDecoder::setup_audio () void FFmpegDecoder::setup_subtitle () { + boost::mutex::scoped_lock lm (_mutex); + if (!_ffmpeg_content->subtitle_stream() || _ffmpeg_content->subtitle_stream()->id >= int (_format_context->nb_streams)) { return; } diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 71ecf7906..5023ac56c 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -82,6 +82,10 @@ public: private: + /* No copy construction */ + FFmpegDecoder (FFmpegDecoder const &); + FFmpegDecoder& operator= (FFmpegDecoder const &); + bool do_seek (double p, bool); PixelFormat pixel_format () const; AVSampleFormat audio_sample_format () const; @@ -134,4 +138,10 @@ private: bool _decode_audio; bool _decode_subtitles; bool _video_sync; + + /* It would appear (though not completely verified) that one must have + a mutex around calls to avcodec_open* and avcodec_close... and here + it is. + */ + static boost::mutex _mutex; }; diff --git a/src/lib/film.cc b/src/lib/film.cc index fd72aa1d5..b21b3454d 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -550,7 +550,7 @@ Film::file (string f) const int Film::target_audio_sample_rate () const { - if (has_audio ()) { + if (!has_audio ()) { return 0; } diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 3da7f938b..dc8ad1ef7 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -25,6 +25,7 @@ #include "ffmpeg_decoder.h" #include "imagemagick_content.h" #include "imagemagick_decoder.h" +#include "job.h" using std::list; using std::cout; @@ -219,7 +220,7 @@ Player::Player (boost::shared_ptr<const Film> f, boost::shared_ptr<const Playlis { } - + void Player::disable_video () { @@ -278,7 +279,27 @@ Player::pass () void Player::set_progress (shared_ptr<Job> job) { - /* XXX */ + /* Assume progress can be divined from how far through the video we are */ + switch (_playlist->video_from ()) { + case Playlist::VIDEO_NONE: + break; + case Playlist::VIDEO_FFMPEG: + if (_playlist->video_length ()) { + job->set_progress (float(_ffmpeg_decoder->video_frame()) / _playlist->video_length ()); + } + break; + case Playlist::VIDEO_IMAGEMAGICK: + { + int n = 0; + for (std::list<boost::shared_ptr<ImageMagickDecoder> >::iterator i = _imagemagick_decoders.begin(); i != _imagemagick_decoders.end(); ++i) { + if (_imagemagick_decoder == i) { + job->set_progress (float (n) / _imagemagick_decoders.size ()); + } + ++n; + } + break; + } + } } void diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index 8b74f7766..0c3b8c37b 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -60,8 +60,8 @@ TranscodeJob::run () _film->log()->log (N_("Transcode job starting")); _film->log()->log (String::compose (N_("Audio delay is %1ms"), _film->audio_delay())); - Transcoder w (_film, shared_from_this ()); - w.go (); + _transcoder.reset (new Transcoder (_film, shared_from_this ())); + _transcoder->go (); set_progress (1); set_state (FINISHED_OK); @@ -80,13 +80,11 @@ TranscodeJob::run () string TranscodeJob::status () const { -// if (!_encoder) { -// return _("0%"); -// } + if (!_transcoder) { + return _("0%"); + } - /* XXX */ -// float const fps = _encoder->current_frames_per_second (); - float const fps = 0; + float const fps = _transcoder->current_encoding_rate (); if (fps == 0) { return Job::status (); } @@ -105,28 +103,28 @@ TranscodeJob::status () const int TranscodeJob::remaining_time () const { - return 0; -#if 0 - XXX - float fps = _encoder->current_frames_per_second (); + if (!_transcoder) { + return 0; + } + + float fps = _transcoder->current_encoding_rate (); + if (fps == 0) { return 0; } - if (!_video->length()) { + if (!_film->video_length()) { return 0; } /* Compute approximate proposed length here, as it's only here that we need it */ - int length = _film->length().get(); - FrameRateConversion const frc (_film->source_frame_rate(), _film->dcp_frame_rate()); + int length = _film->video_length(); + FrameRateConversion const frc (_film->video_frame_rate(), _film->dcp_frame_rate()); if (frc.skip) { length /= 2; } /* If we are repeating it shouldn't affect transcode time, so don't take it into account */ - /* We assume that dcp_length() is valid, if it is set */ - int const left = length - _encoder->video_frames_out(); + int const left = length - _transcoder->video_frames_out(); return left / fps; -#endif } diff --git a/src/lib/transcode_job.h b/src/lib/transcode_job.h index def545958..7880a925e 100644 --- a/src/lib/transcode_job.h +++ b/src/lib/transcode_job.h @@ -24,7 +24,7 @@ #include <boost/shared_ptr.hpp> #include "job.h" -class Encoder; +class Transcoder; /** @class TranscodeJob * @brief A job which transcodes from one format to another. @@ -38,6 +38,8 @@ public: void run (); std::string status () const; -protected: +private: int remaining_time () const; + + boost::shared_ptr<Transcoder> _transcoder; }; diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index 0ee6f523f..ef3a0e8c1 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -99,3 +99,15 @@ Transcoder::go () } _encoder->process_end (); } + +float +Transcoder::current_encoding_rate () const +{ + return _encoder->current_encoding_rate (); +} + +int +Transcoder::video_frames_out () const +{ + return _encoder->video_frames_out (); +} diff --git a/src/lib/transcoder.h b/src/lib/transcoder.h index 2d032fcf6..ecc8ebf62 100644 --- a/src/lib/transcoder.h +++ b/src/lib/transcoder.h @@ -47,6 +47,9 @@ public: void go (); + float current_encoding_rate () const; + int video_frames_out () const; + protected: /** A Job that is running this Transcoder, or 0 */ boost::shared_ptr<Job> _job; diff --git a/src/lib/video_source.cc b/src/lib/video_source.cc index 56742e2b4..8101a6d36 100644 --- a/src/lib/video_source.cc +++ b/src/lib/video_source.cc @@ -21,10 +21,23 @@ #include "video_sink.h" using boost::shared_ptr; +using boost::weak_ptr; using boost::bind; +static void +process_video_proxy (weak_ptr<VideoSink> sink, shared_ptr<Image> i, bool same, shared_ptr<Subtitle> s) +{ + boost::shared_ptr<VideoSink> p = sink.lock (); + if (p) { + p->process_video (i, same, s); + } +} + void VideoSource::connect_video (shared_ptr<VideoSink> s) { - Video.connect (bind (&VideoSink::process_video, s, _1, _2, _3)); + /* If we bind, say, a Playlist (as the VideoSink) to a Decoder (which is owned + by the Playlist) we create a cycle. Use a weak_ptr to break it. + */ + Video.connect (bind (process_video_proxy, boost::weak_ptr<VideoSink> (s), _1, _2, _3)); } |
