Partial fix to sync according to pts.
authorCarl Hetherington <cth@carlh.net>
Mon, 22 Oct 2012 10:21:31 +0000 (11:21 +0100)
committerCarl Hetherington <cth@carlh.net>
Mon, 22 Oct 2012 10:21:31 +0000 (11:21 +0100)
src/lib/decoder.h
src/lib/examine_content_job.cc
src/lib/ffmpeg_decoder.cc
src/lib/ffmpeg_decoder.h

index 2285cf4f9694ecd4edc4c6e9ec6b2a8b209898d2..7559217eb13f914a2acd4f68a5b1407c6893705e 100644 (file)
@@ -71,6 +71,11 @@ public:
        virtual int64_t audio_channel_layout () const = 0;
        virtual bool has_subtitles () const = 0;
 
+       /** @return amount of extra unwanted audio at the start (or -ve for unwanted video) in milliseconds */
+       virtual int audio_to_discard () const {
+               return 0;
+       }
+
        void process_begin ();
        bool pass ();
        void process_end ();
index cad560908c63ffb66c0c5799f894b7fcc515c7dd..d91fc2136e8e3545b32b57e201de8eb3e731712a 100644 (file)
@@ -28,6 +28,7 @@
 #include "decoder.h"
 #include "imagemagick_encoder.h"
 #include "transcoder.h"
+#include "log.h"
 
 using namespace std;
 using namespace boost;
@@ -67,7 +68,12 @@ ExamineContentJob::run ()
 
        _decoder = decoder_factory (fs, o, this, _log, true, true);
        _decoder->go ();
-       fs->set_length (last_video_frame ());
+
+       fs->set_length (_decoder->last_video_frame ());
+       fs->set_audio_delay (-_decoder->audio_to_discard ());
+
+       _log->log (String::compose ("Video length is %1 frames", _decoder->last_video_frame()));
+       _log->log (String::compose ("%1ms of audio to discard", _decoder->audio_to_discard()));
 
        ascend ();
 
index e52ea735f108aed80e850618ca5cc2143a257653..d8a541be39b0539d81be155c1b82d33d877ff483 100644 (file)
@@ -66,6 +66,7 @@ FFmpegDecoder::FFmpegDecoder (boost::shared_ptr<const FilmState> s, boost::share
        , _audio_codec (0)
        , _subtitle_codec_context (0)
        , _subtitle_codec (0)
+       , _first_video_pts (-1)
 {
        setup_general ();
        setup_video ();
@@ -221,6 +222,8 @@ FFmpegDecoder::do_pass ()
                _packet.data = 0;
                _packet.size = 0;
 
+               /* XXX: should we reset _packet.data and size after each *_decode_* call? */
+
                int frame_finished;
 
                while (avcodec_decode_video2 (_video_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
@@ -245,6 +248,9 @@ FFmpegDecoder::do_pass ()
 
                int frame_finished;
                if (avcodec_decode_video2 (_video_codec_context, _frame, &frame_finished, &_packet) >= 0 && frame_finished) {
+                       if (_first_video_pts == -1) {
+                               _first_video_pts = _packet.pts;
+                       }
                        process_video (_frame);
                }
 
@@ -417,3 +423,15 @@ FFmpegDecoder::stream_name (AVStream* s) const
 
        return n.str ();
 }
+
+int
+FFmpegDecoder::audio_to_discard () const
+{
+       AVStream* v = _format_context->streams[_video_stream];
+       AVStream* a = _format_context->streams[_audio_stream];
+
+       assert (v->time_base.num == a->time_base.num);
+       assert (v->time_base.den == a->time_base.den);
+
+       return rint (av_q2d (v->time_base) * 1000 * (_first_video_pts - _first_audio_pts));
+}
index 339afbaef368a1b85def1b1039301ea94dd039e1..dc10635a5da7ad2f8d4fa3ebf47dcd14d9daab4d 100644 (file)
@@ -66,6 +66,7 @@ public:
        int64_t audio_channel_layout () const;
        bool has_subtitles () const;
        int bytes_per_audio_sample () const;
+       int audio_to_discard () const;
 
        std::vector<AudioStream> audio_streams () const;
        std::vector<SubtitleStream> subtitle_streams () const;
@@ -105,4 +106,7 @@ private:
        AVCodec* _subtitle_codec;                ///< may be 0 if there is no subtitle
 
        AVPacket _packet;
+
+       int64_t _first_video_pts;
+       int64_t _first_audio_pts;
 };