Commit 80387f0e authored by Ronald S. Bultje's avatar Ronald S. Bultje

mimic: don't use self as reference, and report completion at end of decode().

Fixes hangs on corrupt samples that reference self-frames.

Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
CC: libav-stable@libav.org
parent e5d40372
...@@ -259,8 +259,8 @@ static int decode(MimicContext *ctx, int quality, int num_coeffs, ...@@ -259,8 +259,8 @@ static int decode(MimicContext *ctx, int quality, int num_coeffs,
int index = (ctx->cur_index+backref)&15; int index = (ctx->cur_index+backref)&15;
uint8_t *p = ctx->flipped_ptrs[index].data[0]; uint8_t *p = ctx->flipped_ptrs[index].data[0];
ff_thread_await_progress(&ctx->buf_ptrs[index], cur_row, 0); if (index != ctx->cur_index && p) {
if(p) { ff_thread_await_progress(&ctx->buf_ptrs[index], cur_row, 0);
p += src - p += src -
ctx->flipped_ptrs[ctx->prev_index].data[plane]; ctx->flipped_ptrs[ctx->prev_index].data[plane];
ctx->dsp.put_pixels_tab[1][0](dst, p, stride, 8); ctx->dsp.put_pixels_tab[1][0](dst, p, stride, 8);
...@@ -311,6 +311,7 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data, ...@@ -311,6 +311,7 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data,
int width, height; int width, height;
int quality, num_coeffs; int quality, num_coeffs;
int swap_buf_size = buf_size - MIMIC_HEADER_SIZE; int swap_buf_size = buf_size - MIMIC_HEADER_SIZE;
int res;
if (buf_size <= MIMIC_HEADER_SIZE) { if (buf_size <= MIMIC_HEADER_SIZE) {
av_log(avctx, AV_LOG_ERROR, "insufficient data\n"); av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
...@@ -379,10 +380,10 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data, ...@@ -379,10 +380,10 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data,
swap_buf_size>>2); swap_buf_size>>2);
init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3); init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
if(!decode(ctx, quality, num_coeffs, !is_pframe)) { res = decode(ctx, quality, num_coeffs, !is_pframe);
if (avctx->active_thread_type&FF_THREAD_FRAME) ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], INT_MAX, 0);
ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], INT_MAX, 0); if (!res) {
else { if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]); ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]);
return -1; return -1;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment