Various more hacks.
authorCarl Hetherington <cth@carlh.net>
Thu, 23 May 2013 11:52:49 +0000 (12:52 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 23 May 2013 11:52:49 +0000 (12:52 +0100)
21 files changed:
src/lib/analyse_audio_job.cc
src/lib/analyse_audio_job.h
src/lib/audio_content.cc
src/lib/audio_content.h
src/lib/audio_decoder.cc
src/lib/audio_decoder.h
src/lib/black_decoder.cc
src/lib/black_decoder.h
src/lib/imagemagick_decoder.cc
src/lib/imagemagick_decoder.h
src/lib/null_content.cc [new file with mode: 0644]
src/lib/null_content.h
src/lib/player.cc
src/lib/player.h
src/lib/playlist.cc
src/lib/silence_decoder.h [new file with mode: 0644]
src/lib/sndfile_decoder.h
src/lib/video_content.cc
src/lib/video_decoder.cc
src/wx/film_viewer.cc
src/wx/timeline.cc

index 433b6c98fa800a36d812aa41588b83d849fa06fd..13cab1a469902f9c31a1d3700258ebe420fb96c4 100644 (file)
@@ -35,7 +35,7 @@ int const AnalyseAudioJob::_num_points = 1024;
 
 AnalyseAudioJob::AnalyseAudioJob (shared_ptr<Film> f)
        : Job (f)
-       , _next (0)
+       , _done (0)
        , _samples_per_point (1)
 {
 
@@ -60,9 +60,9 @@ AnalyseAudioJob::run ()
        _current.resize (MAX_AUDIO_CHANNELS);
        _analysis.reset (new AudioAnalysis (MAX_AUDIO_CHANNELS));
 
-       _next = 0;
-       while (_next < _film->length()) {
-               set_progress (double (_next) / _film->length ());
+       _done = 0;
+       while (player->pass ()) {
+               set_progress (double (_done) / _film->length ());
        }
 
        _analysis->write (_film->audio_analysis_path ());
@@ -94,6 +94,6 @@ AnalyseAudioJob::audio (shared_ptr<const AudioBuffers> b, Time t)
                }
        }
 
-       _next = (t + _film->audio_frames_to_time (b->frames()));
+       _done = t;
 }
 
index 45bf109cc32a1c3589e5285df6713f84416c82b2..a0786a017c8b23cba7133e45c6f78b59ceb35bb9 100644 (file)
@@ -32,9 +32,9 @@ public:
        void run ();
 
 private:
-       void audio (boost::shared_ptr<const AudioBuffers>);
+       void audio (boost::shared_ptr<const AudioBuffers>, Time);
 
-       Time _next;
+       Time _done;
        int64_t _samples_per_point;
        std::vector<AudioPoint> _current;
 
index fc95acd7f2ea25d229b0e6c49a92b0acd9e5afdc..a3942f64bf3d6455922c2742ca0834cc311b28b0 100644 (file)
@@ -32,6 +32,14 @@ int const AudioContentProperty::AUDIO_FRAME_RATE = 202;
 int const AudioContentProperty::AUDIO_GAIN = 203;
 int const AudioContentProperty::AUDIO_DELAY = 204;
 
+AudioContent::AudioContent (Time s)
+       : Content (s)
+       , _audio_gain (0)
+       , _audio_delay (0)
+{
+
+}
+
 AudioContent::AudioContent (boost::filesystem::path f)
        : Content (f)
        , _audio_gain (0)
index 30524b4f4e21f1c491cb7b00fd4aabaa4d7a3c1b..e767fd326c2395378083ddf867eb4cc77fc85c69 100644 (file)
@@ -42,6 +42,7 @@ public:
 class AudioContent : public virtual Content
 {
 public:
+       AudioContent (Time);
        AudioContent (boost::filesystem::path);
        AudioContent (boost::shared_ptr<const cxml::Node>);
        AudioContent (AudioContent const &);
index c33f68c01c0c0bd3e910c8e46b08774772c8688a..ddda816a571d374897ee499f8bfdee155b1b8ee2 100644 (file)
@@ -107,7 +107,7 @@ AudioDecoder::process_end ()
 #endif
 
 void
-AudioDecoder::emit_audio (shared_ptr<const AudioBuffers> data, Time time)
+AudioDecoder::audio (shared_ptr<const AudioBuffers> data, Time time)
 {
        /* XXX: map audio to 5.1 */
        
index 8af519576db64b1c9c790563b9274e224da0e89c..0f7cb6dbdbca441721a9374c48090a7e88cd7b7e 100644 (file)
@@ -41,9 +41,10 @@ public:
        AudioDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<const AudioContent>);
        ~AudioDecoder ();
 
-       void emit_audio (boost::shared_ptr<const AudioBuffers>, Time);
-
 protected:
+
+       void audio (boost::shared_ptr<const AudioBuffers>, Time);
+
        Time _next_audio;
 
 private:
index ef7458711a0a95c79b7da5a2ed40b843f745efef..482cd2ce1ebe2333f714127b3a1724f2d9652edd 100644 (file)
@@ -1,7 +1,26 @@
+/*
+    Copyright (C) 2013 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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
 #include "black_decoder.h"
 
-BlackDecoder::BlackDecoder (shared_ptr<NullContent> c)
-       : Decoder (c)
+BlackDecoder::BlackDecoder (shared_ptr<Film> f, shared_ptr<NullContent> c)
+       : VideoDecoder (f, c)
 {
 
 }
@@ -9,5 +28,34 @@ BlackDecoder::BlackDecoder (shared_ptr<NullContent> c)
 void
 BlackDecoder::pass ()
 {
-       
+       if (!_image) {
+               _image.reset (new SimpleImage (AV_PIX_FMT_RGB24, video_size ()));
+               _image->make_black ();
+               video (_image, false, _next_video);
+       } else {
+               video (_image, true, _next_video);
+       }
+}
+
+float
+BlackDecoder::video_frame_rate () const
+{
+       boost::shared_ptr<const Film> f = _film.lock ();
+       if (!f) {
+               return 24;
+       }
+
+       return f->dcp_video_frame_rate ();
+}
+
+ContentVideoFrame
+BlackDecoder::video_length () const
+{
+       return _video_content->length() * video_frame_rate() / TIME_HZ;
+}
+
+Time
+BlackDecoder::next () const
+{
+       return _next_video;
 }
index a585af7e202e8fb69a1ac40920b48ef0d42920d7..bb3e7711d3431c5a32231a2c1836d88bc7e656f1 100644 (file)
@@ -1,44 +1,43 @@
+/*
+    Copyright (C) 2013 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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
 #include "video_decoder.h"
 
 class BlackDecoder : public VideoDecoder
 {
 public:
-       BlackDecoder (boost::shared_ptr<NullContent>);
+       BlackDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<NullContent>);
 
-       bool pass ();
-       bool seek (double);
+       /* Decoder */
+       
+       void pass ();
+       void seek (Time);
        Time next () const;
 
-       /** @return video frame rate second, or 0 if unknown */
-       float video_frame_rate () const {
-               return 24;
-       }
-       
-       /** @return native size in pixels */
-       libdcp::Size native_size () const {
+       /* VideoDecoder */
+
+       float video_frame_rate () const;
+       libdcp::Size video_size () const {
                return libdcp::Size (256, 256);
        }
-       
-       /** @return length according to our content's header */
-       ContentVideoFrame video_length () const {
-               return _content_length;
-       }
-
-protected:     
+       ContentVideoFrame video_length () const;
 
-       int time_base_numerator () const {
-               return 0;
-       }
-       
-       int time_base_denominator () const {
-               return 1;
-       }
-       
-       int sample_aspect_ratio_numerator () const {
-               return 0;
-       }
-               
-       int sample_aspect_ratio_denominator () const {
-               return 1;
-       }
+private:
+       boost::shared_ptr<Image> _image;
 };
index bea4fafa6223ee3e400a110dc7c610c7c2da54ae..81b3e4b9a3b5c1dc75578f0cc047c5322dc99a84 100644 (file)
@@ -73,13 +73,12 @@ ImageMagickDecoder::video_frame_rate () const
 void
 ImageMagickDecoder::pass ()
 {
-       if (_position < 0 || _position >= _imagemagick_content->video_length ()) {
+       if (_next_video >= _imagemagick_content->video_length ()) {
                return;
        }
 
        if (_image) {
-               video (_image, true, double (_position) / video_frame_rate());
-               _position++;
+               video (_image, true, _next_video);
                return;
        }
 
@@ -103,31 +102,13 @@ ImageMagickDecoder::pass ()
        delete magick_image;
 
        _image = _image->crop (_imagemagick_content->crop(), true);
-       video (_image, false, double (_position) / 24);
-
-       ++_position;
-       return false;
-}
-
-PixelFormat
-ImageMagickDecoder::pixel_format () const
-{
-       /* XXX: always true? */
-       return PIX_FMT_RGB24;
+       video (_image, false, _next_video);
 }
 
-bool
-ImageMagickDecoder::seek (double t)
+void
+ImageMagickDecoder::seek (Time t)
 {
-       int const f = t * _imagemagick_content->video_frame_rate ();
-
-       if (f >= _imagemagick_content->video_length()) {
-               _position = 0;
-               return true;
-       }
-
-       _position = f;
-       return false;
+       _next_video = t;
 }
 
 Time
index 74f01d6bba5ac19d60bcdbb77d82ae85bcccc391..26dbb8ca0dbbb0626e16466595a2871ce7692e52 100644 (file)
@@ -33,7 +33,7 @@ public:
        /* Decoder */
 
        void pass ();
-       void seek (double);
+       void seek (Time);
        Time next () const;
 
        /* VideoDecoder */
diff --git a/src/lib/null_content.cc b/src/lib/null_content.cc
new file mode 100644 (file)
index 0000000..0e275a3
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+    Copyright (C) 2013 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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+NullContent::NullContent (Time s, Time len, shared_ptr<const Film> f)
+       : Content (s)
+       , VideoContent (s, f->time_to_video_frames (len))
+       , AudioContent (s)
+       , _audio_length (f->time_to_audio_frames (len))
+       , _content_audio_frame_rate (f->dcp_audio_frame_rate ())
+{
+
+}
index 4f19c3b0a08eff05044ed4864365f1383f544f10..e680087826d571f523c8a317012228ea8428d53f 100644 (file)
@@ -1,3 +1,22 @@
+/*
+    Copyright (C) 2013 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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
 #include <string>
 #include <boost/shared_ptr.hpp>
 #include "content.h"
@@ -5,12 +24,7 @@
 class NullContent : public VideoContent, public AudioContent
 {
 public:
-       NullContent (Time s, Time len)
-               : Content (s)
-               , VideoContent (s)
-               , AudioContent (s)
-               , _length (len)
-       {}
+       NullContent (Time, Time, boost::shared_ptr<const Film>);
 
        std::string summary () const {
                return "";
@@ -19,9 +33,11 @@ public:
        std::string information () const {
                return "";
        }
+
+       void as_xml (xmlpp::Node *) const {}
        
        boost::shared_ptr<Content> clone () const {
-               return shared_ptr<Content> ();
+               return boost::shared_ptr<Content> ();
        }
 
         int audio_channels () const {
@@ -29,15 +45,15 @@ public:
        }
        
         ContentAudioFrame audio_length () const {
-               return _length * content_audio_frame_rate() / TIME_HZ;
+               return _audio_length;
        }
        
         int content_audio_frame_rate () const {
-               return 48000;
+               return _content_audio_frame_rate;
        }
        
-       int output_audio_frame_rate (boost::shared_ptr<const Film>) const {
-               return _film->dcp_audio_frame_rate (content_audio_frame_rate ());
+       int output_audio_frame_rate (boost::shared_ptr<const Film> f) const {
+               return f->dcp_audio_frame_rate ();
        }
        
        AudioMapping audio_mapping () const {
@@ -49,5 +65,6 @@ public:
        }
 
 private:
-       Time _length;
+       ContentAudioFrame _audio_length;
+       ContentAudioFrame _content_audio_frame_rate;
 };
index 8ca004689920775b379e5574f142c23ddb48c0ba..b0a408c1016a1cfd9bf5307a44975f2fa65e3b72 100644 (file)
@@ -30,6 +30,9 @@
 #include "playlist.h"
 #include "job.h"
 #include "image.h"
+#include "null_content.h"
+#include "black_decoder.h"
+#include "silence_decoder.h"
 
 using std::list;
 using std::cout;
@@ -136,23 +139,33 @@ Player::pass ()
 }
 
 void
-Player::process_video (shared_ptr<Piece> piece, shared_ptr<const Image> image, bool same, shared_ptr<Subtitle> sub, Time time)
+Player::process_video (weak_ptr<Content> weak_content, shared_ptr<const Image> image, bool same, shared_ptr<Subtitle> sub, Time time)
 {
-       time += piece->content->start ();
+       shared_ptr<Content> content = weak_content.lock ();
+       if (!content) {
+               return;
+       }
+       
+       time += content->start ();
        
         Video (image, same, sub, time);
 }
 
 void
-Player::process_audio (shared_ptr<Piece> piece, shared_ptr<const AudioBuffers> audio, Time time)
+Player::process_audio (weak_ptr<Content> weak_content, shared_ptr<const AudioBuffers> audio, Time time)
 {
+       shared_ptr<Content> content = weak_content.lock ();
+       if (!content) {
+               return;
+       }
+       
         /* XXX: mapping */
 
         /* The time of this audio may indicate that some of our buffered audio is not going to
            be added to any more, so it can be emitted.
         */
 
-       time += piece->content->start ();
+       time += content->start ();
 
         if (time > _next_audio) {
                 /* We can emit some audio from our buffers */
@@ -212,14 +225,14 @@ struct ContentSorter
 };
 
 void
-Player::setup_decoders ()
+Player::setup_pieces ()
 {
        list<shared_ptr<Piece> > old_pieces = _pieces;
 
        _pieces.clear ();
 
        Playlist::ContentList content = _playlist->content ();
-       content.sort (ContentSorter ());
+       sort (content.begin(), content.end(), ContentSorter ());
        
        for (Playlist::ContentList::iterator i = content.begin(); i != content.end(); ++i) {
 
@@ -231,8 +244,8 @@ Player::setup_decoders ()
                if (fc) {
                        shared_ptr<FFmpegDecoder> fd (new FFmpegDecoder (_film, fc, _video, _audio, _subtitles));
                        
-                       fd->Video.connect (bind (&Player::process_video, this, dr, _1, _2, _3, _4));
-                       fd->Audio.connect (bind (&Player::process_audio, this, dr, _1, _2));
+                       fd->Video.connect (bind (&Player::process_video, this, *i, _1, _2, _3, _4));
+                       fd->Audio.connect (bind (&Player::process_audio, this, *i, _1, _2));
 
                        decoder = fd;
                }
@@ -242,19 +255,16 @@ Player::setup_decoders ()
                        shared_ptr<ImageMagickDecoder> id;
                        
                        /* See if we can re-use an old ImageMagickDecoder */
-                       for (list<shared_ptr<Piece> >::const_iterator i = old_pieces.begin(); i != old_pieces.end(); ++i) {
-                               shared_ptr<ContentPiece> cp = dynamic_pointer_cast<ContentPiece> (*i);
-                               if (cp) {
-                                       shared_ptr<ImageMagickDecoder> imd = dynamic_pointer_cast<ImageMagickDecoder> (cp->decoder ());
-                                       if (imd && imd->content() == ic) {
-                                               id = imd;
-                                       }
+                       for (list<shared_ptr<Piece> >::const_iterator j = old_pieces.begin(); j != old_pieces.end(); ++j) {
+                               shared_ptr<ImageMagickDecoder> imd = dynamic_pointer_cast<ImageMagickDecoder> ((*j)->decoder);
+                               if (imd && imd->content() == ic) {
+                                       id = imd;
                                }
                        }
 
                        if (!id) {
                                id.reset (new ImageMagickDecoder (_film, ic));
-                               id->Video.connect (bind (&Player::process_video, this, dr, _1, _2, _3, _4));
+                               id->Video.connect (bind (&Player::process_video, this, *i, _1, _2, _3, _4));
                        }
 
                        decoder = id;
@@ -263,12 +273,12 @@ Player::setup_decoders ()
                shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> (*i);
                if (sc) {
                        shared_ptr<AudioDecoder> sd (new SndfileDecoder (_film, sc));
-                       sd->Audio.connect (bind (&Player::process_audio, this, dr, _1, _2));
+                       sd->Audio.connect (bind (&Player::process_audio, this, *i, _1, _2));
 
                        decoder = sd;
                }
 
-               _pieces.push_back (shared_ptr<new ContentPiece> (*i, decoder));
+               _pieces.push_back (shared_ptr<Piece> (new Piece (*i, decoder)));
        }
 
        /* Fill in visual gaps with black and audio gaps with silence */
@@ -278,28 +288,20 @@ Player::setup_decoders ()
        list<shared_ptr<Piece> > pieces_copy = _pieces;
        for (list<shared_ptr<Piece> >::iterator i = pieces_copy.begin(); i != pieces_copy.end(); ++i) {
                if (dynamic_pointer_cast<VideoContent> ((*i)->content)) {
-                       Time const diff = video_pos - (*i)->content->time();
+                       Time const diff = video_pos - (*i)->content->start();
                        if (diff > 0) {
-                               _pieces.push_back (
-                                       shared_ptr<Piece> (
-                                               shared_ptr<Content> (new NullContent (video_pos, diff)),
-                                               shared_ptr<Decoder> (new BlackDecoder (video_pos, diff))
-                                               )
-                                       );
+                               shared_ptr<NullContent> nc (new NullContent (video_pos, diff));
+                               _pieces.push_back (shared_ptr<Piece> (new Piece (nc, shared_ptr<Decoder> (new BlackDecoder (_film, nc)))));
                        }
                                                
-                       video_pos = (*i)->content->time() + (*i)->content->length();
+                       video_pos = (*i)->content->start() + (*i)->content->length(_film);
                } else {
-                       Time const diff = audio_pos - (*i)->content->time();
+                       Time const diff = audio_pos - (*i)->content->start();
                        if (diff > 0) {
-                               _pieces.push_back (
-                                       shared_ptr<Piece> (
-                                               shared_ptr<Content> (new NullContent (audio_pos, diff)),
-                                               shared_ptr<Decoder> (new SilenceDecoder (audio_pos, diff))
-                                               )
-                                       );
+                               shared_ptr<NullContent> nc (new NullContent (audio_pos, diff));
+                               _pieces.push_back (shared_ptr<Piece> (new Piece (nc, shared_ptr<Decoder> (new SilenceDecoder (_film, nc)))));
                        }
-                       audio_pos = (*i)->content->time() + (*i)->content->length();
+                       audio_pos = (*i)->content->start() + (*i)->content->length(_film);
                }
        }
 
@@ -324,26 +326,3 @@ Player::playlist_changed ()
 {
        _have_valid_pieces = false;
 }
-
-void
-Player::emit_black_frame ()
-{
-       shared_ptr<SimpleImage> image (new SimpleImage (AV_PIX_FMT_RGB24, libdcp::Size (128, 128), true));
-       Video (image, _last_was_black, shared_ptr<Subtitle> (), _last_video);
-       _last_video += _film->video_frames_to_time (1);
-}
-
-void
-Player::emit_silence (Time t)
-{
-       OutputAudioFrame frames = _film->time_to_audio_frames (t);
-       while (frames) {
-               /* Do this in half-second chunks so we don't overwhelm anybody */
-               OutputAudioFrame this_time = min (_film->dcp_audio_frame_rate() / 2, frames);
-               shared_ptr<AudioBuffers> silence (new AudioBuffers (MAX_AUDIO_CHANNELS, this_time));
-               silence->make_silent ();
-               Audio (silence, _last_audio);
-               _last_audio += _film->audio_frames_to_time (this_time);
-               frames -= this_time;
-       }
-}
index b0179ca7310039e0c3845e7eb240e0f9beca7e62..c8f6eecb87f9eba46d9d8bc6a3bb029803a39940 100644 (file)
@@ -51,7 +51,7 @@ public:
        void disable_audio ();
        void disable_subtitles ();
 
-       void pass ();
+       bool pass ();
        void seek (Time);
        void seek_back ();
        void seek_forward ();
@@ -62,13 +62,11 @@ public:
 
 private:
 
-       void process_video (boost::shared_ptr<Piece>, boost::shared_ptr<const Image>, bool, boost::shared_ptr<Subtitle>, Time);
-       void process_audio (boost::shared_ptr<Piece>, boost::shared_ptr<const AudioBuffers>, Time);
+       void process_video (boost::weak_ptr<Content>, boost::shared_ptr<const Image>, bool, boost::shared_ptr<Subtitle>, Time);
+       void process_audio (boost::weak_ptr<Content>, boost::shared_ptr<const AudioBuffers>, Time);
        void setup_pieces ();
        void playlist_changed ();
        void content_changed (boost::weak_ptr<Content>, int);
-       void emit_black_frame ();
-       void emit_silence (Time);
 
        boost::shared_ptr<const Film> _film;
        boost::shared_ptr<const Playlist> _playlist;
index fc52abbacf2a88c6ce8f8cfd0390592b6dfa009e..36d6c6b52d789c2f33020b950e49e37efb486c77 100644 (file)
@@ -265,8 +265,7 @@ Playlist::length (shared_ptr<const Film> film) const
 {
        Time len = 0;
        for (ContentList::const_iterator i = _content.begin(); i != _content.end(); ++i) {
-               Time const t = (*i)->time() + (*i)->length (film);
-               len = max (len, t);
+               len = max (len, (*i)->end (film));
        }
 
        return len;
diff --git a/src/lib/silence_decoder.h b/src/lib/silence_decoder.h
new file mode 100644 (file)
index 0000000..eec3c8e
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+    Copyright (C) 2013 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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+class SilenceDecoder : public AudioDecoder
+{
+public:
+       SilenceDecoder (boost::shared_ptr<const Film>, boost::shared_ptr<NullContent>);
+
+       void pass ();
+       void seek (Time);
+       Time next () const;
+};
index a513037d94fed79905a3e1ce489c6ae246eb62c7..1dc484fdc92bf2bef5a80717951c6a17ca9cbdf0 100644 (file)
@@ -30,7 +30,7 @@ public:
        ~SndfileDecoder ();
 
        void pass ();
-       Time next ();
+       Time next () const;
 
        int audio_channels () const;
        ContentAudioFrame audio_length () const;
index cb31b6476863cf506ecb84c006c7e5f32e955684..e077730483988725fd0fb116c1119210bc38357f 100644 (file)
@@ -34,6 +34,13 @@ using std::setprecision;
 using boost::shared_ptr;
 using boost::lexical_cast;
 
+VideoContent::VideoContent (Time s, ContentVideoFrame len)
+       : Content (s)
+       , _video_length (len)
+{
+
+}
+
 VideoContent::VideoContent (boost::filesystem::path f)
        : Content (f)
        , _video_length (0)
@@ -81,7 +88,7 @@ void
 VideoContent::take_from_video_decoder (shared_ptr<VideoDecoder> d)
 {
        /* These decoder calls could call other content methods which take a lock on the mutex */
-       libdcp::Size const vs = d->native_size ();
+       libdcp::Size const vs = d->video_size ();
        float const vfr = d->video_frame_rate ();
        
         {
index 8bb7f3700ec6a54c51f54ff02e5a13b16ee5606c..609594e7652c88d278a2c8df3f618961d85bf16d 100644 (file)
@@ -33,7 +33,7 @@ VideoDecoder::VideoDecoder (shared_ptr<const Film> f, shared_ptr<const VideoCont
        : Decoder (f)
        , _next_video (0)
        , _video_content (c)
-       , _frame_rate_conversion (c->video_frame_rate(), f->dcp_frame_rate())
+       , _frame_rate_conversion (c->video_frame_rate(), f->dcp_video_frame_rate())
        , _odd (false)
 {
 
@@ -59,11 +59,14 @@ VideoDecoder::video (shared_ptr<Image> image, bool same, Time t)
 
        Video (image, same, sub, t);
 
+       shared_ptr<const Film> film = _film.lock ();
+       assert (film);
+
        if (_frame_rate_conversion.repeat) {
-               Video (image, true, sub, t + _film->video_frames_to_time (1));
-               _next_video = t + _film->video_frames_to_time (2);
+               Video (image, true, sub, t + film->video_frames_to_time (1));
+               _next_video = t + film->video_frames_to_time (2);
        } else {
-               _next_video = t + _film->video_frames_to_time (1);
+               _next_video = t + film->video_frames_to_time (1);
        }
 
        _odd = !_odd;
index 6a40e88f7ee141d3b878f63968462c34210d7a03..f64e8d92bacd3c01947298edb6959826f7e07aaf 100644 (file)
@@ -182,10 +182,11 @@ FilmViewer::set_film (shared_ptr<Film> f)
 void
 FilmViewer::update_from_decoder ()
 {
-       if (!_player || _player->seek (_player->last_video ())) {
+       if (!_player) {
                return;
        }
 
+       _player->seek (_player->last_video ());
        get_frame ();
        _panel->Refresh ();
        _panel->Update ();
index 56a40378ea3ef60254f80df98dac25a0313501de..e5457020fd561ee4f5802ef001fed3f920cbeff7 100644 (file)
@@ -74,7 +74,7 @@ public:
                        return;
                }
 
-               Time const start = content->time ();
+               Time const start = content->start ();
                Time const len = content->length (film);
 
                gc->SetPen (*wxBLACK_PEN);
@@ -125,7 +125,7 @@ public:
                }
                
                return Rect (
-                       time_x (content->time ()),
+                       time_x (content->start ()),
                        y_pos (_track),
                        content->length (film) * _timeline.pixels_per_time_unit(),
                        _timeline.track_height()