From ac0a9000d5d6a62c4ef3e4902611b180501e09e1 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 12 Nov 2012 21:06:47 +0000 Subject: [PATCH] Missing files. --- src/lib/audio_sink.h | 11 ++++++ src/lib/audio_source.cc | 11 ++++++ src/lib/audio_source.h | 18 +++++++++ src/lib/matcher.cc | 81 +++++++++++++++++++++++++++++++++++++++++ src/lib/matcher.h | 20 ++++++++++ src/lib/processor.h | 41 +++++++++++++++++++++ src/lib/video_sink.h | 20 ++++++++++ src/lib/video_source.cc | 11 ++++++ src/lib/video_source.h | 25 +++++++++++++ 9 files changed, 238 insertions(+) create mode 100644 src/lib/audio_sink.h create mode 100644 src/lib/audio_source.cc create mode 100644 src/lib/audio_source.h create mode 100644 src/lib/matcher.cc create mode 100644 src/lib/matcher.h create mode 100644 src/lib/processor.h create mode 100644 src/lib/video_sink.h create mode 100644 src/lib/video_source.cc create mode 100644 src/lib/video_source.h diff --git a/src/lib/audio_sink.h b/src/lib/audio_sink.h new file mode 100644 index 000000000..93109a66d --- /dev/null +++ b/src/lib/audio_sink.h @@ -0,0 +1,11 @@ +#ifndef DVDOMATIC_AUDIO_SINK_H +#define DVDOMATIC_AUDIO_SINK_H + +class AudioSink +{ +public: + /** Call with some audio data */ + virtual void process_audio (boost::shared_ptr) = 0; +}; + +#endif diff --git a/src/lib/audio_source.cc b/src/lib/audio_source.cc new file mode 100644 index 000000000..ccb82334c --- /dev/null +++ b/src/lib/audio_source.cc @@ -0,0 +1,11 @@ +#include "audio_source.h" +#include "audio_sink.h" + +using boost::shared_ptr; +using boost::bind; + +void +AudioSource::connect_audio (shared_ptr s) +{ + Audio.connect (bind (&AudioSink::process_audio, s, _1)); +} diff --git a/src/lib/audio_source.h b/src/lib/audio_source.h new file mode 100644 index 000000000..b300e0763 --- /dev/null +++ b/src/lib/audio_source.h @@ -0,0 +1,18 @@ +#ifndef DVDOMATIC_AUDIO_SOURCE_H +#define DVDOMATIC_AUDIO_SOURCE_H + +#include + +class AudioBuffers; +class AudioSink; + +class AudioSource +{ +public: + /** Emitted when some audio data is ready */ + boost::signals2::signal)> Audio; + + void connect_audio (boost::shared_ptr); +}; + +#endif diff --git a/src/lib/matcher.cc b/src/lib/matcher.cc new file mode 100644 index 000000000..f6eff168b --- /dev/null +++ b/src/lib/matcher.cc @@ -0,0 +1,81 @@ +#include "matcher.h" +#include "image.h" +#include "log.h" + +using boost::shared_ptr; + +Matcher::Matcher (Log* log, int sample_rate, float frames_per_second) + : AudioVideoProcessor (log) + , _sample_rate (sample_rate) + , _frames_per_second (frames_per_second) + , _video_frames (0) + , _audio_frames (0) +{ + +} + +void +Matcher::process_video (boost::shared_ptr i, boost::shared_ptr s) +{ + Video (i, s); + _video_frames++; + + _pixel_format = i->pixel_format (); + _size = i->size (); +} + +void +Matcher::process_audio (boost::shared_ptr b) +{ + Audio (b); + _audio_frames += b->frames (); + + _channels = b->channels (); +} + +void +Matcher::process_end () +{ + if (_audio_frames == 0 || !_pixel_format || !_size || !_channels) { + /* We won't do anything */ + return; + } + + int64_t audio_short_by_frames = video_frames_to_audio_frames (_video_frames, _sample_rate, _frames_per_second) - _audio_frames; + + _log->log ( + String::compose ( + "Matching processor has seen %1 video frames (which equals %2 audio frames) and %3 audio frames", + _video_frames, + video_frames_to_audio_frames (_video_frames, _sample_rate, _frames_per_second), + _audio_frames + ) + ); + + if (audio_short_by_frames < 0) { + + _log->log (String::compose ("%1 too many audio frames", -audio_short_by_frames)); + + /* We have seen 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 / _sample_rate); + + _log->log (String::compose ("Emitting %1 frames of black video", black_video_frames)); + + shared_ptr black (new CompactImage (_pixel_format.get(), _size.get())); + black->make_black (); + for (int i = 0; i < black_video_frames; ++i) { + Video (black, shared_ptr()); + } + + /* Now recompute our check value */ + audio_short_by_frames = video_frames_to_audio_frames (_video_frames, _sample_rate, _frames_per_second) - _audio_frames; + } + + if (audio_short_by_frames > 0) { + _log->log (String::compose ("Emitted %1 too few audio frames", audio_short_by_frames)); + shared_ptr b (new AudioBuffers (_channels.get(), audio_short_by_frames)); + b->make_silent (); + Audio (b); + _audio_frames += b->frames (); + } +} diff --git a/src/lib/matcher.h b/src/lib/matcher.h new file mode 100644 index 000000000..5f1a75ef9 --- /dev/null +++ b/src/lib/matcher.h @@ -0,0 +1,20 @@ +#include +#include "processor.h" + +class Matcher : public AudioVideoProcessor +{ +public: + Matcher (Log* log, int sample_rate, float frames_per_second); + void process_video (boost::shared_ptr i, boost::shared_ptr s); + void process_audio (boost::shared_ptr); + void process_end (); + +private: + int _sample_rate; + float _frames_per_second; + int _video_frames; + int64_t _audio_frames; + boost::optional _pixel_format; + boost::optional _size; + boost::optional _channels; +}; diff --git a/src/lib/processor.h b/src/lib/processor.h new file mode 100644 index 000000000..e99ff2d4d --- /dev/null +++ b/src/lib/processor.h @@ -0,0 +1,41 @@ +#ifndef DVDOMATIC_PROCESSOR_H +#define DVDOMATIC_PROCESSOR_H + +#include "video_source.h" +#include "video_sink.h" +#include "audio_source.h" +#include "audio_sink.h" + +class Log; + +class Processor +{ +public: + Processor (Log* log) + : _log (log) + {} + + virtual void process_begin () {} + virtual void process_end () {} + +protected: + Log* _log; +}; + +class AudioVideoProcessor : public Processor, public VideoSource, public VideoSink, public AudioSource, public AudioSink +{ +public: + AudioVideoProcessor (Log* log) + : Processor (log) + {} +}; + +class AudioProcessor : public Processor, public AudioSource, public AudioSink +{ +public: + AudioProcessor (Log* log) + : Processor (log) + {} +}; + +#endif diff --git a/src/lib/video_sink.h b/src/lib/video_sink.h new file mode 100644 index 000000000..a5c16ec7f --- /dev/null +++ b/src/lib/video_sink.h @@ -0,0 +1,20 @@ +#ifndef DVDOMATIC_VIDEO_SINK_H +#define DVDOMATIC_VIDEO_SINK_H + +#include +#include "util.h" + +class Subtitle; +class Image; + +class VideoSink +{ +public: + /** Call with a frame of video. + * @param i Video frame image. + * @param s A subtitle that should be on this frame, or 0. + */ + virtual void process_video (boost::shared_ptr i, boost::shared_ptr s) = 0; +}; + +#endif diff --git a/src/lib/video_source.cc b/src/lib/video_source.cc new file mode 100644 index 000000000..87b33026e --- /dev/null +++ b/src/lib/video_source.cc @@ -0,0 +1,11 @@ +#include "video_source.h" +#include "video_sink.h" + +using boost::shared_ptr; +using boost::bind; + +void +VideoSource::connect_video (shared_ptr s) +{ + Video.connect (bind (&VideoSink::process_video, s, _1, _2)); +} diff --git a/src/lib/video_source.h b/src/lib/video_source.h new file mode 100644 index 000000000..a93bd39d4 --- /dev/null +++ b/src/lib/video_source.h @@ -0,0 +1,25 @@ +#ifndef DVDOMATIC_VIDEO_SOURCE_H +#define DVDOMATIC_VIDEO_SOURCE_H + +#include +#include +#include "util.h" + +class VideoSink; +class Subtitle; +class Image; + +class VideoSource +{ +public: + + /** Emitted when a video frame is ready. + * First parameter is the frame within the source. + * Second parameter is either 0 or a subtitle that should be on this frame. + */ + boost::signals2::signal, boost::shared_ptr)> Video; + + void connect_video (boost::shared_ptr); +}; + +#endif -- 2.30.2