Split audio; builds.
authorCarl Hetherington <cth@carlh.net>
Thu, 14 Apr 2016 00:01:28 +0000 (01:01 +0100)
committerCarl Hetherington <cth@carlh.net>
Wed, 18 May 2016 10:50:29 +0000 (11:50 +0100)
64 files changed:
src/lib/analyse_audio_job.cc
src/lib/audio_analysis.cc
src/lib/audio_content.cc
src/lib/audio_content.h
src/lib/audio_decoder.cc
src/lib/audio_decoder.h
src/lib/audio_decoder_stream.cc
src/lib/audio_decoder_stream.h
src/lib/audio_stream.h
src/lib/content.cc
src/lib/content.h
src/lib/dcp_content.cc
src/lib/dcp_content.h
src/lib/dcp_decoder.cc
src/lib/dcp_subtitle_content.cc
src/lib/dcp_subtitle_content.h
src/lib/ffmpeg_content.cc
src/lib/ffmpeg_content.h
src/lib/ffmpeg_decoder.cc
src/lib/film.cc
src/lib/player.cc
src/lib/playlist.cc
src/lib/sndfile_content.cc
src/lib/sndfile_content.h
src/lib/sndfile_decoder.cc
src/lib/sndfile_decoder.h
src/lib/subtitle_content.cc
src/lib/subtitle_content.h
src/lib/text_subtitle_content.cc
src/lib/text_subtitle_content.h
src/lib/transcoder.cc
src/lib/types.h
src/lib/video_content.cc
src/tools/dcpomatic_cli.cc
src/wx/audio_dialog.cc
src/wx/audio_dialog.h
src/wx/audio_panel.cc
src/wx/content_menu.cc
src/wx/content_panel.cc
src/wx/content_panel.h
src/wx/content_widget.h
src/wx/dcp_panel.cc
src/wx/hints_dialog.cc
src/wx/timeline.cc
src/wx/timing_panel.cc
src/wx/video_panel.cc
test/audio_analysis_test.cc
test/audio_decoder_test.cc
test/audio_delay_test.cc
test/dcp_subtitle_test.cc
test/frame_rate_test.cc
test/isdcf_name_test.cc
test/recover_test.cc
test/reels_test.cc
test/repeat_frame_test.cc
test/scaling_test.cc
test/seek_zero_test.cc
test/skip_frame_test.cc
test/srt_subtitle_test.cc
test/threed_test.cc
test/time_calculation_test.cc
test/video_content_scale_test.cc
test/video_decoder_fill_test.cc
test/xml_subtitle_test.cc

index 7a1a993..9a24a91 100644 (file)
@@ -106,7 +106,7 @@ AnalyseAudioJob::run ()
 
        bool has_any_audio = false;
        BOOST_FOREACH (shared_ptr<Content> c, _playlist->content ()) {
-               if (dynamic_pointer_cast<AudioContent> (c)) {
+               if (c->audio) {
                        has_any_audio = true;
                }
        }
@@ -145,7 +145,7 @@ AnalyseAudioJob::run ()
                /* If there was only one piece of content in this analysis we may later need to know what its
                   gain was when we analysed it.
                */
-               shared_ptr<const AudioContent> ac = dynamic_pointer_cast<const AudioContent> (_playlist->content().front ());
+               shared_ptr<const AudioContent> ac = _playlist->content().front()->audio;
                DCPOMATIC_ASSERT (ac);
                _analysis->set_analysis_gain (ac->audio_gain ());
        }
index 03f35d8..d99b01c 100644 (file)
@@ -153,9 +153,8 @@ AudioAnalysis::gain_correction (shared_ptr<const Playlist> playlist)
                   we know that content's gain when the analysis was run.  Hence we can work out
                   what correction is now needed to make it look `right'.
                */
-               shared_ptr<const AudioContent> ac = dynamic_pointer_cast<const AudioContent> (playlist->content().front ());
-               DCPOMATIC_ASSERT (ac);
-               return ac->audio_gain() - analysis_gain().get ();
+               DCPOMATIC_ASSERT (playlist->content().front()->audio);
+               return playlist->content().front()->audio->audio_gain() - analysis_gain().get ();
        }
 
        return 0.0f;
index bd4bb56..2832e25 100644 (file)
@@ -49,52 +49,34 @@ int const AudioContentProperty::AUDIO_GAIN = 201;
 int const AudioContentProperty::AUDIO_DELAY = 202;
 int const AudioContentProperty::AUDIO_VIDEO_FRAME_RATE = 203;
 
-AudioContent::AudioContent (shared_ptr<const Film> film)
-       : Content (film)
+AudioContent::AudioContent (Content* parent, shared_ptr<const Film> film)
+       : ContentPart (parent, film)
        , _audio_gain (0)
        , _audio_delay (Config::instance()->default_audio_delay ())
 {
 
 }
 
-AudioContent::AudioContent (shared_ptr<const Film> film, DCPTime s)
-       : Content (film, s)
-       , _audio_gain (0)
-       , _audio_delay (Config::instance()->default_audio_delay ())
-{
-
-}
-
-AudioContent::AudioContent (shared_ptr<const Film> film, boost::filesystem::path p)
-       : Content (film, p)
-       , _audio_gain (0)
-       , _audio_delay (Config::instance()->default_audio_delay ())
-{
-
-}
-
-AudioContent::AudioContent (shared_ptr<const Film> film, cxml::ConstNodePtr node)
-       : Content (film, node)
+AudioContent::AudioContent (Content* parent, shared_ptr<const Film> film, cxml::ConstNodePtr node)
+       : ContentPart (parent, film)
 {
        _audio_gain = node->number_child<double> ("AudioGain");
        _audio_delay = node->number_child<int> ("AudioDelay");
        _audio_video_frame_rate = node->optional_number_child<double> ("AudioVideoFrameRate");
 }
 
-AudioContent::AudioContent (shared_ptr<const Film> film, vector<shared_ptr<Content> > c)
-       : Content (film, c)
+AudioContent::AudioContent (Content* parent, shared_ptr<const Film> film, vector<shared_ptr<Content> > c)
+       : ContentPart (parent, film)
 {
-       shared_ptr<AudioContent> ref = dynamic_pointer_cast<AudioContent> (c[0]);
+       shared_ptr<AudioContent> ref = c[0]->audio;
        DCPOMATIC_ASSERT (ref);
 
-       for (size_t i = 0; i < c.size(); ++i) {
-               shared_ptr<AudioContent> ac = dynamic_pointer_cast<AudioContent> (c[i]);
-
-               if (ac->audio_gain() != ref->audio_gain()) {
+       for (size_t i = 1; i < c.size(); ++i) {
+               if (c[i]->audio->audio_gain() != ref->audio_gain()) {
                        throw JoinError (_("Content to be joined must have the same audio gain."));
                }
 
-               if (ac->audio_delay() != ref->audio_delay()) {
+               if (c[i]->audio->audio_delay() != ref->audio_delay()) {
                        throw JoinError (_("Content to be joined must have the same audio delay."));
                }
 
@@ -107,6 +89,7 @@ AudioContent::AudioContent (shared_ptr<const Film> film, vector<shared_ptr<Conte
        _audio_delay = ref->audio_delay ();
        /* Preserve the optional<> part of this */
        _audio_video_frame_rate = ref->_audio_video_frame_rate;
+       _streams = ref->streams ();
 }
 
 void
@@ -120,34 +103,23 @@ AudioContent::as_xml (xmlpp::Node* node) const
        }
 }
 
-
 void
 AudioContent::set_audio_gain (double g)
 {
-       {
-               boost::mutex::scoped_lock lm (_mutex);
-               _audio_gain = g;
-       }
-
-       signal_changed (AudioContentProperty::AUDIO_GAIN);
+       maybe_set (_audio_gain, g, AudioContentProperty::AUDIO_GAIN);
 }
 
 void
 AudioContent::set_audio_delay (int d)
 {
-       {
-               boost::mutex::scoped_lock lm (_mutex);
-               _audio_delay = d;
-       }
-
-       signal_changed (AudioContentProperty::AUDIO_DELAY);
+       maybe_set (_audio_delay, d, AudioContentProperty::AUDIO_DELAY);
 }
 
 string
 AudioContent::technical_summary () const
 {
        string s = "audio :";
-       BOOST_FOREACH (AudioStreamPtr i, audio_streams ()) {
+       BOOST_FOREACH (AudioStreamPtr i, streams ()) {
                s += String::compose ("stream channels %1 rate %2", i->channels(), i->frame_rate());
        }
 
@@ -158,7 +130,7 @@ void
 AudioContent::set_audio_mapping (AudioMapping mapping)
 {
        int c = 0;
-       BOOST_FOREACH (AudioStreamPtr i, audio_streams ()) {
+       BOOST_FOREACH (AudioStreamPtr i, streams ()) {
                AudioMapping stream_mapping (i->channels (), MAX_DCP_AUDIO_CHANNELS);
                for (int j = 0; j < i->channels(); ++j) {
                        for (int k = 0; k < MAX_DCP_AUDIO_CHANNELS; ++k) {
@@ -169,14 +141,14 @@ AudioContent::set_audio_mapping (AudioMapping mapping)
                i->set_mapping (stream_mapping);
        }
 
-       signal_changed (AudioContentProperty::AUDIO_STREAMS);
+       _parent->signal_changed (AudioContentProperty::AUDIO_STREAMS);
 }
 
 AudioMapping
 AudioContent::audio_mapping () const
 {
        int channels = 0;
-       BOOST_FOREACH (AudioStreamPtr i, audio_streams ()) {
+       BOOST_FOREACH (AudioStreamPtr i, streams ()) {
                channels += i->channels ();
        }
 
@@ -185,7 +157,7 @@ AudioContent::audio_mapping () const
 
        int c = 0;
        int s = 0;
-       BOOST_FOREACH (AudioStreamPtr i, audio_streams ()) {
+       BOOST_FOREACH (AudioStreamPtr i, streams ()) {
                AudioMapping mapping = i->mapping ();
                for (int j = 0; j < mapping.input_channels(); ++j) {
                        for (int k = 0; k < MAX_DCP_AUDIO_CHANNELS; ++k) {
@@ -210,7 +182,9 @@ AudioContent::resampled_audio_frame_rate () const
        /* Resample to a DCI-approved sample rate */
        double t = has_rate_above_48k() ? 96000 : 48000;
 
-       FrameRateChange frc (audio_video_frame_rate(), film()->video_frame_rate());
+       shared_ptr<const Film> film = _film.lock ();
+       DCPOMATIC_ASSERT (film);
+       FrameRateChange frc (audio_video_frame_rate(), film->video_frame_rate());
 
        /* Compensate if the DCP is being run at a different frame rate
           to the source; that is, if the video is run such that it will
@@ -227,8 +201,7 @@ AudioContent::resampled_audio_frame_rate () const
 string
 AudioContent::processing_description () const
 {
-       vector<AudioStreamPtr> streams = audio_streams ();
-       if (streams.empty ()) {
+       if (streams().empty ()) {
                return "";
        }
 
@@ -244,7 +217,7 @@ AudioContent::processing_description () const
        bool same = true;
 
        optional<int> common_frame_rate;
-       BOOST_FOREACH (AudioStreamPtr i, streams) {
+       BOOST_FOREACH (AudioStreamPtr i, streams()) {
                if (i->frame_rate() != resampled_audio_frame_rate()) {
                        resampled = true;
                } else {
@@ -280,7 +253,7 @@ AudioContent::processing_description () const
 bool
 AudioContent::has_rate_above_48k () const
 {
-       BOOST_FOREACH (AudioStreamPtr i, audio_streams ()) {
+       BOOST_FOREACH (AudioStreamPtr i, streams ()) {
                if (i->frame_rate() > 48000) {
                        return true;
                }
@@ -296,7 +269,7 @@ AudioContent::audio_channel_names () const
        vector<string> n;
 
        int t = 1;
-       BOOST_FOREACH (AudioStreamPtr i, audio_streams ()) {
+       BOOST_FOREACH (AudioStreamPtr i, streams ()) {
                for (int j = 0; j < i->channels(); ++j) {
                        n.push_back (String::compose ("%1:%2", t, j + 1));
                }
@@ -310,8 +283,8 @@ void
 AudioContent::add_properties (list<UserProperty>& p) const
 {
        shared_ptr<const AudioStream> stream;
-       if (audio_streams().size() == 1) {
-               stream = audio_streams().front ();
+       if (streams().size() == 1) {
+               stream = streams().front ();
        }
 
        if (stream) {
@@ -319,8 +292,11 @@ AudioContent::add_properties (list<UserProperty>& p) const
                p.push_back (UserProperty (_("Audio"), _("Content audio frame rate"), stream->frame_rate(), _("Hz")));
        }
 
-       FrameRateChange const frc (audio_video_frame_rate(), film()->video_frame_rate());
-       ContentTime const c (full_length(), frc);
+       shared_ptr<const Film> film = _film.lock ();
+       DCPOMATIC_ASSERT (film);
+
+       FrameRateChange const frc (audio_video_frame_rate(), film->video_frame_rate());
+       ContentTime const c (_parent->full_length(), frc);
 
        p.push_back (
                UserProperty (_("Length"), _("Full length in video frames at content rate"), c.frames_round(frc.source))
@@ -376,3 +352,44 @@ AudioContent::audio_video_frame_rate () const
        */
        return film()->active_frame_rate_change(position()).source;
 }
+
+AudioContent::set_streams (vector<AudioStreamPtr> streams)
+{
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               _streams = streams;
+       }
+
+       _parent->signal_changed (AudioContentProperty::AUDIO_STREAMS);
+}
+
+AudioStreamPtr
+AudioContent::stream () const
+{
+       boost::mutex::scoped_lock lm (_mutex);
+       DCPOMATIC_ASSERT (_streams.size() == 1);
+       return _streams.front ();
+}
+
+void
+AudioContent::add_stream (AudioStreamPtr stream)
+{
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               _streams.push_back (stream);
+       }
+
+       _parent->signal_changed (AudioContentProperty::AUDIO_STREAMS);
+}
+
+void
+AudioContent::set_stream (AudioStreamPtr stream)
+{
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               _streams.clear ();
+               _streams.push_back (stream);
+       }
+
+       _parent->signal_changed (AudioContentProperty::AUDIO_STREAMS);
+}
index ac91da5..3aa9678 100644 (file)
@@ -24,7 +24,7 @@
 #ifndef DCPOMATIC_AUDIO_CONTENT_H
 #define DCPOMATIC_AUDIO_CONTENT_H
 
-#include "content.h"
+#include "content_part.h"
 #include "audio_stream.h"
 #include "audio_mapping.h"
 
@@ -40,23 +40,16 @@ public:
        static int const AUDIO_VIDEO_FRAME_RATE;
 };
 
-/** @class AudioContent
- *  @brief Parent class for content which may contain audio data.
- */
-class AudioContent : public virtual Content
+class AudioContent : public ContentPart
 {
 public:
-       AudioContent (boost::shared_ptr<const Film>);
-       AudioContent (boost::shared_ptr<const Film>, DCPTime);
-       AudioContent (boost::shared_ptr<const Film>, boost::filesystem::path);
-       AudioContent (boost::shared_ptr<const Film>, cxml::ConstNodePtr);
-       AudioContent (boost::shared_ptr<const Film>, std::vector<boost::shared_ptr<Content> >);
+       AudioContent (Content* parent, boost::shared_ptr<const Film>);
+       AudioContent (Content* parent, boost::shared_ptr<const Film>, cxml::ConstNodePtr);
+       AudioContent (Content* parent, boost::shared_ptr<const Film>, std::vector<boost::shared_ptr<Content> >);
 
        void as_xml (xmlpp::Node *) const;
        std::string technical_summary () const;
 
-       virtual std::vector<AudioStreamPtr> audio_streams () const = 0;
-
        AudioMapping audio_mapping () const;
        void set_audio_mapping (AudioMapping);
        int resampled_audio_frame_rate () const;
@@ -81,16 +74,26 @@ public:
 
        std::string processing_description () const;
 
-protected:
+       std::vector<AudioStreamPtr> streams () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _streams;
+       }
+
+       void add_stream (AudioStreamPtr stream);
+       void set_stream (AudioStreamPtr stream);
+       void set_streams (std::vector<AudioStreamPtr> streams);
+       AudioStreamPtr stream () const;
 
        void add_properties (std::list<UserProperty> &) const;
 
 private:
+
        /** Gain to apply to audio in dB */
        double _audio_gain;
        /** Delay to apply to audio (positive moves audio later) in milliseconds */
        int _audio_delay;
        boost::optional<double> _audio_video_frame_rate;
+       std::vector<AudioStreamPtr> _streams;
 };
 
 #endif
index 2944357..705fdbe 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -30,13 +30,13 @@ using std::cout;
 using std::map;
 using boost::shared_ptr;
 
-AudioDecoder::AudioDecoder (shared_ptr<const AudioContent> content, bool fast)
+AudioDecoder::AudioDecoder (shared_ptr<const AudioContent> content, bool fast, shared_ptr<Log> log)
        : _audio_content (content)
        , _ignore_audio (false)
        , _fast (fast)
 {
-       BOOST_FOREACH (AudioStreamPtr i, content->audio_streams ()) {
-               _streams[i] = shared_ptr<AudioDecoderStream> (new AudioDecoderStream (_audio_content, i, this));
+       BOOST_FOREACH (AudioStreamPtr i, content->streams ()) {
+               _streams[i] = shared_ptr<AudioDecoderStream> (new AudioDecoderStream (_audio_content, i, this, log));
        }
 }
 
index 716b379..679cdd5 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -32,6 +32,7 @@
 class AudioBuffers;
 class AudioContent;
 class AudioDecoderStream;
+class Log;
 
 /** @class AudioDecoder.
  *  @brief Parent class for audio decoders.
@@ -39,7 +40,7 @@ class AudioDecoderStream;
 class AudioDecoder : public virtual Decoder, public boost::enable_shared_from_this<AudioDecoder>
 {
 public:
-       AudioDecoder (boost::shared_ptr<const AudioContent>, bool fast);
+       AudioDecoder (boost::shared_ptr<const AudioContent>, bool fast, boost::shared_ptr<Log> log);
 
        boost::shared_ptr<const AudioContent> audio_content () const {
                return _audio_content;
index cb03722..7037d9f 100644 (file)
@@ -39,10 +39,11 @@ using std::max;
 using boost::optional;
 using boost::shared_ptr;
 
-AudioDecoderStream::AudioDecoderStream (shared_ptr<const AudioContent> content, AudioStreamPtr stream, AudioDecoder* decoder)
+AudioDecoderStream::AudioDecoderStream (shared_ptr<const AudioContent> content, AudioStreamPtr stream, AudioDecoder* decoder, shared_ptr<Log> log)
        : _content (content)
        , _stream (stream)
        , _decoder (decoder)
+       , _log (log)
 {
        if (content->resampled_audio_frame_rate() != _stream->frame_rate() && _stream->channels() > 0) {
                _resampler.reset (new Resampler (_stream->frame_rate(), content->resampled_audio_frame_rate(), _stream->channels (), decoder->fast ()));
@@ -62,7 +63,7 @@ AudioDecoderStream::get (Frame frame, Frame length, bool accurate)
 {
        shared_ptr<ContentAudio> dec;
 
-       _content->film()->log()->log (String::compose ("-> ADS has request for %1 %2", frame, length), LogEntry::TYPE_DEBUG_DECODE);
+       _log->log (String::compose ("-> ADS has request for %1 %2", frame, length), LogEntry::TYPE_DEBUG_DECODE);
 
        Frame const end = frame + length - 1;
 
@@ -93,7 +94,7 @@ AudioDecoderStream::get (Frame frame, Frame length, bool accurate)
 
                decoded_offset = frame - _decoded.frame;
 
-               _content->film()->log()->log (
+               _log->log (
                        String::compose ("Accurate ADS::get has offset %1 from request %2 and available %3", decoded_offset, frame, _decoded.frame),
                        LogEntry::TYPE_DEBUG_DECODE
                        );
@@ -141,7 +142,7 @@ AudioDecoderStream::get (Frame frame, Frame length, bool accurate)
 void
 AudioDecoderStream::audio (shared_ptr<const AudioBuffers> data, ContentTime time)
 {
-       _content->film()->log()->log (String::compose ("ADS receives %1 %2", time, data->frames ()), LogEntry::TYPE_DEBUG_DECODE);
+       _log->log (String::compose ("ADS receives %1 %2", time, data->frames ()), LogEntry::TYPE_DEBUG_DECODE);
 
        if (_resampler) {
                data = _resampler->run (data);
index 3503a46..90269a0 100644 (file)
 class AudioContent;
 class AudioDecoder;
 class Resampler;
+class Log;
 
 class AudioDecoderStream
 {
 public:
-       AudioDecoderStream (boost::shared_ptr<const AudioContent>, AudioStreamPtr, AudioDecoder* decoder);
+       AudioDecoderStream (boost::shared_ptr<const AudioContent>, AudioStreamPtr, AudioDecoder* decoder, boost::shared_ptr<Log> log);
 
        ContentAudio get (Frame time, Frame length, bool accurate);
        void audio (boost::shared_ptr<const AudioBuffers>, ContentTime);
@@ -47,6 +48,7 @@ private:
        boost::shared_ptr<const AudioContent> _content;
        AudioStreamPtr _stream;
        AudioDecoder* _decoder;
+       boost::shared_ptr<Log> _log;
        boost::shared_ptr<Resampler> _resampler;
        boost::optional<Frame> _position;
        /** Currently-available decoded audio data */
index 506a3c0..8d05df2 100644 (file)
@@ -30,6 +30,7 @@ class AudioStream
 public:
        AudioStream (int frame_rate, int channels);
        AudioStream (int frame_rate, AudioMapping mapping);
+       virtual ~AudioStream () {}
 
        void set_mapping (AudioMapping mapping);
 
index 28103e9..499f90d 100644 (file)
@@ -155,6 +155,7 @@ Content::examine (shared_ptr<Job> job)
 void
 Content::signal_changed (int p)
 {
+       changed (p);
        emit (boost::bind (boost::ref (Changed), shared_from_this (), p, _change_signals_frequent));
 }
 
index f488962..60dd89b 100644 (file)
@@ -93,6 +93,8 @@ public:
         */
        virtual std::list<DCPTime> reel_split_points () const;
 
+       virtual void changed (int) {}
+
        boost::shared_ptr<Content> clone () const;
 
        void set_path (boost::filesystem::path);
@@ -167,6 +169,7 @@ public:
        boost::signals2::signal<void (boost::weak_ptr<Content>, int, bool)> Changed;
 
        boost::shared_ptr<VideoContent> video;
+       boost::shared_ptr<AudioContent> audio;
        boost::shared_ptr<SubtitleContent> subtitle;
 
        void signal_changed (int);
index a81a152..cfd19fe 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "dcp_content.h"
 #include "video_content.h"
+#include "audio_content.h"
 #include "dcp_examiner.h"
 #include "job.h"
 #include "film.h"
@@ -55,7 +56,6 @@ int const DCPContentProperty::REFERENCE_SUBTITLE = 603;
 
 DCPContent::DCPContent (shared_ptr<const Film> film, boost::filesystem::path p)
        : Content (film)
-       , AudioContent (film)
        , _has_subtitles (false)
        , _encrypted (false)
        , _kdm_valid (false)
@@ -64,6 +64,7 @@ DCPContent::DCPContent (shared_ptr<const Film> film, boost::filesystem::path p)
        , _reference_subtitle (false)
 {
        video.reset (new VideoContent (this, film));
+       audio.reset (new AudioContent (this, film));
        subtitle.reset (new SubtitleContent (this, film));
 
        read_directory (p);
@@ -72,10 +73,14 @@ DCPContent::DCPContent (shared_ptr<const Film> film, boost::filesystem::path p)
 
 DCPContent::DCPContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
        : Content (film, node)
-       , AudioContent (film, node)
-       , _audio_stream (new AudioStream (node->number_child<int> ("AudioFrameRate"), AudioMapping (node->node_child ("AudioMapping"), version)))
 {
        video.reset (new VideoContent (this, film, node, version));
+       audio.reset (new AudioContent (this, film, node));
+       audio->set_stream (
+               AudioStreamPtr (
+                       new AudioStream (node->number_child<int> ("AudioFrameRate"), AudioMapping (node->node_child ("AudioMapping"), version))
+                       )
+               );
        subtitle.reset (new SubtitleContent (this, film, node, version));
 
        _name = node->string_child ("Name");
@@ -116,10 +121,12 @@ DCPContent::examine (shared_ptr<Job> job)
 
        {
                boost::mutex::scoped_lock lm (_mutex);
-               _audio_stream.reset (new AudioStream (examiner->audio_frame_rate(), examiner->audio_channels ()));
-               AudioMapping m = _audio_stream->mapping ();
+
+               AudioStreamPtr as (new AudioStream (examiner->audio_frame_rate(), examiner->audio_channels ()));
+               audio->set_stream (as);
+               AudioMapping m = as->mapping ();
                film()->make_audio_mapping_default (m);
-               _audio_stream->set_mapping (m);
+               as->set_mapping (m);
        }
 
        signal_changed (AudioContentProperty::AUDIO_STREAMS);
@@ -149,7 +156,7 @@ DCPContent::technical_summary () const
 {
        return Content::technical_summary() + " - "
                + video->technical_summary() + " - "
-               + AudioContent::technical_summary() + " - ";
+               + audio->technical_summary() + " - ";
 }
 
 void
@@ -159,9 +166,9 @@ DCPContent::as_xml (xmlpp::Node* node) const
 
        Content::as_xml (node);
        video->as_xml (node);
-       AudioContent::as_xml (node);
-       node->add_child("AudioFrameRate")->add_child_text (raw_convert<string> (audio_stream()->frame_rate ()));
-       audio_stream()->mapping().as_xml (node->add_child("AudioMapping"));
+       audio->as_xml (node);
+       node->add_child("AudioFrameRate")->add_child_text (raw_convert<string> (audio->stream()->frame_rate()));
+       audio->stream()->mapping().as_xml (node->add_child("AudioMapping"));
        subtitle->as_xml (node);
 
        boost::mutex::scoped_lock lm (_mutex);
@@ -226,7 +233,7 @@ DCPContent::directory () const
 void
 DCPContent::add_properties (list<UserProperty>& p) const
 {
-       AudioContent::add_properties (p);
+       audio->add_properties (p);
 }
 
 void
@@ -337,15 +344,8 @@ DCPContent::can_reference_video (list<string>& why_not) const
 bool
 DCPContent::can_reference_audio (list<string>& why_not) const
 {
-       DCPDecoder decoder (shared_from_this(), film()->log(), false);
-       BOOST_FOREACH (shared_ptr<dcp::Reel> i, decoder.reels()) {
-               if (!i->main_sound()) {
-                       why_not.push_back (_("The DCP does not have sound in all reels."));
-                       return false;
-               }
-       }
-
-       return can_reference<AudioContent> (_("There is other audio content overlapping this DCP; remove it."), why_not);
+       /* XXX: this needs to be fixed */
+       return true;
 }
 
 bool
@@ -355,16 +355,10 @@ DCPContent::can_reference_subtitle (list<string>& why_not) const
        return true;
 }
 
-double
-DCPContent::subtitle_video_frame_rate () const
-{
-       return video->video_frame_rate ();
-}
-
-vector<AudioStreamPtr>
-DCPContent::audio_streams () const
+void
+DCPContent::changed (int property)
 {
-       vector<AudioStreamPtr> s;
-       s.push_back (_audio_stream);
-       return s;
+       if (property == VideoContentProperty::VIDEO_FRAME_RATE && subtitle) {
+               subtitle->set_subtitle_video_frame_rate (video->video_frame_rate ());
+       }
 }
index f3cd6bf..b2bc90e 100644 (file)
@@ -24,7 +24,7 @@
  *  @brief DCPContent class.
  */
 
-#include "audio_content.h"
+#include "content.h"
 #include <libcxml/cxml.h>
 #include <dcp/encrypted_kdm.h>
 
@@ -40,7 +40,7 @@ public:
 /** @class DCPContent
  *  @brief An existing DCP used as input.
  */
-class DCPContent : public AudioContent
+class DCPContent : public Content
 {
 public:
        DCPContent (boost::shared_ptr<const Film>, boost::filesystem::path p);
@@ -65,8 +65,6 @@ public:
        void set_default_colour_conversion ();
        std::list<DCPTime> reel_split_points () const;
 
-       /* SubtitleContent */
-
        bool has_text_subtitles () const {
                boost::mutex::scoped_lock lm (_mutex);
                return _has_subtitles;
@@ -76,7 +74,7 @@ public:
                return false;
        }
 
-       double subtitle_video_frame_rate () const;
+       void changed (int property);
 
        boost::filesystem::path directory () const;
 
@@ -120,16 +118,9 @@ public:
 
        bool can_reference_subtitle (std::list<std::string> &) const;
 
-       std::vector<AudioStreamPtr> audio_streams () const;
-
-       AudioStreamPtr audio_stream () const {
-               return _audio_stream;
-       }
-
-protected:
+private:
        void add_properties (std::list<UserProperty>& p) const;
 
-private:
        void read_directory (boost::filesystem::path);
        std::list<DCPTimePeriod> reels () const;
        template <class T> bool can_reference (std::string overlapping, std::list<std::string>& why_not) const;
@@ -153,8 +144,6 @@ private:
         *  rather than by rewrapping.
         */
        bool _reference_subtitle;
-
-       boost::shared_ptr<AudioStream> _audio_stream;
 };
 
 #endif
index f032ee6..4e28dc7 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
 
 #include "dcp_decoder.h"
 #include "dcp_content.h"
+#include "audio_content.h"
 #include "j2k_image_proxy.h"
 #include "image.h"
 #include "config.h"
@@ -44,7 +45,7 @@ using boost::dynamic_pointer_cast;
 
 DCPDecoder::DCPDecoder (shared_ptr<const DCPContent> c, shared_ptr<Log> log, bool fast)
        : VideoDecoder (c->video, log)
-       , AudioDecoder (c, fast)
+       , AudioDecoder (c->audio, fast, log)
        , SubtitleDecoder (c->subtitle)
        , _dcp_content (c)
 {
@@ -103,7 +104,7 @@ DCPDecoder::pass (PassReason reason, bool)
                shared_ptr<const dcp::SoundFrame> sf = (*_reel)->main_sound()->asset()->get_frame (entry_point + frame);
                uint8_t const * from = sf->data ();
 
-               int const channels = _dcp_content->audio_stream()->channels ();
+               int const channels = _dcp_content->audio->stream()->channels ();
                int const frames = sf->size() / (3 * channels);
                shared_ptr<AudioBuffers> data (new AudioBuffers (channels, frames));
                for (int i = 0; i < frames; ++i) {
@@ -113,7 +114,7 @@ DCPDecoder::pass (PassReason reason, bool)
                        }
                }
 
-               audio (_dcp_content->audio_stream(), data, ContentTime::from_frames (offset, vfr) + _next);
+               audio (_dcp_content->audio->stream(), data, ContentTime::from_frames (offset, vfr) + _next);
        }
 
        if ((*_reel)->main_subtitle ()) {
index b38c0c6..3feb894 100644 (file)
@@ -44,7 +44,6 @@ DCPSubtitleContent::DCPSubtitleContent (shared_ptr<const Film> film, boost::file
 DCPSubtitleContent::DCPSubtitleContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
        : Content (film, node)
        , _length (node->number_child<ContentTime::Type> ("Length"))
-       , _frame_rate (node->optional_number_child<int>("SubtitleFrameRate"))
 {
        subtitle.reset (new SubtitleContent (this, film, node, version));
 }
@@ -68,7 +67,7 @@ DCPSubtitleContent::examine (shared_ptr<Job> job)
        shared_ptr<dcp::SMPTESubtitleAsset> smpte = dynamic_pointer_cast<dcp::SMPTESubtitleAsset> (sc);
        if (smpte) {
                subtitle->set_subtitle_language (smpte->language().get_value_or (""));
-               _frame_rate = smpte->edit_rate().numerator;
+               subtitle->set_subtitle_video_frame_rate (smpte->edit_rate().numerator);
        }
 
        _length = ContentTime::from_seconds (sc->latest_subtitle_out().as_seconds ());
@@ -81,7 +80,7 @@ DCPSubtitleContent::examine (shared_ptr<Job> job)
 DCPTime
 DCPSubtitleContent::full_length () const
 {
-       FrameRateChange const frc (subtitle_video_frame_rate(), film()->video_frame_rate());
+       FrameRateChange const frc (subtitle->subtitle_video_frame_rate(), film()->video_frame_rate());
        return DCPTime (_length, frc);
 }
 
@@ -105,30 +104,3 @@ DCPSubtitleContent::as_xml (xmlpp::Node* node) const
        subtitle->as_xml (node);
        node->add_child("Length")->add_child_text (raw_convert<string> (_length.get ()));
 }
-
-void
-DCPSubtitleContent::set_subtitle_video_frame_rate (int r)
-{
-       {
-               boost::mutex::scoped_lock lm (_mutex);
-               _frame_rate = r;
-       }
-
-       signal_changed (SubtitleContentProperty::SUBTITLE_VIDEO_FRAME_RATE);
-}
-
-double
-DCPSubtitleContent::subtitle_video_frame_rate () const
-{
-       {
-               boost::mutex::scoped_lock lm (_mutex);
-               if (_frame_rate) {
-                       return _frame_rate.get ();
-               }
-       }
-
-       /* No frame rate specified, so assume this content has been
-          prepared for any concurrent video content.
-       */
-       return film()->active_frame_rate_change(position()).source;
-}
index de9fa68..2117657 100644 (file)
@@ -43,11 +43,6 @@ public:
                return false;
        }
 
-       double subtitle_video_frame_rate () const;
-       void set_subtitle_video_frame_rate (int r);
-
 private:
        ContentTime _length;
-       /** Video frame rate that this content has been prepared for, if known */
-       boost::optional<double> _frame_rate;
 };
index f276a16..c67d643 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "ffmpeg_content.h"
 #include "video_content.h"
+#include "audio_content.h"
 #include "ffmpeg_examiner.h"
 #include "ffmpeg_subtitle_stream.h"
 #include "ffmpeg_audio_stream.h"
@@ -62,9 +63,9 @@ int const FFmpegContentProperty::FILTERS = 102;
 
 FFmpegContent::FFmpegContent (shared_ptr<const Film> film, boost::filesystem::path p)
        : Content (film, p)
-       , AudioContent (film, p)
 {
        video.reset (new VideoContent (this, film));
+       audio.reset (new AudioContent (this, film));
        subtitle.reset (new SubtitleContent (this, film));
 
        set_default_colour_conversion ();
@@ -72,9 +73,9 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> film, boost::filesystem::pa
 
 FFmpegContent::FFmpegContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version, list<string>& notes)
        : Content (film, node)
-       , AudioContent (film, node)
 {
        video.reset (new VideoContent (this, film, node, version));
+       audio.reset (new AudioContent (this, film, node));
        subtitle.reset (new SubtitleContent (this, film, node, version));
 
        list<cxml::NodePtr> c = node->node_children ("SubtitleStream");
@@ -87,10 +88,11 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> film, cxml::ConstNodePtr no
 
        c = node->node_children ("AudioStream");
        for (list<cxml::NodePtr>::const_iterator i = c.begin(); i != c.end(); ++i) {
-               _audio_streams.push_back (shared_ptr<FFmpegAudioStream> (new FFmpegAudioStream (*i, version)));
+               shared_ptr<FFmpegAudioStream> as (new FFmpegAudioStream (*i, version));
+               audio->add_stream (as);
                if (version < 11 && !(*i)->optional_node_child ("Selected")) {
                        /* This is an old file and this stream is not selected, so un-map it */
-                       _audio_streams.back()->set_mapping (AudioMapping (_audio_streams.back()->channels (), MAX_DCP_AUDIO_CHANNELS));
+                       as->set_mapping (AudioMapping (_audio_streams.back()->channels (), MAX_DCP_AUDIO_CHANNELS));
                }
        }
 
@@ -121,9 +123,9 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> film, cxml::ConstNodePtr no
 
 FFmpegContent::FFmpegContent (shared_ptr<const Film> film, vector<boost::shared_ptr<Content> > c)
        : Content (film, c)
-       , AudioContent (film, c)
 {
        video.reset (new VideoContent (this, film, c));
+       audio.reset (new AudioContent (this, film, c));
        subtitle.reset (new SubtitleContent (this, film, c));
 
        shared_ptr<FFmpegContent> ref = dynamic_pointer_cast<FFmpegContent> (c[0]);
@@ -140,7 +142,6 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> film, vector<boost::shared_
 
        _subtitle_streams = ref->subtitle_streams ();
        _subtitle_stream = ref->subtitle_stream ();
-       _audio_streams = ref->ffmpeg_audio_streams ();
        _first_video = ref->_first_video;
        _filters = ref->_filters;
        _color_range = ref->_color_range;
@@ -156,7 +157,7 @@ FFmpegContent::as_xml (xmlpp::Node* node) const
        node->add_child("Type")->add_child_text ("FFmpeg");
        Content::as_xml (node);
        video->as_xml (node);
-       AudioContent::as_xml (node);
+       audio->as_xml (node);
        subtitle->as_xml (node);
 
        boost::mutex::scoped_lock lm (_mutex);
@@ -169,8 +170,10 @@ FFmpegContent::as_xml (xmlpp::Node* node) const
                (*i)->as_xml (t);
        }
 
-       for (vector<shared_ptr<FFmpegAudioStream> >::const_iterator i = _audio_streams.begin(); i != _audio_streams.end(); ++i) {
-               (*i)->as_xml (node->add_child("AudioStream"));
+       BOOST_FOREACH (AudioStreamPtr i, audio->streams ()) {
+               shared_ptr<FFmpegAudioStream> f = dynamic_pointer_cast<FFmpegAudioStream> (i);
+               DCPOMATIC_ASSERT (f);
+               f->as_xml (node->add_child("AudioStream"));
        }
 
        for (vector<Filter const *>::const_iterator i = _filters.begin(); i != _filters.end(); ++i) {
@@ -209,12 +212,15 @@ FFmpegContent::examine (shared_ptr<Job> job)
                        _subtitle_stream = _subtitle_streams.front ();
                }
 
-               _audio_streams = examiner->audio_streams ();
+               BOOST_FOREACH (shared_ptr<FFmpegAudioStream> i, examiner->audio_streams ()) {
+                       audio->add_stream (i);
+               }
 
-               if (!_audio_streams.empty ()) {
-                       AudioMapping m = _audio_streams.front()->mapping ();
+               if (!audio->streams().empty ()) {
+                       AudioStreamPtr as = audio->streams().front();
+                       AudioMapping m = as->mapping ();
                        film()->make_audio_mapping_default (m);
-                       _audio_streams.front()->set_mapping (m);
+                       as->set_mapping (m);
                }
 
                _first_video = examiner->first_video ();
@@ -228,7 +234,6 @@ FFmpegContent::examine (shared_ptr<Job> job)
 
        signal_changed (FFmpegContentProperty::SUBTITLE_STREAMS);
        signal_changed (FFmpegContentProperty::SUBTITLE_STREAM);
-       signal_changed (AudioContentProperty::AUDIO_STREAMS);
 }
 
 string
@@ -259,7 +264,7 @@ FFmpegContent::technical_summary () const
 
        return Content::technical_summary() + " - "
                + video->technical_summary() + " - "
-               + AudioContent::technical_summary() + " - "
+               + audio->technical_summary() + " - "
                + String::compose (
                        "ffmpeg: audio %1 subtitle %2 filters %3", as, ss, filt
                        );
@@ -403,7 +408,7 @@ FFmpegContent::add_properties (list<UserProperty>& p) const
 {
        Content::add_properties (p);
        video->add_properties (p);
-       AudioContent::add_properties (p);
+       audio->add_properties (p);
 
        if (_bits_per_pixel) {
                int const sub = 219 * pow (2, _bits_per_pixel.get() - 8);
@@ -528,8 +533,10 @@ FFmpegContent::signal_subtitle_stream_changed ()
        signal_changed (FFmpegContentProperty::SUBTITLE_STREAM);
 }
 
-double
-FFmpegContent::subtitle_video_frame_rate () const
+void
+FFmpegContent::changed (int property)
 {
-       return video->video_frame_rate ();
+       if (property == VideoContentProperty::VIDEO_FRAME_RATE && subtitle) {
+               subtitle->set_subtitle_video_frame_rate (video->video_frame_rate ());
+       }
 }
index da0eb48..f39414a 100644 (file)
@@ -20,7 +20,8 @@
 #ifndef DCPOMATIC_FFMPEG_CONTENT_H
 #define DCPOMATIC_FFMPEG_CONTENT_H
 
-#include "audio_content.h"
+#include "content.h"
+#include "audio_stream.h"
 
 struct AVFormatContext;
 struct AVStream;
@@ -41,7 +42,7 @@ public:
        static int const FILTERS;
 };
 
-class FFmpegContent : public AudioContent
+class FFmpegContent : public Content
 {
 public:
        FFmpegContent (boost::shared_ptr<const Film>, boost::filesystem::path);
@@ -60,19 +61,17 @@ public:
 
        std::string identifier () const;
 
-       /* VideoContent */
        void set_default_colour_conversion ();
 
-       /* AudioContent */
        std::vector<AudioStreamPtr> audio_streams () const;
 
-       /* SubtitleContent */
        bool has_text_subtitles () const;
        bool has_image_subtitles () const;
-       double subtitle_video_frame_rate () const;
 
        void set_filters (std::vector<Filter const *> const &);
 
+       void changed (int property);
+
        std::vector<boost::shared_ptr<FFmpegSubtitleStream> > subtitle_streams () const {
                boost::mutex::scoped_lock lm (_mutex);
                return _subtitle_streams;
@@ -105,10 +104,9 @@ public:
 
        void signal_subtitle_stream_changed ();
 
-protected:
+private:
        void add_properties (std::list<UserProperty> &) const;
 
-private:
        friend struct ffmpeg_pts_offset_test;
        friend struct audio_sampling_rate_test;
 
index 15cc9b2..8e4a1cc 100644 (file)
@@ -73,7 +73,7 @@ using dcp::Size;
 
 FFmpegDecoder::FFmpegDecoder (shared_ptr<const FFmpegContent> c, shared_ptr<Log> log, bool fast)
        : VideoDecoder (c->video, log)
-       , AudioDecoder (c, fast)
+       , AudioDecoder (c->audio, fast, log)
        , SubtitleDecoder (c->subtitle)
        , FFmpeg (c)
        , _log (log)
index 7d319fc..49a0a9b 100644 (file)
@@ -245,13 +245,12 @@ Film::audio_analysis_path (shared_ptr<const Playlist> playlist) const
 
        MD5Digester digester;
        BOOST_FOREACH (shared_ptr<Content> i, playlist->content ()) {
-               shared_ptr<AudioContent> ac = dynamic_pointer_cast<AudioContent> (i);
-               if (!ac) {
+               if (!i->audio) {
                        continue;
                }
 
-               digester.add (ac->digest ());
-               digester.add (ac->audio_mapping().digest ());
+               digester.add (i->digest ());
+               digester.add (i->audio->audio_mapping().digest ());
                if (playlist->content().size() != 1) {
                        /* Analyses should be considered equal regardless of gain
                           if they were made from just one piece of content.  This
@@ -259,7 +258,7 @@ Film::audio_analysis_path (shared_ptr<const Playlist> playlist) const
                           analysis at the plotting stage rather than having to
                           recompute it.
                        */
-                       digester.add (ac->audio_gain ());
+                       digester.add (i->audio->audio_gain ());
                }
        }
 
@@ -505,9 +504,8 @@ Film::mapped_audio_channels () const
                }
        } else {
                BOOST_FOREACH (shared_ptr<Content> i, content ()) {
-                       shared_ptr<const AudioContent> ac = dynamic_pointer_cast<const AudioContent> (i);
-                       if (ac) {
-                               list<int> c = ac->audio_mapping().mapped_output_channels ();
+                       if (i->audio) {
+                               list<int> c = i->audio->mapping().mapped_output_channels ();
                                copy (c.begin(), c.end(), back_inserter (mapped));
                        }
                }
@@ -639,12 +637,11 @@ Film::isdcf_name (bool if_created_now) const
 
                        bool burnt_in = true;
                        BOOST_FOREACH (shared_ptr<Content> i, content ()) {
-                               shared_ptr<SubtitleContent> sc = dynamic_pointer_cast<SubtitleContent> (i);
-                               if (!sc) {
+                               if (!i->subtitle) {
                                        continue;
                                }
 
-                               if (sc->use_subtitles() && !sc->burn_subtitles()) {
+                               if (i->subtitle->use_subtitles() && !i->subtitle->burn_subtitles()) {
                                        burnt_in = false;
                                }
                        }
@@ -1033,7 +1030,7 @@ Film::maybe_add_content (weak_ptr<Job> j, weak_ptr<Content> c)
        }
 
        add_content (content);
-       if (Config::instance()->automatic_audio_analysis() && dynamic_pointer_cast<AudioContent> (content)) {
+       if (Config::instance()->automatic_audio_analysis() && content->audio) {
                shared_ptr<Playlist> playlist (new Playlist);
                playlist->add (content);
                boost::signals2::connection c;
@@ -1050,7 +1047,7 @@ Film::add_content (shared_ptr<Content> c)
        /* Add {video,subtitle} content after any existing {video,subtitle} content */
        if (c->video) {
                c->set_position (_playlist->video_end ());
-       } else if (dynamic_pointer_cast<SubtitleContent> (c)) {
+       } else if (c->subtitle) {
                c->set_position (_playlist->subtitle_end ());
        }
 
@@ -1125,8 +1122,7 @@ int
 Film::audio_frame_rate () const
 {
        BOOST_FOREACH (shared_ptr<Content> i, content ()) {
-               shared_ptr<AudioContent> a = dynamic_pointer_cast<AudioContent> (i);
-               if (a && a->has_rate_above_48k ()) {
+               if (i->audio && i->audio->has_rate_above_48k ()) {
                        return 96000;
                }
        }
@@ -1271,9 +1267,8 @@ Film::subtitle_language () const
 
        ContentList cl = content ();
        BOOST_FOREACH (shared_ptr<Content>& c, cl) {
-               shared_ptr<SubtitleContent> sc = dynamic_pointer_cast<SubtitleContent> (c);
-               if (sc) {
-                       languages.insert (sc->subtitle_language ());
+               if (c->subtitle) {
+                       languages.insert (c->subtitle->subtitle_language ());
                }
        }
 
index 9c216c2..ce048ed 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@
 #include "film.h"
 #include "ffmpeg_decoder.h"
 #include "audio_buffers.h"
+#include "audio_content.h"
 #include "ffmpeg_content.h"
 #include "image_decoder.h"
 #include "image_content.h"
@@ -143,7 +144,7 @@ Player::setup_pieces ()
                /* SndfileContent */
                shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> (i);
                if (sc) {
-                       decoder.reset (new SndfileDecoder (sc, _fast));
+                       decoder.reset (new SndfileDecoder (sc, _fast, _film->log()));
 
                        /* Work out a FrameRateChange for the best overlap video for this content */
                        DCPTime best_overlap_t;
@@ -177,14 +178,14 @@ Player::setup_pieces ()
                shared_ptr<const TextSubtitleContent> rc = dynamic_pointer_cast<const TextSubtitleContent> (i);
                if (rc) {
                        decoder.reset (new TextSubtitleDecoder (rc));
-                       frc = FrameRateChange (rc->subtitle_video_frame_rate(), _film->video_frame_rate());
+                       frc = FrameRateChange (rc->subtitle->subtitle_video_frame_rate(), _film->video_frame_rate());
                }
 
                /* DCPSubtitleContent */
                shared_ptr<const DCPSubtitleContent> dsc = dynamic_pointer_cast<const DCPSubtitleContent> (i);
                if (dsc) {
                        decoder.reset (new DCPSubtitleDecoder (dsc));
-                       frc = FrameRateChange (dsc->subtitle_video_frame_rate(), _film->video_frame_rate());
+                       frc = FrameRateChange (dsc->subtitle->subtitle_video_frame_rate(), _film->video_frame_rate());
                }
 
                shared_ptr<VideoDecoder> vd = dynamic_pointer_cast<VideoDecoder> (decoder);
@@ -480,9 +481,8 @@ Player::get_audio (DCPTime time, DCPTime length, bool accurate)
 
        bool all_referenced = true;
        BOOST_FOREACH (shared_ptr<Piece> i, ov) {
-               shared_ptr<AudioContent> audio_content = dynamic_pointer_cast<AudioContent> (i->content);
                shared_ptr<DCPContent> dcp_content = dynamic_pointer_cast<DCPContent> (i->content);
-               if (audio_content && (!dcp_content || !dcp_content->reference_audio ())) {
+               if (i->content->audio && (!dcp_content || !dcp_content->reference_audio ())) {
                        /* There is audio content which is not from a DCP or not set to be referenced */
                        all_referenced = false;
                }
@@ -494,13 +494,12 @@ Player::get_audio (DCPTime time, DCPTime length, bool accurate)
 
        BOOST_FOREACH (shared_ptr<Piece> i, ov) {
 
-               shared_ptr<AudioContent> content = dynamic_pointer_cast<AudioContent> (i->content);
-               DCPOMATIC_ASSERT (content);
+               DCPOMATIC_ASSERT (i->content->audio);
                shared_ptr<AudioDecoder> decoder = dynamic_pointer_cast<AudioDecoder> (i->decoder);
                DCPOMATIC_ASSERT (decoder);
 
                /* The time that we should request from the content */
-               DCPTime request = time - DCPTime::from_seconds (content->audio_delay() / 1000.0);
+               DCPTime request = time - DCPTime::from_seconds (i->content->audio->audio_delay() / 1000.0);
                Frame request_frames = length_frames;
                DCPTime offset;
                if (request < DCPTime ()) {
@@ -517,7 +516,7 @@ Player::get_audio (DCPTime time, DCPTime length, bool accurate)
 
                Frame const content_frame = dcp_to_resampled_audio (i, request);
 
-               BOOST_FOREACH (AudioStreamPtr j, content->audio_streams ()) {
+               BOOST_FOREACH (AudioStreamPtr j, i->content->audio->streams ()) {
 
                        if (j->channels() == 0) {
                                /* Some content (e.g. DCPs) can have streams with no channels */
@@ -528,9 +527,9 @@ Player::get_audio (DCPTime time, DCPTime length, bool accurate)
                        ContentAudio all = decoder->get_audio (j, content_frame, request_frames, accurate);
 
                        /* Gain */
-                       if (content->audio_gain() != 0) {
+                       if (i->content->audio->audio_gain() != 0) {
                                shared_ptr<AudioBuffers> gain (new AudioBuffers (all.audio));
-                               gain->apply_gain (content->audio_gain ());
+                               gain->apply_gain (i->content->audio->audio_gain ());
                                all.audio = gain;
                        }
 
@@ -572,7 +571,6 @@ Player::get_audio (DCPTime time, DCPTime length, bool accurate)
 Frame
 Player::dcp_to_content_video (shared_ptr<const Piece> piece, DCPTime t) const
 {
-       shared_ptr<const VideoContent> vc = dynamic_pointer_cast<const VideoContent> (piece->content);
        DCPTime s = t - piece->content->position ();
        s = min (piece->content->length_after_trim(), s);
        s = max (DCPTime(), s + DCPTime (piece->content->trim_start(), piece->frc));
@@ -590,7 +588,6 @@ Player::dcp_to_content_video (shared_ptr<const Piece> piece, DCPTime t) const
 DCPTime
 Player::content_video_to_dcp (shared_ptr<const Piece> piece, Frame f) const
 {
-       shared_ptr<const VideoContent> vc = dynamic_pointer_cast<const VideoContent> (piece->content);
        /* See comment in dcp_to_content_video */
        DCPTime const d = DCPTime::from_frames (f * piece->frc.factor(), piece->frc.dcp) - DCPTime (piece->content->trim_start (), piece->frc);
        return max (DCPTime (), d + piece->content->position ());
@@ -704,12 +701,11 @@ Player::get_subtitle_fonts ()
 
        list<shared_ptr<Font> > fonts;
        BOOST_FOREACH (shared_ptr<Piece>& p, _pieces) {
-               shared_ptr<SubtitleContent> sc = dynamic_pointer_cast<SubtitleContent> (p->content);
-               if (sc) {
+               if (p->content->subtitle) {
                        /* XXX: things may go wrong if there are duplicate font IDs
                           with different font files.
                        */
-                       list<shared_ptr<Font> > f = sc->fonts ();
+                       list<shared_ptr<Font> > f = p->content->subtitle->fonts ();
                        copy (f.begin(), f.end(), back_inserter (fonts));
                }
        }
index 6459930..092060f 100644 (file)
@@ -150,12 +150,8 @@ Playlist::video_identifier () const
        string t;
 
        BOOST_FOREACH (shared_ptr<const Content> i, _content) {
-               shared_ptr<const VideoContent> vc = dynamic_pointer_cast<const VideoContent> (i);
-               shared_ptr<const SubtitleContent> sc = dynamic_pointer_cast<const SubtitleContent> (i);
-               if (vc) {
-                       t += vc->identifier ();
-               } else if (sc && sc->burn_subtitles ()) {
-                       t += sc->identifier ();
+               if (i->video || (i->subtitle && i->subtitle->burn_subtitles())) {
+                       t += i->identifier ();
                }
        }
 
@@ -346,7 +342,7 @@ Playlist::video_end () const
 {
        DCPTime end;
        BOOST_FOREACH (shared_ptr<Content> i, _content) {
-               if (dynamic_pointer_cast<const VideoContent> (i)) {
+               if (i->video) {
                        end = max (end, i->end ());
                }
        }
@@ -359,7 +355,7 @@ Playlist::subtitle_end () const
 {
        DCPTime end;
        BOOST_FOREACH (shared_ptr<Content> i, _content) {
-               if (dynamic_pointer_cast<const SubtitleContent> (i)) {
+               if (i->subtitle) {
                        end = max (end, i->end ());
                }
        }
index d843561..d023b27 100644 (file)
@@ -20,6 +20,7 @@
 #include "sndfile_content.h"
 #include "sndfile_decoder.h"
 #include "sndfile_examiner.h"
+#include "audio_content.h"
 #include "film.h"
 #include "compose.hpp"
 #include "job.h"
@@ -39,18 +40,19 @@ using boost::shared_ptr;
 
 SndfileContent::SndfileContent (shared_ptr<const Film> film, boost::filesystem::path p)
        : Content (film, p)
-       , AudioContent (film, p)
 {
-
+       audio.reset (new AudioContent (this, film));
 }
 
 SndfileContent::SndfileContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
        : Content (film, node)
-       , AudioContent (film, node)
        , _audio_length (node->number_child<Frame> ("AudioLength"))
-       , _audio_stream (new AudioStream (node->number_child<int> ("AudioFrameRate"), AudioMapping (node->node_child ("AudioMapping"), version)))
 {
-
+       audio.reset (new AudioContent (this, film, node));
+       audio->set_stream (
+               AudioStreamPtr (
+                       new AudioStream (node->number_child<int> ("AudioFrameRate"), AudioMapping (node->node_child ("AudioMapping"), version)))
+               );
 }
 
 void
@@ -58,9 +60,9 @@ SndfileContent::as_xml (xmlpp::Node* node) const
 {
        node->add_child("Type")->add_child_text ("Sndfile");
        Content::as_xml (node);
-       AudioContent::as_xml (node);
-       node->add_child("AudioFrameRate")->add_child_text (raw_convert<string> (audio_stream()->frame_rate ()));
-       audio_stream()->mapping().as_xml (node->add_child("AudioMapping"));
+       audio->as_xml (node);
+       node->add_child("AudioFrameRate")->add_child_text (raw_convert<string> (audio->stream()->frame_rate ()));
+       audio->stream()->mapping().as_xml (node->add_child("AudioMapping"));
        node->add_child("AudioLength")->add_child_text (raw_convert<string> (audio_length ()));
 }
 
@@ -76,7 +78,7 @@ string
 SndfileContent::technical_summary () const
 {
        return Content::technical_summary() + " - "
-               + AudioContent::technical_summary ()
+               + audio->technical_summary ()
                + " - sndfile";
 }
 
@@ -103,10 +105,11 @@ SndfileContent::take_from_audio_examiner (shared_ptr<AudioExaminer> examiner)
 {
        {
                boost::mutex::scoped_lock lm (_mutex);
-               _audio_stream.reset (new AudioStream (examiner->audio_frame_rate(), examiner->audio_channels ()));
-               AudioMapping m = _audio_stream->mapping ();
+               AudioStreamPtr as (new AudioStream (examiner->audio_frame_rate(), examiner->audio_channels ()));
+               audio->set_stream (as);
+               AudioMapping m = as->mapping ();
                film()->make_audio_mapping_default (m);
-               _audio_stream->set_mapping (m);
+               as->set_mapping (m);
                _audio_length = examiner->audio_length ();
        }
 
@@ -116,14 +119,6 @@ SndfileContent::take_from_audio_examiner (shared_ptr<AudioExaminer> examiner)
 DCPTime
 SndfileContent::full_length () const
 {
-       FrameRateChange const frc (audio_video_frame_rate(), film()->video_frame_rate());
-       return DCPTime::from_frames (audio_length() / frc.speed_up, audio_stream()->frame_rate ());
-}
-
-vector<AudioStreamPtr>
-SndfileContent::audio_streams () const
-{
-       vector<AudioStreamPtr> s;
-       s.push_back (_audio_stream);
-       return s;
+       FrameRateChange const frc (audio->audio_video_frame_rate(), film->video_frame_rate());
+       return DCPTime::from_frames (audio_length() / frc.speed_up, audio->stream()->frame_rate ());
 }
index 5f89b7c..dfd3697 100644 (file)
 #ifndef DCPOMATIC_SNDFILE_CONTENT_H
 #define DCPOMATIC_SNDFILE_CONTENT_H
 
-#include "audio_content.h"
+#include "content.h"
 
 class AudioExaminer;
 
-class SndfileContent : public AudioContent
+class SndfileContent : public Content
 {
 public:
        SndfileContent (boost::shared_ptr<const Film>, boost::filesystem::path);
@@ -44,12 +44,6 @@ public:
 
        void take_from_audio_examiner (boost::shared_ptr<AudioExaminer>);
 
-       std::vector<AudioStreamPtr> audio_streams () const;
-
-       AudioStreamPtr audio_stream () const {
-               return _audio_stream;
-       }
-
        static bool valid_file (boost::filesystem::path);
 
 private:
@@ -59,8 +53,6 @@ private:
        }
 
        Frame _audio_length;
-
-       boost::shared_ptr<AudioStream> _audio_stream;
 };
 
 #endif
index ac01e0d..b05750a 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
 
 #include <iostream>
 #include <sndfile.h>
+#include "audio_content.h"
 #include "sndfile_content.h"
 #include "sndfile_decoder.h"
 #include "exceptions.h"
@@ -32,9 +33,9 @@ using std::min;
 using std::cout;
 using boost::shared_ptr;
 
-SndfileDecoder::SndfileDecoder (shared_ptr<const SndfileContent> c, bool fast)
+SndfileDecoder::SndfileDecoder (shared_ptr<const SndfileContent> c, bool fast, shared_ptr<Log> log)
        : Sndfile (c)
-       , AudioDecoder (c, fast)
+       , AudioDecoder (c->audio, fast, log)
        , _done (0)
        , _remaining (_info.frames)
        , _deinterleave_buffer (0)
@@ -57,14 +58,14 @@ SndfileDecoder::pass (PassReason, bool)
        /* Do things in half second blocks as I think there may be limits
           to what FFmpeg (and in particular the resampler) can cope with.
        */
-       sf_count_t const block = _sndfile_content->audio_stream()->frame_rate() / 2;
+       sf_count_t const block = _sndfile_content->audio->stream()->frame_rate() / 2;
        sf_count_t const this_time = min (block, _remaining);
 
-       int const channels = _sndfile_content->audio_stream()->channels ();
+       int const channels = _sndfile_content->audio->stream()->channels ();
 
        shared_ptr<AudioBuffers> data (new AudioBuffers (channels, this_time));
 
-       if (_sndfile_content->audio_stream()->channels() == 1) {
+       if (_sndfile_content->audio->stream()->channels() == 1) {
                /* No de-interleaving required */
                sf_read_float (_sndfile, data->data(0), this_time);
        } else {
@@ -86,7 +87,7 @@ SndfileDecoder::pass (PassReason, bool)
        }
 
        data->set_frames (this_time);
-       audio (_sndfile_content->audio_stream (), data, ContentTime::from_frames (_done, _info.samplerate));
+       audio (_sndfile_content->audio->stream (), data, ContentTime::from_frames (_done, _info.samplerate));
        _done += this_time;
        _remaining -= this_time;
 
index 844d1cd..6f3a6cc 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@ class SndfileContent;
 class SndfileDecoder : public Sndfile, public AudioDecoder
 {
 public:
-       SndfileDecoder (boost::shared_ptr<const SndfileContent> c, bool fast);
+       SndfileDecoder (boost::shared_ptr<const SndfileContent> c, bool fast, boost::shared_ptr<Log> log);
        ~SndfileDecoder ();
 
 private:
index 03c188b..089e3a3 100644 (file)
@@ -24,6 +24,7 @@
 #include "font.h"
 #include "raw_convert.h"
 #include "content.h"
+#include "film.h"
 #include <libcxml/cxml.h>
 #include <libxml++/libxml++.h>
 #include <boost/foreach.hpp>
@@ -85,6 +86,7 @@ SubtitleContent::SubtitleContent (Content* parent, shared_ptr<const Film> film,
                node->optional_number_child<int>("OutlineGreen").get_value_or(255),
                node->optional_number_child<int>("OutlineBlue").get_value_or(255)
                )
+       , _frame_rate (node->optional_number_child<double>("SubtitleFrameRate"))
 {
        if (version >= 32) {
                _use_subtitles = node->bool_child ("UseSubtitles");
@@ -118,38 +120,37 @@ SubtitleContent::SubtitleContent (Content* parent, shared_ptr<const Film> film,
 SubtitleContent::SubtitleContent (Content* parent, shared_ptr<const Film> film, vector<shared_ptr<Content> > c)
        : ContentPart (parent, film)
 {
-       shared_ptr<SubtitleContent> ref = dynamic_pointer_cast<SubtitleContent> (c[0]);
+       shared_ptr<SubtitleContent> ref = c[0]->subtitle;
        DCPOMATIC_ASSERT (ref);
        list<shared_ptr<Font> > ref_fonts = ref->fonts ();
 
-       for (size_t i = 0; i < c.size(); ++i) {
-               shared_ptr<SubtitleContent> sc = dynamic_pointer_cast<SubtitleContent> (c[i]);
+       for (size_t i = 1; i < c.size(); ++i) {
 
-               if (sc->use_subtitles() != ref->use_subtitles()) {
+               if (c[i]->subtitle->use_subtitles() != ref->use_subtitles()) {
                        throw JoinError (_("Content to be joined must have the same 'use subtitles' setting."));
                }
 
-               if (sc->burn_subtitles() != ref->burn_subtitles()) {
+               if (c[i]->subtitle->burn_subtitles() != ref->burn_subtitles()) {
                        throw JoinError (_("Content to be joined must have the same 'burn subtitles' setting."));
                }
 
-               if (sc->subtitle_x_offset() != ref->subtitle_x_offset()) {
+               if (c[i]->subtitle->subtitle_x_offset() != ref->subtitle_x_offset()) {
                        throw JoinError (_("Content to be joined must have the same subtitle X offset."));
                }
 
-               if (sc->subtitle_y_offset() != ref->subtitle_y_offset()) {
+               if (c[i]->subtitle->subtitle_y_offset() != ref->subtitle_y_offset()) {
                        throw JoinError (_("Content to be joined must have the same subtitle Y offset."));
                }
 
-               if (sc->subtitle_x_scale() != ref->subtitle_x_scale()) {
+               if (c[i]->subtitle->subtitle_x_scale() != ref->subtitle_x_scale()) {
                        throw JoinError (_("Content to be joined must have the same subtitle X scale."));
                }
 
-               if (sc->subtitle_y_scale() != ref->subtitle_y_scale()) {
+               if (c[i]->subtitle->subtitle_y_scale() != ref->subtitle_y_scale()) {
                        throw JoinError (_("Content to be joined must have the same subtitle Y scale."));
                }
 
-               list<shared_ptr<Font> > fonts = sc->fonts ();
+               list<shared_ptr<Font> > fonts = c[i]->subtitle->fonts ();
                if (fonts.size() != ref_fonts.size()) {
                        throw JoinError (_("Content to be joined must use the same fonts."));
                }
@@ -315,3 +316,27 @@ SubtitleContent::set_subtitle_language (string language)
 {
        maybe_set (_subtitle_language, language, SubtitleContentProperty::SUBTITLE_LANGUAGE);
 }
+
+void
+SubtitleContent::set_subtitle_video_frame_rate (double r)
+{
+       maybe_set (_frame_rate, r, SubtitleContentProperty::SUBTITLE_VIDEO_FRAME_RATE);
+}
+
+double
+SubtitleContent::subtitle_video_frame_rate () const
+{
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               if (_frame_rate) {
+                       return _frame_rate.get ();
+               }
+       }
+
+       /* No frame rate specified, so assume this content has been
+          prepared for any concurrent video content.
+       */
+       shared_ptr<const Film> film = _film.lock ();
+       DCPOMATIC_ASSERT (film);
+       return film->active_frame_rate_change(_parent->position()).source;
+}
index 5982cc5..0adb12c 100644 (file)
@@ -130,6 +130,9 @@ public:
                return _outline_colour;
        }
 
+       double subtitle_video_frame_rate () const;
+       void set_subtitle_video_frame_rate (double r);
+
 protected:
        /** subtitle language (e.g. "German") or empty if it is not known */
        std::string _subtitle_language;
@@ -158,6 +161,8 @@ private:
        bool _outline;
        dcp::Colour _outline_colour;
        std::list<boost::signals2::connection> _font_connections;
+       /** Video frame rate that this content has been prepared for, if known */
+       boost::optional<double> _frame_rate;
 };
 
 #endif
index c7dd19d..79a225c 100644 (file)
@@ -86,33 +86,6 @@ TextSubtitleContent::as_xml (xmlpp::Node* node) const
 DCPTime
 TextSubtitleContent::full_length () const
 {
-       FrameRateChange const frc (subtitle_video_frame_rate(), film()->video_frame_rate ());
+       FrameRateChange const frc (subtitle->subtitle_video_frame_rate(), film()->video_frame_rate ());
        return DCPTime (_length, frc);
 }
-
-void
-TextSubtitleContent::set_subtitle_video_frame_rate (double r)
-{
-       {
-               boost::mutex::scoped_lock lm (_mutex);
-               _frame_rate = r;
-       }
-
-       signal_changed (SubtitleContentProperty::SUBTITLE_VIDEO_FRAME_RATE);
-}
-
-double
-TextSubtitleContent::subtitle_video_frame_rate () const
-{
-       {
-               boost::mutex::scoped_lock lm (_mutex);
-               if (_frame_rate) {
-                       return _frame_rate.get ();
-               }
-       }
-
-       /* No frame rate specified, so assume this content has been
-          prepared for any concurrent video content.
-       */
-       return film()->active_frame_rate_change(position()).source;
-}
index 76440ba..61dac48 100644 (file)
@@ -40,13 +40,8 @@ public:
        void as_xml (xmlpp::Node *) const;
        DCPTime full_length () const;
 
-       double subtitle_video_frame_rate () const;
-       void set_subtitle_video_frame_rate (double r);
-
        static std::string const font_id;
 
 private:
        ContentTime _length;
-       /** Video frame rate that this content has been prepared for, if known */
-       boost::optional<double> _frame_rate;
 };
index c018c92..b7b0566 100644 (file)
@@ -72,9 +72,8 @@ Transcoder::go ()
        int burnt_subtitles = 0;
        int non_burnt_subtitles = 0;
        BOOST_FOREACH (shared_ptr<const Content> c, _film->content ()) {
-               shared_ptr<const SubtitleContent> sc = dynamic_pointer_cast<const SubtitleContent> (c);
-               if (sc && sc->use_subtitles()) {
-                       if (sc->burn_subtitles()) {
+               if (c->subtitle && c->subtitle->use_subtitles()) {
+                       if (c->subtitle->burn_subtitles()) {
                                ++burnt_subtitles;
                        } else {
                                ++non_burnt_subtitles;
index 2bc6fa3..8eabdbf 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -48,7 +48,6 @@ namespace xmlpp {
 #define SERVER_LINK_VERSION (64+0)
 
 typedef std::vector<boost::shared_ptr<Content> > ContentList;
-typedef std::vector<boost::shared_ptr<AudioContent> > AudioContentList;
 typedef std::vector<boost::shared_ptr<FFmpegContent> > FFmpegContentList;
 
 typedef int64_t Frame;
index 561ebb6..567ab3c 100644 (file)
@@ -119,43 +119,42 @@ VideoContent::VideoContent (Content* parent, shared_ptr<const Film> film, vector
        , _video_length (0)
        , _yuv (false)
 {
-       shared_ptr<VideoContent> ref = dynamic_pointer_cast<VideoContent> (c[0]);
+       shared_ptr<VideoContent> ref = c[0]->video;
        DCPOMATIC_ASSERT (ref);
 
-       for (size_t i = 0; i < c.size(); ++i) {
-               shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> (c[i]);
+       for (size_t i = 1; i < c.size(); ++i) {
 
-               if (vc->video_size() != ref->video_size()) {
+               if (c[i]->video->video_size() != ref->video_size()) {
                        throw JoinError (_("Content to be joined must have the same picture size."));
                }
 
-               if (vc->video_frame_rate() != ref->video_frame_rate()) {
+               if (c[i]->video->video_frame_rate() != ref->video_frame_rate()) {
                        throw JoinError (_("Content to be joined must have the same video frame rate."));
                }
 
-               if (vc->video_frame_type() != ref->video_frame_type()) {
+               if (c[i]->video->video_frame_type() != ref->video_frame_type()) {
                        throw JoinError (_("Content to be joined must have the same video frame type."));
                }
 
-               if (vc->crop() != ref->crop()) {
+               if (c[i]->video->crop() != ref->crop()) {
                        throw JoinError (_("Content to be joined must have the same crop."));
                }
 
-               if (vc->scale() != ref->scale()) {
+               if (c[i]->video->scale() != ref->scale()) {
                        throw JoinError (_("Content to be joined must have the same scale setting."));
                }
 
-               if (vc->colour_conversion() != ref->colour_conversion()) {
+               if (c[i]->video->colour_conversion() != ref->colour_conversion()) {
                        throw JoinError (_("Content to be joined must have the same colour conversion."));
                }
 
-               if (vc->fade_in() != ref->fade_in() || vc->fade_out() != ref->fade_out()) {
+               if (c[i]->video->fade_in() != ref->fade_in() || c[i]->video->fade_out() != ref->fade_out()) {
                        throw JoinError (_("Content to be joined must have the same fades."));
                }
 
-               _video_length += vc->video_length ();
+               _video_length += c[i]->video->video_length ();
 
-               if (vc->yuv ()) {
+               if (c[i]->video->yuv ()) {
                        _yuv = true;
                }
        }
index 7ab6d28..63dd7f4 100644 (file)
@@ -84,19 +84,18 @@ print_dump (shared_ptr<Film> film)
                     << " start trim " << c->trim_start().seconds ()
                     << " end trim " << c->trim_end().seconds () << "\n";
 
-               shared_ptr<VideoContent> video = dynamic_pointer_cast<VideoContent> (c);
-               if (video) {
-                       cout << "\t" << video->video_size().width << "x" << video->video_size().height << "\n"
-                            << "\t" << video->video_frame_rate() << "fps\n"
-                            << "\tcrop left " << video->left_crop()
-                            << " right " << video->right_crop()
-                            << " top " << video->top_crop()
-                            << " bottom " << video->bottom_crop() << "\n"
-                            << "\tscale " << video->scale().name() << "\n";
-                       if (video->colour_conversion()) {
-                               if (video->colour_conversion().get().preset()) {
+               if (c->video) {
+                       cout << "\t" << c->video->video_size().width << "x" << c->video->video_size().height << "\n"
+                            << "\t" << c->video->video_frame_rate() << "fps\n"
+                            << "\tcrop left " << c->video->left_crop()
+                            << " right " << c->video->right_crop()
+                            << " top " << c->video->top_crop()
+                            << " bottom " << c->video->bottom_crop() << "\n"
+                            << "\tscale " << c->video->scale().name() << "\n";
+                       if (c->video->colour_conversion()) {
+                               if (c->video->colour_conversion().get().preset()) {
                                        cout << "\tcolour conversion "
-                                            << PresetColourConversion::all()[video->colour_conversion().get().preset().get()].name
+                                            << PresetColourConversion::all()[c->video->colour_conversion().get().preset().get()].name
                                             << "\n";
                                } else {
                                        cout << "\tcustom colour conversion\n";
@@ -107,10 +106,9 @@ print_dump (shared_ptr<Film> film)
 
                }
 
-               shared_ptr<AudioContent> audio = dynamic_pointer_cast<AudioContent> (c);
-               if (audio) {
-                       cout << "\t" << audio->audio_delay() << " delay\n"
-                            << "\t" << audio->audio_gain() << " gain\n";
+               if (c->audio) {
+                       cout << "\t" << c->audio->audio_delay() << " delay\n"
+                            << "\t" << c->audio->audio_gain() << " gain\n";
                }
        }
 }
index 20185bf..2120c3a 100644 (file)
@@ -39,7 +39,7 @@ using boost::const_pointer_cast;
 using boost::dynamic_pointer_cast;
 
 /** @param content Content to analyse, or 0 to analyse all of the film's audio */
-AudioDialog::AudioDialog (wxWindow* parent, shared_ptr<Film> film, shared_ptr<AudioContent> content)
+AudioDialog::AudioDialog (wxWindow* parent, shared_ptr<Film> film, shared_ptr<Content> content)
        : wxDialog (parent, wxID_ANY, _("Audio"), wxDefaultPosition, wxSize (640, 512), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxFULL_REPAINT_ON_RESIZE)
        , _film (film)
        , _content (content)
index 8320171..8624b7a 100644 (file)
@@ -30,7 +30,7 @@ class Film;
 class AudioDialog : public wxDialog
 {
 public:
-       AudioDialog (wxWindow *, boost::shared_ptr<Film> film, boost::shared_ptr<AudioContent> content = boost::shared_ptr<AudioContent> ());
+       AudioDialog (wxWindow *, boost::shared_ptr<Film> film, boost::shared_ptr<Content> content = boost::shared_ptr<Content> ());
 
        bool Show (bool show = true);
 
index 9e2ba98..a41e428 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -28,6 +28,7 @@
 #include "lib/cinema_sound_processor.h"
 #include "lib/job_manager.h"
 #include "lib/dcp_content.h"
+#include "lib/audio_content.h"
 #include <wx/spinctrl.h>
 #include <boost/foreach.hpp>
 #include <iostream>
@@ -65,6 +66,7 @@ AudioPanel::AudioPanel (ContentPanel* p)
                this,
                new wxSpinCtrlDouble (this),
                AudioContentProperty::AUDIO_GAIN,
+               &Content::audio,
                boost::mem_fn (&AudioContent::audio_gain),
                boost::mem_fn (&AudioContent::set_audio_gain)
                );
@@ -80,6 +82,7 @@ AudioPanel::AudioPanel (ContentPanel* p)
                this,
                new wxSpinCtrl (this),
                AudioContentProperty::AUDIO_DELAY,
+               &Content::audio,
                boost::mem_fn (&AudioContent::audio_delay),
                boost::mem_fn (&AudioContent::set_audio_delay)
                );
@@ -145,11 +148,11 @@ AudioPanel::film_changed (Film::Property property)
 void
 AudioPanel::film_content_changed (int property)
 {
-       AudioContentList ac = _parent->selected_audio ();
+       ContentList ac = _parent->selected_audio ();
        if (property == AudioContentProperty::AUDIO_STREAMS) {
                if (ac.size() == 1) {
-                       _mapping->set (ac.front()->audio_mapping());
-                       _mapping->set_input_channels (ac.front()->audio_channel_names ());
+                       _mapping->set (ac.front()->audio->audio_mapping());
+                       _mapping->set_input_channels (ac.front()->audio->audio_channel_names ());
                } else {
                        _mapping->set (AudioMapping ());
                }
@@ -201,28 +204,28 @@ AudioPanel::gain_calculate_button_clicked ()
 void
 AudioPanel::setup_description ()
 {
-       AudioContentList ac = _parent->selected_audio ();
+       ContentList ac = _parent->selected_audio ();
        if (ac.size () != 1) {
                checked_set (_description, wxT (""));
                return;
        }
 
-       checked_set (_description, ac.front()->processing_description ());
+       checked_set (_description, ac.front()->audio->processing_description ());
 }
 
 void
 AudioPanel::mapping_changed (AudioMapping m)
 {
-       AudioContentList c = _parent->selected_audio ();
+       ContentList c = _parent->selected_audio ();
        if (c.size() == 1) {
-               c.front()->set_audio_mapping (m);
+               c.front()->audio->set_audio_mapping (m);
        }
 }
 
 void
 AudioPanel::content_selection_changed ()
 {
-       AudioContentList sel = _parent->selected_audio ();
+       ContentList sel = _parent->selected_audio ();
 
        _gain->set_content (sel);
        _delay->set_content (sel);
@@ -236,7 +239,7 @@ AudioPanel::content_selection_changed ()
 void
 AudioPanel::setup_sensitivity ()
 {
-       AudioContentList sel = _parent->selected_audio ();
+       ContentList sel = _parent->selected_audio ();
 
        shared_ptr<DCPContent> dcp;
        if (sel.size() == 1) {
@@ -272,7 +275,7 @@ AudioPanel::show_clicked ()
                _audio_dialog = 0;
        }
 
-       AudioContentList ac = _parent->selected_audio ();
+       ContentList ac = _parent->selected_audio ();
        if (ac.size() != 1) {
                return;
        }
@@ -284,7 +287,7 @@ AudioPanel::show_clicked ()
 void
 AudioPanel::setup_peak ()
 {
-       AudioContentList sel = _parent->selected_audio ();
+       ContentList sel = _parent->selected_audio ();
        bool alert = false;
 
        if (sel.size() != 1) {
index c643602..f2e00ea 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -32,6 +32,7 @@
 #include "lib/exceptions.h"
 #include "lib/dcp_content.h"
 #include "lib/ffmpeg_content.h"
+#include "lib/audio_content.h"
 #include <wx/wx.h>
 #include <wx/dirdlg.h>
 #include <boost/foreach.hpp>
@@ -205,9 +206,9 @@ ContentMenu::remove ()
                        }
 
                        if (!video && audio) {
-                               AudioMapping m = fc->audio_mapping ();
+                               AudioMapping m = fc->audio->audio_mapping ();
                                m.unmap_all ();
-                               fc->set_audio_mapping (m);
+                               fc->audio->set_audio_mapping (m);
                                handled = true;
                        }
                }
index ad48948..36f0a6b 100644 (file)
@@ -163,15 +163,14 @@ ContentPanel::selected_video ()
        return vc;
 }
 
-AudioContentList
+ContentList
 ContentPanel::selected_audio ()
 {
-       AudioContentList ac;
+       ContentList ac;
 
        BOOST_FOREACH (shared_ptr<Content> i, selected ()) {
-               shared_ptr<AudioContent> t = dynamic_pointer_cast<AudioContent> (i);
-               if (t) {
-                       ac.push_back (t);
+               if (i->audio) {
+                       ac.push_back (i);
                }
        }
 
@@ -387,7 +386,7 @@ ContentPanel::setup_sensitivity ()
 
        ContentList selection = selected ();
        ContentList video_selection = selected_video ();
-       AudioContentList audio_selection = selected_audio ();
+       ContentList audio_selection = selected_audio ();
 
        _remove->Enable   (!selection.empty() && _generally_sensitive);
        _earlier->Enable  (selection.size() == 1 && _generally_sensitive);
@@ -396,7 +395,7 @@ ContentPanel::setup_sensitivity ()
 
        _video_panel->Enable    (video_selection.size() > 0 && _generally_sensitive);
        _audio_panel->Enable    (audio_selection.size() > 0 && _generally_sensitive);
-       _subtitle_panel->Enable (selection.size() == 1 && dynamic_pointer_cast<SubtitleContent> (selection.front()) && _generally_sensitive);
+       _subtitle_panel->Enable (selection.size() == 1 && selection.front()->subtitle && _generally_sensitive);
        _timing_panel->Enable   (selection.size() == 1 && _generally_sensitive);
 }
 
index f4e2dba..caaa2de 100644 (file)
@@ -60,7 +60,7 @@ public:
 
        ContentList selected ();
        ContentList selected_video ();
-       AudioContentList selected_audio ();
+       ContentList selected_audio ();
        ContentList selected_subtitle ();
        FFmpegContentList selected_ffmpeg ();
 
index 3fa1f0d..49dceef 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
  *  @brief ContentWidget class.
  */
 
-#ifndef DCPOMATIC_MULTIPLE_WIDGET_H
-#define DCPOMATIC_MULTIPLE_WIDGET_H
+#ifndef DCPOMATIC_CONTENT_WIDGET_H
+#define DCPOMATIC_CONTENT_WIDGET_H
 
-#include <vector>
+#include "wx_util.h"
+#include "lib/content.h"
 #include <wx/wx.h>
 #include <wx/gbsizer.h>
 #include <wx/spinctrl.h>
 #include <boost/function.hpp>
-#include "wx_util.h"
+#include <vector>
 
 /** @class ContentWidget
  *  @brief A widget which represents some Content state and which can be used
  *  when multiple pieces of content are selected.
  *
- *  @param S Type containing the content being represented (e.g. VideoContent)
+ *  @param S Type of ContentPart being manipulated (e.g. VideoContent)
  *  @param T Type of the widget (e.g. wxSpinCtrl)
  *  @param U Data type of state as used by the model.
  *  @param V Data type of state as used by the view.
@@ -54,6 +55,7 @@ public:
                wxWindow* parent,
                T* wrapped,
                int property,
+               boost::function<boost::shared_ptr<S> (Content*)> part,
                boost::function<U (S*)> model_getter,
                boost::function<void (S*, U)> model_setter,
                boost::function<U (V)> view_to_model,
@@ -63,6 +65,7 @@ public:
                , _sizer (0)
                , _button (new wxButton (parent, wxID_ANY, _("Multiple values")))
                , _property (property)
+               , _part (part)
                , _model_getter (model_getter)
                , _model_setter (model_setter)
                , _view_to_model (view_to_model)
@@ -80,7 +83,7 @@ public:
                return _wrapped;
        }
 
-       typedef std::vector<boost::shared_ptr<S> > List;
+       typedef std::vector<boost::shared_ptr<Content> > List;
 
        /** Set the content that this control is working on (i.e. the selected content) */
        void set_content (List content)
@@ -120,8 +123,8 @@ public:
                }
 
                typename List::iterator i = _content.begin ();
-               U const v = boost::bind (_model_getter, _content.front().get())();
-               while (i != _content.end() && boost::bind (_model_getter, i->get())() == v) {
+               U const v = boost::bind (_model_getter, _part(_content.front().get()).get())();
+               while (i != _content.end() && boost::bind (_model_getter, _part(i->get()).get())() == v) {
                        ++i;
                }
 
@@ -137,7 +140,7 @@ public:
        {
                _ignore_model_changes = true;
                for (size_t i = 0; i < _content.size(); ++i) {
-                       boost::bind (_model_setter, _content[i].get(), _view_to_model (wx_get (_wrapped))) ();
+                       boost::bind (_model_setter, _part (_content[i].get()).get(), _view_to_model (wx_get (_wrapped))) ();
                }
                _ignore_model_changes = false;
        }
@@ -172,9 +175,9 @@ private:
 
        void button_clicked ()
        {
-               U const v = boost::bind (_model_getter, _content.front().get())();
+               U const v = boost::bind (_model_getter, _part(_content.front().get()).get())();
                for (typename List::iterator i = _content.begin (); i != _content.end(); ++i) {
-                       boost::bind (_model_setter, i->get(), v) ();
+                       boost::bind (_model_setter, _part(i->get()).get(), v) ();
                }
        }
 
@@ -192,6 +195,7 @@ private:
        wxButton* _button;
        List _content;
        int _property;
+       boost::function<boost::shared_ptr<S> (Content *)> _part;
        boost::function<U (S*)> _model_getter;
        boost::function<void (S*, U)> _model_setter;
        boost::function<U (V)> _view_to_model;
@@ -214,6 +218,7 @@ public:
                wxWindow* parent,
                wxSpinCtrl* wrapped,
                int property,
+               boost::function<boost::shared_ptr<S> (Content *)> part,
                boost::function<int (S*)> getter,
                boost::function<void (S*, int)> setter
                )
@@ -221,6 +226,7 @@ public:
                        parent,
                        wrapped,
                        property,
+                       part,
                        getter, setter,
                        &caster<int, int>,
                        &caster<int, int>
@@ -238,6 +244,7 @@ public:
                wxWindow* parent,
                wxSpinCtrlDouble* wrapped,
                int property,
+               boost::function<boost::shared_ptr<S> (Content *)> part,
                boost::function<double (S*)> getter,
                boost::function<void (S*, double)> setter
                )
@@ -245,6 +252,7 @@ public:
                        parent,
                        wrapped,
                        property,
+                       part,
                        getter, setter,
                        &caster<double, double>,
                        &caster<double, double>
@@ -262,6 +270,7 @@ public:
                wxWindow* parent,
                wxChoice* wrapped,
                int property,
+               boost::function<boost::shared_ptr<S> (Content *)> part,
                boost::function<U (S*)> getter,
                boost::function<void (S*, U)> setter,
                boost::function<U (int)> view_to_model,
@@ -271,6 +280,7 @@ public:
                        parent,
                        wrapped,
                        property,
+                       part,
                        getter,
                        setter,
                        view_to_model,
index c62767c..30657f8 100644 (file)
@@ -32,6 +32,7 @@
 #include "lib/video_content.h"
 #include "lib/subtitle_content.h"
 #include "lib/dcp_content.h"
+#include "lib/audio_content.h"
 #include <dcp/key.h>
 #include <dcp/raw_convert.h>
 #include <wx/wx.h>
index 75643c3..1c49a20 100644 (file)
@@ -78,11 +78,10 @@ HintsDialog::film_changed ()
        bool big_font_files = false;
        if (film->interop ()) {
                BOOST_FOREACH (shared_ptr<Content> i, content) {
-                       shared_ptr<SubtitleContent> s = dynamic_pointer_cast<SubtitleContent> (i);
-                       if (s) {
-                               BOOST_FOREACH (shared_ptr<Font> j, s->fonts ()) {
-                                       for (int i = 0; i < FontFiles::VARIANTS; ++i) {
-                                               optional<boost::filesystem::path> const p = j->file (static_cast<FontFiles::Variant> (i));
+                       if (i->subtitle) {
+                               BOOST_FOREACH (shared_ptr<Font> j, i->subtitle->fonts ()) {
+                                       for (int k = 0; k < FontFiles::VARIANTS; ++k) {
+                                               optional<boost::filesystem::path> const p = j->file (static_cast<FontFiles::Variant> (k));
                                                if (p && boost::filesystem::file_size (p.get()) >= (640 * 1024)) {
                                                        big_font_files = true;
                                                }
@@ -106,9 +105,8 @@ HintsDialog::film_changed ()
        int flat_or_narrower = 0;
        int scope = 0;
        BOOST_FOREACH (shared_ptr<const Content> i, content) {
-               shared_ptr<const VideoContent> vc = dynamic_pointer_cast<const VideoContent> (i);
-               if (vc) {
-                       Ratio const * r = vc->scale().ratio ();
+               if (i->video) {
+                       Ratio const * r = i->video->scale().ratio ();
                        if (r && r->id() == "239") {
                                ++scope;
                        } else if (r && r->id() != "239" && r->id() != "full-frame") {
@@ -162,8 +160,7 @@ HintsDialog::film_changed ()
 
        int three_d = 0;
        BOOST_FOREACH (shared_ptr<const Content> i, content) {
-               shared_ptr<const VideoContent> vc = dynamic_pointer_cast<const VideoContent> (i);
-               if (vc && vc->video_frame_type() != VIDEO_FRAME_TYPE_2D) {
+               if (i->video && i->video->video_frame_type() != VIDEO_FRAME_TYPE_2D) {
                        ++three_d;
                }
        }
index 56af6f7..f9fd165 100644 (file)
@@ -149,8 +149,7 @@ Timeline::recreate_views ()
                        _views.push_back (shared_ptr<TimelineView> (new TimelineVideoContentView (*this, i)));
                }
 
-               shared_ptr<AudioContent> ac = dynamic_pointer_cast<AudioContent> (i);
-               if (ac && !ac->audio_mapping().mapped_output_channels().empty ()) {
+               if (i->audio && !i->audio->audio_mapping().mapped_output_channels().empty ()) {
                        _views.push_back (shared_ptr<TimelineView> (new TimelineAudioContentView (*this, i)));
                }
 
index 18a07ad..573d76f 100644 (file)
@@ -290,7 +290,7 @@ TimingPanel::film_content_changed (int property)
                        } else if (ac) {
                                checked_set (_video_frame_rate, raw_convert<string> (ac->audio->audio_video_frame_rate (), 5));
                        } else if (sc) {
-                               checked_set (_video_frame_rate, raw_convert<string> (sc->subtitle_video_frame_rate (), 5));
+                               checked_set (_video_frame_rate, raw_convert<string> (sc->subtitle->subtitle_video_frame_rate (), 5));
                        }
                        _video_frame_rate->Enable (true);
                } else {
@@ -403,16 +403,14 @@ void
 TimingPanel::set_video_frame_rate ()
 {
        BOOST_FOREACH (shared_ptr<Content> i, _parent->selected ()) {
-               shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> (i);
-               shared_ptr<AudioContent> ac = dynamic_pointer_cast<AudioContent> (i);
                shared_ptr<DCPSubtitleContent> dsc = dynamic_pointer_cast<DCPSubtitleContent> (i);
                shared_ptr<TextSubtitleContent> tsc = dynamic_pointer_cast<TextSubtitleContent> (i);
                double const fr = raw_convert<double> (wx_to_std (_video_frame_rate->GetValue ()));
-               if (vc) {
-                       vc->set_video_frame_rate (fr);
-               } else if (ac) {
+               if (i->video) {
+                       i->video->set_video_frame_rate (fr);
+               } else if (i->audio) {
                        /* Audio but not video, i.e. SndfileContent */
-                       ac->set_audio_video_frame_rate (fr);
+                       i->audio->set_audio_video_frame_rate (fr);
                } else if (dsc) {
                        dsc->set_subtitle_video_frame_rate (fr);
                } else if (tsc) {
index b5bd27b..8bdac00 100644 (file)
@@ -87,6 +87,7 @@ VideoPanel::VideoPanel (ContentPanel* p)
                this,
                new wxChoice (this, wxID_ANY),
                VideoContentProperty::VIDEO_FRAME_TYPE,
+               &Content::video,
                boost::mem_fn (&VideoContent::video_frame_type),
                boost::mem_fn (&VideoContent::set_video_frame_type),
                &caster<int, VideoFrameType>,
@@ -105,6 +106,7 @@ VideoPanel::VideoPanel (ContentPanel* p)
                this,
                new wxSpinCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)),
                VideoContentProperty::VIDEO_CROP,
+               &Content::video,
                boost::mem_fn (&VideoContent::left_crop),
                boost::mem_fn (&VideoContent::set_left_crop)
                );
@@ -115,6 +117,7 @@ VideoPanel::VideoPanel (ContentPanel* p)
                this,
                new wxSpinCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)),
                VideoContentProperty::VIDEO_CROP,
+               &Content::video,
                boost::mem_fn (&VideoContent::right_crop),
                boost::mem_fn (&VideoContent::set_right_crop)
                );
@@ -127,6 +130,7 @@ VideoPanel::VideoPanel (ContentPanel* p)
                this,
                new wxSpinCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)),
                VideoContentProperty::VIDEO_CROP,
+               &Content::video,
                boost::mem_fn (&VideoContent::top_crop),
                boost::mem_fn (&VideoContent::set_top_crop)
                );
@@ -137,6 +141,7 @@ VideoPanel::VideoPanel (ContentPanel* p)
                this,
                new wxSpinCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (64, -1)),
                VideoContentProperty::VIDEO_CROP,
+               &Content::video,
                boost::mem_fn (&VideoContent::bottom_crop),
                boost::mem_fn (&VideoContent::set_bottom_crop)
                );
@@ -160,6 +165,7 @@ VideoPanel::VideoPanel (ContentPanel* p)
                this,
                new wxChoice (this, wxID_ANY),
                VideoContentProperty::VIDEO_SCALE,
+               &Content::video,
                boost::mem_fn (&VideoContent::scale),
                boost::mem_fn (&VideoContent::set_scale),
                &index_to_scale,
index 83ed458..75306d8 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -30,6 +30,7 @@
 #include "lib/ffmpeg_content.h"
 #include "lib/ratio.h"
 #include "lib/job_manager.h"
+#include "lib/audio_content.h"
 #include "test.h"
 
 using boost::shared_ptr;
@@ -110,8 +111,8 @@ BOOST_AUTO_TEST_CASE (audio_analysis_negative_delay_test)
 {
        shared_ptr<Film> film = new_test_film ("audio_analysis_negative_delay_test");
        film->set_name ("audio_analysis_negative_delay_test");
-       shared_ptr<AudioContent> c (new FFmpegContent (film, private_data / "boon_telly.mkv"));
-       c->set_audio_delay (-250);
+       shared_ptr<FFmpegContent> c (new FFmpegContent (film, private_data / "boon_telly.mkv"));
+       c->audio->set_audio_delay (-250);
        film->examine_and_add_content (c);
        wait_for_jobs ();
 
@@ -126,7 +127,7 @@ BOOST_AUTO_TEST_CASE (audio_analysis_test2)
 {
        shared_ptr<Film> film = new_test_film ("audio_analysis_test2");
        film->set_name ("audio_analysis_test2");
-       shared_ptr<AudioContent> c (new FFmpegContent (film, private_data / "3d_thx_broadway_2010_lossless.m2ts"));
+       shared_ptr<FFmpegContent> c (new FFmpegContent (film, private_data / "3d_thx_broadway_2010_lossless.m2ts"));
        film->examine_and_add_content (c);
        wait_for_jobs ();
 
index 2c6794a..f714e06 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
  *  @brief Tests of the AudioDecoder class.
  */
 
-#include <cassert>
-#include <boost/test/unit_test.hpp>
 #include "test.h"
+#include "lib/content.h"
 #include "lib/audio_decoder.h"
-#include "lib/single_stream_audio_content.h"
+#include "lib/audio_content.h"
+#include "lib/film.h"
+#include <boost/test/unit_test.hpp>
+#include <cassert>
 #include <iostream>
 
 using std::string;
@@ -33,14 +35,14 @@ using std::cout;
 using std::min;
 using boost::shared_ptr;
 
-class TestAudioContent : public SingleStreamAudioContent
+class TestAudioContent : public Content
 {
 public:
        TestAudioContent (shared_ptr<const Film> film)
                : Content (film)
-               , SingleStreamAudioContent (film)
        {
-               _audio_stream.reset (new AudioStream (48000, 2));
+               audio.reset (new AudioContent (this, film));
+               audio->set_stream (AudioStreamPtr (new AudioStream (48000, 2)));
        }
 
        std::string summary () const {
@@ -48,19 +50,19 @@ public:
        }
 
        DCPTime full_length () const {
-               return DCPTime::from_seconds (float (audio_length()) / audio_stream()->frame_rate ());
+               return DCPTime::from_seconds (float (audio_length()) / audio->stream()->frame_rate ());
        }
 
        Frame audio_length () const {
-               return llrint (61.2942 * audio_stream()->frame_rate ());
+               return llrint (61.2942 * audio->stream()->frame_rate ());
        }
 };
 
 class TestAudioDecoder : public AudioDecoder
 {
 public:
-       TestAudioDecoder (shared_ptr<TestAudioContent> content)
-               : AudioDecoder (content, false)
+       TestAudioDecoder (shared_ptr<TestAudioContent> content, shared_ptr<Log> log)
+               : AudioDecoder (content->audio, false, log)
                , _test_audio_content (content)
                , _position (0)
        {}
@@ -72,14 +74,14 @@ public:
                        _test_audio_content->audio_length() - _position
                        );
 
-               shared_ptr<AudioBuffers> buffers (new AudioBuffers (_test_audio_content->audio_stream()->channels(), N));
-               for (int i = 0; i < _test_audio_content->audio_stream()->channels(); ++i) {
+               shared_ptr<AudioBuffers> buffers (new AudioBuffers (_test_audio_content->audio->stream()->channels(), N));
+               for (int i = 0; i < _test_audio_content->audio->stream()->channels(); ++i) {
                        for (int j = 0; j < N; ++j) {
                                buffers->data(i)[j] = j + _position;
                        }
                }
 
-               audio (_test_audio_content->audio_stream(), buffers, ContentTime::from_frames (_position, 48000));
+               audio (_test_audio_content->audio->stream(), buffers, ContentTime::from_frames (_position, 48000));
                _position += N;
 
                return N < 2000;
@@ -88,7 +90,7 @@ public:
        void seek (ContentTime t, bool accurate)
        {
                AudioDecoder::seek (t, accurate);
-               _position = t.frames_round (_test_audio_content->resampled_audio_frame_rate ());
+               _position = t.frames_round (_test_audio_content->audio->resampled_audio_frame_rate ());
        }
 
 private:
@@ -102,8 +104,8 @@ shared_ptr<TestAudioDecoder> decoder;
 static ContentAudio
 get (Frame from, Frame length)
 {
-       decoder->seek (ContentTime::from_frames (from, content->resampled_audio_frame_rate ()), true);
-       ContentAudio ca = decoder->get_audio (content->audio_stream(), from, length, true);
+       decoder->seek (ContentTime::from_frames (from, content->audio->resampled_audio_frame_rate ()), true);
+       ContentAudio ca = decoder->get_audio (content->audio->stream(), from, length, true);
        BOOST_CHECK_EQUAL (ca.frame, from);
        return ca;
 }
@@ -112,7 +114,7 @@ static void
 check (Frame from, Frame length)
 {
        ContentAudio ca = get (from, length);
-       for (int i = 0; i < content->audio_stream()->channels(); ++i) {
+       for (int i = 0; i < content->audio->stream()->channels(); ++i) {
                for (int j = 0; j < length; ++j) {
                        BOOST_REQUIRE_EQUAL (ca.audio->data(i)[j], j + from);
                }
@@ -125,20 +127,21 @@ BOOST_AUTO_TEST_CASE (audio_decoder_get_audio_test)
        shared_ptr<Film> film = new_test_film ("audio_decoder_test");
 
        content.reset (new TestAudioContent (film));
-       decoder.reset (new TestAudioDecoder (content));
+       decoder.reset (new TestAudioDecoder (content, film->log()));
 
        /* Simple reads */
+
        check (0, 48000);
        check (44, 9123);
        check (9991, 22);
 
        /* Read off the end */
 
-       Frame const from = content->resampled_audio_frame_rate() * 61;
-       Frame const length = content->resampled_audio_frame_rate() * 4;
+       Frame const from = content->audio->resampled_audio_frame_rate() * 61;
+       Frame const length = content->audio->resampled_audio_frame_rate() * 4;
        ContentAudio ca = get (from, length);
 
-       for (int i = 0; i < content->audio_stream()->channels(); ++i) {
+       for (int i = 0; i < content->audio->stream()->channels(); ++i) {
                for (int j = 0; j < ca.audio->frames(); ++j) {
                        BOOST_REQUIRE_EQUAL (ca.audio->data(i)[j], j + from);
                }
index a455110..f12e871 100644 (file)
@@ -33,6 +33,7 @@
 #include "lib/dcp_content_type.h"
 #include "lib/ratio.h"
 #include "lib/film.h"
+#include "lib/audio_content.h"
 #include "test.h"
 #include <iostream>
 
@@ -53,7 +54,7 @@ void test_audio_delay (int delay_in_ms)
        film->set_name (film_name);
 
        shared_ptr<SndfileContent> content (new SndfileContent (film, "test/data/staircase.wav"));
-       content->set_audio_delay (delay_in_ms);
+       content->audio->set_audio_delay (delay_in_ms);
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
index 7e13b1c..84ec322 100644 (file)
@@ -28,6 +28,7 @@
 #include "lib/ratio.h"
 #include "lib/dcp_decoder.h"
 #include "lib/dcp_content_type.h"
+#include "lib/subtitle_content.h"
 #include "test.h"
 #include <iostream>
 
@@ -48,8 +49,8 @@ BOOST_AUTO_TEST_CASE (dcp_subtitle_test)
 
        BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (2));
 
-       content->set_use_subtitles (true);
-       content->set_burn_subtitles (false);
+       content->subtitle->set_use_subtitles (true);
+       content->subtitle->set_burn_subtitles (false);
        film->make_dcp ();
        wait_for_jobs ();
 
index 78d092b..4d865de 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -30,6 +30,7 @@
 #include "lib/ffmpeg_audio_stream.h"
 #include "lib/frame_rate_change.h"
 #include "lib/video_content.h"
+#include "lib/audio_content.h"
 #include "test.h"
 
 using boost::shared_ptr;
@@ -265,34 +266,34 @@ BOOST_AUTO_TEST_CASE (audio_sampling_rate_test)
        content->video->_video_frame_rate = 24;
        film->set_video_frame_rate (24);
        stream->_frame_rate = 48000;
-       BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 48000);
+       BOOST_CHECK_EQUAL (content->audio->resampled_audio_frame_rate(), 48000);
 
        stream->_frame_rate = 44100;
-       BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 48000);
+       BOOST_CHECK_EQUAL (content->audio->resampled_audio_frame_rate(), 48000);
 
        stream->_frame_rate = 80000;
-       BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 96000);
+       BOOST_CHECK_EQUAL (content->audio->resampled_audio_frame_rate(), 96000);
 
        content->video->_video_frame_rate = 23.976;
        film->set_video_frame_rate (24);
        stream->_frame_rate = 48000;
-       BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 47952);
+       BOOST_CHECK_EQUAL (content->audio->resampled_audio_frame_rate(), 47952);
 
        content->video->_video_frame_rate = 29.97;
        film->set_video_frame_rate (30);
        BOOST_CHECK_EQUAL (film->video_frame_rate (), 30);
        stream->_frame_rate = 48000;
-       BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 47952);
+       BOOST_CHECK_EQUAL (content->audio->resampled_audio_frame_rate(), 47952);
 
        content->video->_video_frame_rate = 25;
        film->set_video_frame_rate (24);
        stream->_frame_rate = 48000;
-       BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 50000);
+       BOOST_CHECK_EQUAL (content->audio->resampled_audio_frame_rate(), 50000);
 
        content->video->_video_frame_rate = 25;
        film->set_video_frame_rate (24);
        stream->_frame_rate = 44100;
-       BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 50000);
+       BOOST_CHECK_EQUAL (content->audio->resampled_audio_frame_rate(), 50000);
 
        /* Check some out-there conversions (not the best) */
 
@@ -302,5 +303,5 @@ BOOST_AUTO_TEST_CASE (audio_sampling_rate_test)
        /* The FrameRateChange within resampled_audio_frame_rate should choose to double-up
           the 14.99 fps video to 30 and then run it slow at 25.
        */
-       BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), lrint (48000 * 2 * 14.99 / 25));
+       BOOST_CHECK_EQUAL (content->audio->resampled_audio_frame_rate(), lrint (48000 * 2 * 14.99 / 25));
 }
index fb5e26a..de56d47 100644 (file)
@@ -24,6 +24,8 @@
 #include "lib/image_content.h"
 #include "lib/sndfile_content.h"
 #include "lib/video_content.h"
+#include "lib/audio_mapping.h"
+#include "lib/audio_content.h"
 #include "test.h"
 #include <iostream>
 
@@ -130,31 +132,31 @@ BOOST_AUTO_TEST_CASE (isdcf_name_test)
        wait_for_jobs ();
        BOOST_CHECK_EQUAL (film->isdcf_name(false), "LikeShouting_XSN-2_F-133_DE-fr_US-R_10_4K_DI_20140704_PP_SMPTE_OV");
 
-       AudioMapping mapping = sound->audio_mapping ();
+       AudioMapping mapping = sound->audio->audio_mapping ();
 
        mapping.set (0, dcp::LEFT, 1.0);
-       sound->set_audio_mapping (mapping);
+       sound->audio->set_mapping (mapping);
        BOOST_CHECK_EQUAL (film->isdcf_name(false), "LikeShouting_XSN-2_F-133_DE-fr_US-R_20_4K_DI_20140704_PP_SMPTE_OV");
        mapping.set (0, dcp::RIGHT, 1.0);
-       sound->set_audio_mapping (mapping);
+       sound->audio->set_mapping (mapping);
        BOOST_CHECK_EQUAL (film->isdcf_name(false), "LikeShouting_XSN-2_F-133_DE-fr_US-R_30_4K_DI_20140704_PP_SMPTE_OV");
        mapping.set (0, dcp::LFE, 1.0);
-       sound->set_audio_mapping (mapping);
+       sound->audio->set_mapping (mapping);
        BOOST_CHECK_EQUAL (film->isdcf_name(false), "LikeShouting_XSN-2_F-133_DE-fr_US-R_31_4K_DI_20140704_PP_SMPTE_OV");
        mapping.set (0, dcp::LS, 1.0);
-       sound->set_audio_mapping (mapping);
+       sound->audio->set_mapping (mapping);
        BOOST_CHECK_EQUAL (film->isdcf_name(false), "LikeShouting_XSN-2_F-133_DE-fr_US-R_41_4K_DI_20140704_PP_SMPTE_OV");
        mapping.set (0, dcp::RS, 1.0);
-       sound->set_audio_mapping (mapping);
+       sound->audio->set_mapping (mapping);
        BOOST_CHECK_EQUAL (film->isdcf_name(false), "LikeShouting_XSN-2_F-133_DE-fr_US-R_51_4K_DI_20140704_PP_SMPTE_OV");
        mapping.set (0, dcp::HI, 1.0);
-       sound->set_audio_mapping (mapping);
+       sound->audio->set_mapping (mapping);
        BOOST_CHECK_EQUAL (film->isdcf_name(false), "LikeShouting_XSN-2_F-133_DE-fr_US-R_51_4K_DI_20140704_PP_SMPTE_OV");
        film->set_audio_channels (8);
        mapping.set (0, dcp::HI, 1.0);
-       sound->set_audio_mapping (mapping);
+       sound->audio->set_mapping (mapping);
        BOOST_CHECK_EQUAL (film->isdcf_name(false), "LikeShouting_XSN-2_F-133_DE-fr_US-R_61_4K_DI_20140704_PP_SMPTE_OV");
        mapping.set (0, dcp::VI, 1.0);
-       sound->set_audio_mapping (mapping);
+       sound->audio->set_mapping (mapping);
        BOOST_CHECK_EQUAL (film->isdcf_name(false), "LikeShouting_XSN-2_F-133_DE-fr_US-R_71_4K_DI_20140704_PP_SMPTE_OV");
 }
index b650aba..006a216 100644 (file)
@@ -26,6 +26,7 @@
 #include "lib/dcp_content_type.h"
 #include "lib/image_content.h"
 #include "lib/ffmpeg_content.h"
+#include "lib/video_content.h"
 #include "lib/ratio.h"
 #include <dcp/mono_picture_asset.h>
 #include <dcp/stereo_picture_asset.h>
@@ -86,7 +87,7 @@ BOOST_AUTO_TEST_CASE (recover_test_3d)
        film->set_three_d (true);
 
        shared_ptr<ImageContent> content (new ImageContent (film, "test/data/3d_test"));
-       content->set_video_frame_type (VIDEO_FRAME_TYPE_3D_LEFT_RIGHT);
+       content->video->set_video_frame_type (VIDEO_FRAME_TYPE_3D_LEFT_RIGHT);
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
index 223391f..ac4fcdd 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2015-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -23,6 +23,7 @@
 #include "lib/image_content.h"
 #include "lib/dcp_content_type.h"
 #include "lib/dcp_content.h"
+#include "lib/video_content.h"
 #include "lib/text_subtitle_content.h"
 #include "test.h"
 #include <boost/test/unit_test.hpp>
@@ -88,21 +89,21 @@ BOOST_AUTO_TEST_CASE (reels_test2)
                shared_ptr<ImageContent> c (new ImageContent (film, "test/data/flat_red.png"));
                film->examine_and_add_content (c);
                wait_for_jobs ();
-               c->set_video_length (24);
+               c->video->set_video_length (24);
        }
 
        {
                shared_ptr<ImageContent> c (new ImageContent (film, "test/data/flat_green.png"));
                film->examine_and_add_content (c);
                wait_for_jobs ();
-               c->set_video_length (24);
+               c->video->set_video_length (24);
        }
 
        {
                shared_ptr<ImageContent> c (new ImageContent (film, "test/data/flat_blue.png"));
                film->examine_and_add_content (c);
                wait_for_jobs ();
-               c->set_video_length (24);
+               c->video->set_video_length (24);
        }
 
        film->set_reel_type (REELTYPE_BY_VIDEO_CONTENT);
@@ -192,7 +193,7 @@ BOOST_AUTO_TEST_CASE (reels_test4)
                content[i].reset (new ImageContent (film, "test/data/flat_green.png"));
                film->examine_and_add_content (content[i]);
                wait_for_jobs ();
-               content[i]->set_video_length (24);
+               content[i]->video->set_video_length (24);
        }
 
        shared_ptr<TextSubtitleContent> subs (new TextSubtitleContent (film, "test/data/subrip3.srt"));
index 2e325af..cba5e05 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -30,6 +30,7 @@
 #include "lib/ratio.h"
 #include "lib/ffmpeg_content.h"
 #include "lib/dcp_content_type.h"
+#include "lib/video_content.h"
 
 using boost::shared_ptr;
 
@@ -44,7 +45,7 @@ BOOST_AUTO_TEST_CASE (repeat_frame_test)
 
        wait_for_jobs ();
 
-       c->set_scale (VideoContentScale (Ratio::from_id ("185")));
+       c->video->set_scale (VideoContentScale (Ratio::from_id ("185")));
 
        film->set_video_frame_rate (48);
        film->make_dcp ();
@@ -53,4 +54,3 @@ BOOST_AUTO_TEST_CASE (repeat_frame_test)
        /* Should be 32 frames of red */
        check_dcp ("test/data/repeat_frame_test", film->dir (film->dcp_name ()));
 }
-
index b6b38e1..25359c6 100644 (file)
 #include "lib/ratio.h"
 #include "lib/film.h"
 #include "lib/dcp_content_type.h"
+#include "lib/video_content.h"
 #include "test.h"
 
 using std::string;
 using boost::shared_ptr;
 
-static void scaling_test_for (shared_ptr<Film> film, shared_ptr<VideoContent> content, string image, string container)
+static void scaling_test_for (shared_ptr<Film> film, shared_ptr<Content> content, string image, string container)
 {
-       content->set_scale (VideoContentScale (Ratio::from_id (image)));
+       content->video->set_scale (VideoContentScale (Ratio::from_id (image)));
        film->set_container (Ratio::from_id (container));
        film->make_dcp ();
 
@@ -64,7 +65,7 @@ BOOST_AUTO_TEST_CASE (scaling_test)
 
        wait_for_jobs ();
 
-       imc->set_video_length (1);
+       imc->video->set_video_length (1);
 
        /* F-133: 133 image in a flat container */
        scaling_test_for (film, imc, "133", "185");
@@ -80,4 +81,3 @@ BOOST_AUTO_TEST_CASE (scaling_test)
        /* S: scope image in a scope container */
        scaling_test_for (film, imc, "239", "239");
 }
-
index ad8ecb0..612a5f5 100644 (file)
@@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE (seek_zero_test)
        shared_ptr<FFmpegContent> content (new FFmpegContent (film, "test/data/count300bd48.m2ts"));
        film->examine_and_add_content (content);
        wait_for_jobs ();
-       content->set_scale (VideoContentScale (Ratio::from_id ("185")));
+       content->video->set_scale (VideoContentScale (Ratio::from_id ("185")));
 
        /* Work out the first video frame index that we will be given, taking into account
         * the difference between first video and first audio.
@@ -58,7 +58,7 @@ BOOST_AUTO_TEST_CASE (seek_zero_test)
                video_delay = ContentTime ();
        }
 
-       Frame const first_frame = video_delay.round_up (content->video_frame_rate ()).frames_round (content->video_frame_rate ());
+       Frame const first_frame = video_delay.round_up (content->video->video_frame_rate ()).frames_round (content->video->video_frame_rate ());
 
        FFmpegDecoder decoder (content, film->log(), false);
        list<ContentVideo> a = decoder.get_video (first_frame, true);
index da3997f..6f3e2ef 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -30,6 +30,7 @@
 #include "lib/ratio.h"
 #include "lib/ffmpeg_content.h"
 #include "lib/dcp_content_type.h"
+#include "lib/video_content.h"
 
 using boost::shared_ptr;
 
@@ -44,7 +45,7 @@ BOOST_AUTO_TEST_CASE (skip_frame_test)
 
        wait_for_jobs ();
 
-       c->set_scale (VideoContentScale (Ratio::from_id ("185")));
+       c->video->set_scale (VideoContentScale (Ratio::from_id ("185")));
        film->write_metadata ();
 
        film->set_video_frame_rate (24);
@@ -56,4 +57,3 @@ BOOST_AUTO_TEST_CASE (skip_frame_test)
        */
        check_dcp ("test/data/skip_frame_test", film->dir (film->dcp_name ()));
 }
-
index 918cdba..b6dce58 100644 (file)
@@ -26,6 +26,7 @@
 #include "lib/dcp_content_type.h"
 #include "lib/font.h"
 #include "lib/ratio.h"
+#include "lib/subtitle_content.h"
 #include "test.h"
 #include <boost/test/unit_test.hpp>
 #include <boost/algorithm/string.hpp>
@@ -46,8 +47,8 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test)
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
-       content->set_use_subtitles (true);
-       content->set_burn_subtitles (false);
+       content->subtitle->set_use_subtitles (true);
+       content->subtitle->set_burn_subtitles (false);
        film->make_dcp ();
        wait_for_jobs ();
 
@@ -66,10 +67,10 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test2)
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
-       content->set_use_subtitles (true);
-       content->set_burn_subtitles (false);
+       content->subtitle->set_use_subtitles (true);
+       content->subtitle->set_burn_subtitles (false);
        /* Use test/data/subrip2.srt as if it were a font file  */
-       content->fonts().front()->set_file (FontFiles::NORMAL, "test/data/subrip2.srt");
+       content->subtitle->fonts().front()->set_file (FontFiles::NORMAL, "test/data/subrip2.srt");
 
        film->make_dcp ();
        wait_for_jobs ();
@@ -91,8 +92,8 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test3)
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
-       content->set_use_subtitles (true);
-       content->set_burn_subtitles (false);
+       content->subtitle->set_use_subtitles (true);
+       content->subtitle->set_burn_subtitles (false);
 
        film->make_dcp ();
        wait_for_jobs ();
index d71ad5b..05fd77a 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -27,6 +27,7 @@
 #include "lib/ratio.h"
 #include "lib/dcp_content_type.h"
 #include "lib/ffmpeg_content.h"
+#include "lib/video_content.h"
 #include <iostream>
 
 using std::cout;
@@ -37,12 +38,12 @@ BOOST_AUTO_TEST_CASE (threed_test)
        shared_ptr<Film> film = new_test_film ("threed_test");
        film->set_name ("test_film2");
        shared_ptr<FFmpegContent> c (new FFmpegContent (film, "test/data/test.mp4"));
-       c->set_video_frame_type (VIDEO_FRAME_TYPE_3D_LEFT_RIGHT);
+       c->video->set_video_frame_type (VIDEO_FRAME_TYPE_3D_LEFT_RIGHT);
        film->examine_and_add_content (c);
 
        wait_for_jobs ();
 
-       c->set_scale (VideoContentScale (Ratio::from_id ("185")));
+       c->video->set_scale (VideoContentScale (Ratio::from_id ("185")));
 
        film->set_container (Ratio::from_id ("185"));
        film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test"));
index 272d3ed..7c8259f 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2015-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
 
 #include "lib/film.h"
 #include "lib/ffmpeg_content.h"
+#include "lib/video_content.h"
 #include "lib/player.h"
 #include "test.h"
 #include <boost/test/unit_test.hpp>
@@ -127,19 +128,19 @@ BOOST_AUTO_TEST_CASE (ffmpeg_time_calculation_test)
 
        /* 25fps content, 25fps DCP */
        film->set_video_frame_rate (25);
-       BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video_length() / 25.0));
+       BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video->video_length() / 25.0));
        /* 25fps content, 24fps DCP; length should be increased */
        film->set_video_frame_rate (24);
-       BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video_length() / 24.0));
+       BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video->video_length() / 24.0));
        /* 25fps content, 30fps DCP; length should be decreased */
        film->set_video_frame_rate (30);
-       BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video_length() / 30.0));
+       BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video->video_length() / 30.0));
        /* 25fps content, 50fps DCP; length should be the same */
        film->set_video_frame_rate (50);
-       BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video_length() / 25.0));
+       BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video->video_length() / 25.0));
        /* 25fps content, 60fps DCP; length should be decreased */
        film->set_video_frame_rate (60);
-       BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video_length() * (50.0 / 60) / 25.0));
+       BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video->video_length() * (50.0 / 60) / 25.0));
 }
 
 /** Test Player::dcp_to_content_video */
@@ -160,7 +161,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test1)
        /* Position 0, no trim, content rate = DCP rate */
        content->set_position (DCPTime ());
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (24);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -172,7 +173,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test1)
        /* Position 3s, no trim, content rate = DCP rate */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (24);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -186,7 +187,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test1)
        /* Position 3s, 1.5s trim, content rate = DCP rate */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime::from_seconds (1.5));
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (24);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -203,7 +204,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test1)
        */
        content->set_position (DCPTime ());
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (25);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -215,7 +216,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test1)
        /* Position 3s, no trim, content rate 24, DCP rate 25 */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (25);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -231,7 +232,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test1)
         */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime::from_seconds (1.6));
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (25);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -250,7 +251,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test1)
        */
        content->set_position (DCPTime ());
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (48);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -262,7 +263,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test1)
        /* Position 3s, no trim, content rate 24, DCP rate 48 */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (48);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -276,7 +277,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test1)
        /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime::from_seconds (1.5));
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (48);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -294,7 +295,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test1)
        */
        content->set_position (DCPTime ());
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (48);
+       content->video->set_video_frame_rate (48);
        film->set_video_frame_rate (24);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -306,7 +307,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test1)
        /* Position 3s, no trim, content rate 24, DCP rate 48 */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (48);
+       content->video->set_video_frame_rate (48);
        film->set_video_frame_rate (24);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -320,7 +321,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test1)
        /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime::from_seconds (1.5));
-       content->set_video_frame_rate (48);
+       content->video->set_video_frame_rate (48);
        film->set_video_frame_rate (24);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -334,7 +335,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test1)
        /* Position 0s, no trim, content rate 29.9978733, DCP rate 30 */
        content->set_position (DCPTime::from_seconds (0));
        content->set_trim_start (ContentTime::from_seconds (0));
-       content->set_video_frame_rate (29.9978733);
+       content->video->set_video_frame_rate (29.9978733);
        film->set_video_frame_rate (30);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -365,7 +366,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        /* Position 0, no trim, content rate = DCP rate */
        content->set_position (DCPTime ());
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (24);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -377,7 +378,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        /* Position 3s, no trim, content rate = DCP rate */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (24);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -389,7 +390,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        /* Position 3s, 1.5s trim, content rate = DCP rate */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime::from_seconds (1.5));
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (24);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -405,7 +406,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        */
        content->set_position (DCPTime ());
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (25);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -417,7 +418,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        /* Position 3s, no trim, content rate 24, DCP rate 25 */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (25);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -429,7 +430,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        /* Position 3s, 1.6s trim, content rate 24, DCP rate 25, so the 1.6s trim is at 24fps */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime::from_seconds (1.6));
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (25);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -447,7 +448,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        */
        content->set_position (DCPTime ());
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (48);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -459,7 +460,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        /* Position 3s, no trim, content rate 24, DCP rate 48 */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (48);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -471,7 +472,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime::from_seconds (1.5));
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (48);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -488,7 +489,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        */
        content->set_position (DCPTime ());
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (48);
+       content->video->set_video_frame_rate (48);
        film->set_video_frame_rate (24);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -500,7 +501,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        /* Position 3s, no trim, content rate 24, DCP rate 48 */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (48);
+       content->video->set_video_frame_rate (48);
        film->set_video_frame_rate (24);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -512,7 +513,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
        /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime::from_seconds (1.5));
-       content->set_video_frame_rate (48);
+       content->video->set_video_frame_rate (48);
        film->set_video_frame_rate (24);
        player->setup_pieces ();
        BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
@@ -542,7 +543,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
        /* Position 0, no trim, video/audio content rate = video/audio DCP rate */
        content->set_position (DCPTime ());
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (24);
        stream->_frame_rate = 48000;
        player->setup_pieces ();
@@ -555,7 +556,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
        /* Position 3s, no trim, video/audio content rate = video/audio DCP rate */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (24);
        stream->_frame_rate = 48000;
        player->setup_pieces ();
@@ -570,7 +571,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
        /* Position 3s, 1.5s trim, video/audio content rate = video/audio DCP rate */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime::from_seconds (1.5));
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (24);
        stream->_frame_rate = 48000;
        player->setup_pieces ();
@@ -585,7 +586,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
        /* Position 0, no trim, content video rate 24, DCP video rate 25, both audio rates still 48k */
        content->set_position (DCPTime ());
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (25);
        stream->_frame_rate = 48000;
        player->setup_pieces ();
@@ -598,7 +599,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
        /* Position 3s, no trim, content video rate 24, DCP rate 25, both audio rates still 48k. */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (25);
        stream->_frame_rate = 48000;
        player->setup_pieces ();
@@ -615,7 +616,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
        */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime::from_seconds (1.6));
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (25);
        stream->_frame_rate = 48000;
        player->setup_pieces ();
@@ -634,7 +635,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
        */
        content->set_position (DCPTime ());
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (48);
        stream->_frame_rate = 48000;
        player->setup_pieces ();
@@ -647,7 +648,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
        /* Position 3s, no trim, content rate 24, DCP rate 48 */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (24);
        stream->_frame_rate = 48000;
        player->setup_pieces ();
@@ -662,7 +663,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
        /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime::from_seconds (1.5));
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (24);
        stream->_frame_rate = 48000;
        player->setup_pieces ();
@@ -680,7 +681,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
        */
        content->set_position (DCPTime ());
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (48);
        stream->_frame_rate = 48000;
        player->setup_pieces ();
@@ -693,7 +694,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
        /* Position 3s, no trim, content rate 24, DCP rate 48 */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (24);
        stream->_frame_rate = 48000;
        player->setup_pieces ();
@@ -708,7 +709,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
        /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime::from_seconds (1.5));
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (24);
        stream->_frame_rate = 48000;
        player->setup_pieces ();
@@ -723,7 +724,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
        /* Position 0, no trim, video content rate = video DCP rate, content audio rate = 44.1k */
        content->set_position (DCPTime ());
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (24);
        stream->_frame_rate = 44100;
        player->setup_pieces ();
@@ -736,7 +737,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
        /* Position 3s, no trim, video content rate = video DCP rate, content audio rate = 44.1k */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime ());
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (24);
        stream->_frame_rate = 44100;
        player->setup_pieces ();
@@ -751,7 +752,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
        /* Position 3s, 1.5s trim, video content rate = video DCP rate, content audio rate = 44.1k */
        content->set_position (DCPTime::from_seconds (3));
        content->set_trim_start (ContentTime::from_seconds (1.5));
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (24);
        stream->_frame_rate = 44100;
        player->setup_pieces ();
@@ -766,7 +767,7 @@ BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
        /* Check with a large start trim */
        content->set_position (DCPTime::from_seconds (0));
        content->set_trim_start (ContentTime::from_seconds (54143));
-       content->set_video_frame_rate (24);
+       content->video->set_video_frame_rate (24);
        film->set_video_frame_rate (24);
        stream->_frame_rate = 48000;
        player->setup_pieces ();
index 1acac8a..78f3bf9 100644 (file)
@@ -20,6 +20,7 @@
 #include <boost/test/unit_test.hpp>
 #include "lib/ffmpeg_content.h"
 #include "lib/ratio.h"
+#include "lib/video_content.h"
 
 using std::list;
 using std::string;
@@ -88,7 +89,7 @@ test (dcp::Size content_size, dcp::Size display_size, dcp::Size film_size, Crop
        doc->read_string(s.str ());
 
        list<string> notes;
-       shared_ptr<VideoContent> vc (new FFmpegContent (film, doc, 10, notes));
+       shared_ptr<FFmpegContent> vc (new FFmpegContent (film, doc, 10, notes));
 
        optional<VideoContentScale> sc;
        if (ratio) {
@@ -97,9 +98,9 @@ test (dcp::Size content_size, dcp::Size display_size, dcp::Size film_size, Crop
                sc = VideoContentScale (scale);
        }
 
-       dcp::Size answer = sc.get().size (vc, display_size, film_size);
+       dcp::Size answer = sc.get().size (vc->video, display_size, film_size);
        if (answer != correct) {
-               cerr << "Testing " << vc->video_size().width << "x" << vc->video_size().height << "\n";
+               cerr << "Testing " << vc->video->video_size().width << "x" << vc->video->video_size().height << "\n";
                cerr << "Testing " << display_size.width << "x" << display_size.height << "\n";
                cerr << answer.width << "x" << answer.height << " instead of " << correct.width << "x" << correct.height << "\n";
        }
index 67e84b7..190a469 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
 #include <boost/test/unit_test.hpp>
 #include "lib/image_decoder.h"
 #include "lib/image_content.h"
+#include "lib/film.h"
 #include "test.h"
 #include <iostream>
 
@@ -31,7 +32,7 @@ BOOST_AUTO_TEST_CASE (video_decoder_fill_test1)
 {
        shared_ptr<Film> film = new_test_film ("video_decoder_fill_test");
        shared_ptr<ImageContent> c (new ImageContent (film, "test/data/simple_testcard_640x480.png"));
-       ImageDecoder decoder (c);
+       ImageDecoder decoder (c, film->log());
 
        decoder.fill_one_eye (0, 4, EYES_BOTH);
        BOOST_CHECK_EQUAL (decoder._decoded_video.size(), 4U);
@@ -56,7 +57,7 @@ BOOST_AUTO_TEST_CASE (video_decoder_fill_test2)
 {
        shared_ptr<Film> film = new_test_film ("video_decoder_fill_test");
        shared_ptr<ImageContent> c (new ImageContent (film, "test/data/simple_testcard_640x480.png"));
-       ImageDecoder decoder (c);
+       ImageDecoder decoder (c, film->log());
 
        decoder.fill_both_eyes (0, 4, EYES_LEFT);
        BOOST_CHECK_EQUAL (decoder._decoded_video.size(), 8);
index 0d73847..8b051d0 100644 (file)
@@ -26,6 +26,7 @@
 #include "lib/film.h"
 #include "lib/ratio.h"
 #include "lib/dcp_content_type.h"
+#include "lib/subtitle_content.h"
 #include "test.h"
 #include <iostream>
 
@@ -40,8 +41,8 @@ BOOST_AUTO_TEST_CASE (xml_subtitle_test)
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
        shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, "test/data/subrip2.srt"));
-       content->set_use_subtitles (true);
-       content->set_burn_subtitles (false);
+       content->subtitle->set_use_subtitles (true);
+       content->subtitle->set_burn_subtitles (false);
        film->examine_and_add_content (content);
        wait_for_jobs ();
        film->make_dcp ();
@@ -61,8 +62,8 @@ BOOST_AUTO_TEST_CASE (xml_subtitle_test2)
        film->set_interop (true);
        film->set_sequence (false);
        shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, "test/data/subrip2.srt"));
-       content->set_use_subtitles (true);
-       content->set_burn_subtitles (false);
+       content->subtitle->set_use_subtitles (true);
+       content->subtitle->set_burn_subtitles (false);
        film->examine_and_add_content (content);
        film->examine_and_add_content (content);
        wait_for_jobs ();