X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fvc1dec.c;h=3cb766139777505167d3229e769fbada03ba6901;hb=3a2ddf7c2c4d27b595a601c55af23129a5a8be0d;hp=3f84df2d6cd8f63e8e1d519c0440c37ca1ce1b2f;hpb=4f3667ba59750bf7e4c0954394c7c9e164e01c69;p=ffmpeg diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 3f84df2d6cd..3cb76613977 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -5425,14 +5425,13 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, MpegEncContext *s = &v->s; AVFrame *pict = data; uint8_t *buf2 = NULL; - uint8_t *buf_field2 = NULL; const uint8_t *buf_start = buf; int mb_height, n_slices1; struct { uint8_t *buf; GetBitContext gb; int mby_start; - } *slices = NULL; + } *slices = NULL, *tmp; /* no supplementary picture */ if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == VC1_CODE_ENDOFSEQ)) { @@ -5492,9 +5491,6 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, slices[n_slices].mby_start = s->mb_height >> 1; n_slices1 = n_slices - 1; // index of the last slice of the first field n_slices++; - // not necessary, ad hoc until I find a way to handle WVC1i - buf_field2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - vc1_unescape_buffer(start + 4, size, buf_field2); break; } case VC1_CODE_ENTRYPOINT: /* it should be before frame data */ @@ -5522,14 +5518,26 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, } } else if (v->interlace && ((buf[0] & 0xC0) == 0xC0)) { /* WVC1 interlaced stores both fields divided by marker */ const uint8_t *divider; + int buf_size3; divider = find_next_marker(buf, buf + buf_size); if ((divider == (buf + buf_size)) || AV_RB32(divider) != VC1_CODE_FIELD) { av_log(avctx, AV_LOG_ERROR, "Error in WVC1 interlaced frame\n"); goto err; } else { // found field marker, unescape second field - buf_field2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - vc1_unescape_buffer(divider + 4, buf + buf_size - divider - 4, buf_field2); + tmp = av_realloc(slices, sizeof(*slices) * (n_slices+1)); + if (!tmp) + goto err; + slices = tmp; + slices[n_slices].buf = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!slices[n_slices].buf) + goto err; + buf_size3 = vc1_unescape_buffer(divider + 4, buf + buf_size - divider - 4, slices[n_slices].buf); + init_get_bits(&slices[n_slices].gb, slices[n_slices].buf, + buf_size3 << 3); + slices[n_slices].mby_start = s->mb_height >> 1; + n_slices1 = n_slices - 1; + n_slices++; } buf_size2 = vc1_unescape_buffer(buf, divider - buf, buf2); } else { @@ -5579,6 +5587,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, * otherwise we cannot store anything in there. */ if (s->current_picture_ptr == NULL || s->current_picture_ptr->f.data[0]) { int i = ff_find_unused_picture(s, 0); + if (i < 0) + goto err; s->current_picture_ptr = &s->picture[i]; } @@ -5700,10 +5710,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, s->gb = slices[i].gb; } if (v->field_mode) { - av_free(buf_field2); v->second_field = 0; - } - if (v->field_mode) { if (s->pict_type == AV_PICTURE_TYPE_B) { memcpy(v->mv_f_base, v->mv_f_next_base, 2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2)); @@ -5758,7 +5765,6 @@ err: for (i = 0; i < n_slices; i++) av_free(slices[i].buf); av_free(slices); - av_free(buf_field2); return -1; }