diff options
| author | Carl Hetherington <cth@carlh.net> | 2012-11-12 21:04:06 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2012-11-12 21:04:06 +0000 |
| commit | 17cea71c34ed6bdba67aac8614572c7511844c2a (patch) | |
| tree | 41464576c5e2e6ab360789faf4b5fcc4358ee556 /src/lib | |
| parent | 13b935067e892875ea9e76c3d63fcc11d2c429b0 (diff) | |
Untested; more movement of stuff out of decoder.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/ab_transcoder.cc | 17 | ||||
| -rw-r--r-- | src/lib/ab_transcoder.h | 3 | ||||
| -rw-r--r-- | src/lib/decoder.cc | 89 | ||||
| -rw-r--r-- | src/lib/decoder.h | 23 | ||||
| -rw-r--r-- | src/lib/delay_line.cc | 32 | ||||
| -rw-r--r-- | src/lib/delay_line.h | 10 | ||||
| -rw-r--r-- | src/lib/encoder.cc | 29 | ||||
| -rw-r--r-- | src/lib/encoder.h | 25 | ||||
| -rw-r--r-- | src/lib/imagemagick_encoder.cc | 16 | ||||
| -rw-r--r-- | src/lib/imagemagick_encoder.h | 4 | ||||
| -rw-r--r-- | src/lib/j2k_still_encoder.cc | 4 | ||||
| -rw-r--r-- | src/lib/j2k_still_encoder.h | 4 | ||||
| -rw-r--r-- | src/lib/j2k_wav_encoder.cc | 12 | ||||
| -rw-r--r-- | src/lib/j2k_wav_encoder.h | 4 | ||||
| -rw-r--r-- | src/lib/transcode_job.cc | 2 | ||||
| -rw-r--r-- | src/lib/transcoder.cc | 17 | ||||
| -rw-r--r-- | src/lib/transcoder.h | 3 | ||||
| -rw-r--r-- | src/lib/wscript | 3 |
18 files changed, 112 insertions, 185 deletions
diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc index 4183749c8..868ce9079 100644 --- a/src/lib/ab_transcoder.cc +++ b/src/lib/ab_transcoder.cc @@ -50,14 +50,13 @@ ABTranscoder::ABTranscoder ( , _opt (o) , _job (j) , _encoder (e) - , _last_frame (0) { _da = decoder_factory (_film_a, o, j); _db = decoder_factory (_film_b, o, j); - _da->Video.connect (bind (&ABTranscoder::process_video, this, _1, _2, _3, 0)); - _db->Video.connect (bind (&ABTranscoder::process_video, this, _1, _2, _3, 1)); - _da->Audio.connect (bind (&Encoder::process_audio, e, _1, _2)); + _da->Video.connect (bind (&ABTranscoder::process_video, this, _1, _2, 0)); + _db->Video.connect (bind (&ABTranscoder::process_video, this, _1, _2, 1)); + _da->Audio.connect (bind (&Encoder::process_audio, e, _1)); } ABTranscoder::~ABTranscoder () @@ -66,7 +65,7 @@ ABTranscoder::~ABTranscoder () } void -ABTranscoder::process_video (shared_ptr<Image> yuv, SourceFrame frame, shared_ptr<Subtitle> sub, int index) +ABTranscoder::process_video (shared_ptr<Image> yuv, shared_ptr<Subtitle> sub, int index) { if (index == 0) { /* Keep this image around until we get the other half */ @@ -89,11 +88,9 @@ ABTranscoder::process_video (shared_ptr<Image> yuv, SourceFrame frame, shared_pt } /* And pass it to the encoder */ - _encoder->process_video (_image, frame, sub); + _encoder->process_video (_image, sub); _image.reset (); } - - _last_frame = frame; } @@ -101,8 +98,6 @@ void ABTranscoder::go () { _encoder->process_begin (); - _da->process_begin (); - _db->process_begin (); while (1) { bool const a = _da->pass (); @@ -114,7 +109,5 @@ ABTranscoder::go () } _encoder->process_end (); - _da->process_end (); - _db->process_end (); } diff --git a/src/lib/ab_transcoder.h b/src/lib/ab_transcoder.h index a136fd270..c75398b5c 100644 --- a/src/lib/ab_transcoder.h +++ b/src/lib/ab_transcoder.h @@ -55,7 +55,7 @@ public: void go (); private: - void process_video (boost::shared_ptr<Image>, SourceFrame, boost::shared_ptr<Subtitle>, int); + void process_video (boost::shared_ptr<Image>, boost::shared_ptr<Subtitle>, int); boost::shared_ptr<Film> _film_a; boost::shared_ptr<Film> _film_b; @@ -64,6 +64,5 @@ private: boost::shared_ptr<Encoder> _encoder; boost::shared_ptr<Decoder> _da; boost::shared_ptr<Decoder> _db; - SourceFrame _last_frame; boost::shared_ptr<Image> _image; }; diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc index eb9667471..73e17e7ea 100644 --- a/src/lib/decoder.cc +++ b/src/lib/decoder.cc @@ -56,89 +56,14 @@ Decoder::Decoder (boost::shared_ptr<Film> f, boost::shared_ptr<const Options> o, , _opt (o) , _job (j) , _video_frame (0) - , _audio_frame (0) - , _delay_line (0) - , _delay_in_frames (0) { } -Decoder::~Decoder () -{ - delete _delay_line; -} - -/** Start off a decode processing run. This should only be called once on - * a given Decoder object. - */ -void -Decoder::process_begin () -{ - if (_audio_stream) { - _delay_in_frames = _film->audio_delay() * _audio_stream.get().sample_rate() / 1000; - _delay_line = new DelayLine (_audio_stream.get().channels(), _delay_in_frames); - } -} - -/** Finish off a decode processing run */ -void -Decoder::process_end () -{ - if (_delay_in_frames < 0 && _opt->decode_audio && _audio_stream) { - shared_ptr<AudioBuffers> b (new AudioBuffers (_audio_stream.get().channels(), -_delay_in_frames)); - b->make_silent (); - emit_audio (b); - } - - if (_opt->decode_audio && _audio_stream) { - - /* Ensure that our video and audio emissions are the same length */ - - int64_t audio_short_by_frames = video_frames_to_audio_frames (_video_frame, _audio_stream.get().sample_rate(), frames_per_second()) - _audio_frame; - - _film->log()->log ( - String::compose ( - "Decoder has emitted %1 video frames (which equals %2 audio frames) and %3 audio frames", - _video_frame, - video_frames_to_audio_frames (_video_frame, _audio_stream.get().sample_rate(), frames_per_second()), - _audio_frame - ) - ); - - if (audio_short_by_frames < 0) { - - _film->log()->log (String::compose ("Emitted %1 too many audio frames", -audio_short_by_frames)); - - /* We have emitted more audio than video. Emit enough black video frames so that we reverse this */ - int const black_video_frames = ceil (-audio_short_by_frames * frames_per_second() / _audio_stream.get().sample_rate()); - - _film->log()->log (String::compose ("Emitting %1 frames of black video", black_video_frames)); - - shared_ptr<Image> black (new CompactImage (pixel_format(), native_size())); - black->make_black (); - for (int i = 0; i < black_video_frames; ++i) { - emit_video (black, shared_ptr<Subtitle> ()); - } - - /* Now recompute our check value */ - audio_short_by_frames = video_frames_to_audio_frames (_video_frame, _audio_stream.get().sample_rate(), frames_per_second()) - _audio_frame; - } - - if (audio_short_by_frames > 0) { - _film->log()->log (String::compose ("Emitted %1 too few audio frames", audio_short_by_frames)); - shared_ptr<AudioBuffers> b (new AudioBuffers (_audio_stream.get().channels(), audio_short_by_frames)); - b->make_silent (); - emit_audio (b); - } - } -} - /** Start decoding */ void Decoder::go () { - process_begin (); - if (_job && !_film->dcp_length()) { _job->set_progress_unknown (); } @@ -148,8 +73,6 @@ Decoder::go () _job->set_progress (float (_video_frame) / _film->length().get()); } } - - process_end (); } /** Called to tell the world that some audio data is ready @@ -168,8 +91,7 @@ Decoder::process_audio (shared_ptr<AudioBuffers> audio) } } - _delay_line->feed (audio); - emit_audio (audio); + Audio (audio); } /** Called by subclasses to tell the world that some video data is ready. @@ -221,7 +143,7 @@ void Decoder::emit_video (shared_ptr<Image> image, shared_ptr<Subtitle> sub) { TIMING ("Decoder emits %1", _video_frame); - Video (image, _video_frame, sub); + Video (image, sub); ++_video_frame; _last_image = image; @@ -229,13 +151,6 @@ Decoder::emit_video (shared_ptr<Image> image, shared_ptr<Subtitle> sub) } void -Decoder::emit_audio (shared_ptr<AudioBuffers> audio) -{ - Audio (audio, _audio_frame); - _audio_frame += audio->frames (); -} - -void Decoder::process_subtitle (shared_ptr<TimedSubtitle> s) { _timed_subtitle = s; diff --git a/src/lib/decoder.h b/src/lib/decoder.h index d0e20b03a..71dfed1e0 100644 --- a/src/lib/decoder.h +++ b/src/lib/decoder.h @@ -31,6 +31,8 @@ #include <boost/signals2.hpp> #include "util.h" #include "stream.h" +#include "video_source.h" +#include "audio_source.h" class Job; class Options; @@ -49,11 +51,11 @@ class FilterGraph; * (by calling ::go), and they emit signals when video or audio data is ready for something else * to process. */ -class Decoder +class Decoder : public VideoSource, public AudioSource { public: Decoder (boost::shared_ptr<Film>, boost::shared_ptr<const Options>, Job *); - virtual ~Decoder (); + virtual ~Decoder () {} /* Methods to query our input video */ @@ -67,9 +69,7 @@ public: virtual int sample_aspect_ratio_numerator () const = 0; virtual int sample_aspect_ratio_denominator () const = 0; - void process_begin (); virtual bool pass () = 0; - void process_end (); void go (); SourceFrame video_frame () const { @@ -95,16 +95,6 @@ public: return _subtitle_streams; } - /** Emitted when a video frame is ready. - * First parameter is the frame within the source. - * Second parameter is its index within the content. - * Third parameter is either 0 or a subtitle that should be on this frame. - */ - boost::signals2::signal<void (boost::shared_ptr<Image>, SourceFrame, boost::shared_ptr<Subtitle>)> Video; - - /** Emitted when some audio data is ready */ - boost::signals2::signal<void (boost::shared_ptr<AudioBuffers>, int64_t)> Audio; - protected: virtual PixelFormat pixel_format () const = 0; @@ -129,16 +119,11 @@ protected: private: void emit_video (boost::shared_ptr<Image>, boost::shared_ptr<Subtitle>); - void emit_audio (boost::shared_ptr<AudioBuffers>); SourceFrame _video_frame; - int64_t _audio_frame; std::list<boost::shared_ptr<FilterGraph> > _filter_graphs; - DelayLine* _delay_line; - int _delay_in_frames; - boost::shared_ptr<TimedSubtitle> _timed_subtitle; boost::shared_ptr<Image> _last_image; diff --git a/src/lib/delay_line.cc b/src/lib/delay_line.cc index e7cd8dc94..45d8e9d9d 100644 --- a/src/lib/delay_line.cc +++ b/src/lib/delay_line.cc @@ -30,28 +30,25 @@ using boost::shared_ptr; /** @param channels Number of channels of audio. * @param frames Delay in frames, +ve to move audio later. */ -DelayLine::DelayLine (int channels, int frames) - : _negative_delay_remaining (0) +DelayLine::DelayLine (Log* log, int channels, int frames) + : AudioProcessor (log) + , _negative_delay_remaining (0) + , _frames (frames) { - if (frames > 0) { + if (_frames > 0) { /* We need a buffer to keep some data in */ - _buffers.reset (new AudioBuffers (channels, frames)); + _buffers.reset (new AudioBuffers (channels, _frames)); _buffers->make_silent (); - } else if (frames < 0) { + } else if (_frames < 0) { /* We can do -ve delays just by chopping off the start, so no buffer needed. */ - _negative_delay_remaining = -frames; + _negative_delay_remaining = -_frames; } } -DelayLine::~DelayLine () -{ - -} - void -DelayLine::feed (shared_ptr<AudioBuffers> data) +DelayLine::process_audio (shared_ptr<AudioBuffers> data) { if (_buffers) { /* We have some buffers, so we are moving the audio later */ @@ -91,4 +88,15 @@ DelayLine::feed (shared_ptr<AudioBuffers> data) _negative_delay_remaining -= to_do; } } + + Audio (data); +} + +void +DelayLine::process_end () +{ + if (_frames < 0) { + _buffers->make_silent (); + Audio (_buffers); + } } diff --git a/src/lib/delay_line.h b/src/lib/delay_line.h index e8d9560af..fa2870ae7 100644 --- a/src/lib/delay_line.h +++ b/src/lib/delay_line.h @@ -18,19 +18,21 @@ */ #include <boost/shared_ptr.hpp> +#include "processor.h" class AudioBuffers; /** A delay line for audio */ -class DelayLine +class DelayLine : public AudioProcessor { public: - DelayLine (int channels, int frames); - ~DelayLine (); + DelayLine (Log* log, int channels, int frames); - void feed (boost::shared_ptr<AudioBuffers>); + void process_audio (boost::shared_ptr<AudioBuffers>); + void process_end (); private: boost::shared_ptr<AudioBuffers> _buffers; int _negative_delay_remaining; ///< number of frames of negative delay that remain to emit + int _frames; }; diff --git a/src/lib/encoder.cc b/src/lib/encoder.cc index b322be04c..17a6726a6 100644 --- a/src/lib/encoder.cc +++ b/src/lib/encoder.cc @@ -37,7 +37,8 @@ Encoder::Encoder (shared_ptr<const Film> f, shared_ptr<const Options> o) : _film (f) , _opt (o) , _just_skipped (false) - , _last_frame (0) + , _video_frame (0) + , _audio_frame (0) { } @@ -68,23 +69,22 @@ Encoder::skipping () const return _just_skipped; } -/** @return Index of last frame to be successfully encoded */ +/** @return Number of video frames that have been received */ SourceFrame -Encoder::last_frame () const +Encoder::video_frame () const { boost::mutex::scoped_lock (_history_mutex); - return _last_frame; + return _video_frame; } /** Should be called when a frame has been encoded successfully. * @param n Source frame index. */ void -Encoder::frame_done (SourceFrame n) +Encoder::frame_done () { boost::mutex::scoped_lock lock (_history_mutex); _just_skipped = false; - _last_frame = n; struct timeval tv; gettimeofday (&tv, 0); @@ -105,24 +105,27 @@ Encoder::frame_skipped () } void -Encoder::process_video (shared_ptr<const Image> i, SourceFrame f, boost::shared_ptr<Subtitle> s) +Encoder::process_video (shared_ptr<Image> i, boost::shared_ptr<Subtitle> s) { - if (_opt->decode_video_skip != 0 && (f % _opt->decode_video_skip) != 0) { + if (_opt->decode_video_skip != 0 && (_video_frame % _opt->decode_video_skip) != 0) { + ++_video_frame; return; } if (_opt->video_decode_range) { pair<SourceFrame, SourceFrame> const r = _opt->video_decode_range.get(); - if (f < r.first || f >= r.second) { + if (_video_frame < r.first || _video_frame >= r.second) { + ++_video_frame; return; } } - do_process_video (i, f, s); + do_process_video (i, s); + ++_video_frame; } void -Encoder::process_audio (shared_ptr<const AudioBuffers> data, int64_t f) +Encoder::process_audio (shared_ptr<AudioBuffers> data) { if (_opt->audio_decode_range) { @@ -131,7 +134,7 @@ Encoder::process_audio (shared_ptr<const AudioBuffers> data, int64_t f) /* Range that we are encoding */ pair<int64_t, int64_t> required_range = _opt->audio_decode_range.get(); /* Range of this block of data */ - pair<int64_t, int64_t> this_range (f, f + trimmed->frames()); + pair<int64_t, int64_t> this_range (_audio_frame, _audio_frame + trimmed->frames()); if (this_range.second < required_range.first || required_range.second < this_range.first) { /* No part of this audio is within the required range */ @@ -150,4 +153,6 @@ Encoder::process_audio (shared_ptr<const AudioBuffers> data, int64_t f) } do_process_audio (data); + + _audio_frame += data->frames (); } diff --git a/src/lib/encoder.h b/src/lib/encoder.h index e04397f78..68a5f6139 100644 --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@ -32,6 +32,8 @@ extern "C" { #include <libavutil/samplefmt.h> } #include "util.h" +#include "video_sink.h" +#include "audio_sink.h" class Options; class Image; @@ -49,7 +51,7 @@ class Film; * some way and write it to disk. */ -class Encoder +class Encoder : public VideoSink, public AudioSink { public: Encoder (boost::shared_ptr<const Film> f, boost::shared_ptr<const Options> o); @@ -59,34 +61,32 @@ public: /** Call with a frame of video. * @param i Video frame image. - * @param f Frame number within the film's source. * @param s A subtitle that should be on this frame, or 0. */ - void process_video (boost::shared_ptr<const Image> i, SourceFrame f, boost::shared_ptr<Subtitle> s); + void process_video (boost::shared_ptr<Image> i, boost::shared_ptr<Subtitle> s); /** Call with some audio data */ - void process_audio (boost::shared_ptr<const AudioBuffers>, int64_t); + void process_audio (boost::shared_ptr<AudioBuffers>); /** Called when a processing run has finished */ virtual void process_end () {} float current_frames_per_second () const; bool skipping () const; - SourceFrame last_frame () const; + SourceFrame video_frame () const; protected: /** Called with a frame of video. * @param i Video frame image. - * @param f Frame number within the film's source. * @param s A subtitle that should be on this frame, or 0. */ - virtual void do_process_video (boost::shared_ptr<const Image> i, SourceFrame f, boost::shared_ptr<Subtitle> s) = 0; + virtual void do_process_video (boost::shared_ptr<Image> i, boost::shared_ptr<Subtitle> s) = 0; /** Called with some audio data */ - virtual void do_process_audio (boost::shared_ptr<const AudioBuffers>) = 0; + virtual void do_process_audio (boost::shared_ptr<AudioBuffers>) = 0; - void frame_done (SourceFrame n); + void frame_done (); void frame_skipped (); /** Film that we are encoding */ @@ -104,8 +104,11 @@ protected: static int const _history_size; /** true if the last frame we processed was skipped (because it was already done) */ bool _just_skipped; - /** Source index of the last frame to be processed */ - SourceFrame _last_frame; + + /** Number of video frames received so far */ + SourceFrame _video_frame; + /** Number of audio frames received so far */ + int64_t _audio_frame; }; #endif diff --git a/src/lib/imagemagick_encoder.cc b/src/lib/imagemagick_encoder.cc index 6c70e3749..480dec8bc 100644 --- a/src/lib/imagemagick_encoder.cc +++ b/src/lib/imagemagick_encoder.cc @@ -50,22 +50,22 @@ ImageMagickEncoder::ImageMagickEncoder (shared_ptr<const Film> f, shared_ptr<con } void -ImageMagickEncoder::do_process_video (shared_ptr<const Image> image, SourceFrame frame, shared_ptr<Subtitle> sub) +ImageMagickEncoder::do_process_video (shared_ptr<Image> image, shared_ptr<Subtitle> sub) { shared_ptr<Image> scaled = image->scale_and_convert_to_rgb (_opt->out_size, _opt->padding, _film->scaler()); shared_ptr<Image> compact (new CompactImage (scaled)); - string tmp_file = _opt->frame_out_path (frame, true); + string tmp_file = _opt->frame_out_path (_video_frame, true); Magick::Image thumb (compact->size().width, compact->size().height, "RGB", MagickCore::CharPixel, compact->data()[0]); thumb.magick ("PNG"); thumb.write (tmp_file); - boost::filesystem::rename (tmp_file, _opt->frame_out_path (frame, false)); + boost::filesystem::rename (tmp_file, _opt->frame_out_path (_video_frame, false)); if (sub) { float const x_scale = float (_opt->out_size.width) / _film->size().width; float const y_scale = float (_opt->out_size.height) / _film->size().height; - string tmp_metadata_file = _opt->frame_out_path (frame, false, ".sub"); + string tmp_metadata_file = _opt->frame_out_path (_video_frame, false, ".sub"); ofstream metadata (tmp_metadata_file.c_str ()); Size new_size = sub->image()->size (); @@ -74,18 +74,18 @@ ImageMagickEncoder::do_process_video (shared_ptr<const Image> image, SourceFrame shared_ptr<Image> scaled = sub->image()->scale (new_size, _film->scaler()); shared_ptr<Image> compact (new CompactImage (scaled)); - string tmp_sub_file = _opt->frame_out_path (frame, true, ".sub.png"); + string tmp_sub_file = _opt->frame_out_path (_video_frame, true, ".sub.png"); Magick::Image sub_thumb (compact->size().width, compact->size().height, "RGBA", MagickCore::CharPixel, compact->data()[0]); sub_thumb.magick ("PNG"); sub_thumb.write (tmp_sub_file); - boost::filesystem::rename (tmp_sub_file, _opt->frame_out_path (frame, false, ".sub.png")); + boost::filesystem::rename (tmp_sub_file, _opt->frame_out_path (_video_frame, false, ".sub.png")); metadata << "x " << sub->position().x << "\n" << "y " << sub->position().y << "\n"; metadata.close (); - boost::filesystem::rename (tmp_metadata_file, _opt->frame_out_path (frame, false, ".sub")); + boost::filesystem::rename (tmp_metadata_file, _opt->frame_out_path (_video_frame, false, ".sub")); } - frame_done (frame); + frame_done (); } diff --git a/src/lib/imagemagick_encoder.h b/src/lib/imagemagick_encoder.h index 02458fc5b..dfc741cb2 100644 --- a/src/lib/imagemagick_encoder.h +++ b/src/lib/imagemagick_encoder.h @@ -37,6 +37,6 @@ public: ImageMagickEncoder (boost::shared_ptr<const Film> f, boost::shared_ptr<const Options> o); private: - void do_process_video (boost::shared_ptr<const Image>, SourceFrame, boost::shared_ptr<Subtitle>); - void do_process_audio (boost::shared_ptr<const AudioBuffers>) {} + void do_process_video (boost::shared_ptr<Image>, boost::shared_ptr<Subtitle>); + void do_process_audio (boost::shared_ptr<AudioBuffers>) {} }; diff --git a/src/lib/j2k_still_encoder.cc b/src/lib/j2k_still_encoder.cc index 2d6c457fc..a4ac54e7a 100644 --- a/src/lib/j2k_still_encoder.cc +++ b/src/lib/j2k_still_encoder.cc @@ -49,7 +49,7 @@ J2KStillEncoder::J2KStillEncoder (shared_ptr<const Film> f, shared_ptr<const Opt } void -J2KStillEncoder::do_process_video (shared_ptr<const Image> yuv, SourceFrame frame, shared_ptr<Subtitle> sub) +J2KStillEncoder::do_process_video (shared_ptr<Image> yuv, shared_ptr<Subtitle> sub) { pair<string, string> const s = Filter::ffmpeg_strings (_film->filters()); DCPVideoFrame* f = new DCPVideoFrame ( @@ -77,6 +77,6 @@ J2KStillEncoder::do_process_video (shared_ptr<const Image> yuv, SourceFrame fram boost::filesystem::copy_file (real, link); #endif } - frame_done (0); + frame_done (); } } diff --git a/src/lib/j2k_still_encoder.h b/src/lib/j2k_still_encoder.h index 65cfa7cac..4ffe876af 100644 --- a/src/lib/j2k_still_encoder.h +++ b/src/lib/j2k_still_encoder.h @@ -37,6 +37,6 @@ public: J2KStillEncoder (boost::shared_ptr<const Film>, boost::shared_ptr<const Options>); private: - void do_process_video (boost::shared_ptr<const Image>, SourceFrame, boost::shared_ptr<Subtitle>); - void do_process_audio (boost::shared_ptr<const AudioBuffers>) {} + void do_process_video (boost::shared_ptr<Image>, boost::shared_ptr<Subtitle>); + void do_process_audio (boost::shared_ptr<AudioBuffers>) {} }; diff --git a/src/lib/j2k_wav_encoder.cc b/src/lib/j2k_wav_encoder.cc index 108320d32..847ee9486 100644 --- a/src/lib/j2k_wav_encoder.cc +++ b/src/lib/j2k_wav_encoder.cc @@ -108,7 +108,7 @@ J2KWAVEncoder::close_sound_files () } void -J2KWAVEncoder::do_process_video (shared_ptr<const Image> yuv, SourceFrame frame, shared_ptr<Subtitle> sub) +J2KWAVEncoder::do_process_video (shared_ptr<Image> yuv, shared_ptr<Subtitle> sub) { boost::mutex::scoped_lock lock (_worker_mutex); @@ -124,13 +124,13 @@ J2KWAVEncoder::do_process_video (shared_ptr<const Image> yuv, SourceFrame frame, } /* Only do the processing if we don't already have a file for this frame */ - if (!boost::filesystem::exists (_opt->frame_out_path (frame, false))) { + if (!boost::filesystem::exists (_opt->frame_out_path (_video_frame, false))) { pair<string, string> const s = Filter::ffmpeg_strings (_film->filters()); TIMING ("adding to queue of %1", _queue.size ()); _queue.push_back (boost::shared_ptr<DCPVideoFrame> ( new DCPVideoFrame ( yuv, sub, _opt->out_size, _opt->padding, _film->subtitle_offset(), _film->subtitle_scale(), - _film->scaler(), frame, _film->frames_per_second(), s.second, + _film->scaler(), _video_frame, _film->frames_per_second(), s.second, Config::instance()->colour_lut_index (), Config::instance()->j2k_bandwidth (), _film->log() ) @@ -207,7 +207,7 @@ J2KWAVEncoder::encoder_thread (ServerDescription* server) if (encoded) { encoded->write (_opt, vf->frame ()); - frame_done (vf->frame ()); + frame_done (); } else { lock.lock (); _film->log()->log ( @@ -305,7 +305,7 @@ J2KWAVEncoder::process_end () try { shared_ptr<EncodedData> e = (*i)->encode_locally (); e->write (_opt, (*i)->frame ()); - frame_done ((*i)->frame ()); + frame_done (); } catch (std::exception& e) { _film->log()->log (String::compose ("Local encode failed (%1)", e.what ())); } @@ -355,7 +355,7 @@ J2KWAVEncoder::process_end () } void -J2KWAVEncoder::do_process_audio (shared_ptr<const AudioBuffers> audio) +J2KWAVEncoder::do_process_audio (shared_ptr<AudioBuffers> audio) { shared_ptr<AudioBuffers> resampled; diff --git a/src/lib/j2k_wav_encoder.h b/src/lib/j2k_wav_encoder.h index 5cf508cff..f3340ba72 100644 --- a/src/lib/j2k_wav_encoder.h +++ b/src/lib/j2k_wav_encoder.h @@ -55,8 +55,8 @@ public: private: - void do_process_video (boost::shared_ptr<const Image>, SourceFrame, boost::shared_ptr<Subtitle>); - void do_process_audio (boost::shared_ptr<const AudioBuffers>); + void do_process_video (boost::shared_ptr<Image>, boost::shared_ptr<Subtitle>); + void do_process_audio (boost::shared_ptr<AudioBuffers>); void write_audio (boost::shared_ptr<const AudioBuffers> audio); void encoder_thread (ServerDescription *); diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index 25581c8f5..5e9e58667 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -116,6 +116,6 @@ TranscodeJob::remaining_time () const } /* We assume that dcp_length() is valid */ - SourceFrame const left = _film->dcp_trim_start() + _film->dcp_length().get() - _encoder->last_frame(); + SourceFrame const left = _film->dcp_trim_start() + _film->dcp_length().get() - _encoder->video_frame(); return left / fps; } diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc index ac908768e..f53fc4001 100644 --- a/src/lib/transcoder.cc +++ b/src/lib/transcoder.cc @@ -30,6 +30,8 @@ #include "encoder.h" #include "decoder_factory.h" #include "film.h" +#include "matcher.h" +#include "delay_line.h" using std::string; using boost::shared_ptr; @@ -47,12 +49,21 @@ Transcoder::Transcoder (shared_ptr<Film> f, shared_ptr<const Options> o, Job* j, { assert (_encoder); + AudioStream st = f->audio_stream().get(); + + _matcher.reset (new Matcher (f->log(), st.sample_rate(), f->frames_per_second())); + _delay_line.reset (new DelayLine (f->log(), st.channels(), f->audio_delay() * st.sample_rate() / 1000)); + /* Set up the decoder to use the film's set streams */ _decoder->set_audio_stream (f->audio_stream ()); _decoder->set_subtitle_stream (f->subtitle_stream ()); - - _decoder->Video.connect (bind (&Encoder::process_video, e, _1, _2, _3)); - _decoder->Audio.connect (bind (&Encoder::process_audio, e, _1, _2)); + + _decoder->connect_video (_matcher); + _matcher->connect_video (_encoder); + + _decoder->connect_audio (_delay_line); + _delay_line->connect_audio (_matcher); + _matcher->connect_audio (_delay_line); } /** Run the decoder, passing its output to the encoder, until the decoder diff --git a/src/lib/transcoder.h b/src/lib/transcoder.h index 79ef89a18..d5597ad0e 100644 --- a/src/lib/transcoder.h +++ b/src/lib/transcoder.h @@ -30,6 +30,7 @@ class Film; class Job; class Encoder; class FilmState; +class Matcher; /** @class Transcoder * @brief A class which takes a FilmState and some Options, then uses those to transcode a Film. @@ -56,4 +57,6 @@ protected: boost::shared_ptr<Encoder> _encoder; /** The decoder that we will use */ boost::shared_ptr<Decoder> _decoder; + boost::shared_ptr<Matcher> _matcher; + boost::shared_ptr<DelayLine> _delay_line; }; diff --git a/src/lib/wscript b/src/lib/wscript index 969a69606..4fc839097 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -8,6 +8,7 @@ def build(bld): obj.source = """ ab_transcode_job.cc ab_transcoder.cc + audio_source.cc check_hashes_job.cc config.cc copy_from_dvd_job.cc @@ -38,6 +39,7 @@ def build(bld): log.cc lut.cc make_dcp_job.cc + matcher.cc scp_dcp_job.cc scaler.cc screen.cc @@ -52,6 +54,7 @@ def build(bld): ui_signaller.cc util.cc version.cc + video_source.cc """ if not bld.env.DISABLE_PLAYER: |
