summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-04-04 00:13:27 +0100
committerCarl Hetherington <cth@carlh.net>2013-04-04 00:13:27 +0100
commit190c074cc1508c0aa429452ea920f8f94ef0d0f2 (patch)
tree88cfc25fdfc67837aaf84dc3980cce9ee98094bb /src/lib
parent675e849d19812f5ed2d63b3bc0e34f142e6abb89 (diff)
More various bits.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/audio_source.cc12
-rw-r--r--src/lib/encoder.cc2
-rw-r--r--src/lib/encoder.h2
-rw-r--r--src/lib/ffmpeg_content.cc10
-rw-r--r--src/lib/ffmpeg_decoder.cc12
-rw-r--r--src/lib/ffmpeg_decoder.h10
-rw-r--r--src/lib/film.cc2
-rw-r--r--src/lib/playlist.cc25
-rw-r--r--src/lib/transcode_job.cc34
-rw-r--r--src/lib/transcode_job.h6
-rw-r--r--src/lib/transcoder.cc12
-rw-r--r--src/lib/transcoder.h3
-rw-r--r--src/lib/video_source.cc15
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));
}