]> git.sesse.net Git - nageru/commitdiff
Correct FFmpeg audio PTS.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Wed, 18 Apr 2018 22:59:47 +0000 (00:59 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 22 Apr 2018 13:17:32 +0000 (15:17 +0200)
The PTS should come from received (decoded) samples, not what we send
into the codec -- if there's codec delay, the difference could be
significant.

ffmpeg_capture.cpp

index c79ecf337fe8213efe16b26f3e3cd436c5c4dfe5..4f6e1685f282e358339a1e95dbf700525da719b1 100644 (file)
@@ -597,6 +597,7 @@ AVFrameWithDeleter FFmpegCapture::decode_frame(AVFormatContext *format_ctx, AVCo
        AVFrameWithDeleter video_avframe = av_frame_alloc_unique();
        bool eof = false;
        *audio_pts = -1;
+       bool has_audio = false;
        do {
                AVPacket pkt;
                unique_ptr<AVPacket, decltype(av_packet_unref)*> pkt_cleanup(
@@ -615,9 +616,7 @@ AVFrameWithDeleter FFmpegCapture::decode_frame(AVFormatContext *format_ctx, AVCo
                                        return AVFrameWithDeleter(nullptr);
                                }
                        } else if (pkt.stream_index == audio_stream_index) {
-                               if (*audio_pts == -1) {
-                                       *audio_pts = pkt.pts;
-                               }
+                               has_audio = true;
                                if (avcodec_send_packet(audio_codec_ctx, &pkt) < 0) {
                                        fprintf(stderr, "%s: Cannot send packet to audio codec.\n", pathname.c_str());
                                        *error = true;
@@ -629,10 +628,13 @@ AVFrameWithDeleter FFmpegCapture::decode_frame(AVFormatContext *format_ctx, AVCo
                }
 
                // Decode audio, if any.
-               if (*audio_pts != -1) {
+               if (has_audio) {
                        for ( ;; ) {
                                int err = avcodec_receive_frame(audio_codec_ctx, audio_avframe.get());
                                if (err == 0) {
+                                       if (*audio_pts == -1) {
+                                               *audio_pts = audio_avframe->pts;
+                                       }
                                        convert_audio(audio_avframe.get(), audio_frame, audio_format);
                                } else if (err == AVERROR(EAGAIN)) {
                                        break;