From c4590c33343beecbf0934fe9be60d85b4f9c8398 Mon Sep 17 00:00:00 2001
From: Richard <peper03@yahoo.com>
Date: Tue, 22 Jan 2013 21:59:21 +0100
Subject: Detect when the audio timestamp resets to ensure we don't get stuck
 buffering video frames until we either hit the limit or the audio
 buffer is full.

---
 mythtv/libs/libmythtv/avformatdecoder.cpp |   29 +++++++++++++++++++++++++++++
 mythtv/libs/libmythtv/avformatdecoder.h   |    1 +
 2 files changed, 30 insertions(+)

diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
index ea21273..cadd09c 100644
--- a/mythtv/libs/libmythtv/avformatdecoder.cpp
+++ b/mythtv/libs/libmythtv/avformatdecoder.cpp
@@ -318,6 +318,7 @@ AvFormatDecoder::AvFormatDecoder(MythPlayer *parent,
       pts_detected(false),
       reordered_pts_detected(false),
       pts_selected(true),
+      wait_for_vpts_reset(false),
       force_dts_timestamps(false),
       playerFlags(flags),
       video_codec_id(kCodec_NONE),
@@ -3048,6 +3049,7 @@ void AvFormatDecoder::MpegPreProcessPkt(AVStream *stream, AVPacket *pkt)
                 prevgoppos = 0;
                 firstvpts = lastapts = lastvpts = lastccptsu = 0;
                 firstvptsinuse = true;
+                wait_for_vpts_reset = false;
                 faulty_pts = faulty_dts = 0;
                 last_pts_for_fault_detection = 0;
                 last_dts_for_fault_detection = 0;
@@ -3151,6 +3153,7 @@ bool AvFormatDecoder::H264PreProcessPkt(AVStream *stream, AVPacket *pkt)
             prevgoppos = 0;
             firstvpts = lastapts = lastvpts = lastccptsu = 0;
             firstvptsinuse = true;
+            wait_for_vpts_reset = false;
             faulty_pts = faulty_dts = 0;
             last_pts_for_fault_detection = 0;
             last_dts_for_fault_detection = 0;
@@ -3489,6 +3492,17 @@ bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic)
     gotVideoFrame = 1;
     framesPlayed++;
 
+    // if vpts reset has happened, no need to wait for it any more
+    if (temppts < lastvpts)
+    {
+        LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_DEBUG, LOC + QString("vpts reset! %1->%2, apts %3")
+            .arg(lastvpts)
+            .arg(temppts)
+            .arg(lastapts));
+
+        wait_for_vpts_reset = false;
+    }
+
     lastvpts = temppts;
     if (!firstvpts && firstvptsinuse)
         firstvpts = temppts;
@@ -4384,8 +4398,22 @@ bool AvFormatDecoder::ProcessAudioPacket(AVStream *curstream, AVPacket *pkt,
             break;
 
         if (firstloop && pkt->pts != (int64_t)AV_NOPTS_VALUE)
+        {
+            long long previous = lastapts;
             lastapts = (long long)(av_q2d(curstream->time_base) * pkt->pts * 1000);
 
+            if ((previous > lastapts) && (lastapts < lastvpts))
+            {
+                wait_for_vpts_reset = true;
+
+                LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_DEBUG, LOC + QString("apts reset! %1->%2, pts %3, vpts %4")
+                    .arg(previous)
+                    .arg(lastapts)
+                    .arg(pkt->pts)
+                    .arg(lastvpts));
+            }
+        }
+
         if (skipaudio && selectedTrack[kTrackTypeVideo].av_stream_index > -1)
         {
             if ((lastapts < lastvpts - (10.0 / fps)) || lastvpts == 0)
@@ -4597,6 +4625,7 @@ bool AvFormatDecoder::GetFrame(DecodeType decodetype)
             else if (lowbuffers && ((decodetype & kDecodeAV) == kDecodeAV) &&
                      (storedPackets.count() < max_video_queue_size) &&
                      (lastapts < lastvpts + 100) &&
+                     !wait_for_vpts_reset &&
                      !ringBuffer->IsInStillFrame())
             {
                 storevideoframes = true;
diff --git a/mythtv/libs/libmythtv/avformatdecoder.h b/mythtv/libs/libmythtv/avformatdecoder.h
index f76c26b..d5b64ac 100644
--- a/mythtv/libs/libmythtv/avformatdecoder.h
+++ b/mythtv/libs/libmythtv/avformatdecoder.h
@@ -316,6 +316,7 @@ class AvFormatDecoder : public DecoderBase
     bool pts_detected;
     bool reordered_pts_detected;
     bool pts_selected;
+    bool wait_for_vpts_reset;
 
     bool force_dts_timestamps;
 
-- 
1.7.9.5

