Various fix-ups.
authorCarl Hetherington <cth@carlh.net>
Fri, 3 Jan 2014 00:47:32 +0000 (00:47 +0000)
committerCarl Hetherington <cth@carlh.net>
Fri, 3 Jan 2014 00:47:32 +0000 (00:47 +0000)
15 files changed:
src/lib/audio_decoder.cc
src/lib/audio_decoder.h
src/lib/decoded.h
src/lib/decoder.cc
src/lib/ffmpeg_decoder.cc
src/lib/ffmpeg_decoder.h
src/lib/image_decoder.cc
src/lib/image_decoder.h
src/lib/player.cc
src/lib/sndfile_decoder.cc
src/lib/sndfile_decoder.h
src/lib/video_decoder.cc
src/lib/video_decoder.h
test/ffmpeg_pts_offset.cc
test/seek_zero_test.cc

index aecf396440d63153a3c1c8a9cef4130af05502a4..d85bfaee22aaf79f0e5b512724334384a733ae11 100644 (file)
@@ -22,6 +22,8 @@
 #include "exceptions.h"
 #include "log.h"
 #include "resampler.h"
+#include "util.h"
+#include "film.h"
 
 #include "i18n.h"
 
@@ -35,22 +37,26 @@ using boost::shared_ptr;
 AudioDecoder::AudioDecoder (shared_ptr<const Film> film, shared_ptr<const AudioContent> content)
        : Decoder (film)
        , _audio_content (content)
-       , _last_audio (0)
+       , _audio_position (0)
 {
        if (content->output_audio_frame_rate() != content->content_audio_frame_rate() && content->audio_channels ()) {
                _resampler.reset (new Resampler (content->content_audio_frame_rate(), content->output_audio_frame_rate(), content->audio_channels ()));
        }
 }
 
+/** Audio timestamping is made hard by many factors, but the final nail in the coffin is resampling.
+ *  We have to assume that we are feeding continuous data into the resampler, and so we get continuous
+ *  data out.  Hence we do the timestamping here, post-resampler, just by counting samples.
+ */
 void
-AudioDecoder::audio (shared_ptr<const AudioBuffers> data, ContentTime time)
+AudioDecoder::audio (shared_ptr<const AudioBuffers> data)
 {
        if (_resampler) {
                data = _resampler->run (data);
        }
        
-       _pending.push_back (shared_ptr<DecodedAudio> (new DecodedAudio (data, time)));
-       _last_audio = time + (data->frames() * TIME_HZ / _audio_content->output_audio_frame_rate());
+       _pending.push_back (shared_ptr<DecodedAudio> (new DecodedAudio (data, _audio_position)));
+       _audio_position += data->frames ();
 }
 
 void
@@ -62,6 +68,17 @@ AudioDecoder::flush ()
 
        shared_ptr<const AudioBuffers> b = _resampler->flush ();
        if (b) {
-               audio (b, _last_audio);
+               _pending.push_back (shared_ptr<DecodedAudio> (new DecodedAudio (b, _audio_position)));
+               _audio_position += b->frames ();
        }
 }
+
+void
+AudioDecoder::seek (ContentTime t, bool)
+{
+       shared_ptr<const Film> film = _film.lock ();
+       assert (film);
+       
+       FrameRateChange frc = film->active_frame_rate_change (_audio_content->position ());
+       _audio_position = (t + first_audio()) / frc.speed_up;
+}
index a295df0ccbbf9d770b7f60afb0926ec99c56f659..12f8505f64814244f4a5d1a0cba530df3e648f22 100644 (file)
@@ -44,15 +44,17 @@ public:
                return _audio_content;
        }
 
+       void seek (ContentTime time, bool accurate);
+       
 protected:
 
-       void audio (boost::shared_ptr<const AudioBuffers>, ContentTime);
+       virtual ContentTime first_audio () const = 0;
+       void audio (boost::shared_ptr<const AudioBuffers>);
        void flush ();
 
        boost::shared_ptr<const AudioContent> _audio_content;
        boost::shared_ptr<Resampler> _resampler;
-       /* End time of last audio that we wrote to _pending; only used for flushing the resampler */
-       ContentTime _last_audio;
+       AudioFrame _audio_position;
 };
 
 #endif
index 1de2ff79e5222e76156c368f10f263e3c3cf158a..ff32e43f2b67a115673a53268b229618e0815750 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "types.h"
 #include "rect.h"
+#include "util.h"
 
 class Image;
 
@@ -29,20 +30,13 @@ class Decoded
 {
 public:
        Decoded ()
-               : content_time (0)
-               , dcp_time (0)
-       {}
-
-       Decoded (DCPTime ct)
-               : content_time (ct)
-               , dcp_time (0)
+               : dcp_time (0)
        {}
 
        virtual ~Decoded () {}
 
-       virtual void set_dcp_times (float speed_up, DCPTime offset) = 0;
+       virtual void set_dcp_times (VideoFrame, AudioFrame, FrameRateChange, DCPTime) = 0;
 
-       ContentTime content_time;
        DCPTime dcp_time;
 };
 
@@ -53,62 +47,70 @@ public:
        DecodedVideo ()
                : eyes (EYES_BOTH)
                , same (false)
+               , frame (0)
        {}
 
-       DecodedVideo (boost::shared_ptr<const Image> im, Eyes e, bool s, ContentTime ct)
-               : Decoded (ct)
-               , image (im)
+       DecodedVideo (boost::shared_ptr<const Image> im, Eyes e, bool s, VideoFrame f)
+               : image (im)
                , eyes (e)
                , same (s)
+               , frame (f)
        {}
 
-       void set_dcp_times (float speed_up, DCPTime offset) {
-               dcp_time = rint (content_time / speed_up) + offset;
+       void set_dcp_times (VideoFrame video_frame_rate, AudioFrame, FrameRateChange frc, DCPTime offset)
+       {
+               dcp_time = frame * TIME_HZ * frc.factor() / video_frame_rate + offset;
        }
        
        boost::shared_ptr<const Image> image;
        Eyes eyes;
        bool same;
+       VideoFrame frame;
 };
 
 class DecodedAudio : public Decoded
 {
 public:
-       DecodedAudio (boost::shared_ptr<const AudioBuffers> d, ContentTime ct)
-               : Decoded (ct)
-               , data (d)
+       DecodedAudio (boost::shared_ptr<const AudioBuffers> d, AudioFrame f)
+               : data (d)
+               , frame (f)
        {}
 
-       void set_dcp_times (float speed_up, DCPTime offset) {
-               dcp_time = rint (content_time / speed_up) + offset;
+       void set_dcp_times (VideoFrame, AudioFrame audio_frame_rate, FrameRateChange, DCPTime offset)
+       {
+               dcp_time = frame * TIME_HZ / audio_frame_rate + offset;
        }
        
        boost::shared_ptr<const AudioBuffers> data;
+       AudioFrame frame;
 };
 
 class DecodedSubtitle : public Decoded
 {
 public:
        DecodedSubtitle ()
-               : content_time_to (0)
+               : content_time (0)
+               , content_time_to (0)
                , dcp_time_to (0)
        {}
 
        DecodedSubtitle (boost::shared_ptr<Image> im, dcpomatic::Rect<double> r, ContentTime f, ContentTime t)
-               : Decoded (f)
-               , image (im)
+               : image (im)
                , rect (r)
+               , content_time (f)
                , content_time_to (t)
                , dcp_time_to (0)
        {}
 
-       void set_dcp_times (float speed_up, DCPTime offset) {
-               dcp_time = rint (content_time / speed_up) + offset;
-               dcp_time_to = rint (content_time_to / speed_up) + offset;
+       void set_dcp_times (VideoFrame, AudioFrame, FrameRateChange frc, DCPTime offset)
+       {
+               dcp_time = rint (content_time / frc.speed_up) + offset;
+               dcp_time_to = rint (content_time_to / frc.speed_up) + offset;
        }
 
        boost::shared_ptr<Image> image;
        dcpomatic::Rect<double> rect;
+       ContentTime content_time;
        ContentTime content_time_to;
        DCPTime dcp_time_to;
 };
index 4e136d619e075b3d49f52e147365ded667cd3d15..30244b40b5eae2591bbde3301e4ddb5e3f033f20 100644 (file)
@@ -47,7 +47,7 @@ Decoder::peek ()
                _done = pass ();
        }
 
-       if (_done) {
+       if (_done && _pending.empty ()) {
                return shared_ptr<Decoded> ();
        }
 
index 298284512371b87c53ba21edee018434f218d009..25fe655be10c6b99f1b7b31c55b3b1867a5d5f3b 100644 (file)
@@ -68,8 +68,7 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> f, shared_ptr<const FFmpegC
        , _subtitle_codec (0)
        , _decode_video (video)
        , _decode_audio (audio)
-       , _video_pts_offset (0)
-       , _audio_pts_offset (0)
+       , _pts_offset (0)
 {
        setup_subtitle ();
 
@@ -82,9 +81,7 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> f, shared_ptr<const FFmpegC
           Then we remove big initial gaps in PTS and we allow our
           insertion of black frames to work.
 
-          We will do:
-            audio_pts_to_use = audio_pts_from_ffmpeg + audio_pts_offset;
-            video_pts_to_use = video_pts_from_ffmpeg + video_pts_offset;
+          We will do pts_to_use = pts_from_ffmpeg + pts_offset;
        */
 
        bool const have_video = video && c->first_video();
@@ -93,16 +90,16 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> f, shared_ptr<const FFmpegC
        /* First, make one of them start at 0 */
 
        if (have_audio && have_video) {
-               _video_pts_offset = _audio_pts_offset = - min (c->first_video().get(), c->audio_stream()->first_audio.get());
+               _pts_offset = - min (c->first_video().get(), c->audio_stream()->first_audio.get());
        } else if (have_video) {
-               _video_pts_offset = - c->first_video().get();
+               _pts_offset = - c->first_video().get();
        } else if (have_audio) {
-               _audio_pts_offset = - c->audio_stream()->first_audio.get();
+               _pts_offset = - c->audio_stream()->first_audio.get();
        }
 
        /* Now adjust both so that the video pts starts on a frame */
        if (have_video && have_audio) {
-               double first_video = c->first_video().get() + _video_pts_offset;
+               double first_video = c->first_video().get() + _pts_offset;
                double const old_first_video = first_video;
                
                /* Round the first video up to a frame boundary */
@@ -110,8 +107,7 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> f, shared_ptr<const FFmpegC
                        first_video = ceil (first_video * c->video_frame_rate()) / c->video_frame_rate ();
                }
 
-               _video_pts_offset += first_video - old_first_video;
-               _audio_pts_offset += first_video - old_first_video;
+               _pts_offset += first_video - old_first_video;
        }
 }
 
@@ -325,10 +321,10 @@ FFmpegDecoder::minimal_run (boost::function<bool (optional<ContentTime>, optiona
                        r = avcodec_decode_video2 (video_codec_context(), _frame, &finished, &_packet);
                        if (r >= 0 && finished) {
                                last_video = rint (
-                                       (av_frame_get_best_effort_timestamp (_frame) * time_base + _video_pts_offset) * TIME_HZ
+                                       (av_frame_get_best_effort_timestamp (_frame) * time_base + _pts_offset) * TIME_HZ
                                        );
                        }
-                               
+
                } else if (_ffmpeg_content->audio_stream() && _packet.stream_index == _ffmpeg_content->audio_stream()->index (_format_context)) {
                        AVPacket copy_packet = _packet;
                        while (copy_packet.size > 0) {
@@ -337,7 +333,7 @@ FFmpegDecoder::minimal_run (boost::function<bool (optional<ContentTime>, optiona
                                r = avcodec_decode_audio4 (audio_codec_context(), _frame, &finished, &_packet);
                                if (r >= 0 && finished) {
                                        last_audio = rint (
-                                               (av_frame_get_best_effort_timestamp (_frame) * time_base + _audio_pts_offset) * TIME_HZ
+                                               (av_frame_get_best_effort_timestamp (_frame) * time_base + _pts_offset) * TIME_HZ
                                                );
                                }
                                        
@@ -367,18 +363,21 @@ FFmpegDecoder::seek_final_finished (int n, int done) const
 void
 FFmpegDecoder::seek_and_flush (ContentTime t)
 {
-       int64_t s = ((double (t) / TIME_HZ) - _video_pts_offset) /
+       int64_t s = ((double (t) / TIME_HZ) - _pts_offset) /
                av_q2d (_format_context->streams[_video_stream]->time_base);
-       
+
        if (_ffmpeg_content->audio_stream ()) {
                s = min (
                        s, int64_t (
-                               ((double (t) / TIME_HZ) - _audio_pts_offset) /
+                               ((double (t) / TIME_HZ) - _pts_offset) /
                                av_q2d (_ffmpeg_content->audio_stream()->stream(_format_context)->time_base)
                                )
                        );
        }
 
+       /* Ridiculous empirical hack */
+       s--;
+
        av_seek_frame (_format_context, _video_stream, s, AVSEEK_FLAG_BACKWARD);
 
        avcodec_flush_buffers (video_codec_context());
@@ -394,6 +393,7 @@ void
 FFmpegDecoder::seek (ContentTime time, bool accurate)
 {
        Decoder::seek (time, accurate);
+       AudioDecoder::seek (time, accurate);
        
        /* If we are doing an accurate seek, our initial shot will be 200ms (200 being
           a number plucked from the air) earlier than we want to end up.  The loop below
@@ -405,7 +405,7 @@ FFmpegDecoder::seek (ContentTime time, bool accurate)
        if (initial_seek < 0) {
                initial_seek = 0;
        }
-       
+
        /* Initial seek time in the video stream's timebase */
 
        seek_and_flush (initial_seek);
@@ -416,7 +416,7 @@ FFmpegDecoder::seek (ContentTime time, bool accurate)
        }
 
        int const N = minimal_run (boost::bind (&FFmpegDecoder::seek_overrun_finished, this, time, _1, _2));
-       
+
        seek_and_flush (initial_seek);
        if (N > 0) {
                minimal_run (boost::bind (&FFmpegDecoder::seek_final_finished, this, N - 1, _3));
@@ -445,16 +445,11 @@ FFmpegDecoder::decode_audio_packet ()
                }
 
                if (frame_finished) {
-                       ContentTime const t = rint (
-                               (av_q2d (_format_context->streams[copy_packet.stream_index]->time_base)
-                                * av_frame_get_best_effort_timestamp(_frame) + _audio_pts_offset) * TIME_HZ
-                               );
-
                        int const data_size = av_samples_get_buffer_size (
                                0, audio_codec_context()->channels, _frame->nb_samples, audio_sample_format (), 1
                                );
                        
-                       audio (deinterleave_audio (_frame->data, data_size), t);
+                       audio (deinterleave_audio (_frame->data, data_size));
                }
                        
                copy_packet.data += decode_result;
@@ -503,8 +498,9 @@ FFmpegDecoder::decode_video_packet ()
                }
                
                if (i->second != AV_NOPTS_VALUE) {
-                       ContentTime const t = rint ((i->second * av_q2d (_format_context->streams[_video_stream]->time_base) + _video_pts_offset) * TIME_HZ);
-                       video (image, false, t);
+                       double const pts = i->second * av_q2d (_format_context->streams[_video_stream]->time_base) + _pts_offset;
+                       VideoFrame const f = rint (pts * _ffmpeg_content->video_frame_rate ());
+                       video (image, false, f);
                } else {
                        shared_ptr<const Film> film = _film.lock ();
                        assert (film);
@@ -607,3 +603,13 @@ FFmpegDecoder::decode_subtitle_packet ()
        
        avsubtitle_free (&sub);
 }
+
+ContentTime
+FFmpegDecoder::first_audio () const
+{
+       if (!_ffmpeg_content->audio_stream ()) {
+               return 0;
+       }
+
+       return _ffmpeg_content->audio_stream()->first_audio.get_value_or(0) + _pts_offset;
+}
index 55b624bd60e1df843fbfb7eb0aacd7ef9c9746a6..680e39c393a9dad5aca9e71cae4337e9108e1472 100644 (file)
@@ -58,6 +58,7 @@ private:
 
        bool pass ();
        void flush ();
+       ContentTime first_audio () const;
 
        void setup_subtitle ();
 
@@ -85,6 +86,5 @@ private:
        bool _decode_video;
        bool _decode_audio;
 
-       double _video_pts_offset;
-       double _audio_pts_offset;
+       double _pts_offset;
 };
index a5ca67e0d95856c4de867b4f5ea70a17a5dd7a6a..204849ecf8bd1ddc3ca415d5152eb4085863816e 100644 (file)
@@ -49,7 +49,7 @@ ImageDecoder::pass ()
        }
 
        if (_image && _image_content->still ()) {
-               video (_image, true, _video_position * TIME_HZ / _video_content->video_frame_rate ());
+               video (_image, true, _video_position);
                ++_video_position;
                return false;
        }
@@ -82,7 +82,7 @@ ImageDecoder::pass ()
 
        delete magick_image;
 
-       video (_image, false, _video_position * TIME_HZ / _video_content->video_frame_rate ());
+       video (_image, false, _video_position);
        ++_video_position;
 
        return false;
index f4d81dfb507a5ef545c0f573542904472d023956..63b4c58e344f42ece958d7a58e75441d00da216c 100644 (file)
@@ -41,6 +41,6 @@ private:
        
        boost::shared_ptr<const ImageContent> _image_content;
        boost::shared_ptr<Image> _image;
-       ContentTime _video_position;
+       VideoFrame _video_position;
 };
 
index 4fe81d4b2a9e86053fb1e5c8965cd0e4bec1a90b..da7e7c147c0b06605aad90fb81db1da0eb57f1db 100644 (file)
@@ -119,10 +119,10 @@ Player::pass ()
                                break;
                        }
 
-                       dec->set_dcp_times ((*i)->frc.speed_up, offset);
+                       dec->set_dcp_times (_film->video_frame_rate(), _film->audio_frame_rate(), (*i)->frc, offset);
                        DCPTime const t = dec->dcp_time - offset;
                        if (t >= (*i)->content->full_length() - (*i)->content->trim_end ()) {
-                               /* In the end-trimmed part; decoder has nothing eles to give us */
+                               /* In the end-trimmed part; decoder has nothing else to give us */
                                dec.reset ();
                                done = true;
                        } else if (t >= (*i)->content->trim_start ()) {
index 5e3f3313b50451939dac51171844c77aa1af6cd0..1c651e6142abb1cc583011adee35723dad6d505f 100644 (file)
@@ -45,7 +45,6 @@ SndfileDecoder::SndfileDecoder (shared_ptr<const Film> f, shared_ptr<const Sndfi
                throw DecodeError (_("could not open audio file for reading"));
        }
 
-       _done = 0;
        _remaining = _info.frames;
 }
 
@@ -94,8 +93,7 @@ SndfileDecoder::pass ()
        }
                
        data->set_frames (this_time);
-       audio (data, _done * TIME_HZ / audio_frame_rate ());
-       _done += this_time;
+       audio (data);
        _remaining -= this_time;
 
        return _remaining == 0;
@@ -123,7 +121,7 @@ void
 SndfileDecoder::seek (ContentTime t, bool accurate)
 {
        Decoder::seek (t, accurate);
+       AudioDecoder::seek (t, accurate);
 
-       _done = t * audio_frame_rate() / TIME_HZ;
        _remaining = _info.frames - _done;
 }
index 9cbddc9f683f63e7d7d9ea9f75cba664c3ad3831..4ecea0846ef030ea22324c53e93d9be785958db6 100644 (file)
@@ -36,15 +36,15 @@ public:
        int audio_frame_rate () const;
 
 private:
-       bool has_audio () const {
-               return true;
+       ContentTime first_audio () const {
+               return 0;
        }
+
        bool pass ();
        
        boost::shared_ptr<const SndfileContent> _sndfile_content;
        SNDFILE* _sndfile;
        SF_INFO _info;
-       AudioFrame _done;
        AudioFrame _remaining;
        float* _deinterleave_buffer;
 };
index 6a16557cdc65e8aac476eeb290a1f5b3c48d8c32..a3b45716c532887473d76c17f50957bf80dba5ac 100644 (file)
@@ -35,25 +35,27 @@ VideoDecoder::VideoDecoder (shared_ptr<const Film> f, shared_ptr<const VideoCont
 
 /** Called by subclasses when they have a video frame ready */
 void
-VideoDecoder::video (shared_ptr<const Image> image, bool same, ContentTime time)
+VideoDecoder::video (shared_ptr<const Image> image, bool same, VideoFrame frame)
 {
        switch (_video_content->video_frame_type ()) {
        case VIDEO_FRAME_TYPE_2D:
-               _pending.push_back (shared_ptr<DecodedVideo> (new DecodedVideo (image, EYES_BOTH, same, time)));
+               _pending.push_back (shared_ptr<DecodedVideo> (new DecodedVideo (image, EYES_BOTH, same, frame)));
                break;
        case VIDEO_FRAME_TYPE_3D_LEFT_RIGHT:
        {
                int const half = image->size().width / 2;
-               _pending.push_back (shared_ptr<DecodedVideo> (new DecodedVideo (image->crop (Crop (0, half, 0, 0), true), EYES_LEFT, same, time)));
-               _pending.push_back (shared_ptr<DecodedVideo> (new DecodedVideo (image->crop (Crop (half, 0, 0, 0), true), EYES_RIGHT, same, time)));
+               _pending.push_back (shared_ptr<DecodedVideo> (new DecodedVideo (image->crop (Crop (0, half, 0, 0), true), EYES_LEFT, same, frame)));
+               _pending.push_back (shared_ptr<DecodedVideo> (new DecodedVideo (image->crop (Crop (half, 0, 0, 0), true), EYES_RIGHT, same, frame)));
                break;
        }
        case VIDEO_FRAME_TYPE_3D_TOP_BOTTOM:
        {
                int const half = image->size().height / 2;
-               _pending.push_back (shared_ptr<DecodedVideo> (new DecodedVideo (image->crop (Crop (0, 0, 0, half), true), EYES_LEFT, same, time)));
-               _pending.push_back (shared_ptr<DecodedVideo> (new DecodedVideo (image->crop (Crop (0, 0, half, 0), true), EYES_RIGHT, same, time)));
+               _pending.push_back (shared_ptr<DecodedVideo> (new DecodedVideo (image->crop (Crop (0, 0, 0, half), true), EYES_LEFT, same, frame)));
+               _pending.push_back (shared_ptr<DecodedVideo> (new DecodedVideo (image->crop (Crop (0, 0, half, 0), true), EYES_RIGHT, same, frame)));
                break;
        }
+       default:
+               assert (false);
        }
 }
index d8c362354ee02b2f9614b265c6159ee1b200bf7d..8947c27089b2b718c819ce42b39fdfa794aee425 100644 (file)
@@ -41,7 +41,7 @@ public:
 
 protected:
 
-       void video (boost::shared_ptr<const Image>, bool, ContentTime);
+       void video (boost::shared_ptr<const Image>, bool, VideoFrame);
        boost::shared_ptr<const VideoContent> _video_content;
 };
 
index 2090e517bdd7eeea1d6ff8dea84dd89d30c4a55d..53303f1543bcda650274f7d2736a1668a7691af8 100644 (file)
@@ -37,8 +37,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_pts_offset_test)
                content->_first_video = 0;
                content->_audio_stream->first_audio = 0;
                FFmpegDecoder decoder (film, content, true, true);
-               BOOST_CHECK_EQUAL (decoder._video_pts_offset, 0);
-               BOOST_CHECK_EQUAL (decoder._audio_pts_offset, 0);
+               BOOST_CHECK_EQUAL (decoder._pts_offset, 0);
        }
 
        {
@@ -46,8 +45,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_pts_offset_test)
                content->_first_video = 600;
                content->_audio_stream->first_audio = 600;
                FFmpegDecoder decoder (film, content, true, true);
-               BOOST_CHECK_EQUAL (decoder._video_pts_offset, -600);
-               BOOST_CHECK_EQUAL (decoder._audio_pts_offset, -600);
+               BOOST_CHECK_EQUAL (decoder._pts_offset, -600);
        }
 
        {
@@ -55,8 +53,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_pts_offset_test)
                content->_first_video = 1.0 / 24.0;
                content->_audio_stream->first_audio = 0;
                FFmpegDecoder decoder (film, content, true, true);
-               BOOST_CHECK_EQUAL (decoder._video_pts_offset, 0);
-               BOOST_CHECK_EQUAL (decoder._audio_pts_offset, 0);
+               BOOST_CHECK_EQUAL (decoder._pts_offset, 0);
        }
 
        {
@@ -65,8 +62,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_pts_offset_test)
                content->_first_video = frame + 0.0215;
                content->_audio_stream->first_audio = 0;
                FFmpegDecoder decoder (film, content, true, true);
-               BOOST_CHECK_CLOSE (decoder._video_pts_offset, (frame - 0.0215), 0.00001);
-               BOOST_CHECK_CLOSE (decoder._audio_pts_offset, (frame - 0.0215), 0.00001);
+               BOOST_CHECK_CLOSE (decoder._pts_offset, (frame - 0.0215), 0.00001);
        }
 
        {
@@ -75,7 +71,6 @@ BOOST_AUTO_TEST_CASE (ffmpeg_pts_offset_test)
                content->_first_video = frame + 0.0215 + 4.1;
                content->_audio_stream->first_audio = 4.1;
                FFmpegDecoder decoder (film, content, true, true);
-               BOOST_CHECK_EQUAL (decoder._video_pts_offset, (frame - 0.0215) - 4.1);
-               BOOST_CHECK_EQUAL (decoder._audio_pts_offset, (frame - 0.0215) - 4.1);
+               BOOST_CHECK_EQUAL (decoder._pts_offset, (frame - 0.0215) - 4.1);
        }
 }
index 0987f6b9b20e44f9a48da63a68cf2cb3fece309f..c20c99ee7372a48c14b39666b3b53f342edf17c6 100644 (file)
@@ -32,6 +32,7 @@
 
 using std::cout;
 using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
 
 BOOST_AUTO_TEST_CASE (seek_zero_test)
 {
@@ -45,14 +46,12 @@ BOOST_AUTO_TEST_CASE (seek_zero_test)
        wait_for_jobs ();
 
        FFmpegDecoder decoder (film, content, true, false);
-       shared_ptr<Decoded> a = decoder.peek ();
-       cout << a->content_time << "\n";
+       shared_ptr<DecodedVideo> a = dynamic_pointer_cast<DecodedVideo> (decoder.peek ());
        decoder.seek (0, true);
-       shared_ptr<Decoded> b = decoder.peek ();
-       cout << b->content_time << "\n";
+       shared_ptr<DecodedVideo> b = dynamic_pointer_cast<DecodedVideo> (decoder.peek ());
 
        /* a will be after no seek, and b after a seek to zero, which should
           have the same effect.
        */
-       BOOST_CHECK_EQUAL (a->content_time, b->content_time);
+       BOOST_CHECK_EQUAL (a->frame, b->frame);
 }