Skip to content

Commit

Permalink
Fixes #10745. Fix segfault on H.264 resolution change.
Browse files Browse the repository at this point in the history
The H264PreProcessPkt() code was stubbed out for resolution change,
but we were not actually uning the m_h264_parser values. Without this
we wouldn't actually know about changes until after they had occurred
and then we'd be giving ffmpeg improperly sized video frames in the
meantime.

Note: For this to work you will need to disable ffmpeg's multi-threaded
decoding. This is a limitation of the ffmpeg library we're using.
We shouldn't crash if multi-threading is enabled but simply end
playback at the resolution change.
  • Loading branch information
daniel-kristjansson committed Jul 25, 2012
1 parent c353a84 commit 83e227a
Showing 1 changed file with 33 additions and 5 deletions.
38 changes: 33 additions & 5 deletions mythtv/libs/libmythtv/avformatdecoder.cpp
Expand Up @@ -125,6 +125,35 @@ static float get_aspect(const AVCodecContext &ctx)

return aspect_ratio;
}
static float get_aspect(H264Parser &p)
{
static const float default_aspect = 4.0f / 3.0f;
int asp = p.aspectRatio();
switch (asp)
{
case 0: return default_aspect;
case 2: return 4.0f / 3.0f;
case 3: return 16.0f / 9.0f;
case 4: return 2.21f;
default: break;
}

float aspect_ratio = asp * 0.000001f;
if (aspect_ratio <= 0.0f || aspect_ratio > 6.0f)
{
if (p.pictureHeight() && p.pictureWidth())
{
aspect_ratio =
(float) p.pictureWidth() /(float) p.pictureHeight();
}
else
{
aspect_ratio = default_aspect;
}
}
return aspect_ratio;
}


int get_avf_buffer(struct AVCodecContext *c, AVFrame *pic);
void release_avf_buffer(struct AVCodecContext *c, AVFrame *pic);
Expand Down Expand Up @@ -2954,11 +2983,10 @@ bool AvFormatDecoder::H264PreProcessPkt(AVStream *stream, AVPacket *pkt)
continue;
}

current_aspect = get_aspect(*context);
QSize dim = get_video_dim(*context);
uint width = dim.width();
uint height = dim.height();
float seqFPS = normalized_fps(stream, context);
current_aspect = get_aspect(*m_h264_parser);
uint width = m_h264_parser->pictureWidth();
uint height = m_h264_parser->pictureHeight();
float seqFPS = m_h264_parser->frameRate() * 0.001f;

bool changed = (seqFPS > fps+0.01f) || (seqFPS < fps-0.01f);
changed |= (width != (uint)current_width );
Expand Down

0 comments on commit 83e227a

Please sign in to comment.