Skip to content
Permalink
Browse files

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.
  • Loading branch information...
tralph authored and jyavenard committed Dec 13, 2010
1 parent ee906d1 commit 4eba49f884c4b05dcb6fb14b11d72e6b6437b21e
Showing with 63 additions and 0 deletions.
  1. +62 −0 mythtv/libs/libmythtv/avformatdecoder.cpp
  2. +1 −0 mythtv/libs/libmythtv/avformatdecoder.h
@@ -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: */
@@ -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;

0 comments on commit 4eba49f

Please sign in to comment.
You can’t perform that action at this time.