summaryrefslogtreecommitdiff
path: root/libavcodec/mpeg12dec.c
diff options
context:
space:
mode:
authorJanne Grunau <janne-libav@jannau.net>2013-05-21 10:40:01 +0200
committerJanne Grunau <janne-libav@jannau.net>2013-05-28 19:18:10 +0200
commitbf20cdbd86b13d474babecfea13682cc7c9ff2c7 (patch)
tree44fec5a3df8efa63fe050b84b5b95c5d91ea6f3a /libavcodec/mpeg12dec.c
parent2d2d6a4883479403798f4ed46941d5b365823570 (diff)
mpeg12: skip frames consistently
The decoder did not start predicted frames with missing references but called the end of frame handling on them anyway. This caused an assertion in the VA API HW accelorator since it tried to render a picture with uninitialized buffers.
Diffstat (limited to 'libavcodec/mpeg12dec.c')
-rw-r--r--libavcodec/mpeg12dec.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index 67518640b0..d7d893b10a 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -2059,14 +2059,14 @@ static int decode_chunks(AVCodecContext *avctx,
const uint8_t *buf_ptr = buf;
const uint8_t *buf_end = buf + buf_size;
int ret, input_size;
- int last_code = 0;
+ int last_code = 0, skip_frame = 0;
for (;;) {
/* find next start code */
uint32_t start_code = -1;
buf_ptr = avpriv_find_start_code(buf_ptr, buf_end, &start_code);
if (start_code > 0x1ff) {
- if (s2->pict_type != AV_PICTURE_TYPE_B || avctx->skip_frame <= AVDISCARD_DEFAULT) {
+ if (!skip_frame) {
if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE)) {
int i;
@@ -2210,20 +2210,27 @@ static int decode_chunks(AVCodecContext *avctx,
if (s2->last_picture_ptr == NULL) {
/* Skip B-frames if we do not have reference frames and gop is not closed */
if (s2->pict_type == AV_PICTURE_TYPE_B) {
- if (!s->closed_gop)
+ if (!s->closed_gop) {
+ skip_frame = 1;
break;
+ }
}
}
if (s2->pict_type == AV_PICTURE_TYPE_I)
s->sync=1;
if (s2->next_picture_ptr == NULL) {
/* Skip P-frames if we do not have a reference frame or we have an invalid header. */
- if (s2->pict_type == AV_PICTURE_TYPE_P && !s->sync) break;
+ if (s2->pict_type == AV_PICTURE_TYPE_P && !s->sync) {
+ skip_frame = 1;
+ break;
+ }
}
if ((avctx->skip_frame >= AVDISCARD_NONREF && s2->pict_type == AV_PICTURE_TYPE_B) ||
(avctx->skip_frame >= AVDISCARD_NONKEY && s2->pict_type != AV_PICTURE_TYPE_I) ||
- avctx->skip_frame >= AVDISCARD_ALL)
+ avctx->skip_frame >= AVDISCARD_ALL) {
+ skip_frame = 1;
break;
+ }
if (!s->mpeg_enc_ctx_allocated)
break;
@@ -2241,6 +2248,7 @@ static int decode_chunks(AVCodecContext *avctx,
}
if (s2->first_slice) {
+ skip_frame = 0;
s2->first_slice = 0;
if (mpeg_field_start(s2, buf, buf_size) < 0)
return -1;