libschroedinger: Properly use AVFrame API
[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
RP
51 AVPicture flipped_ptrs[16];
52
88bd7fdc 53 DECLARE_ALIGNED(16, int16_t, dct_block)[64];
a7129de5
RP
54
55 GetBitContext gb;
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 }
e74433a8 152 ff_blockdsp_init(&ctx->bdsp, avctx);
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
a75529e8
AS
180 memcpy(dst->flipped_ptrs, src->flipped_ptrs, sizeof(src->flipped_ptrs));
181
759001c5
AK
182 for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) {
183 ff_thread_release_buffer(avctx, &dst->frames[i]);
184 if (src->frames[i].f->data[0]) {
185 ret = ff_thread_ref_frame(&dst->frames[i], &src->frames[i]);
186 if (ret < 0)
187 return ret;
188 }
189 }
a75529e8
AS
190
191 return 0;
192}
193
1bf6e565 194static const int8_t vlcdec_lookup[9][64] = {
a7129de5
RP
195 { 0, },
196 { -1, 1, },
197 { -3, 3, -2, 2, },
198 { -7, 7, -6, 6, -5, 5, -4, 4, },
199 { -15, 15, -14, 14, -13, 13, -12, 12,
200 -11, 11, -10, 10, -9, 9, -8, 8, },
201 { -31, 31, -30, 30, -29, 29, -28, 28,
202 -27, 27, -26, 26, -25, 25, -24, 24,
203 -23, 23, -22, 22, -21, 21, -20, 20,
204 -19, 19, -18, 18, -17, 17, -16, 16, },
205 { -63, 63, -62, 62, -61, 61, -60, 60,
206 -59, 59, -58, 58, -57, 57, -56, 56,
207 -55, 55, -54, 54, -53, 53, -52, 52,
208 -51, 51, -50, 50, -49, 49, -48, 48,
209 -47, 47, -46, 46, -45, 45, -44, 44,
210 -43, 43, -42, 42, -41, 41, -40, 40,
211 -39, 39, -38, 38, -37, 37, -36, 36,
212 -35, 35, -34, 34, -33, 33, -32, 32, },
213 { -127, 127, -126, 126, -125, 125, -124, 124,
214 -123, 123, -122, 122, -121, 121, -120, 120,
215 -119, 119, -118, 118, -117, 117, -116, 116,
216 -115, 115, -114, 114, -113, 113, -112, 112,
217 -111, 111, -110, 110, -109, 109, -108, 108,
218 -107, 107, -106, 106, -105, 105, -104, 104,
219 -103, 103, -102, 102, -101, 101, -100, 100,
220 -99, 99, -98, 98, -97, 97, -96, 96, },
221 { -95, 95, -94, 94, -93, 93, -92, 92,
222 -91, 91, -90, 90, -89, 89, -88, 88,
223 -87, 87, -86, 86, -85, 85, -84, 84,
224 -83, 83, -82, 82, -81, 81, -80, 80,
225 -79, 79, -78, 78, -77, 77, -76, 76,
226 -75, 75, -74, 74, -73, 73, -72, 72,
227 -71, 71, -70, 70, -69, 69, -68, 68,
228 -67, 67, -66, 66, -65, 65, -64, 64, },
229};
230
bebfc16a 231static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
a7129de5 232{
88bd7fdc 233 int16_t *block = ctx->dct_block;
a7129de5
RP
234 unsigned int pos;
235
e74433a8 236 ctx->bdsp.clear_block(block);
a7129de5
RP
237
238 block[0] = get_bits(&ctx->gb, 8) << 3;
239
a0cabd0a 240 for (pos = 1; pos < num_coeffs; pos++) {
a7129de5
RP
241 uint32_t vlc, num_bits;
242 int value;
243 int coeff;
244
630e1b27 245 vlc = get_vlc2(&ctx->gb, ctx->vlc.table, ctx->vlc.bits, 3);
a0cabd0a 246 if (!vlc) /* end-of-block code */
a7129de5 247 return 0;
b965cb90
AK
248 if (vlc == -1)
249 return AVERROR_INVALIDDATA;
a7129de5
RP
250
251 /* pos_add and num_bits are coded in the vlc code */
a0cabd0a
AK
252 pos += vlc & 15; // pos_add
253 num_bits = vlc >> 4; // num_bits
a7129de5 254
a0cabd0a 255 if (pos >= 64)
b965cb90 256 return AVERROR_INVALIDDATA;
a7129de5
RP
257
258 value = get_bits(&ctx->gb, num_bits);
259
6001dad6 260 /* Libav's IDCT behaves somewhat different from the original code, so
a7129de5
RP
261 * a factor of 4 was added to the input */
262
263 coeff = vlcdec_lookup[num_bits][value];
a0cabd0a 264 if (pos < 3)
a7129de5
RP
265 coeff <<= 4;
266 else /* TODO Use >> 10 instead of / 1001 */
267 coeff = (coeff * qscale) / 1001;
268
269 block[ctx->scantable.permutated[pos]] = coeff;
270 }
271
b965cb90 272 return 0;
a7129de5
RP
273}
274
275static int decode(MimicContext *ctx, int quality, int num_coeffs,
276 int is_iframe)
277{
b965cb90 278 int ret, y, x, plane, cur_row = 0;
a7129de5 279
a0cabd0a 280 for (plane = 0; plane < 3; plane++) {
a7129de5 281 const int is_chroma = !!plane;
a0cabd0a
AK
282 const int qscale = av_clip(10000 - quality, is_chroma ? 1000 : 2000,
283 10000) << 2;
284 const int stride = ctx->flipped_ptrs[ctx->cur_index ].linesize[plane];
285 const uint8_t *src = ctx->flipped_ptrs[ctx->prev_index].data[plane];
286 uint8_t *dst = ctx->flipped_ptrs[ctx->cur_index ].data[plane];
287
288 for (y = 0; y < ctx->num_vblocks[plane]; y++) {
289 for (x = 0; x < ctx->num_hblocks[plane]; x++) {
a7129de5
RP
290 /* Check for a change condition in the current block.
291 * - iframes always change.
292 * - Luma plane changes on get_bits1 == 0
293 * - Chroma planes change on get_bits1 == 1 */
a0cabd0a 294 if (is_iframe || get_bits1(&ctx->gb) == is_chroma) {
a7129de5
RP
295 /* Luma planes may use a backreference from the 15 last
296 * frames preceding the previous. (get_bits1 == 1)
297 * Chroma planes don't use backreferences. */
a0cabd0a 298 if (is_chroma || is_iframe || !get_bits1(&ctx->gb)) {
b965cb90
AK
299 if ((ret = vlc_decode_block(ctx, num_coeffs,
300 qscale)) < 0) {
301 av_log(ctx->avctx, AV_LOG_ERROR, "Error decoding "
302 "block.\n");
303 return ret;
304 }
e3fcb143 305 ctx->idsp.idct_put(dst, stride, ctx->dct_block);
a7129de5
RP
306 } else {
307 unsigned int backref = get_bits(&ctx->gb, 4);
a0cabd0a
AK
308 int index = (ctx->cur_index + backref) & 15;
309 uint8_t *p = ctx->flipped_ptrs[index].data[0];
a7129de5 310
80387f0e 311 if (index != ctx->cur_index && p) {
759001c5 312 ff_thread_await_progress(&ctx->frames[index],
a0cabd0a 313 cur_row, 0);
a7129de5 314 p += src -
a0cabd0a 315 ctx->flipped_ptrs[ctx->prev_index].data[plane];
c1047003 316 ctx->hdsp.put_pixels_tab[1][0](dst, p, stride, 8);
a7129de5
RP
317 } else {
318 av_log(ctx->avctx, AV_LOG_ERROR,
319 "No such backreference! Buggy sample.\n");
320 }
321 }
322 } else {
759001c5 323 ff_thread_await_progress(&ctx->frames[ctx->prev_index],
a0cabd0a 324 cur_row, 0);
c1047003 325 ctx->hdsp.put_pixels_tab[1][0](dst, src, stride, 8);
a7129de5
RP
326 }
327 src += 8;
328 dst += 8;
329 }
a0cabd0a
AK
330 src += (stride - ctx->num_hblocks[plane]) << 3;
331 dst += (stride - ctx->num_hblocks[plane]) << 3;
a75529e8 332
759001c5 333 ff_thread_report_progress(&ctx->frames[ctx->cur_index],
a0cabd0a 334 cur_row++, 0);
a7129de5
RP
335 }
336 }
337
b965cb90 338 return 0;
a7129de5
RP
339}
340
341/**
342 * Flip the buffer upside-down and put it in the YVU order to match the
343 * way Mimic encodes frames.
344 */
e6da5d21 345static void prepare_avpic(MimicContext *ctx, AVPicture *dst, AVFrame *src)
a7129de5
RP
346{
347 int i;
a0cabd0a
AK
348 dst->data[0] = src->data[0] + ( ctx->avctx->height - 1) * src->linesize[0];
349 dst->data[1] = src->data[2] + ((ctx->avctx->height >> 1) - 1) * src->linesize[2];
350 dst->data[2] = src->data[1] + ((ctx->avctx->height >> 1) - 1) * src->linesize[1];
351 for (i = 0; i < 3; i++)
a7129de5
RP
352 dst->linesize[i] = -src->linesize[i];
353}
354
355static int mimic_decode_frame(AVCodecContext *avctx, void *data,
df9b9567 356 int *got_frame, AVPacket *avpkt)
a7129de5 357{
7a00bbad 358 const uint8_t *buf = avpkt->data;
a0cabd0a
AK
359 int buf_size = avpkt->size;
360 int swap_buf_size = buf_size - MIMIC_HEADER_SIZE;
361 MimicContext *ctx = avctx->priv_data;
dba425ad 362 GetByteContext gb;
a7129de5
RP
363 int is_pframe;
364 int width, height;
365 int quality, num_coeffs;
80387f0e 366 int res;
a7129de5 367
33c5c3ad 368 if (buf_size <= MIMIC_HEADER_SIZE) {
a7129de5 369 av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
b965cb90 370 return AVERROR_INVALIDDATA;
a7129de5
RP
371 }
372
dba425ad
PM
373 bytestream2_init(&gb, buf, MIMIC_HEADER_SIZE);
374 bytestream2_skip(&gb, 2); /* some constant (always 256) */
375 quality = bytestream2_get_le16u(&gb);
376 width = bytestream2_get_le16u(&gb);
377 height = bytestream2_get_le16u(&gb);
378 bytestream2_skip(&gb, 4); /* some constant */
379 is_pframe = bytestream2_get_le32u(&gb);
380 num_coeffs = bytestream2_get_byteu(&gb);
381 bytestream2_skip(&gb, 3); /* some constant */
a7129de5 382
a0cabd0a 383 if (!ctx->avctx) {
a7129de5
RP
384 int i;
385
a0cabd0a
AK
386 if (!(width == 160 && height == 120) &&
387 !(width == 320 && height == 240)) {
a7129de5 388 av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n");
b965cb90 389 return AVERROR_INVALIDDATA;
a7129de5
RP
390 }
391
392 ctx->avctx = avctx;
393 avctx->width = width;
394 avctx->height = height;
716d413c 395 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
a0cabd0a 396 for (i = 0; i < 3; i++) {
a7129de5 397 ctx->num_vblocks[i] = -((-height) >> (3 + !!i));
a0cabd0a 398 ctx->num_hblocks[i] = width >> (3 + !!i);
a7129de5 399 }
a0cabd0a 400 } else if (width != ctx->avctx->width || height != ctx->avctx->height) {
12e25ed2 401 avpriv_request_sample(avctx, "Resolution changing");
b965cb90 402 return AVERROR_PATCHWELCOME;
a7129de5
RP
403 }
404
759001c5 405 if (is_pframe && !ctx->frames[ctx->prev_index].f->data[0]) {
a7129de5 406 av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
b965cb90 407 return AVERROR_INVALIDDATA;
a7129de5
RP
408 }
409
759001c5
AK
410 ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
411 ctx->frames[ctx->cur_index].f->pict_type = is_pframe ? AV_PICTURE_TYPE_P :
412 AV_PICTURE_TYPE_I;
413 if ((res = ff_thread_get_buffer(avctx, &ctx->frames[ctx->cur_index],
414 AV_GET_BUFFER_FLAG_REF)) < 0) {
a7129de5 415 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
b965cb90 416 return res;
a7129de5
RP
417 }
418
a75529e8
AS
419 ctx->next_prev_index = ctx->cur_index;
420 ctx->next_cur_index = (ctx->cur_index - 1) & 15;
421
a7129de5 422 prepare_avpic(ctx, &ctx->flipped_ptrs[ctx->cur_index],
759001c5 423 ctx->frames[ctx->cur_index].f);
a7129de5 424
a75529e8
AS
425 ff_thread_finish_setup(avctx);
426
c15fea79 427 av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);
a0cabd0a 428 if (!ctx->swap_buf)
55775b09 429 return AVERROR(ENOMEM);
a7129de5 430
c67b449b
DB
431 ctx->bbdsp.bswap_buf(ctx->swap_buf,
432 (const uint32_t *) (buf + MIMIC_HEADER_SIZE),
433 swap_buf_size >> 2);
a7129de5
RP
434 init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
435
80387f0e 436 res = decode(ctx, quality, num_coeffs, !is_pframe);
759001c5 437 ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0);
b965cb90 438 if (res < 0) {
80387f0e 439 if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
759001c5 440 ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
b965cb90 441 return res;
a75529e8 442 }
a7129de5
RP
443 }
444
759001c5
AK
445 if ((res = av_frame_ref(data, ctx->frames[ctx->cur_index].f)) < 0)
446 return res;
df9b9567 447 *got_frame = 1;
a7129de5 448
a75529e8
AS
449 ctx->prev_index = ctx->next_prev_index;
450 ctx->cur_index = ctx->next_cur_index;
a7129de5
RP
451
452 /* Only release frames that aren't used for backreferences anymore */
759001c5 453 ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
a7129de5
RP
454
455 return buf_size;
456}
457
759001c5 458static av_cold int mimic_init_thread_copy(AVCodecContext *avctx)
a7129de5
RP
459{
460 MimicContext *ctx = avctx->priv_data;
461 int i;
462
759001c5
AK
463 for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
464 ctx->frames[i].f = av_frame_alloc();
465 if (!ctx->frames[i].f) {
466 mimic_decode_end(avctx);
467 return AVERROR(ENOMEM);
468 }
469 }
a7129de5
RP
470
471 return 0;
472}
473
d36beb3f 474AVCodec ff_mimic_decoder = {
00c3b67b 475 .name = "mimic",
b2bed932 476 .long_name = NULL_IF_CONFIG_SMALL("Mimic"),
00c3b67b 477 .type = AVMEDIA_TYPE_VIDEO,
36ef5369 478 .id = AV_CODEC_ID_MIMIC,
00c3b67b
MS
479 .priv_data_size = sizeof(MimicContext),
480 .init = mimic_decode_init,
481 .close = mimic_decode_end,
482 .decode = mimic_decode_frame,
def97856 483 .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
759001c5
AK
484 .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context),
485 .init_thread_copy = ONLY_IF_THREADS_ENABLED(mimic_init_thread_copy),
a7129de5 486};