summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTaylor Ralph <tralph@mythtv.org>2010-12-13 04:02:32 (GMT)
committer Jean-Yves Avenard <jyavenard@mythtv.org>2010-12-14 14:53:43 (GMT)
commit4eba49f884c4b05dcb6fb14b11d72e6b6437b21e (patch)
treed136285ceb331ba60ca6347544a942bbb84c5ca6
parentee906d1fb57cc1adf83f84dfd68c43cecace00cf (diff)
Generate duration and bitrate based off of the video stream.
Recent ffmpeg sometimes generates bogus timings due to non-video streams. This should fix issues with incorrect duration being displayed and ring buffer calculations causing playback issues.
-rw-r--r--mythtv/libs/libmythtv/avformatdecoder.cpp62
-rw-r--r--mythtv/libs/libmythtv/avformatdecoder.h1
2 files changed, 63 insertions, 0 deletions
diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
index b5e1209..8a009c7 100644
--- a/mythtv/libs/libmythtv/avformatdecoder.cpp
+++ b/mythtv/libs/libmythtv/avformatdecoder.cpp
@@ -914,7 +914,12 @@ int AvFormatDecoder::OpenFile(RingBuffer *rbuffer, bool novideo,
fmt->flags &= ~AVFMT_NOFILE;
if (!livetv && !ringBuffer->IsDisc())
+ {
av_estimate_timings(ic, 0);
+ // generate timings based on the video stream to avoid bogus ffmpeg
+ // values for duration and bitrate
+ av_update_stream_timings_video(ic);
+ }
// Scan for the initial A/V streams
ret = ScanStreams(novideo);
@@ -4461,4 +4466,61 @@ bool AvFormatDecoder::SetupAudioStream(void)
return true;
}
+void AvFormatDecoder::av_update_stream_timings_video(AVFormatContext *ic)
+{
+ int64_t start_time, start_time1, end_time, end_time1;
+ int64_t duration, duration1;
+ int i;
+ AVStream *st = NULL;
+
+ start_time = INT64_MAX;
+ end_time = INT64_MIN;
+
+ for (uint i = 0; i < ic->nb_streams; i++)
+ {
+ AVStream *st1 = ic->streams[i];
+ if (st1 && st1->codec->codec_type == CODEC_TYPE_VIDEO)
+ {
+ st = st1;
+ break;
+ }
+ }
+ if (!st)
+ return;
+
+ duration = INT64_MIN;
+ st = ic->streams[i];
+ if (st->start_time != AV_NOPTS_VALUE && st->time_base.den) {
+ start_time1= av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q);
+ if (start_time1 < start_time)
+ start_time = start_time1;
+ if (st->duration != AV_NOPTS_VALUE) {
+ end_time1 = start_time1
+ + av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
+ if (end_time1 > end_time)
+ end_time = end_time1;
+ }
+ }
+ if (st->duration != AV_NOPTS_VALUE) {
+ duration1 = av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
+ if (duration1 > duration)
+ duration = duration1;
+ }
+ if (start_time != INT64_MAX) {
+ ic->start_time = start_time;
+ if (end_time != INT64_MIN) {
+ if (end_time - start_time > duration)
+ duration = end_time - start_time;
+ }
+ }
+ if (duration != INT64_MIN) {
+ ic->duration = duration;
+ if (ic->file_size > 0) {
+ /* compute the bitrate */
+ ic->bit_rate = (double)ic->file_size * 8.0 * AV_TIME_BASE /
+ (double)ic->duration;
+ }
+ }
+}
+
/* vim: set expandtab tabstop=4 shiftwidth=4: */
diff --git a/mythtv/libs/libmythtv/avformatdecoder.h b/mythtv/libs/libmythtv/avformatdecoder.h
index dd71731..7aae8b0 100644
--- a/mythtv/libs/libmythtv/avformatdecoder.h
+++ b/mythtv/libs/libmythtv/avformatdecoder.h
@@ -229,6 +229,7 @@ class AvFormatDecoder : public DecoderBase
bool GenerateDummyVideoFrame(void);
bool HasVideo(const AVFormatContext *ic);
float normalized_fps(AVStream *stream, AVCodecContext *enc);
+ void av_update_stream_timings_video(AVFormatContext *ic);
private:
PrivateDecoder *private_dec;