summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-03-05 23:10:16 +0000
committerCarl Hetherington <cth@carlh.net>2013-03-05 23:10:16 +0000
commit18614dda0d53b713ace5ad1df57298d049dba87f (patch)
treee68887db77ec57a2de344f8230b0e801030bdca5 /src/lib
parent8fa7b8c13a76bd54207156de7bb0d09316bad379 (diff)
Split timed from untimed sinks / sources. Should produce same output, in theory.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/ab_transcoder.cc7
-rw-r--r--src/lib/audio_decoder.h2
-rw-r--r--src/lib/audio_sink.h7
-rw-r--r--src/lib/audio_source.cc6
-rw-r--r--src/lib/audio_source.h12
-rw-r--r--src/lib/combiner.cc8
-rw-r--r--src/lib/combiner.h6
-rw-r--r--src/lib/delay_line.cc7
-rw-r--r--src/lib/delay_line.h4
-rw-r--r--src/lib/external_audio_decoder.cc4
-rw-r--r--src/lib/ffmpeg_decoder.cc8
-rw-r--r--src/lib/gain.cc2
-rw-r--r--src/lib/gain.h2
-rw-r--r--src/lib/imagemagick_decoder.cc3
-rw-r--r--src/lib/matcher.cc6
-rw-r--r--src/lib/matcher.h6
-rw-r--r--src/lib/processor.h42
-rw-r--r--src/lib/transcoder.cc3
-rw-r--r--src/lib/video_decoder.cc10
-rw-r--r--src/lib/video_decoder.h6
-rw-r--r--src/lib/video_sink.h12
-rw-r--r--src/lib/video_source.cc6
-rw-r--r--src/lib/video_source.h23
23 files changed, 110 insertions, 82 deletions
diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc
index 4ed5d02ca..373549b57 100644
--- a/src/lib/ab_transcoder.cc
+++ b/src/lib/ab_transcoder.cc
@@ -70,14 +70,15 @@ ABTranscoder::ABTranscoder (
_db.video->set_subtitle_stream (_film_a->subtitle_stream ());
_da.audio->set_audio_stream (_film_a->audio_stream ());
- _da.video->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3));
- _db.video->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3));
+ _da.video->Video.connect (bind (&Combiner::process_video, _combiner, _1, _2, _3, _4));
+ _db.video->Video.connect (bind (&Combiner::process_video_b, _combiner, _1, _2, _3, _4));
if (_matcher) {
_combiner->connect_video (_matcher);
_matcher->connect_video (_encoder);
} else {
- _combiner->connect_video (_encoder);
+ /* Remove timestamp from the output of the combiner */
+ _combiner->Video.connect (bind (&Encoder::process_video, _encoder, _1, _2, _3));
}
if (_matcher && _delay_line) {
diff --git a/src/lib/audio_decoder.h b/src/lib/audio_decoder.h
index 9bef8e0e7..cfe94b528 100644
--- a/src/lib/audio_decoder.h
+++ b/src/lib/audio_decoder.h
@@ -31,7 +31,7 @@
/** @class AudioDecoder.
* @brief Parent class for audio decoders.
*/
-class AudioDecoder : public AudioSource, public virtual Decoder
+class AudioDecoder : public TimedAudioSource, public virtual Decoder
{
public:
AudioDecoder (boost::shared_ptr<Film>, DecodeOptions);
diff --git a/src/lib/audio_sink.h b/src/lib/audio_sink.h
index 11d578a60..a222bd6a0 100644
--- a/src/lib/audio_sink.h
+++ b/src/lib/audio_sink.h
@@ -27,4 +27,11 @@ public:
virtual void process_audio (boost::shared_ptr<AudioBuffers>) = 0;
};
+class TimedAudioSink
+{
+public:
+ /** Call with some audio data */
+ virtual void process_audio (boost::shared_ptr<AudioBuffers>, double t) = 0;
+};
+
#endif
diff --git a/src/lib/audio_source.cc b/src/lib/audio_source.cc
index 53b0dda15..bca3562cf 100644
--- a/src/lib/audio_source.cc
+++ b/src/lib/audio_source.cc
@@ -28,3 +28,9 @@ AudioSource::connect_audio (shared_ptr<AudioSink> s)
{
Audio.connect (bind (&AudioSink::process_audio, s, _1));
}
+
+void
+TimedAudioSource::connect_audio (shared_ptr<TimedAudioSink> s)
+{
+ Audio.connect (bind (&TimedAudioSink::process_audio, s, _1, _2));
+}
diff --git a/src/lib/audio_source.h b/src/lib/audio_source.h
index 5a1510d3c..3dc998cca 100644
--- a/src/lib/audio_source.h
+++ b/src/lib/audio_source.h
@@ -28,6 +28,7 @@
class AudioBuffers;
class AudioSink;
+class TimedAudioSink;
/** A class that emits audio data */
class AudioSource
@@ -39,4 +40,15 @@ public:
void connect_audio (boost::shared_ptr<AudioSink>);
};
+
+/** A class that emits audio data with timestamps */
+class TimedAudioSource
+{
+public:
+ /** Emitted when some audio data is ready */
+ boost::signals2::signal<void (boost::shared_ptr<AudioBuffers>, double)> Audio;
+
+ void connect_audio (boost::shared_ptr<TimedAudioSink>);
+};
+
#endif
diff --git a/src/lib/combiner.cc b/src/lib/combiner.cc
index 68aafd2a2..e628f3a84 100644
--- a/src/lib/combiner.cc
+++ b/src/lib/combiner.cc
@@ -23,7 +23,7 @@
using boost::shared_ptr;
Combiner::Combiner (Log* log)
- : VideoProcessor (log)
+ : Processor (log)
{
}
@@ -33,7 +33,7 @@ Combiner::Combiner (Log* log)
* @param image Frame image.
*/
void
-Combiner::process_video (shared_ptr<Image> image, bool, shared_ptr<Subtitle>)
+Combiner::process_video (shared_ptr<Image> image, bool, shared_ptr<Subtitle>, double)
{
_image = image;
}
@@ -43,7 +43,7 @@ Combiner::process_video (shared_ptr<Image> image, bool, shared_ptr<Subtitle>)
* @param sub Subtitle (which will be put onto the whole frame)
*/
void
-Combiner::process_video_b (shared_ptr<Image> image, bool, shared_ptr<Subtitle> sub)
+Combiner::process_video_b (shared_ptr<Image> image, bool, shared_ptr<Subtitle> sub, double t)
{
/* Copy the right half of this image into our _image */
/* XXX: this should probably be in the Image class */
@@ -62,6 +62,6 @@ Combiner::process_video_b (shared_ptr<Image> image, bool, shared_ptr<Subtitle> s
}
}
- Video (_image, false, sub);
+ Video (_image, false, sub, t);
_image.reset ();
}
diff --git a/src/lib/combiner.h b/src/lib/combiner.h
index 7fad1aeae..c52c53ed9 100644
--- a/src/lib/combiner.h
+++ b/src/lib/combiner.h
@@ -28,13 +28,13 @@
* one image used for the left half of the screen and the other for
* the right.
*/
-class Combiner : public VideoProcessor
+class Combiner : public Processor, public TimedVideoSink, public TimedVideoSource
{
public:
Combiner (Log* log);
- void process_video (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s);
- void process_video_b (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s);
+ void process_video (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s, double t);
+ void process_video_b (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s, double t);
private:
/** The image that we are currently working on */
diff --git a/src/lib/delay_line.cc b/src/lib/delay_line.cc
index 4ad172781..84785cfc6 100644
--- a/src/lib/delay_line.cc
+++ b/src/lib/delay_line.cc
@@ -31,7 +31,7 @@ using boost::shared_ptr;
* @param frames Delay in frames, +ve to move audio later.
*/
DelayLine::DelayLine (Log* log, int channels, int frames)
- : AudioProcessor (log)
+ : Processor (log)
, _negative_delay_remaining (0)
, _frames (frames)
{
@@ -47,8 +47,9 @@ DelayLine::DelayLine (Log* log, int channels, int frames)
}
}
+/* XXX: can we just get rid of all this and fiddle with the timestamp? */
void
-DelayLine::process_audio (shared_ptr<AudioBuffers> data)
+DelayLine::process_audio (shared_ptr<AudioBuffers> data, double t)
{
if (_buffers) {
/* We have some buffers, so we are moving the audio later */
@@ -89,5 +90,5 @@ DelayLine::process_audio (shared_ptr<AudioBuffers> data)
}
}
- Audio (data);
+ Audio (data, t);
}
diff --git a/src/lib/delay_line.h b/src/lib/delay_line.h
index 4d6f1313b..8c4a3953c 100644
--- a/src/lib/delay_line.h
+++ b/src/lib/delay_line.h
@@ -23,12 +23,12 @@
class AudioBuffers;
/** A delay line for audio */
-class DelayLine : public AudioProcessor
+class DelayLine : public Processor, public TimedAudioSink, public TimedAudioSource
{
public:
DelayLine (Log* log, int channels, int frames);
- void process_audio (boost::shared_ptr<AudioBuffers>);
+ void process_audio (boost::shared_ptr<AudioBuffers>, double);
private:
boost::shared_ptr<AudioBuffers> _buffers;
diff --git a/src/lib/external_audio_decoder.cc b/src/lib/external_audio_decoder.cc
index 1248b5a3b..50e5852c5 100644
--- a/src/lib/external_audio_decoder.cc
+++ b/src/lib/external_audio_decoder.cc
@@ -115,6 +115,7 @@ ExternalAudioDecoder::pass ()
sf_count_t const block = _audio_stream->sample_rate() / 2;
shared_ptr<AudioBuffers> audio (new AudioBuffers (_audio_stream->channels(), block));
+ sf_count_t done = 0;
while (frames > 0) {
sf_count_t const this_time = min (block, frames);
for (size_t i = 0; i < sndfiles.size(); ++i) {
@@ -126,7 +127,8 @@ ExternalAudioDecoder::pass ()
}
audio->set_frames (this_time);
- Audio (audio);
+ Audio (audio, double(done) / _audio_stream->sample_rate());
+ done += this_time;
frames -= this_time;
}
diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc
index ac25844e3..32c8e224a 100644
--- a/src/lib/ffmpeg_decoder.cc
+++ b/src/lib/ffmpeg_decoder.cc
@@ -640,7 +640,8 @@ FFmpegDecoder::out_with_sync ()
if (delta > one_frame) {
int const extra = rint (delta / one_frame);
for (int i = 0; i < extra; ++i) {
- repeat_last_video ();
+ /* XXX: timestamp is wrong */
+ repeat_last_video (source_pts_seconds);
_film->log()->log (
String::compose (
N_("Extra video frame inserted at %1s; source frame %2, source PTS %3 (at %4 fps)"),
@@ -739,7 +740,8 @@ FFmpegDecoder::decode_audio_packet ()
if (s) {
shared_ptr<AudioBuffers> audio (new AudioBuffers (ffa->channels(), s));
audio->make_silent ();
- Audio (audio);
+ /* XXX: this time stamp is wrong */
+ Audio (audio, source_pts_seconds);
}
}
@@ -748,7 +750,7 @@ FFmpegDecoder::decode_audio_packet ()
);
assert (_audio_codec_context->channels == _film->audio_channels());
- Audio (deinterleave_audio (_frame->data, data_size));
+ Audio (deinterleave_audio (_frame->data, data_size), source_pts_seconds );
}
}
diff --git a/src/lib/gain.cc b/src/lib/gain.cc
index cec3b3c62..35ce27cea 100644
--- a/src/lib/gain.cc
+++ b/src/lib/gain.cc
@@ -23,7 +23,7 @@ using boost::shared_ptr;
/** @param gain gain in dB */
Gain::Gain (Log* log, float gain)
- : AudioProcessor (log)
+ : Processor (log)
, _gain (gain)
{
diff --git a/src/lib/gain.h b/src/lib/gain.h
index 716ee9b51..449473582 100644
--- a/src/lib/gain.h
+++ b/src/lib/gain.h
@@ -19,7 +19,7 @@
#include "processor.h"
-class Gain : public AudioProcessor
+class Gain : public Processor, public AudioSink, public AudioSource
{
public:
Gain (Log* log, float gain);
diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc
index 5dc0b7b06..38dace6de 100644
--- a/src/lib/imagemagick_decoder.cc
+++ b/src/lib/imagemagick_decoder.cc
@@ -77,7 +77,8 @@ ImageMagickDecoder::pass ()
return true;
}
- repeat_last_video ();
+ /* XXX: timestamp is wrong */
+ repeat_last_video (0);
return false;
}
diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc
index 4cd264338..3a513b24e 100644
--- a/src/lib/matcher.cc
+++ b/src/lib/matcher.cc
@@ -27,7 +27,7 @@ using std::min;
using boost::shared_ptr;
Matcher::Matcher (Log* log, int sample_rate, float frames_per_second)
- : AudioVideoProcessor (log)
+ : Processor (log)
, _sample_rate (sample_rate)
, _frames_per_second (frames_per_second)
, _video_frames (0)
@@ -37,7 +37,7 @@ Matcher::Matcher (Log* log, int sample_rate, float frames_per_second)
}
void
-Matcher::process_video (boost::shared_ptr<Image> i, bool same, boost::shared_ptr<Subtitle> s)
+Matcher::process_video (boost::shared_ptr<Image> i, bool same, boost::shared_ptr<Subtitle> s, double)
{
Video (i, same, s);
_video_frames++;
@@ -47,7 +47,7 @@ Matcher::process_video (boost::shared_ptr<Image> i, bool same, boost::shared_ptr
}
void
-Matcher::process_audio (boost::shared_ptr<AudioBuffers> b)
+Matcher::process_audio (boost::shared_ptr<AudioBuffers> b, double)
{
Audio (b);
_audio_frames += b->frames ();
diff --git a/src/lib/matcher.h b/src/lib/matcher.h
index 60bb87432..4a66f4e70 100644
--- a/src/lib/matcher.h
+++ b/src/lib/matcher.h
@@ -21,12 +21,12 @@
#include "processor.h"
#include "ffmpeg_compatibility.h"
-class Matcher : public AudioVideoProcessor
+class Matcher : public Processor, public TimedVideoSink, public TimedAudioSink, public VideoSource, public AudioSource
{
public:
Matcher (Log* log, int sample_rate, float frames_per_second);
- void process_video (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s);
- void process_audio (boost::shared_ptr<AudioBuffers>);
+ void process_video (boost::shared_ptr<Image> i, bool, boost::shared_ptr<Subtitle> s, double t);
+ void process_audio (boost::shared_ptr<AudioBuffers>, double t);
void process_end ();
private:
diff --git a/src/lib/processor.h b/src/lib/processor.h
index 19d7c4b0c..863bfdbb5 100644
--- a/src/lib/processor.h
+++ b/src/lib/processor.h
@@ -53,46 +53,4 @@ protected:
Log* _log; ///< log to write to
};
-/** @class AudioVideoProcessor
- * @brief A processor which handles both video and audio data.
- */
-class AudioVideoProcessor : public Processor, public VideoSource, public VideoSink, public AudioSource, public AudioSink
-{
-public:
- /** Construct an AudioVideoProcessor.
- * @param log Log to write to.
- */
- AudioVideoProcessor (Log* log)
- : Processor (log)
- {}
-};
-
-/** @class AudioProcessor
- * @brief A processor which handles just audio data.
- */
-class AudioProcessor : public Processor, public AudioSource, public AudioSink
-{
-public:
- /** Construct an AudioProcessor.
- * @param log Log to write to.
- */
- AudioProcessor (Log* log)
- : Processor (log)
- {}
-};
-
-/** @class VideoProcessor
- * @brief A processor which handles just video data.
- */
-class VideoProcessor : public Processor, public VideoSource, public VideoSink
-{
-public:
- /** Construct an VideoProcessor.
- * @param log Log to write to.
- */
- VideoProcessor (Log* log)
- : Processor (log)
- {}
-};
-
#endif
diff --git a/src/lib/transcoder.cc b/src/lib/transcoder.cc
index 9720ca56a..3beda2b8b 100644
--- a/src/lib/transcoder.cc
+++ b/src/lib/transcoder.cc
@@ -72,7 +72,8 @@ Transcoder::Transcoder (shared_ptr<Film> f, DecodeOptions o, Job* j, shared_ptr<
_decoders.video->connect_video (_matcher);
_matcher->connect_video (_encoder);
} else {
- _decoders.video->connect_video (_encoder);
+ /* Discard timestamps here */
+ _decoders.video->Video.connect (boost::bind (&Encoder::process_video, _encoder, _1, _2, _3));
}
if (_matcher && _delay_line && _decoders.audio) {
diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc
index 891720f6b..773688b34 100644
--- a/src/lib/video_decoder.cc
+++ b/src/lib/video_decoder.cc
@@ -51,7 +51,7 @@ VideoDecoder::emit_video (shared_ptr<Image> image, double t)
sub = _timed_subtitle->subtitle ();
}
- signal_video (image, false, sub);
+ signal_video (image, false, sub, t);
_last_source_time = t;
}
@@ -60,14 +60,14 @@ VideoDecoder::emit_video (shared_ptr<Image> image, double t)
* we will generate a black frame.
*/
void
-VideoDecoder::repeat_last_video ()
+VideoDecoder::repeat_last_video (double t)
{
if (!_last_image) {
_last_image.reset (new SimpleImage (pixel_format(), native_size(), true));
_last_image->make_black ();
}
- signal_video (_last_image, true, _last_subtitle);
+ signal_video (_last_image, true, _last_subtitle, t);
}
/** Emit our signal to say that some video data is ready.
@@ -76,10 +76,10 @@ VideoDecoder::repeat_last_video ()
* @param sub Subtitle for this frame, or 0.
*/
void
-VideoDecoder::signal_video (shared_ptr<Image> image, bool same, shared_ptr<Subtitle> sub)
+VideoDecoder::signal_video (shared_ptr<Image> image, bool same, shared_ptr<Subtitle> sub, double t)
{
TIMING (N_("Decoder emits %1"), _video_frame);
- Video (image, same, sub);
+ Video (image, same, sub, t);
++_video_frame;
_last_image = image;
diff --git a/src/lib/video_decoder.h b/src/lib/video_decoder.h
index 283ab5d88..5e9c60d08 100644
--- a/src/lib/video_decoder.h
+++ b/src/lib/video_decoder.h
@@ -24,7 +24,7 @@
#include "stream.h"
#include "decoder.h"
-class VideoDecoder : public VideoSource, public virtual Decoder
+class VideoDecoder : public TimedVideoSource, public virtual Decoder
{
public:
VideoDecoder (boost::shared_ptr<Film>, DecodeOptions);
@@ -67,7 +67,7 @@ protected:
void emit_video (boost::shared_ptr<Image>, double);
void emit_subtitle (boost::shared_ptr<TimedSubtitle>);
- void repeat_last_video ();
+ void repeat_last_video (double t);
/** Subtitle stream to use when decoding */
boost::shared_ptr<SubtitleStream> _subtitle_stream;
@@ -75,7 +75,7 @@ protected:
std::vector<boost::shared_ptr<SubtitleStream> > _subtitle_streams;
private:
- void signal_video (boost::shared_ptr<Image>, bool, boost::shared_ptr<Subtitle>);
+ void signal_video (boost::shared_ptr<Image>, bool, boost::shared_ptr<Subtitle>, double);
int _video_frame;
double _last_source_time;
diff --git a/src/lib/video_sink.h b/src/lib/video_sink.h
index 7c128cf73..32c7f3b38 100644
--- a/src/lib/video_sink.h
+++ b/src/lib/video_sink.h
@@ -37,4 +37,16 @@ public:
virtual void process_video (boost::shared_ptr<Image> i, bool same, boost::shared_ptr<Subtitle> s) = 0;
};
+class TimedVideoSink
+{
+public:
+ /** Call with a frame of video.
+ * @param i Video frame image.
+ * @param same true if i is the same as last time we were called.
+ * @param s A subtitle that should be on this frame, or 0.
+ * @param t Source timestamp.
+ */
+ virtual void process_video (boost::shared_ptr<Image> i, bool same, boost::shared_ptr<Subtitle> s, double t) = 0;
+};
+
#endif
diff --git a/src/lib/video_source.cc b/src/lib/video_source.cc
index 56742e2b4..af6f941fd 100644
--- a/src/lib/video_source.cc
+++ b/src/lib/video_source.cc
@@ -28,3 +28,9 @@ VideoSource::connect_video (shared_ptr<VideoSink> s)
{
Video.connect (bind (&VideoSink::process_video, s, _1, _2, _3));
}
+
+void
+TimedVideoSource::connect_video (shared_ptr<TimedVideoSink> s)
+{
+ Video.connect (bind (&TimedVideoSink::process_video, s, _1, _2, _3, _4));
+}
diff --git a/src/lib/video_source.h b/src/lib/video_source.h
index 893629160..705b0023a 100644
--- a/src/lib/video_source.h
+++ b/src/lib/video_source.h
@@ -29,11 +29,12 @@
#include "util.h"
class VideoSink;
+class TimedVideoSink;
class Subtitle;
class Image;
-/** @class VideoSink
- * @param A class that emits video data.
+/** @class VideoSource
+ * @param A class that emits video data without timestamps.
*/
class VideoSource
{
@@ -49,4 +50,22 @@ public:
void connect_video (boost::shared_ptr<VideoSink>);
};
+/** @class TimedVideoSource
+ * @param A class that emits video data with timestamps.
+ */
+class TimedVideoSource
+{
+public:
+
+ /** Emitted when a video frame is ready.
+ * First parameter is the video image.
+ * Second parameter is true if the image is the same as the last one that was emitted.
+ * Third parameter is either 0 or a subtitle that should be on this frame.
+ * Fourth parameter is the source timestamp of this frame.
+ */
+ boost::signals2::signal<void (boost::shared_ptr<Image>, bool, boost::shared_ptr<Subtitle>, double)> Video;
+
+ void connect_video (boost::shared_ptr<TimedVideoSink>);
+};
+
#endif