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