mimic: Always return on failure
[libav.git] / libavcodec / mimic.c
CommitLineData
a7129de5 1/*
6d27d8b1 2 * Copyright (C) 2005 Ole André Vadla Ravnås <oleavr@gmail.com>
cbf5d22d 3 * Copyright (C) 2008 Ramiro Polla
a7129de5 4 *
2912e87a 5 * This file is part of Libav.
a7129de5 6 *
2912e87a 7 * Libav is free software; you can redistribute it and/or
a7129de5
RP
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
2912e87a 12 * Libav is distributed in the hope that it will be useful,
a7129de5
RP
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
2912e87a 18 * License along with Libav; if not, write to the Free Software
a7129de5
RP
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include <stdlib.h>
23#include <string.h>
24#include <stdint.h>
25
26#include "avcodec.h"
e74433a8 27#include "blockdsp.h"
f3a29b75 28#include "internal.h"
9106a698 29#include "get_bits.h"
fc22c009 30#include "bytestream.h"
c67b449b 31#include "bswapdsp.h"
c1047003 32#include "hpeldsp.h"
e3fcb143 33#include "idctdsp.h"
a75529e8 34#include "thread.h"
a7129de5
RP
35
36#define MIMIC_HEADER_SIZE 20
37
7f9f771e 38typedef struct MimicContext {
a7129de5
RP
39 AVCodecContext *avctx;
40
41 int num_vblocks[3];
42 int num_hblocks[3];
43
9bf993a5 44 void *swap_buf;
a7129de5
RP
45 int swap_buf_size;
46
47 int cur_index;
48 int prev_index;
49
759001c5 50 ThreadFrame frames [16];
a7129de5 51
88bd7fdc 52 DECLARE_ALIGNED(16, int16_t, dct_block)[64];
a7129de5
RP
53
54 GetBitContext gb;
55 ScanTable scantable;
e74433a8 56 BlockDSPContext bdsp;
c67b449b 57 BswapDSPContext bbdsp;
c1047003 58 HpelDSPContext hdsp;
e3fcb143 59 IDCTDSPContext idsp;
c9108634 60 VLC vlc;
a75529e8
AS
61
62 /* Kept in the context so multithreading can have a constant to read from */
63 int next_cur_index;
64 int next_prev_index;
a7129de5
RP
65} MimicContext;
66
67static const uint32_t huffcodes[] = {
68 0x0000000a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
69 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
70 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000b,
71 0x0000001b, 0x00000038, 0x00000078, 0x00000079, 0x0000007a, 0x000000f9,
72 0x000000fa, 0x000003fb, 0x000007f8, 0x000007f9, 0x000007fa, 0x000007fb,
73 0x00000ff8, 0x00000ff9, 0x00000001, 0x00000039, 0x0000007b, 0x000000fb,
74 0x000001f8, 0x000001f9, 0x00000ffa, 0x00000ffb, 0x00001ff8, 0x00001ff9,
75 0x00001ffa, 0x00001ffb, 0x00003ff8, 0x00003ff9, 0x00003ffa, 0x00000000,
76 0x00000004, 0x0000003a, 0x000001fa, 0x00003ffb, 0x00007ff8, 0x00007ff9,
77 0x00007ffa, 0x00007ffb, 0x0000fff8, 0x0000fff9, 0x0000fffa, 0x0000fffb,
78 0x0001fff8, 0x0001fff9, 0x0001fffa, 0x00000000, 0x0000000c, 0x000000f8,
79 0x000001fb, 0x0001fffb, 0x0003fff8, 0x0003fff9, 0x0003fffa, 0x0003fffb,
80 0x0007fff8, 0x0007fff9, 0x0007fffa, 0x0007fffb, 0x000ffff8, 0x000ffff9,
81 0x000ffffa, 0x00000000, 0x0000001a, 0x000003f8, 0x000ffffb, 0x001ffff8,
82 0x001ffff9, 0x001ffffa, 0x001ffffb, 0x003ffff8, 0x003ffff9, 0x003ffffa,
83 0x003ffffb, 0x007ffff8, 0x007ffff9, 0x007ffffa, 0x007ffffb, 0x00000000,
84 0x0000003b, 0x000003f9, 0x00fffff8, 0x00fffff9, 0x00fffffa, 0x00fffffb,
85 0x01fffff8, 0x01fffff9, 0x01fffffa, 0x01fffffb, 0x03fffff8, 0x03fffff9,
86 0x03fffffa, 0x03fffffb, 0x07fffff8, 0x00000000, 0x000003fa, 0x07fffff9,
87 0x07fffffa, 0x07fffffb, 0x0ffffff8, 0x0ffffff9, 0x0ffffffa, 0x0ffffffb,
88 0x1ffffff8, 0x1ffffff9, 0x1ffffffa, 0x1ffffffb, 0x3ffffff8, 0x3ffffff9,
89 0x3ffffffa,
90};
91
92static const uint8_t huffbits[] = {
93 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
94 0, 0, 0, 0, 2, 4, 5, 6, 7, 7, 7, 8,
95 8, 10, 11, 11, 11, 11, 12, 12, 2, 6, 7, 8,
96 9, 9, 12, 12, 13, 13, 13, 13, 14, 14, 14, 0,
97 3, 6, 9, 14, 15, 15, 15, 15, 16, 16, 16, 16,
98 17, 17, 17, 0, 4, 8, 9, 17, 18, 18, 18, 18,
99 19, 19, 19, 19, 20, 20, 20, 0, 5, 10, 20, 21,
100 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 0,
101 6, 10, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26,
102 26, 26, 27, 0, 10, 27, 27, 27, 28, 28, 28, 28,
103 29, 29, 29, 29, 30, 30, 30,
104};
105
106static const uint8_t col_zag[64] = {
107 0, 8, 1, 2, 9, 16, 24, 17,
108 10, 3, 4, 11, 18, 25, 32, 40,
109 33, 26, 19, 12, 5, 6, 13, 20,
110 27, 34, 41, 48, 56, 49, 42, 35,
111 28, 21, 14, 7, 15, 22, 29, 36,
112 43, 50, 57, 58, 51, 44, 37, 30,
113 23, 31, 38, 45, 52, 59, 39, 46,
399e4652 114 53, 60, 61, 54, 47, 55, 62, 63,
a7129de5
RP
115};
116
759001c5
AK
117static av_cold int mimic_decode_end(AVCodecContext *avctx)
118{
119 MimicContext *ctx = avctx->priv_data;
120 int i;
121
122 av_free(ctx->swap_buf);
123
124 for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
125 if (ctx->frames[i].f)
126 ff_thread_release_buffer(avctx, &ctx->frames[i]);
127 av_frame_free(&ctx->frames[i].f);
128 }
129
130 if (!avctx->internal->is_copy)
131 ff_free_vlc(&ctx->vlc);
132
133 return 0;
134}
135
98a6fff9 136static av_cold int mimic_decode_init(AVCodecContext *avctx)
a7129de5
RP
137{
138 MimicContext *ctx = avctx->priv_data;
759001c5
AK
139 int ret, i;
140
141 avctx->internal->allocate_progress = 1;
a7129de5
RP
142
143 ctx->prev_index = 0;
a0cabd0a 144 ctx->cur_index = 15;
a7129de5 145
b965cb90
AK
146 if ((ret = init_vlc(&ctx->vlc, 11, FF_ARRAY_ELEMS(huffbits),
147 huffbits, 1, 1, huffcodes, 4, 4, 0)) < 0) {
a7129de5 148 av_log(avctx, AV_LOG_ERROR, "error initializing vlc table\n");
b965cb90 149 return ret;
a7129de5 150 }
e74433a8 151 ff_blockdsp_init(&ctx->bdsp, avctx);
c67b449b 152 ff_bswapdsp_init(&ctx->bbdsp);
c1047003 153 ff_hpeldsp_init(&ctx->hdsp, avctx->flags);
e3fcb143
DB
154 ff_idctdsp_init(&ctx->idsp, avctx);
155 ff_init_scantable(ctx->idsp.idct_permutation, &ctx->scantable, col_zag);
a7129de5 156
759001c5
AK
157 for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
158 ctx->frames[i].f = av_frame_alloc();
159 if (!ctx->frames[i].f) {
160 mimic_decode_end(avctx);
161 return AVERROR(ENOMEM);
162 }
163 }
164
a7129de5
RP
165 return 0;
166}
167
a75529e8
AS
168static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from)
169{
170 MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data;
759001c5 171 int i, ret;
a75529e8 172
a0cabd0a
AK
173 if (avctx == avctx_from)
174 return 0;
a75529e8
AS
175
176 dst->cur_index = src->next_cur_index;
177 dst->prev_index = src->next_prev_index;
178
759001c5
AK
179 for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) {
180 ff_thread_release_buffer(avctx, &dst->frames[i]);
181 if (src->frames[i].f->data[0]) {
182 ret = ff_thread_ref_frame(&dst->frames[i], &src->frames[i]);
183 if (ret < 0)
184 return ret;
185 }
186 }
a75529e8
AS
187
188 return 0;
189}
190
1bf6e565 191static const int8_t vlcdec_lookup[9][64] = {
a7129de5
RP
192 { 0, },
193 { -1, 1, },
194 { -3, 3, -2, 2, },
195 { -7, 7, -6, 6, -5, 5, -4, 4, },
196 { -15, 15, -14, 14, -13, 13, -12, 12,
197 -11, 11, -10, 10, -9, 9, -8, 8, },
198 { -31, 31, -30, 30, -29, 29, -28, 28,
199 -27, 27, -26, 26, -25, 25, -24, 24,
200 -23, 23, -22, 22, -21, 21, -20, 20,
201 -19, 19, -18, 18, -17, 17, -16, 16, },
202 { -63, 63, -62, 62, -61, 61, -60, 60,
203 -59, 59, -58, 58, -57, 57, -56, 56,
204 -55, 55, -54, 54, -53, 53, -52, 52,
205 -51, 51, -50, 50, -49, 49, -48, 48,
206 -47, 47, -46, 46, -45, 45, -44, 44,
207 -43, 43, -42, 42, -41, 41, -40, 40,
208 -39, 39, -38, 38, -37, 37, -36, 36,
209 -35, 35, -34, 34, -33, 33, -32, 32, },
210 { -127, 127, -126, 126, -125, 125, -124, 124,
211 -123, 123, -122, 122, -121, 121, -120, 120,
212 -119, 119, -118, 118, -117, 117, -116, 116,
213 -115, 115, -114, 114, -113, 113, -112, 112,
214 -111, 111, -110, 110, -109, 109, -108, 108,
215 -107, 107, -106, 106, -105, 105, -104, 104,
216 -103, 103, -102, 102, -101, 101, -100, 100,
217 -99, 99, -98, 98, -97, 97, -96, 96, },
218 { -95, 95, -94, 94, -93, 93, -92, 92,
219 -91, 91, -90, 90, -89, 89, -88, 88,
220 -87, 87, -86, 86, -85, 85, -84, 84,
221 -83, 83, -82, 82, -81, 81, -80, 80,
222 -79, 79, -78, 78, -77, 77, -76, 76,
223 -75, 75, -74, 74, -73, 73, -72, 72,
224 -71, 71, -70, 70, -69, 69, -68, 68,
225 -67, 67, -66, 66, -65, 65, -64, 64, },
226};
227
bebfc16a 228static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
a7129de5 229{
88bd7fdc 230 int16_t *block = ctx->dct_block;
a7129de5
RP
231 unsigned int pos;
232
e74433a8 233 ctx->bdsp.clear_block(block);
a7129de5
RP
234
235 block[0] = get_bits(&ctx->gb, 8) << 3;
236
a0cabd0a 237 for (pos = 1; pos < num_coeffs; pos++) {
a7129de5
RP
238 uint32_t vlc, num_bits;
239 int value;
240 int coeff;
241
630e1b27 242 vlc = get_vlc2(&ctx->gb, ctx->vlc.table, ctx->vlc.bits, 3);
a0cabd0a 243 if (!vlc) /* end-of-block code */
a7129de5 244 return 0;
b965cb90
AK
245 if (vlc == -1)
246 return AVERROR_INVALIDDATA;
a7129de5
RP
247
248 /* pos_add and num_bits are coded in the vlc code */
a0cabd0a
AK
249 pos += vlc & 15; // pos_add
250 num_bits = vlc >> 4; // num_bits
a7129de5 251
a0cabd0a 252 if (pos >= 64)
b965cb90 253 return AVERROR_INVALIDDATA;
a7129de5
RP
254
255 value = get_bits(&ctx->gb, num_bits);
256
6001dad6 257 /* Libav's IDCT behaves somewhat different from the original code, so
a7129de5
RP
258 * a factor of 4 was added to the input */
259
260 coeff = vlcdec_lookup[num_bits][value];
a0cabd0a 261 if (pos < 3)
a7129de5
RP
262 coeff <<= 4;
263 else /* TODO Use >> 10 instead of / 1001 */
264 coeff = (coeff * qscale) / 1001;
265
266 block[ctx->scantable.permutated[pos]] = coeff;
267 }
268
b965cb90 269 return 0;
a7129de5
RP
270}
271
272static int decode(MimicContext *ctx, int quality, int num_coeffs,
273 int is_iframe)
274{
b965cb90 275 int ret, y, x, plane, cur_row = 0;
a7129de5 276
a0cabd0a 277 for (plane = 0; plane < 3; plane++) {
a7129de5 278 const int is_chroma = !!plane;
a0cabd0a
AK
279 const int qscale = av_clip(10000 - quality, is_chroma ? 1000 : 2000,
280 10000) << 2;
6a23a342 281 const int stride = ctx->frames[ctx->cur_index ].f->linesize[plane];
282 const uint8_t *src = ctx->frames[ctx->prev_index].f->data[plane];
283 uint8_t *dst = ctx->frames[ctx->cur_index ].f->data[plane];
a0cabd0a
AK
284
285 for (y = 0; y < ctx->num_vblocks[plane]; y++) {
286 for (x = 0; x < ctx->num_hblocks[plane]; x++) {
a7129de5
RP
287 /* Check for a change condition in the current block.
288 * - iframes always change.
289 * - Luma plane changes on get_bits1 == 0
290 * - Chroma planes change on get_bits1 == 1 */
a0cabd0a 291 if (is_iframe || get_bits1(&ctx->gb) == is_chroma) {
a7129de5
RP
292 /* Luma planes may use a backreference from the 15 last
293 * frames preceding the previous. (get_bits1 == 1)
294 * Chroma planes don't use backreferences. */
a0cabd0a 295 if (is_chroma || is_iframe || !get_bits1(&ctx->gb)) {
b965cb90
AK
296 if ((ret = vlc_decode_block(ctx, num_coeffs,
297 qscale)) < 0) {
298 av_log(ctx->avctx, AV_LOG_ERROR, "Error decoding "
299 "block.\n");
300 return ret;
301 }
e3fcb143 302 ctx->idsp.idct_put(dst, stride, ctx->dct_block);
a7129de5
RP
303 } else {
304 unsigned int backref = get_bits(&ctx->gb, 4);
a0cabd0a 305 int index = (ctx->cur_index + backref) & 15;
6a23a342 306 uint8_t *p = ctx->frames[index].f->data[0];
a7129de5 307
80387f0e 308 if (index != ctx->cur_index && p) {
759001c5 309 ff_thread_await_progress(&ctx->frames[index],
a0cabd0a 310 cur_row, 0);
a7129de5 311 p += src -
6a23a342 312 ctx->frames[ctx->prev_index].f->data[plane];
c1047003 313 ctx->hdsp.put_pixels_tab[1][0](dst, p, stride, 8);
a7129de5
RP
314 } else {
315 av_log(ctx->avctx, AV_LOG_ERROR,
316 "No such backreference! Buggy sample.\n");
317 }
318 }
319 } else {
759001c5 320 ff_thread_await_progress(&ctx->frames[ctx->prev_index],
a0cabd0a 321 cur_row, 0);
c1047003 322 ctx->hdsp.put_pixels_tab[1][0](dst, src, stride, 8);
a7129de5
RP
323 }
324 src += 8;
325 dst += 8;
326 }
a0cabd0a
AK
327 src += (stride - ctx->num_hblocks[plane]) << 3;
328 dst += (stride - ctx->num_hblocks[plane]) << 3;
a75529e8 329
759001c5 330 ff_thread_report_progress(&ctx->frames[ctx->cur_index],
a0cabd0a 331 cur_row++, 0);
a7129de5
RP
332 }
333 }
334
b965cb90 335 return 0;
a7129de5
RP
336}
337
338/**
6a23a342 339 * Flip the buffer upside-down and put it in the YVU order to revert the
a7129de5
RP
340 * way Mimic encodes frames.
341 */
6a23a342 342static void flip_swap_frame(AVFrame *f)
a7129de5
RP
343{
344 int i;
6a23a342 345 uint8_t *data_1 = f->data[1];
346 f->data[0] = f->data[0] + ( f->height - 1) * f->linesize[0];
347 f->data[1] = f->data[2] + ((f->height >> 1) - 1) * f->linesize[2];
348 f->data[2] = data_1 + ((f->height >> 1) - 1) * f->linesize[1];
a0cabd0a 349 for (i = 0; i < 3; i++)
6a23a342 350 f->linesize[i] *= -1;
a7129de5
RP
351}
352
353static int mimic_decode_frame(AVCodecContext *avctx, void *data,
df9b9567 354 int *got_frame, AVPacket *avpkt)
a7129de5 355{
7a00bbad 356 const uint8_t *buf = avpkt->data;
a0cabd0a
AK
357 int buf_size = avpkt->size;
358 int swap_buf_size = buf_size - MIMIC_HEADER_SIZE;
359 MimicContext *ctx = avctx->priv_data;
dba425ad 360 GetByteContext gb;
a7129de5
RP
361 int is_pframe;
362 int width, height;
363 int quality, num_coeffs;
80387f0e 364 int res;
a7129de5 365
33c5c3ad 366 if (buf_size <= MIMIC_HEADER_SIZE) {
a7129de5 367 av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
b965cb90 368 return AVERROR_INVALIDDATA;
a7129de5
RP
369 }
370
dba425ad
PM
371 bytestream2_init(&gb, buf, MIMIC_HEADER_SIZE);
372 bytestream2_skip(&gb, 2); /* some constant (always 256) */
373 quality = bytestream2_get_le16u(&gb);
374 width = bytestream2_get_le16u(&gb);
375 height = bytestream2_get_le16u(&gb);
376 bytestream2_skip(&gb, 4); /* some constant */
377 is_pframe = bytestream2_get_le32u(&gb);
378 num_coeffs = bytestream2_get_byteu(&gb);
379 bytestream2_skip(&gb, 3); /* some constant */
a7129de5 380
a0cabd0a 381 if (!ctx->avctx) {
a7129de5
RP
382 int i;
383
a0cabd0a
AK
384 if (!(width == 160 && height == 120) &&
385 !(width == 320 && height == 240)) {
a7129de5 386 av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n");
b965cb90 387 return AVERROR_INVALIDDATA;
a7129de5
RP
388 }
389
390 ctx->avctx = avctx;
391 avctx->width = width;
392 avctx->height = height;
716d413c 393 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
a0cabd0a 394 for (i = 0; i < 3; i++) {
a7129de5 395 ctx->num_vblocks[i] = -((-height) >> (3 + !!i));
a0cabd0a 396 ctx->num_hblocks[i] = width >> (3 + !!i);
a7129de5 397 }
a0cabd0a 398 } else if (width != ctx->avctx->width || height != ctx->avctx->height) {
12e25ed2 399 avpriv_request_sample(avctx, "Resolution changing");
b965cb90 400 return AVERROR_PATCHWELCOME;
a7129de5
RP
401 }
402
759001c5 403 if (is_pframe && !ctx->frames[ctx->prev_index].f->data[0]) {
a7129de5 404 av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
b965cb90 405 return AVERROR_INVALIDDATA;
a7129de5
RP
406 }
407
759001c5
AK
408 ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
409 ctx->frames[ctx->cur_index].f->pict_type = is_pframe ? AV_PICTURE_TYPE_P :
410 AV_PICTURE_TYPE_I;
411 if ((res = ff_thread_get_buffer(avctx, &ctx->frames[ctx->cur_index],
412 AV_GET_BUFFER_FLAG_REF)) < 0) {
a7129de5 413 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
b965cb90 414 return res;
a7129de5
RP
415 }
416
a75529e8
AS
417 ctx->next_prev_index = ctx->cur_index;
418 ctx->next_cur_index = (ctx->cur_index - 1) & 15;
419
a75529e8
AS
420 ff_thread_finish_setup(avctx);
421
c15fea79 422 av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);
a0cabd0a 423 if (!ctx->swap_buf)
55775b09 424 return AVERROR(ENOMEM);
a7129de5 425
c67b449b
DB
426 ctx->bbdsp.bswap_buf(ctx->swap_buf,
427 (const uint32_t *) (buf + MIMIC_HEADER_SIZE),
428 swap_buf_size >> 2);
a7129de5
RP
429 init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
430
80387f0e 431 res = decode(ctx, quality, num_coeffs, !is_pframe);
759001c5 432 ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0);
b965cb90 433 if (res < 0) {
4a326923 434 if (!(avctx->active_thread_type & FF_THREAD_FRAME))
759001c5 435 ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
4a326923 436 return res;
a7129de5
RP
437 }
438
759001c5
AK
439 if ((res = av_frame_ref(data, ctx->frames[ctx->cur_index].f)) < 0)
440 return res;
df9b9567 441 *got_frame = 1;
a7129de5 442
6a23a342 443 flip_swap_frame(data);
444
a75529e8
AS
445 ctx->prev_index = ctx->next_prev_index;
446 ctx->cur_index = ctx->next_cur_index;
a7129de5
RP
447
448 /* Only release frames that aren't used for backreferences anymore */
759001c5 449 ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
a7129de5
RP
450
451 return buf_size;
452}
453
759001c5 454static av_cold int mimic_init_thread_copy(AVCodecContext *avctx)
a7129de5
RP
455{
456 MimicContext *ctx = avctx->priv_data;
457 int i;
458
759001c5
AK
459 for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
460 ctx->frames[i].f = av_frame_alloc();
461 if (!ctx->frames[i].f) {
462 mimic_decode_end(avctx);
463 return AVERROR(ENOMEM);
464 }
465 }
a7129de5
RP
466
467 return 0;
468}
469
d36beb3f 470AVCodec ff_mimic_decoder = {
00c3b67b 471 .name = "mimic",
b2bed932 472 .long_name = NULL_IF_CONFIG_SMALL("Mimic"),
00c3b67b 473 .type = AVMEDIA_TYPE_VIDEO,
36ef5369 474 .id = AV_CODEC_ID_MIMIC,
00c3b67b
MS
475 .priv_data_size = sizeof(MimicContext),
476 .init = mimic_decode_init,
477 .close = mimic_decode_end,
478 .decode = mimic_decode_frame,
def97856 479 .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
759001c5
AK
480 .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context),
481 .init_thread_copy = ONLY_IF_THREADS_ENABLED(mimic_init_thread_copy),
a7129de5 482};