Tests pass again.
authorCarl Hetherington <cth@carlh.net>
Wed, 14 Nov 2012 20:04:15 +0000 (20:04 +0000)
committerCarl Hetherington <cth@carlh.net>
Wed, 14 Nov 2012 20:04:15 +0000 (20:04 +0000)
20 files changed:
src/lib/decoder.cc
src/lib/decoder.h
src/lib/ffmpeg_decoder.cc
src/lib/ffmpeg_decoder.h
src/lib/filter_graph.cc
src/lib/filter_graph.h
src/lib/gain.cc [new file with mode: 0644]
src/lib/gain.h [new file with mode: 0644]
src/lib/image.cc
src/lib/image.h
src/lib/imagemagick_decoder.cc
src/lib/processor.h
src/lib/tiff_decoder.cc
src/lib/transcoder.cc
src/lib/transcoder.h
src/lib/util.cc
src/lib/util.h
src/lib/wscript
test/metadata.ref
test/test.cc

index e91b5e19e739bffb39463ec9021298543a6698c0..8e1e4e3c59e791abe2fa494e05fe2b7f207620ae 100644 (file)
@@ -73,57 +73,19 @@ Decoder::go ()
        }
 }
 
-/** Called to tell the world that some audio data is ready
- *  @param audio Audio data.
- */
-void
-Decoder::process_audio (shared_ptr<AudioBuffers> audio)
-{
-       /* Maybe apply gain */
-       if (_film->audio_gain() != 0) {
-               float const linear_gain = pow (10, _film->audio_gain() / 20);
-               for (int i = 0; i < audio->channels(); ++i) {
-                       for (int j = 0; j < audio->frames(); ++j) {
-                               audio->data(i)[j] *= linear_gain;
-                       }
-               }
-       }
-
-       Audio (audio);
-}
-
 /** Called by subclasses to tell the world that some video data is ready.
  *  We do some post-processing / filtering then emit it for listeners.
  *  @param frame to decode; caller manages memory.
  */
 void
-Decoder::process_video (AVFrame const * frame)
+Decoder::emit_video (shared_ptr<Image> image)
 {
-       shared_ptr<FilterGraph> graph;
-
-       list<shared_ptr<FilterGraph> >::iterator i = _filter_graphs.begin();
-       while (i != _filter_graphs.end() && !(*i)->can_process (Size (frame->width, frame->height), (AVPixelFormat) frame->format)) {
-               ++i;
-       }
-
-       if (i == _filter_graphs.end ()) {
-               graph.reset (new FilterGraph (_film, this, _opt->apply_crop, Size (frame->width, frame->height), (AVPixelFormat) frame->format));
-               _filter_graphs.push_back (graph);
-               _film->log()->log (String::compose ("New graph for %1x%2, pixel format %3", frame->width, frame->height, frame->format));
-       } else {
-               graph = *i;
+       shared_ptr<Subtitle> sub;
+       if (_timed_subtitle && _timed_subtitle->displayed_at (double (video_frame()) / _film->frames_per_second())) {
+               sub = _timed_subtitle->subtitle ();
        }
 
-       list<shared_ptr<Image> > images = graph->process (frame);
-
-       for (list<shared_ptr<Image> >::iterator i = images.begin(); i != images.end(); ++i) {
-               shared_ptr<Subtitle> sub;
-               if (_timed_subtitle && _timed_subtitle->displayed_at (double (video_frame()) / _film->frames_per_second())) {
-                       sub = _timed_subtitle->subtitle ();
-               }
-
-               emit_video (*i, sub);
-       }
+       Video (image, sub);
 }
 
 void
@@ -149,7 +111,7 @@ Decoder::emit_video (shared_ptr<Image> image, shared_ptr<Subtitle> sub)
 }
 
 void
-Decoder::process_subtitle (shared_ptr<TimedSubtitle> s)
+Decoder::emit_subtitle (shared_ptr<TimedSubtitle> s)
 {
        _timed_subtitle = s;
        
index a458c348b04e7195aa890ec958058db53a6556cb..5bb5b574d5038d7b6686489ca0d5c688d17b1db2 100644 (file)
@@ -99,9 +99,8 @@ protected:
        
        virtual PixelFormat pixel_format () const = 0;
        
-       void process_video (AVFrame const *);
-       void process_audio (boost::shared_ptr<AudioBuffers>);
-       void process_subtitle (boost::shared_ptr<TimedSubtitle>);
+       void emit_video (boost::shared_ptr<Image>);
+       void emit_subtitle (boost::shared_ptr<TimedSubtitle>);
        void repeat_last_video ();
 
        /** our Film */
@@ -122,8 +121,6 @@ private:
 
        SourceFrame _video_frame;
 
-       std::list<boost::shared_ptr<FilterGraph> > _filter_graphs;
-
        boost::shared_ptr<TimedSubtitle> _timed_subtitle;
 
        boost::shared_ptr<Image> _last_image;
index 78d0c48c40f4b76bf56e4a73db1ff2807d3b81ab..3767d7c5fd0ce2b8d679600c93f0ed327e86d040 100644 (file)
@@ -47,12 +47,14 @@ extern "C" {
 #include "util.h"
 #include "log.h"
 #include "ffmpeg_decoder.h"
+#include "filter_graph.h"
 #include "subtitle.h"
 
 using std::cout;
 using std::string;
 using std::vector;
 using std::stringstream;
+using std::list;
 using boost::shared_ptr;
 using boost::optional;
 
@@ -223,7 +225,7 @@ FFmpegDecoder::pass ()
                int frame_finished;
 
                while (avcodec_decode_video2 (_video_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
-                       process_video (_frame);
+                       filter_and_emit_video (_frame);
                }
 
                if (_audio_stream && _opt->decode_audio && _film->use_content_audio()) {
@@ -233,7 +235,7 @@ FFmpegDecoder::pass ()
                                        );
 
                                assert (_audio_codec_context->channels == _film->audio_channels());
-                               process_audio (deinterleave_audio (_frame->data[0], data_size));
+                               Audio (deinterleave_audio (_frame->data[0], data_size));
                        }
                }
 
@@ -283,7 +285,7 @@ FFmpegDecoder::pass ()
 
                        if (delta > -one_frame) {
                                /* Process this frame */
-                               process_video (_frame);
+                               filter_and_emit_video (_frame);
                        } else {
                                /* Otherwise we are omitting a frame to keep things right */
                                _film->log()->log (String::compose ("Frame removed at %1s", out_pts_seconds));
@@ -326,7 +328,7 @@ FFmpegDecoder::pass ()
                                        if (s) {
                                                shared_ptr<AudioBuffers> audio (new AudioBuffers (_audio_stream.get().channels(), s));
                                                audio->make_silent ();
-                                               process_audio (audio);
+                                               Audio (audio);
                                        }
                                }
 
@@ -335,7 +337,7 @@ FFmpegDecoder::pass ()
                                        );
                                
                                assert (_audio_codec_context->channels == _film->audio_channels());
-                               process_audio (deinterleave_audio (_frame->data[0], data_size));
+                               Audio (deinterleave_audio (_frame->data[0], data_size));
                        }
                }
                        
@@ -348,9 +350,9 @@ FFmpegDecoder::pass ()
                           indicate that the previous subtitle should stop.
                        */
                        if (sub.num_rects > 0) {
-                               process_subtitle (shared_ptr<TimedSubtitle> (new TimedSubtitle (sub, _first_video.get())));
+                               emit_subtitle (shared_ptr<TimedSubtitle> (new TimedSubtitle (sub, _first_video.get())));
                        } else {
-                               process_subtitle (shared_ptr<TimedSubtitle> ());
+                               emit_subtitle (shared_ptr<TimedSubtitle> ());
                        }
                        avsubtitle_free (&sub);
                }
@@ -527,3 +529,28 @@ FFmpegDecoder::set_subtitle_stream (optional<SubtitleStream> s)
        Decoder::set_subtitle_stream (s);
        setup_subtitle ();
 }
+
+void
+FFmpegDecoder::filter_and_emit_video (AVFrame* frame)
+{
+       shared_ptr<FilterGraph> graph;
+
+       list<shared_ptr<FilterGraph> >::iterator i = _filter_graphs.begin();
+       while (i != _filter_graphs.end() && !(*i)->can_process (Size (frame->width, frame->height), (AVPixelFormat) frame->format)) {
+               ++i;
+       }
+
+       if (i == _filter_graphs.end ()) {
+               graph.reset (new FilterGraph (_film, this, _opt->apply_crop, Size (frame->width, frame->height), (AVPixelFormat) frame->format));
+               _filter_graphs.push_back (graph);
+               _film->log()->log (String::compose ("New graph for %1x%2, pixel format %3", frame->width, frame->height, frame->format));
+       } else {
+               graph = *i;
+       }
+
+       list<shared_ptr<Image> > images = graph->process (frame);
+
+       for (list<shared_ptr<Image> >::iterator i = images.begin(); i != images.end(); ++i) {
+               emit_video (*i);
+       }
+}
index 856ac0801fcbffc4067c596f4e1ee6f855ddee67..5c6f8ab2691c0bcaa7661859d651333c7c4d95ed 100644 (file)
@@ -58,6 +58,10 @@ public:
        /* Methods to query our input video */
        float frames_per_second () const;
        Size native_size () const;
+       int time_base_numerator () const;
+       int time_base_denominator () const;
+       int sample_aspect_ratio_numerator () const;
+       int sample_aspect_ratio_denominator () const;
 
        void set_audio_stream (boost::optional<AudioStream>);
        void set_subtitle_stream (boost::optional<SubtitleStream>);
@@ -66,13 +70,11 @@ private:
 
        bool pass ();
        PixelFormat pixel_format () const;
-       int time_base_numerator () const;
-       int time_base_denominator () const;
-       int sample_aspect_ratio_numerator () const;
-       int sample_aspect_ratio_denominator () const;
        AVSampleFormat audio_sample_format () const;
        int bytes_per_audio_sample () const;
 
+       void filter_and_emit_video (AVFrame *);
+
        void setup_general ();
        void setup_video ();
        void setup_audio ();
@@ -99,4 +101,6 @@ private:
 
        boost::optional<double> _first_video;
        boost::optional<double> _first_audio;
+
+       std::list<boost::shared_ptr<FilterGraph> > _filter_graphs;
 };
index 72bb8deb771107232bfbb1c198642a78b4d2a5af..aaa9e07baa9628929ec3a1c1a8a31de10376eb41 100644 (file)
@@ -28,42 +28,36 @@ extern "C" {
 #endif
 #include <libavformat/avio.h>
 }
-#include "film.h"
 #include "decoder.h"
 #include "filter_graph.h"
 #include "ffmpeg_compatibility.h"
 #include "filter.h"
 #include "exceptions.h"
 #include "image.h"
+#include "film.h"
+#include "ffmpeg_decoder.h"
 
 using std::stringstream;
 using std::string;
 using std::list;
 using boost::shared_ptr;
 
-FilterGraph::FilterGraph (shared_ptr<Film> film, Decoder* decoder, bool crop, Size s, AVPixelFormat p)
+FilterGraph::FilterGraph (shared_ptr<Film> film, FFmpegDecoder* decoder, bool crop, Size s, AVPixelFormat p)
        : _buffer_src_context (0)
        , _buffer_sink_context (0)
        , _size (s)
        , _pixel_format (p)
 {
-       stringstream fs;
-       Size size_after_crop;
-       
-       if (crop) {
-               size_after_crop = film->cropped_size (decoder->native_size ());
-               fs << crop_string (Position (film->crop().left, film->crop().top), size_after_crop);
-       } else {
-               size_after_crop = decoder->native_size ();
-               fs << crop_string (Position (0, 0), size_after_crop);
-       }
-
        string filters = Filter::ffmpeg_strings (film->filters()).first;
        if (!filters.empty ()) {
                filters += ",";
        }
 
-       filters += fs.str ();
+       if (crop) {
+               filters += crop_string (Position (film->crop().left, film->crop().top), film->cropped_size (decoder->native_size()));
+       } else {
+               filters += crop_string (Position (0, 0), decoder->native_size());
+       }
 
        avfilter_register_all ();
        
index 4ff10dece1a3dfe996076110dc3c41231eec1344..5c0c83d165d56eb68fe87ae329f7c8ff90476c73 100644 (file)
 
 #include "util.h"
 
-class Decoder;
 class Image;
-class Film;
+class VideoFilter;
+class FFmpegDecoder;
 
 class FilterGraph
 {
 public:
-       FilterGraph (boost::shared_ptr<Film> film, Decoder* decoder, bool crop, Size s, AVPixelFormat p);
+       FilterGraph (boost::shared_ptr<Film> film, FFmpegDecoder* decoder, bool crop, Size s, AVPixelFormat p);
 
        bool can_process (Size s, AVPixelFormat p) const;
        std::list<boost::shared_ptr<Image> > process (AVFrame const * frame);
diff --git a/src/lib/gain.cc b/src/lib/gain.cc
new file mode 100644 (file)
index 0000000..80d3b7c
--- /dev/null
@@ -0,0 +1,26 @@
+#include "gain.h"
+
+using boost::shared_ptr;
+
+/** @param gain gain in dB */
+Gain::Gain (Log* log, float gain)
+       : AudioProcessor (log)
+       , _gain (gain)
+{
+
+}
+
+void
+Gain::process_audio (shared_ptr<AudioBuffers> b)
+{
+       if (_gain != 0) {
+               float const linear_gain = pow (10, _gain / 20);
+               for (int i = 0; i < b->channels(); ++i) {
+                       for (int j = 0; j < b->frames(); ++j) {
+                               b->data(i)[j] *= linear_gain;
+                       }
+               }
+       }
+
+       Audio (b);
+}
diff --git a/src/lib/gain.h b/src/lib/gain.h
new file mode 100644 (file)
index 0000000..c1221ed
--- /dev/null
@@ -0,0 +1,12 @@
+#include "processor.h"
+
+class Gain : public AudioProcessor
+{
+public:
+       Gain (Log* log, float gain);
+
+       void process_audio (boost::shared_ptr<AudioBuffers>);
+
+private:
+       float _gain;
+};
index 05270954dd6309271efacf30bd00f8f6d4849f5f..4f818b739e14d262c1b97f307f1eb85acd19d8d5 100644 (file)
@@ -293,7 +293,7 @@ Image::write_to_socket (shared_ptr<Socket> socket) const
  *  @param p Pixel format.
  *  @param s Size in pixels.
  */
-SimpleImage::SimpleImage (AVPixelFormat p, Size s, function<int (int)> rounder)
+SimpleImage::SimpleImage (AVPixelFormat p, Size s, function<int (int, int const *)> stride_computer)
        : Image (p)
        , _size (s)
 {
@@ -329,7 +329,7 @@ SimpleImage::SimpleImage (AVPixelFormat p, Size s, function<int (int)> rounder)
        }
 
        for (int i = 0; i < components(); ++i) {
-               _stride[i] = rounder (_line_size[i]);
+               _stride[i] = stride_computer (i, _line_size);
                _data[i] = (uint8_t *) av_malloc (_stride[i] * lines (i));
        }
 }
@@ -371,19 +371,13 @@ SimpleImage::size () const
 }
 
 AlignedImage::AlignedImage (AVPixelFormat f, Size s)
-       : SimpleImage (f, s, boost::bind (round_up, _1, 32))
+       : SimpleImage (f, s, boost::bind (stride_round_up, _1, _2, 32))
 {
 
 }
 
-CompactImage::CompactImage (AVPixelFormat f, Size s)
-       : SimpleImage (f, s, boost::bind (round_up, _1, 1))
-{
-       setup_picture ();
-}
-
-CompactImage::CompactImage (shared_ptr<Image> im)
-       : SimpleImage (im->pixel_format(), im->size(), boost::bind (round_up, _1, 1))
+AlignedImage::AlignedImage (shared_ptr<Image> im)
+       : SimpleImage (im->pixel_format(), im->size(), boost::bind (stride_round_up, _1, _2, 1))
 {
        assert (components() == im->components());
 
@@ -400,16 +394,31 @@ CompactImage::CompactImage (shared_ptr<Image> im)
                        o += im->stride()[c];
                }
        }
+}
+
+CompactImage::CompactImage (AVPixelFormat f, Size s)
+       : SimpleImage (f, s, boost::bind (stride_round_up, _1, _2, 1))
+{
 
-       setup_picture ();
 }
 
-void
-CompactImage::setup_picture ()
+CompactImage::CompactImage (shared_ptr<Image> im)
+       : SimpleImage (im->pixel_format(), im->size(), boost::bind (stride_round_up, _1, _2, 1))
 {
+       assert (components() == im->components());
+
        for (int c = 0; c < components(); ++c) {
-               _picture.data[c] = data()[c];
-               _picture.linesize[c] = line_size()[c];
+
+               assert (line_size()[c] == im->line_size()[c]);
+
+               uint8_t* t = data()[c];
+               uint8_t* o = im->data()[c];
+               
+               for (int y = 0; y < lines(c); ++y) {
+                       memcpy (t, o, line_size()[c]);
+                       t += stride()[c];
+                       o += im->stride()[c];
+               }
        }
 }
 
index bb4a32319e0643f4047637a9fc9c3752484a7f20..69f3a883722b3f10a4c8e609ee4bf35834b8a01e 100644 (file)
@@ -111,7 +111,7 @@ private:
 class SimpleImage : public Image
 {
 public:
-       SimpleImage (AVPixelFormat, Size, boost::function<int (int)> rounder);
+       SimpleImage (AVPixelFormat, Size, boost::function<int (int, int const *)> rounder);
        ~SimpleImage ();
 
        uint8_t ** data () const;
@@ -131,6 +131,7 @@ class AlignedImage : public SimpleImage
 {
 public:
        AlignedImage (AVPixelFormat, Size);
+       AlignedImage (boost::shared_ptr<Image>);
 };
 
 class CompactImage : public SimpleImage
@@ -138,15 +139,6 @@ class CompactImage : public SimpleImage
 public:
        CompactImage (AVPixelFormat, Size);
        CompactImage (boost::shared_ptr<Image>);
-
-       AVPicture const * picture () const {
-               return &_picture;
-       }
-
-private:
-       void setup_picture ();
-       
-       AVPicture _picture;
 };
 
 #endif
index fd4e5b18df91aa00aeb4ea638f13c6258d5cb657..53e1db879e16ea94a45b4e64860f37fc1c92869b 100644 (file)
@@ -23,8 +23,8 @@
 #include "image.h"
 #include "film.h"
 
-using namespace std;
-using namespace boost;
+using std::cout;
+using boost::shared_ptr;
 
 ImageMagickDecoder::ImageMagickDecoder (
        boost::shared_ptr<Film> f, boost::shared_ptr<const Options> o, Job* j)
@@ -50,9 +50,9 @@ ImageMagickDecoder::pass ()
        }
 
        Size size = native_size ();
-       CompactImage image (PIX_FMT_RGB24, size);
+       shared_ptr<CompactImage> image (new CompactImage (PIX_FMT_RGB24, size));
 
-       uint8_t* p = image.data()[0];
+       uint8_t* p = image->data()[0];
        for (int y = 0; y < size.height; ++y) {
                for (int x = 0; x < size.width; ++x) {
                        Magick::Color c = _magick_image->pixelColor (x, y);
@@ -63,7 +63,7 @@ ImageMagickDecoder::pass ()
 
        }
        
-       process_video ((AVFrame const *) image.picture());
+       emit_video (image);
 
        _done = true;
        return false;
index e99ff2d4dd2cde6c45421dccfb0f8fe7b1b023b5..f7785c34683db74144d9d7b9fd173e8acd28e825 100644 (file)
@@ -38,4 +38,12 @@ public:
        {}
 };
 
+class VideoProcessor : public Processor, public VideoSource, public VideoSink
+{
+public:
+       VideoProcessor (Log* log)
+               : Processor (log)
+       {}
+};
+
 #endif
index 7e9bda139a43f9967d4556fee975f6f6d36bd2d7..a58ea99748c97fa2e1d68223b9c4655a76f790a3 100644 (file)
@@ -38,8 +38,10 @@ extern "C" {
 #include "options.h"
 #include "film.h"
 
-using namespace std;
-using namespace boost;
+using std::cout;
+using std::string;
+using std::stringstream;
+using boost::shared_ptr;
 
 /** @param f Our Film.
  *  @param o Options.
@@ -50,17 +52,17 @@ TIFFDecoder::TIFFDecoder (boost::shared_ptr<Film> f, boost::shared_ptr<const Opt
 {
        string const dir = _film->content_path ();
        
-       if (!filesystem::is_directory (dir)) {
+       if (!boost::filesystem::is_directory (dir)) {
                throw DecodeError ("TIFF content must be in a directory");
        }
 
-       for (filesystem::directory_iterator i = filesystem::directory_iterator (dir); i != filesystem::directory_iterator(); ++i) {
+       for (boost::filesystem::directory_iterator i = boost::filesystem::directory_iterator (dir); i != boost::filesystem::directory_iterator(); ++i) {
                /* Aah, the sweet smell of progress */
 #if BOOST_FILESYSTEM_VERSION == 3
-               string const ext = filesystem::path(*i).extension().string();
-               string const l = filesystem::path(*i).leaf().generic_string();
+               string const ext = boost::filesystem::path(*i).extension().string();
+               string const l = boost::filesystem::path(*i).leaf().generic_string();
 #else
-               string const ext = filesystem::path(*i).extension();
+               string const ext = boost::filesystem::path(*i).extension();
                string const l = i->leaf ();
 #endif
                if (ext == ".tif" || ext == ".tiff") {
@@ -71,7 +73,6 @@ TIFFDecoder::TIFFDecoder (boost::shared_ptr<Film> f, boost::shared_ptr<const Opt
        _files.sort ();
 
        _iter = _files.begin ();
-
 }
 
 float
@@ -147,9 +148,9 @@ TIFFDecoder::pass ()
                throw DecodeError ("could not read TIFF data");
        }
 
-       CompactImage image (PIX_FMT_RGB24, Size (width, height));
+       shared_ptr<CompactImage> image (new CompactImage (PIX_FMT_RGB24, Size (width, height)));
 
-       uint8_t* p = image.data()[0];
+       uint8_t* p = image->data()[0];
        for (uint32_t y = 0; y < height; ++y) {
                for (uint32_t x = 0; x < width; ++x) {
                        uint32_t const i = (height - y - 1) * width + x;
@@ -162,7 +163,7 @@ TIFFDecoder::pass ()
        _TIFFfree (raster);
        TIFFClose (t);
 
-       process_video ((AVFrame const *) image.picture ());
+       emit_video (image);
 
        ++_iter;
        return false;
index f53fc4001204ec09a74a75ecb74aed55a9495e2d..01f54be3fa1381d1ef14a1f3c88520812f3b2f24 100644 (file)
@@ -32,6 +32,8 @@
 #include "film.h"
 #include "matcher.h"
 #include "delay_line.h"
+#include "options.h"
+#include "gain.h"
 
 using std::string;
 using boost::shared_ptr;
@@ -49,21 +51,30 @@ 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));
+       if (f->audio_stream()) {
+               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));
+               _gain.reset (new Gain (f->log(), f->audio_gain()));
+       }
 
        /* 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->connect_video (_matcher);
-       _matcher->connect_video (_encoder);
-
-       _decoder->connect_audio (_delay_line);
-       _delay_line->connect_audio (_matcher);
-       _matcher->connect_audio (_delay_line);
+       if (_matcher) {
+               _decoder->connect_video (_matcher);
+               _matcher->connect_video (_encoder);
+       } else {
+               _decoder->connect_video (_encoder);
+       }
+       
+       if (_matcher && _delay_line) {
+               _decoder->connect_audio (_delay_line);
+               _delay_line->connect_audio (_matcher);
+               _matcher->connect_audio (_gain);
+               _gain->connect_audio (_encoder);
+       }
 }
 
 /** Run the decoder, passing its output to the encoder, until the decoder
index d5597ad0ecc4d653826f64afc12aaa97d447f00c..324a72037752f5bef2f1f07584996c66be803c7a 100644 (file)
@@ -31,6 +31,8 @@ class Job;
 class Encoder;
 class FilmState;
 class Matcher;
+class VideoFilter;
+class Gain;
 
 /** @class Transcoder
  *  @brief A class which takes a FilmState and some Options, then uses those to transcode a Film.
@@ -59,4 +61,5 @@ protected:
        boost::shared_ptr<Decoder> _decoder;
        boost::shared_ptr<Matcher> _matcher;
        boost::shared_ptr<DelayLine> _delay_line;
+       boost::shared_ptr<Gain> _gain;
 };
index 2194418653b96d4a753e54218bdf3ce3dc1e98e5..5e82650a56c6e29a5c00ff988cf1c493fe3e3b1b 100644 (file)
@@ -620,12 +620,18 @@ Rect::intersection (Rect const & other) const
  */
 
 int
-round_up (int a, int t)
+stride_round_up (int c, int const * stride, int t)
 {
-       a += (t - 1);
+       int const a = stride[c] + (t - 1);
        return a - (a % t);
 }
 
+int
+stride_lookup (int c, int const * stride)
+{
+       return stride[c];
+}
+
 /** Read a sequence of key / value pairs from a text stream;
  *  the keys are the first words on the line, and the values are
  *  the remainder of the line following the key.  Lines beginning
index 577b9ba1bbf22c0c1a225f3de6b3692529de0360..bb68b627355cf1604aada40a2cd1d51460802e0f 100644 (file)
@@ -170,7 +170,8 @@ extern std::string crop_string (Position, Size);
 extern int dcp_audio_sample_rate (int);
 extern DCPFrameRate dcp_frame_rate (float);
 extern std::string colour_lut_index_to_name (int index);
-extern int round_up (int, int);
+extern int stride_round_up (int, int const *, int);
+extern int stride_lookup (int c, int const * stride);
 extern std::multimap<std::string, std::string> read_key_value (std::istream& s);
 extern int get_required_int (std::multimap<std::string, std::string> const & kv, std::string k);
 extern float get_required_float (std::multimap<std::string, std::string> const & kv, std::string k);
index 4fc83909768a41074accbbeff90055c13b55a490..ef4011c5f7ccab07dd42266e05ff6bcbc8b62746 100644 (file)
@@ -29,6 +29,7 @@ def build(bld):
                 film.cc
                 filter.cc
                 format.cc
+                 gain.cc
                  image.cc
                  imagemagick_decoder.cc
                  imagemagick_encoder.cc
index 8276d59e2812dacadb74c0c3948804dd765d3d0a..af6e9fddbffdeb4ac34af1092abb7ee039d2b9ee 100644 (file)
@@ -13,11 +13,10 @@ scaler bicubic
 dcp_trim_start 42
 dcp_trim_end 99
 dcp_ab 1
-selected_audio_stream -1
+use_content_audio 1
 audio_gain 0
 audio_delay 0
 still_duration 10
-selected_subtitle_stream -1
 with_subtitles 0
 subtitle_offset 0
 subtitle_scale 1
@@ -31,7 +30,5 @@ package_type
 width 0
 height 0
 length 0
-audio_sample_rate 0
 content_digest 
-has_subtitles 0
 frames_per_second 0
index 4235012967f719c3aa8f0dc151e872be4fad5adb..89a56872b38499c1608a7e3254b8bdf8d4a2392c 100644 (file)
@@ -520,11 +520,12 @@ BOOST_AUTO_TEST_CASE (job_manager_test)
 
 BOOST_AUTO_TEST_CASE (stream_test)
 {
-       AudioStream a ("4 9 hello there world");
+       AudioStream a ("4 44100 1 hello there world");
        BOOST_CHECK_EQUAL (a.id(), 4);
-       BOOST_CHECK_EQUAL (a.channels(), 9);
+       BOOST_CHECK_EQUAL (a.sample_rate(), 44100);
+       BOOST_CHECK_EQUAL (a.channel_layout(), 1);
        BOOST_CHECK_EQUAL (a.name(), "hello there world");
-       BOOST_CHECK_EQUAL (a.to_string(), "4 9 hello there world");
+       BOOST_CHECK_EQUAL (a.to_string(), "4 44100 1 hello there world");
 
        SubtitleStream s ("5 a b c");
        BOOST_CHECK_EQUAL (s.id(), 5);