| 244 | } |
| 245 | |
| 246 | static int decode(MimicContext *ctx, int quality, int num_coeffs, |
| 247 | int is_iframe) |
| 248 | { |
| 249 | int ret, y, x, plane, cur_row = 0; |
| 250 | |
| 251 | for (plane = 0; plane < 3; plane++) { |
| 252 | const int is_chroma = !!plane; |
| 253 | const int qscale = av_clip(10000 - quality, is_chroma ? 1000 : 2000, |
| 254 | 10000) << 2; |
| 255 | const int stride = ctx->frames[ctx->cur_index ].f->linesize[plane]; |
| 256 | uint8_t *dst = ctx->frames[ctx->cur_index ].f->data[plane]; |
| 257 | /* src is unused for I frames; set to avoid UB pointer arithmetic. */ |
| 258 | const uint8_t *src = is_iframe ? dst : ctx->frames[ctx->prev_index].f->data[plane]; |
| 259 | |
| 260 | for (y = 0; y < ctx->num_vblocks[plane]; y++) { |
| 261 | for (x = 0; x < ctx->num_hblocks[plane]; x++) { |
| 262 | /* Check for a change condition in the current block. |
| 263 | * - iframes always change. |
| 264 | * - Luma plane changes on get_bits1 == 0 |
| 265 | * - Chroma planes change on get_bits1 == 1 */ |
| 266 | if (is_iframe || get_bits1(&ctx->gb) == is_chroma) { |
| 267 | /* Luma planes may use a backreference from the 15 last |
| 268 | * frames preceding the previous. (get_bits1 == 1) |
| 269 | * Chroma planes don't use backreferences. */ |
| 270 | if (is_chroma || is_iframe || !get_bits1(&ctx->gb)) { |
| 271 | if ((ret = vlc_decode_block(ctx, num_coeffs, |
| 272 | qscale)) < 0) { |
| 273 | av_log(ctx->avctx, AV_LOG_ERROR, "Error decoding " |
| 274 | "block.\n"); |
| 275 | return ret; |
| 276 | } |
| 277 | ctx->idsp.idct_put(dst, stride, ctx->dct_block); |
| 278 | } else { |
| 279 | unsigned int backref = get_bits(&ctx->gb, 4); |
| 280 | int index = (ctx->cur_index + backref) & 15; |
| 281 | |
| 282 | if (index != ctx->cur_index && ctx->frames[index].f) { |
| 283 | const uint8_t *p = ctx->frames[index].f->data[0]; |
| 284 | ff_progress_frame_await(&ctx->frames[index], cur_row); |
| 285 | p += src - |
| 286 | ctx->frames[ctx->prev_index].f->data[plane]; |
| 287 | ctx->hdsp.put_pixels_tab[1][0](dst, p, stride, 8); |
| 288 | } else { |
| 289 | av_log(ctx->avctx, AV_LOG_ERROR, |
| 290 | "No such backreference! Buggy sample.\n"); |
| 291 | } |
| 292 | } |
| 293 | } else { |
| 294 | ff_progress_frame_await(&ctx->frames[ctx->prev_index], cur_row); |
| 295 | ctx->hdsp.put_pixels_tab[1][0](dst, src, stride, 8); |
| 296 | } |
| 297 | src += 8; |
| 298 | dst += 8; |
| 299 | } |
| 300 | src += (stride - ctx->num_hblocks[plane]) << 3; |
| 301 | dst += (stride - ctx->num_hblocks[plane]) << 3; |
| 302 | |
| 303 | ff_progress_frame_report(&ctx->frames[ctx->cur_index], cur_row++); |
no test coverage detected