FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/mimic.c
Date: 2022-07-06 18:02:43
Exec Total Coverage
Lines: 130 164 79.3%
Branches: 61 94 64.9%

Line Branch Exec Source
1 /*
2 * Copyright (C) 2005 Ole André Vadla Ravnås <oleavr@gmail.com>
3 * Copyright (C) 2008 Ramiro Polla
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
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 *
12 * FFmpeg is distributed in the hope that it will be useful,
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
18 * License along with FFmpeg; if not, write to the Free Software
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 "libavutil/mem_internal.h"
27 #include "libavutil/thread.h"
28
29 #include "avcodec.h"
30 #include "blockdsp.h"
31 #include "codec_internal.h"
32 #include "internal.h"
33 #include "get_bits.h"
34 #include "bytestream.h"
35 #include "bswapdsp.h"
36 #include "hpeldsp.h"
37 #include "idctdsp.h"
38 #include "thread.h"
39 #include "threadframe.h"
40
41 #define MIMIC_HEADER_SIZE 20
42 #define MIMIC_VLC_BITS 11
43
44 typedef struct MimicContext {
45 AVCodecContext *avctx;
46
47 int num_vblocks[3];
48 int num_hblocks[3];
49
50 void *swap_buf;
51 int swap_buf_size;
52
53 int cur_index;
54 int prev_index;
55
56 ThreadFrame frames [16];
57
58 DECLARE_ALIGNED(32, int16_t, dct_block)[64];
59
60 GetBitContext gb;
61 ScanTable scantable;
62 BlockDSPContext bdsp;
63 BswapDSPContext bbdsp;
64 HpelDSPContext hdsp;
65 IDCTDSPContext idsp;
66
67 /* Kept in the context so multithreading can have a constant to read from */
68 int next_cur_index;
69 int next_prev_index;
70 } MimicContext;
71
72 static VLC block_vlc;
73
74 static const uint8_t huffsyms[] = {
75 0x10, 0x20, 0x30, 0x00, 0x11, 0x40, 0x50, 0x12, 0x13, 0x21, 0x31, 0x60,
76 0x14, 0x15, 0x16, 0x22, 0x41, 0x17, 0x18, 0x23, 0x24, 0x25, 0x32, 0x42,
77 0x51, 0x61, 0x70, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x26, 0x27,
78 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x33, 0x34, 0x35, 0x36, 0x37,
79 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x43, 0x44, 0x45, 0x46, 0x47,
80 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x52, 0x53, 0x54, 0x55, 0x56,
81 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x62, 0x63, 0x64, 0x65,
82 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x71, 0x72, 0x73,
83 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E,
84 };
85
86 static const uint8_t huffbits[] = {
87 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8,
88 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12,
89 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17,
90 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21,
91 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26,
92 26, 26, 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30,
93 };
94
95 static const uint8_t col_zag[64] = {
96 0, 8, 1, 2, 9, 16, 24, 17,
97 10, 3, 4, 11, 18, 25, 32, 40,
98 33, 26, 19, 12, 5, 6, 13, 20,
99 27, 34, 41, 48, 56, 49, 42, 35,
100 28, 21, 14, 7, 15, 22, 29, 36,
101 43, 50, 57, 58, 51, 44, 37, 30,
102 23, 31, 38, 45, 52, 59, 39, 46,
103 53, 60, 61, 54, 47, 55, 62, 63,
104 };
105
106 2 static av_cold int mimic_decode_end(AVCodecContext *avctx)
107 {
108 2 MimicContext *ctx = avctx->priv_data;
109 int i;
110
111 2 av_freep(&ctx->swap_buf);
112 2 ctx->swap_buf_size = 0;
113
114
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 2 times.
34 for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
115
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 if (ctx->frames[i].f)
116 32 ff_thread_release_ext_buffer(avctx, &ctx->frames[i]);
117 32 av_frame_free(&ctx->frames[i].f);
118 }
119
120 2 return 0;
121 }
122
123 1 static av_cold void mimic_init_static(void)
124 {
125 1 INIT_VLC_STATIC_FROM_LENGTHS(&block_vlc, MIMIC_VLC_BITS, FF_ARRAY_ELEMS(huffbits),
126 huffbits, 1, huffsyms, 1, 1, 0, 0, 4368);
127 1 }
128
129 2 static av_cold int mimic_decode_init(AVCodecContext *avctx)
130 {
131 static AVOnce init_static_once = AV_ONCE_INIT;
132 2 MimicContext *ctx = avctx->priv_data;
133 int i;
134
135 2 ctx->prev_index = 0;
136 2 ctx->cur_index = 15;
137
138 2 ff_blockdsp_init(&ctx->bdsp, avctx);
139 2 ff_bswapdsp_init(&ctx->bbdsp);
140 2 ff_hpeldsp_init(&ctx->hdsp, avctx->flags);
141 2 ff_idctdsp_init(&ctx->idsp, avctx);
142 2 ff_init_scantable(ctx->idsp.idct_permutation, &ctx->scantable, col_zag);
143
144
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 2 times.
34 for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
145 32 ctx->frames[i].f = av_frame_alloc();
146
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 if (!ctx->frames[i].f)
147 return AVERROR(ENOMEM);
148 }
149
150 2 ff_thread_once(&init_static_once, mimic_init_static);
151
152 2 return 0;
153 }
154
155 #if HAVE_THREADS
156 static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from)
157 {
158 MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data;
159 int i, ret;
160
161 if (avctx == avctx_from)
162 return 0;
163
164 dst->cur_index = src->next_cur_index;
165 dst->prev_index = src->next_prev_index;
166
167 for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) {
168 ff_thread_release_ext_buffer(avctx, &dst->frames[i]);
169 if (i != src->next_cur_index && src->frames[i].f->data[0]) {
170 ret = ff_thread_ref_frame(&dst->frames[i], &src->frames[i]);
171 if (ret < 0)
172 return ret;
173 }
174 }
175
176 return 0;
177 }
178 #endif
179
180 static const int8_t vlcdec_lookup[9][64] = {
181 { 0, },
182 { -1, 1, },
183 { -3, 3, -2, 2, },
184 { -7, 7, -6, 6, -5, 5, -4, 4, },
185 { -15, 15, -14, 14, -13, 13, -12, 12,
186 -11, 11, -10, 10, -9, 9, -8, 8, },
187 { -31, 31, -30, 30, -29, 29, -28, 28,
188 -27, 27, -26, 26, -25, 25, -24, 24,
189 -23, 23, -22, 22, -21, 21, -20, 20,
190 -19, 19, -18, 18, -17, 17, -16, 16, },
191 { -63, 63, -62, 62, -61, 61, -60, 60,
192 -59, 59, -58, 58, -57, 57, -56, 56,
193 -55, 55, -54, 54, -53, 53, -52, 52,
194 -51, 51, -50, 50, -49, 49, -48, 48,
195 -47, 47, -46, 46, -45, 45, -44, 44,
196 -43, 43, -42, 42, -41, 41, -40, 40,
197 -39, 39, -38, 38, -37, 37, -36, 36,
198 -35, 35, -34, 34, -33, 33, -32, 32, },
199 { -127, 127, -126, 126, -125, 125, -124, 124,
200 -123, 123, -122, 122, -121, 121, -120, 120,
201 -119, 119, -118, 118, -117, 117, -116, 116,
202 -115, 115, -114, 114, -113, 113, -112, 112,
203 -111, 111, -110, 110, -109, 109, -108, 108,
204 -107, 107, -106, 106, -105, 105, -104, 104,
205 -103, 103, -102, 102, -101, 101, -100, 100,
206 -99, 99, -98, 98, -97, 97, -96, 96, },
207 { -95, 95, -94, 94, -93, 93, -92, 92,
208 -91, 91, -90, 90, -89, 89, -88, 88,
209 -87, 87, -86, 86, -85, 85, -84, 84,
210 -83, 83, -82, 82, -81, 81, -80, 80,
211 -79, 79, -78, 78, -77, 77, -76, 76,
212 -75, 75, -74, 74, -73, 73, -72, 72,
213 -71, 71, -70, 70, -69, 69, -68, 68,
214 -67, 67, -66, 66, -65, 65, -64, 64, },
215 };
216
217 44548 static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
218 {
219 44548 int16_t *block = ctx->dct_block;
220 unsigned int pos;
221
222 44548 ctx->bdsp.clear_block(block);
223
224 44548 block[0] = get_bits(&ctx->gb, 8) << 3;
225
226
2/2
✓ Branch 0 taken 302169 times.
✓ Branch 1 taken 2724 times.
304893 for (pos = 1; pos < num_coeffs; pos++) {
227 uint32_t vlc, num_bits;
228 int value;
229 int coeff;
230
231 302169 vlc = get_vlc2(&ctx->gb, block_vlc.table, MIMIC_VLC_BITS, 3);
232
2/2
✓ Branch 0 taken 41824 times.
✓ Branch 1 taken 260345 times.
302169 if (!vlc) /* end-of-block code */
233 41824 return 0;
234
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 260345 times.
260345 if (vlc == -1)
235 return AVERROR_INVALIDDATA;
236
237 /* pos_add and num_bits are coded in the vlc code */
238 260345 pos += vlc & 15; // pos_add
239 260345 num_bits = vlc >> 4; // num_bits
240
241
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 260345 times.
260345 if (pos >= 64)
242 return AVERROR_INVALIDDATA;
243
244 260345 value = get_bits(&ctx->gb, num_bits);
245
246 /* FFmpeg's IDCT behaves somewhat different from the original code, so
247 * a factor of 4 was added to the input */
248
249 260345 coeff = ((int8_t*)vlcdec_lookup[num_bits])[value];
250
2/2
✓ Branch 0 taken 50048 times.
✓ Branch 1 taken 210297 times.
260345 if (pos < 3)
251 50048 coeff *= 16;
252 else /* TODO Use >> 10 instead of / 1001 */
253 210297 coeff = (coeff * qscale) / 1001;
254
255 260345 block[ctx->scantable.permutated[pos]] = coeff;
256 }
257
258 2724 return 0;
259 }
260
261 77 static int decode(MimicContext *ctx, int quality, int num_coeffs,
262 int is_iframe)
263 {
264 77 int ret, y, x, plane, cur_row = 0;
265
266
2/2
✓ Branch 0 taken 231 times.
✓ Branch 1 taken 77 times.
308 for (plane = 0; plane < 3; plane++) {
267 231 const int is_chroma = !!plane;
268
2/2
✓ Branch 0 taken 154 times.
✓ Branch 1 taken 77 times.
231 const int qscale = av_clip(10000 - quality, is_chroma ? 1000 : 2000,
269 10000) << 2;
270 231 const int stride = ctx->frames[ctx->cur_index ].f->linesize[plane];
271 231 const uint8_t *src = ctx->frames[ctx->prev_index].f->data[plane];
272 231 uint8_t *dst = ctx->frames[ctx->cur_index ].f->data[plane];
273
274
2/2
✓ Branch 0 taken 4620 times.
✓ Branch 1 taken 231 times.
4851 for (y = 0; y < ctx->num_vblocks[plane]; y++) {
275
2/2
✓ Branch 0 taken 138600 times.
✓ Branch 1 taken 4620 times.
143220 for (x = 0; x < ctx->num_hblocks[plane]; x++) {
276 /* Check for a change condition in the current block.
277 * - iframes always change.
278 * - Luma plane changes on get_bits1 == 0
279 * - Chroma planes change on get_bits1 == 1 */
280
4/4
✓ Branch 0 taken 133200 times.
✓ Branch 1 taken 5400 times.
✓ Branch 3 taken 45091 times.
✓ Branch 4 taken 88109 times.
138600 if (is_iframe || get_bits1(&ctx->gb) == is_chroma) {
281 /* Luma planes may use a backreference from the 15 last
282 * frames preceding the previous. (get_bits1 == 1)
283 * Chroma planes don't use backreferences. */
284
6/6
✓ Branch 0 taken 37390 times.
✓ Branch 1 taken 13101 times.
✓ Branch 2 taken 33790 times.
✓ Branch 3 taken 3600 times.
✓ Branch 5 taken 27847 times.
✓ Branch 6 taken 5943 times.
50491 if (is_chroma || is_iframe || !get_bits1(&ctx->gb)) {
285
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 44548 times.
44548 if ((ret = vlc_decode_block(ctx, num_coeffs,
286 qscale)) < 0) {
287 av_log(ctx->avctx, AV_LOG_ERROR, "Error decoding "
288 "block.\n");
289 return ret;
290 }
291 44548 ctx->idsp.idct_put(dst, stride, ctx->dct_block);
292 } else {
293 5943 unsigned int backref = get_bits(&ctx->gb, 4);
294 5943 int index = (ctx->cur_index + backref) & 15;
295 5943 uint8_t *p = ctx->frames[index].f->data[0];
296
297
2/4
✓ Branch 0 taken 5943 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5943 times.
✗ Branch 3 not taken.
5943 if (index != ctx->cur_index && p) {
298 5943 ff_thread_await_progress(&ctx->frames[index],
299 cur_row, 0);
300 5943 p += src -
301 5943 ctx->frames[ctx->prev_index].f->data[plane];
302 5943 ctx->hdsp.put_pixels_tab[1][0](dst, p, stride, 8);
303 } else {
304 av_log(ctx->avctx, AV_LOG_ERROR,
305 "No such backreference! Buggy sample.\n");
306 }
307 }
308 } else {
309 88109 ff_thread_await_progress(&ctx->frames[ctx->prev_index],
310 cur_row, 0);
311 88109 ctx->hdsp.put_pixels_tab[1][0](dst, src, stride, 8);
312 }
313 138600 src += 8;
314 138600 dst += 8;
315 }
316 4620 src += (stride - ctx->num_hblocks[plane]) << 3;
317 4620 dst += (stride - ctx->num_hblocks[plane]) << 3;
318
319 4620 ff_thread_report_progress(&ctx->frames[ctx->cur_index],
320 cur_row++, 0);
321 }
322 }
323
324 77 return 0;
325 }
326
327 /**
328 * Flip the buffer upside-down and put it in the YVU order to revert the
329 * way Mimic encodes frames.
330 */
331 77 static void flip_swap_frame(AVFrame *f)
332 {
333 int i;
334 77 uint8_t *data_1 = f->data[1];
335 77 f->data[0] = f->data[0] + ( f->height - 1) * f->linesize[0];
336 77 f->data[1] = f->data[2] + ((f->height >> 1) - 1) * f->linesize[2];
337 77 f->data[2] = data_1 + ((f->height >> 1) - 1) * f->linesize[1];
338
2/2
✓ Branch 0 taken 231 times.
✓ Branch 1 taken 77 times.
308 for (i = 0; i < 3; i++)
339 231 f->linesize[i] *= -1;
340 77 }
341
342 77 static int mimic_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
343 int *got_frame, AVPacket *avpkt)
344 {
345 77 const uint8_t *buf = avpkt->data;
346 77 int buf_size = avpkt->size;
347 77 int swap_buf_size = buf_size - MIMIC_HEADER_SIZE;
348 77 MimicContext *ctx = avctx->priv_data;
349 GetByteContext gb;
350 int is_pframe;
351 int width, height;
352 int quality, num_coeffs;
353 int res;
354
355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 77 times.
77 if (buf_size <= MIMIC_HEADER_SIZE) {
356 av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
357 return AVERROR_INVALIDDATA;
358 }
359
360 77 bytestream2_init(&gb, buf, MIMIC_HEADER_SIZE);
361 77 bytestream2_skip(&gb, 2); /* some constant (always 256) */
362 77 quality = bytestream2_get_le16u(&gb);
363 77 width = bytestream2_get_le16u(&gb);
364 77 height = bytestream2_get_le16u(&gb);
365 77 bytestream2_skip(&gb, 4); /* some constant */
366 77 is_pframe = bytestream2_get_le32u(&gb);
367 77 num_coeffs = bytestream2_get_byteu(&gb);
368 77 bytestream2_skip(&gb, 3); /* some constant */
369
370
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 75 times.
77 if (!ctx->avctx) {
371 int i;
372
373
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if (!(width == 160 && height == 120) &&
374
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 !(width == 320 && height == 240)) {
375 av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n");
376 return AVERROR_INVALIDDATA;
377 }
378
379 2 res = ff_set_dimensions(avctx, width, height);
380
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (res < 0)
381 return res;
382
383 2 ctx->avctx = avctx;
384 2 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
385
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 for (i = 0; i < 3; i++) {
386
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 ctx->num_vblocks[i] = AV_CEIL_RSHIFT(height, 3 + !!i);
387
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 ctx->num_hblocks[i] = width >> (3 + !!i);
388 }
389
2/4
✓ Branch 0 taken 75 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 75 times.
75 } else if (width != ctx->avctx->width || height != ctx->avctx->height) {
390 avpriv_request_sample(avctx, "Resolution changing");
391 return AVERROR_PATCHWELCOME;
392 }
393
394
3/4
✓ Branch 0 taken 74 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 74 times.
77 if (is_pframe && !ctx->frames[ctx->prev_index].f->data[0]) {
395 av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
396 return AVERROR_INVALIDDATA;
397 }
398
399 77 ff_thread_release_ext_buffer(avctx, &ctx->frames[ctx->cur_index]);
400
2/2
✓ Branch 0 taken 74 times.
✓ Branch 1 taken 3 times.
77 ctx->frames[ctx->cur_index].f->pict_type = is_pframe ? AV_PICTURE_TYPE_P :
401 AV_PICTURE_TYPE_I;
402
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 77 times.
77 if ((res = ff_thread_get_ext_buffer(avctx, &ctx->frames[ctx->cur_index],
403 AV_GET_BUFFER_FLAG_REF)) < 0)
404 return res;
405
406 77 ctx->next_prev_index = ctx->cur_index;
407 77 ctx->next_cur_index = (ctx->cur_index - 1) & 15;
408
409 77 ff_thread_finish_setup(avctx);
410
411 77 av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);
412
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 77 times.
77 if (!ctx->swap_buf)
413 return AVERROR(ENOMEM);
414
415 77 ctx->bbdsp.bswap_buf(ctx->swap_buf,
416 77 (const uint32_t *) (buf + MIMIC_HEADER_SIZE),
417 swap_buf_size >> 2);
418 77 init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
419
420 77 res = decode(ctx, quality, num_coeffs, !is_pframe);
421 77 ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0);
422
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 77 times.
77 if (res < 0) {
423 if (!(avctx->active_thread_type & FF_THREAD_FRAME))
424 ff_thread_release_ext_buffer(avctx, &ctx->frames[ctx->cur_index]);
425 return res;
426 }
427
428
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 77 times.
77 if ((res = av_frame_ref(rframe, ctx->frames[ctx->cur_index].f)) < 0)
429 return res;
430 77 *got_frame = 1;
431
432 77 flip_swap_frame(rframe);
433
434 77 ctx->prev_index = ctx->next_prev_index;
435 77 ctx->cur_index = ctx->next_cur_index;
436
437 77 return buf_size;
438 }
439
440 const FFCodec ff_mimic_decoder = {
441 .p.name = "mimic",
442 .p.long_name = NULL_IF_CONFIG_SMALL("Mimic"),
443 .p.type = AVMEDIA_TYPE_VIDEO,
444 .p.id = AV_CODEC_ID_MIMIC,
445 .priv_data_size = sizeof(MimicContext),
446 .init = mimic_decode_init,
447 .close = mimic_decode_end,
448 FF_CODEC_DECODE_CB(mimic_decode_frame),
449 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
450 .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context),
451 .caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS |
452 FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
453 };
454