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
|
b
|
AvFormatDecoder::AvFormatDecoder(MythPlayer *parent,
|
| 318 | 318 | pts_detected(false), |
| 319 | 319 | reordered_pts_detected(false), |
| 320 | 320 | pts_selected(true), |
| | 321 | wait_for_vpts_reset(false), |
| 321 | 322 | force_dts_timestamps(false), |
| 322 | 323 | playerFlags(flags), |
| 323 | 324 | video_codec_id(kCodec_NONE), |
| … |
… |
void AvFormatDecoder::MpegPreProcessPkt(AVStream *stream, AVPacket *pkt)
|
| 3048 | 3049 | prevgoppos = 0; |
| 3049 | 3050 | firstvpts = lastapts = lastvpts = lastccptsu = 0; |
| 3050 | 3051 | firstvptsinuse = true; |
| | 3052 | wait_for_vpts_reset = false; |
| 3051 | 3053 | faulty_pts = faulty_dts = 0; |
| 3052 | 3054 | last_pts_for_fault_detection = 0; |
| 3053 | 3055 | last_dts_for_fault_detection = 0; |
| … |
… |
bool AvFormatDecoder::H264PreProcessPkt(AVStream *stream, AVPacket *pkt)
|
| 3151 | 3153 | prevgoppos = 0; |
| 3152 | 3154 | firstvpts = lastapts = lastvpts = lastccptsu = 0; |
| 3153 | 3155 | firstvptsinuse = true; |
| | 3156 | wait_for_vpts_reset = false; |
| 3154 | 3157 | faulty_pts = faulty_dts = 0; |
| 3155 | 3158 | last_pts_for_fault_detection = 0; |
| 3156 | 3159 | last_dts_for_fault_detection = 0; |
| … |
… |
bool AvFormatDecoder::ProcessVideoFrame(AVStream *stream, AVFrame *mpa_pic)
|
| 3489 | 3492 | gotVideoFrame = 1; |
| 3490 | 3493 | framesPlayed++; |
| 3491 | 3494 | |
| | 3495 | // if vpts reset has happened, no need to wait for it any more |
| | 3496 | if (temppts < lastvpts) |
| | 3497 | { |
| | 3498 | LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_DEBUG, LOC + QString("vpts reset! %1->%2, apts %3") |
| | 3499 | .arg(lastvpts) |
| | 3500 | .arg(temppts) |
| | 3501 | .arg(lastapts)); |
| | 3502 | |
| | 3503 | wait_for_vpts_reset = false; |
| | 3504 | } |
| | 3505 | |
| 3492 | 3506 | lastvpts = temppts; |
| 3493 | 3507 | if (!firstvpts && firstvptsinuse) |
| 3494 | 3508 | firstvpts = temppts; |
| … |
… |
bool AvFormatDecoder::ProcessAudioPacket(AVStream *curstream, AVPacket *pkt,
|
| 4384 | 4398 | break; |
| 4385 | 4399 | |
| 4386 | 4400 | if (firstloop && pkt->pts != (int64_t)AV_NOPTS_VALUE) |
| | 4401 | { |
| | 4402 | long long previous = lastapts; |
| 4387 | 4403 | lastapts = (long long)(av_q2d(curstream->time_base) * pkt->pts * 1000); |
| 4388 | 4404 | |
| | 4405 | if ((previous > lastapts) && (lastapts < lastvpts)) |
| | 4406 | { |
| | 4407 | wait_for_vpts_reset = true; |
| | 4408 | |
| | 4409 | LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_DEBUG, LOC + QString("apts reset! %1->%2, pts %3, vpts %4") |
| | 4410 | .arg(previous) |
| | 4411 | .arg(lastapts) |
| | 4412 | .arg(pkt->pts) |
| | 4413 | .arg(lastvpts)); |
| | 4414 | } |
| | 4415 | } |
| | 4416 | |
| 4389 | 4417 | if (skipaudio && selectedTrack[kTrackTypeVideo].av_stream_index > -1) |
| 4390 | 4418 | { |
| 4391 | 4419 | if ((lastapts < lastvpts - (10.0 / fps)) || lastvpts == 0) |
| … |
… |
bool AvFormatDecoder::GetFrame(DecodeType decodetype)
|
| 4597 | 4625 | else if (lowbuffers && ((decodetype & kDecodeAV) == kDecodeAV) && |
| 4598 | 4626 | (storedPackets.count() < max_video_queue_size) && |
| 4599 | 4627 | (lastapts < lastvpts + 100) && |
| | 4628 | !wait_for_vpts_reset && |
| 4600 | 4629 | !ringBuffer->IsInStillFrame()) |
| 4601 | 4630 | { |
| 4602 | 4631 | storevideoframes = true; |
diff --git a/mythtv/libs/libmythtv/avformatdecoder.h b/mythtv/libs/libmythtv/avformatdecoder.h
index f76c26b..d5b64ac 100644
|
a
|
b
|
class AvFormatDecoder : public DecoderBase
|
| 316 | 316 | bool pts_detected; |
| 317 | 317 | bool reordered_pts_detected; |
| 318 | 318 | bool pts_selected; |
| | 319 | bool wait_for_vpts_reset; |
| 319 | 320 | |
| 320 | 321 | bool force_dts_timestamps; |
| 321 | 322 | |