xref: /third_party/ffmpeg/libavcodec/xan.c (revision cabdff1a)
1/*
2 * Wing Commander/Xan Video Decoder
3 * Copyright (C) 2003 The FFmpeg project
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/**
23 * @file
24 * Xan video decoder for Wing Commander III computer game
25 * by Mario Brito (mbrito@student.dei.uc.pt)
26 * and Mike Melanson (melanson@pcisys.net)
27 *
28 * The xan_wc3 decoder outputs PAL8 data.
29 */
30
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34
35#include "libavutil/intreadwrite.h"
36#include "libavutil/mem.h"
37
38#define BITSTREAM_READER_LE
39#include "avcodec.h"
40#include "bytestream.h"
41#include "codec_internal.h"
42#include "get_bits.h"
43#include "internal.h"
44
45#define RUNTIME_GAMMA 0
46
47#define VGA__TAG MKTAG('V', 'G', 'A', ' ')
48#define PALT_TAG MKTAG('P', 'A', 'L', 'T')
49#define SHOT_TAG MKTAG('S', 'H', 'O', 'T')
50#define PALETTE_COUNT 256
51#define PALETTE_SIZE (PALETTE_COUNT * 3)
52#define PALETTES_MAX 256
53
54typedef struct XanContext {
55
56    AVCodecContext *avctx;
57    AVFrame *last_frame;
58
59    const uint8_t *buf;
60    int size;
61
62    /* scratch space */
63    uint8_t *buffer1;
64    int buffer1_size;
65    uint8_t *buffer2;
66    int buffer2_size;
67
68    unsigned *palettes;
69    int palettes_count;
70    int cur_palette;
71
72    int frame_size;
73
74} XanContext;
75
76static av_cold int xan_decode_end(AVCodecContext *avctx)
77{
78    XanContext *s = avctx->priv_data;
79
80    av_frame_free(&s->last_frame);
81
82    av_freep(&s->buffer1);
83    av_freep(&s->buffer2);
84    av_freep(&s->palettes);
85
86    return 0;
87}
88
89static av_cold int xan_decode_init(AVCodecContext *avctx)
90{
91    XanContext *s = avctx->priv_data;
92
93    s->avctx = avctx;
94    s->frame_size = 0;
95
96    avctx->pix_fmt = AV_PIX_FMT_PAL8;
97
98    s->buffer1_size = avctx->width * avctx->height;
99    s->buffer1 = av_malloc(s->buffer1_size);
100    if (!s->buffer1)
101        return AVERROR(ENOMEM);
102    s->buffer2_size = avctx->width * avctx->height;
103    s->buffer2 = av_malloc(s->buffer2_size + 130);
104    if (!s->buffer2)
105        return AVERROR(ENOMEM);
106
107    s->last_frame = av_frame_alloc();
108    if (!s->last_frame)
109        return AVERROR(ENOMEM);
110
111    return 0;
112}
113
114static int xan_huffman_decode(uint8_t *dest, int dest_len,
115                              const uint8_t *src, int src_len)
116{
117    uint8_t byte = *src++;
118    uint8_t ival = byte + 0x16;
119    const uint8_t * ptr = src + byte*2;
120    int ptr_len = src_len - 1 - byte*2;
121    uint8_t val = ival;
122    uint8_t *dest_end = dest + dest_len;
123    uint8_t *dest_start = dest;
124    int ret;
125    GetBitContext gb;
126
127    if ((ret = init_get_bits8(&gb, ptr, ptr_len)) < 0)
128        return ret;
129
130    while (val != 0x16) {
131        unsigned idx;
132        if (get_bits_left(&gb) < 1)
133            return AVERROR_INVALIDDATA;
134        idx = val - 0x17 + get_bits1(&gb) * byte;
135        if (idx >= 2 * byte)
136            return AVERROR_INVALIDDATA;
137        val = src[idx];
138
139        if (val < 0x16) {
140            if (dest >= dest_end)
141                return dest_len;
142            *dest++ = val;
143            val = ival;
144        }
145    }
146
147    return dest - dest_start;
148}
149
150/**
151 * unpack simple compression
152 *
153 * @param dest destination buffer of dest_len, must be padded with at least 130 bytes
154 */
155static void xan_unpack(uint8_t *dest, int dest_len,
156                       const uint8_t *src, int src_len)
157{
158    uint8_t opcode;
159    int size;
160    uint8_t *dest_org = dest;
161    uint8_t *dest_end = dest + dest_len;
162    GetByteContext ctx;
163
164    bytestream2_init(&ctx, src, src_len);
165    while (dest < dest_end && bytestream2_get_bytes_left(&ctx)) {
166        opcode = bytestream2_get_byte(&ctx);
167
168        if (opcode < 0xe0) {
169            int size2, back;
170            if ((opcode & 0x80) == 0) {
171                size = opcode & 3;
172
173                back  = ((opcode & 0x60) << 3) + bytestream2_get_byte(&ctx) + 1;
174                size2 = ((opcode & 0x1c) >> 2) + 3;
175            } else if ((opcode & 0x40) == 0) {
176                size = bytestream2_peek_byte(&ctx) >> 6;
177
178                back  = (bytestream2_get_be16(&ctx) & 0x3fff) + 1;
179                size2 = (opcode & 0x3f) + 4;
180            } else {
181                size = opcode & 3;
182
183                back  = ((opcode & 0x10) << 12) + bytestream2_get_be16(&ctx) + 1;
184                size2 = ((opcode & 0x0c) <<  6) + bytestream2_get_byte(&ctx) + 5;
185            }
186
187            if (dest_end - dest < size + size2 ||
188                dest + size - dest_org < back ||
189                bytestream2_get_bytes_left(&ctx) < size)
190                return;
191            bytestream2_get_buffer(&ctx, dest, size);
192            dest += size;
193            av_memcpy_backptr(dest, back, size2);
194            dest += size2;
195        } else {
196            int finish = opcode >= 0xfc;
197            size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
198
199            if (dest_end - dest < size || bytestream2_get_bytes_left(&ctx) < size)
200                return;
201            bytestream2_get_buffer(&ctx, dest, size);
202            dest += size;
203            if (finish)
204                return;
205        }
206    }
207}
208
209static inline void xan_wc3_output_pixel_run(XanContext *s, AVFrame *frame,
210    const uint8_t *pixel_buffer, int x, int y, int pixel_count)
211{
212    int stride;
213    int line_inc;
214    int index;
215    int current_x;
216    int width = s->avctx->width;
217    uint8_t *palette_plane;
218
219    palette_plane = frame->data[0];
220    stride = frame->linesize[0];
221    line_inc = stride - width;
222    index = y * stride + x;
223    current_x = x;
224    while (pixel_count && index < s->frame_size) {
225        int count = FFMIN(pixel_count, width - current_x);
226        memcpy(palette_plane + index, pixel_buffer, count);
227        pixel_count  -= count;
228        index        += count;
229        pixel_buffer += count;
230        current_x    += count;
231
232        if (current_x >= width) {
233            index += line_inc;
234            current_x = 0;
235        }
236    }
237}
238
239static inline void xan_wc3_copy_pixel_run(XanContext *s, AVFrame *frame,
240                                          int x, int y,
241                                          int pixel_count, int motion_x,
242                                          int motion_y)
243{
244    int stride;
245    int line_inc;
246    int curframe_index, prevframe_index;
247    int curframe_x, prevframe_x;
248    int width = s->avctx->width;
249    uint8_t *palette_plane, *prev_palette_plane;
250
251    if (y + motion_y < 0 || y + motion_y >= s->avctx->height ||
252        x + motion_x < 0 || x + motion_x >= s->avctx->width)
253        return;
254
255    palette_plane = frame->data[0];
256    prev_palette_plane = s->last_frame->data[0];
257    if (!prev_palette_plane)
258        prev_palette_plane = palette_plane;
259    stride = frame->linesize[0];
260    line_inc = stride - width;
261    curframe_index = y * stride + x;
262    curframe_x = x;
263    prevframe_index = (y + motion_y) * stride + x + motion_x;
264    prevframe_x = x + motion_x;
265
266    if (prev_palette_plane == palette_plane && FFABS(motion_x + width*motion_y) < pixel_count) {
267         avpriv_request_sample(s->avctx, "Overlapping copy");
268         return ;
269    }
270
271    while (pixel_count &&
272           curframe_index  < s->frame_size &&
273           prevframe_index < s->frame_size) {
274        int count = FFMIN3(pixel_count, width - curframe_x,
275                           width - prevframe_x);
276
277        memcpy(palette_plane + curframe_index,
278               prev_palette_plane + prevframe_index, count);
279        pixel_count     -= count;
280        curframe_index  += count;
281        prevframe_index += count;
282        curframe_x      += count;
283        prevframe_x     += count;
284
285        if (curframe_x >= width) {
286            curframe_index += line_inc;
287            curframe_x = 0;
288        }
289
290        if (prevframe_x >= width) {
291            prevframe_index += line_inc;
292            prevframe_x = 0;
293        }
294    }
295}
296
297static int xan_wc3_decode_frame(XanContext *s, AVFrame *frame)
298{
299
300    int width  = s->avctx->width;
301    int height = s->avctx->height;
302    int total_pixels = width * height;
303    uint8_t opcode;
304    uint8_t flag = 0;
305    int size = 0;
306    int motion_x, motion_y;
307    int x, y, ret;
308
309    uint8_t *opcode_buffer = s->buffer1;
310    uint8_t *opcode_buffer_end = s->buffer1 + s->buffer1_size;
311    int opcode_buffer_size = s->buffer1_size;
312    const uint8_t *imagedata_buffer = s->buffer2;
313
314    /* pointers to segments inside the compressed chunk */
315    const uint8_t *huffman_segment;
316    GetByteContext       size_segment;
317    GetByteContext       vector_segment;
318    const uint8_t *imagedata_segment;
319    int huffman_offset, size_offset, vector_offset, imagedata_offset,
320        imagedata_size;
321
322    if (s->size < 8)
323        return AVERROR_INVALIDDATA;
324
325    huffman_offset    = AV_RL16(&s->buf[0]);
326    size_offset       = AV_RL16(&s->buf[2]);
327    vector_offset     = AV_RL16(&s->buf[4]);
328    imagedata_offset  = AV_RL16(&s->buf[6]);
329
330    if (huffman_offset   >= s->size ||
331        size_offset      >= s->size ||
332        vector_offset    >= s->size ||
333        imagedata_offset >= s->size)
334        return AVERROR_INVALIDDATA;
335
336    huffman_segment   = s->buf + huffman_offset;
337    bytestream2_init(&size_segment,   s->buf + size_offset,   s->size - size_offset);
338    bytestream2_init(&vector_segment, s->buf + vector_offset, s->size - vector_offset);
339    imagedata_segment = s->buf + imagedata_offset;
340
341    if ((ret = xan_huffman_decode(opcode_buffer, opcode_buffer_size,
342                                  huffman_segment, s->size - huffman_offset)) < 0)
343        return AVERROR_INVALIDDATA;
344    opcode_buffer_end = opcode_buffer + ret;
345
346    if (imagedata_segment[0] == 2) {
347        xan_unpack(s->buffer2, s->buffer2_size,
348                   &imagedata_segment[1], s->size - imagedata_offset - 1);
349        imagedata_size = s->buffer2_size;
350    } else {
351        imagedata_size = s->size - imagedata_offset - 1;
352        imagedata_buffer = &imagedata_segment[1];
353    }
354
355    /* use the decoded data segments to build the frame */
356    x = y = 0;
357    while (total_pixels && opcode_buffer < opcode_buffer_end) {
358
359        opcode = *opcode_buffer++;
360        size = 0;
361
362        switch (opcode) {
363
364        case 0:
365            flag ^= 1;
366            continue;
367
368        case 1:
369        case 2:
370        case 3:
371        case 4:
372        case 5:
373        case 6:
374        case 7:
375        case 8:
376            size = opcode;
377            break;
378
379        case 12:
380        case 13:
381        case 14:
382        case 15:
383        case 16:
384        case 17:
385        case 18:
386            size += (opcode - 10);
387            break;
388
389        case 9:
390        case 19:
391            if (bytestream2_get_bytes_left(&size_segment) < 1) {
392                av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
393                return AVERROR_INVALIDDATA;
394            }
395            size = bytestream2_get_byte(&size_segment);
396            break;
397
398        case 10:
399        case 20:
400            if (bytestream2_get_bytes_left(&size_segment) < 2) {
401                av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
402                return AVERROR_INVALIDDATA;
403            }
404            size = bytestream2_get_be16(&size_segment);
405            break;
406
407        case 11:
408        case 21:
409            if (bytestream2_get_bytes_left(&size_segment) < 3) {
410                av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
411                return AVERROR_INVALIDDATA;
412            }
413            size = bytestream2_get_be24(&size_segment);
414            break;
415        }
416
417        if (size > total_pixels)
418            break;
419
420        if (opcode < 12) {
421            flag ^= 1;
422            if (flag) {
423                /* run of (size) pixels is unchanged from last frame */
424                xan_wc3_copy_pixel_run(s, frame, x, y, size, 0, 0);
425            } else {
426                /* output a run of pixels from imagedata_buffer */
427                if (imagedata_size < size)
428                    break;
429                xan_wc3_output_pixel_run(s, frame, imagedata_buffer, x, y, size);
430                imagedata_buffer += size;
431                imagedata_size -= size;
432            }
433        } else {
434            uint8_t vector;
435            if (bytestream2_get_bytes_left(&vector_segment) <= 0) {
436                av_log(s->avctx, AV_LOG_ERROR, "vector_segment overread\n");
437                return AVERROR_INVALIDDATA;
438            }
439            /* run-based motion compensation from last frame */
440            vector = bytestream2_get_byte(&vector_segment);
441            motion_x = sign_extend(vector >> 4,  4);
442            motion_y = sign_extend(vector & 0xF, 4);
443
444            /* copy a run of pixels from the previous frame */
445            xan_wc3_copy_pixel_run(s, frame, x, y, size, motion_x, motion_y);
446
447            flag = 0;
448        }
449
450        /* coordinate accounting */
451        total_pixels -= size;
452        y += (x + size) / width;
453        x  = (x + size) % width;
454    }
455    return 0;
456}
457
458#if RUNTIME_GAMMA
459static inline unsigned mul(unsigned a, unsigned b)
460{
461    return (a * b) >> 16;
462}
463
464static inline unsigned pow4(unsigned a)
465{
466    unsigned square = mul(a, a);
467    return mul(square, square);
468}
469
470static inline unsigned pow5(unsigned a)
471{
472    return mul(pow4(a), a);
473}
474
475static uint8_t gamma_corr(uint8_t in) {
476    unsigned lo, hi = 0xff40, target;
477    int i = 15;
478    in = (in << 2) | (in >> 6);
479    /*  equivalent float code:
480    if (in >= 252)
481        return 253;
482    return round(pow(in / 256.0, 0.8) * 256);
483    */
484    lo = target = in << 8;
485    do {
486        unsigned mid = (lo + hi) >> 1;
487        unsigned pow = pow5(mid);
488        if (pow > target) hi = mid;
489        else lo = mid;
490    } while (--i);
491    return (pow4((lo + hi) >> 1) + 0x80) >> 8;
492}
493#else
494/**
495 * This is a gamma correction that xan3 applies to all palette entries.
496 *
497 * There is a peculiarity, namely that the values are clamped to 253 -
498 * it seems likely that this table was calculated by a buggy fixed-point
499 * implementation, the one above under RUNTIME_GAMMA behaves like this for
500 * example.
501 * The exponent value of 0.8 can be explained by this as well, since 0.8 = 4/5
502 * and thus pow(x, 0.8) is still easy to calculate.
503 * Also, the input values are first rotated to the left by 2.
504 */
505static const uint8_t gamma_lookup[256] = {
506    0x00, 0x09, 0x10, 0x16, 0x1C, 0x21, 0x27, 0x2C,
507    0x31, 0x35, 0x3A, 0x3F, 0x43, 0x48, 0x4C, 0x50,
508    0x54, 0x59, 0x5D, 0x61, 0x65, 0x69, 0x6D, 0x71,
509    0x75, 0x79, 0x7D, 0x80, 0x84, 0x88, 0x8C, 0x8F,
510    0x93, 0x97, 0x9A, 0x9E, 0xA2, 0xA5, 0xA9, 0xAC,
511    0xB0, 0xB3, 0xB7, 0xBA, 0xBE, 0xC1, 0xC5, 0xC8,
512    0xCB, 0xCF, 0xD2, 0xD5, 0xD9, 0xDC, 0xDF, 0xE3,
513    0xE6, 0xE9, 0xED, 0xF0, 0xF3, 0xF6, 0xFA, 0xFD,
514    0x03, 0x0B, 0x12, 0x18, 0x1D, 0x23, 0x28, 0x2D,
515    0x32, 0x36, 0x3B, 0x40, 0x44, 0x49, 0x4D, 0x51,
516    0x56, 0x5A, 0x5E, 0x62, 0x66, 0x6A, 0x6E, 0x72,
517    0x76, 0x7A, 0x7D, 0x81, 0x85, 0x89, 0x8D, 0x90,
518    0x94, 0x98, 0x9B, 0x9F, 0xA2, 0xA6, 0xAA, 0xAD,
519    0xB1, 0xB4, 0xB8, 0xBB, 0xBF, 0xC2, 0xC5, 0xC9,
520    0xCC, 0xD0, 0xD3, 0xD6, 0xDA, 0xDD, 0xE0, 0xE4,
521    0xE7, 0xEA, 0xED, 0xF1, 0xF4, 0xF7, 0xFA, 0xFD,
522    0x05, 0x0D, 0x13, 0x19, 0x1F, 0x24, 0x29, 0x2E,
523    0x33, 0x38, 0x3C, 0x41, 0x45, 0x4A, 0x4E, 0x52,
524    0x57, 0x5B, 0x5F, 0x63, 0x67, 0x6B, 0x6F, 0x73,
525    0x77, 0x7B, 0x7E, 0x82, 0x86, 0x8A, 0x8D, 0x91,
526    0x95, 0x99, 0x9C, 0xA0, 0xA3, 0xA7, 0xAA, 0xAE,
527    0xB2, 0xB5, 0xB9, 0xBC, 0xBF, 0xC3, 0xC6, 0xCA,
528    0xCD, 0xD0, 0xD4, 0xD7, 0xDA, 0xDE, 0xE1, 0xE4,
529    0xE8, 0xEB, 0xEE, 0xF1, 0xF5, 0xF8, 0xFB, 0xFD,
530    0x07, 0x0E, 0x15, 0x1A, 0x20, 0x25, 0x2A, 0x2F,
531    0x34, 0x39, 0x3D, 0x42, 0x46, 0x4B, 0x4F, 0x53,
532    0x58, 0x5C, 0x60, 0x64, 0x68, 0x6C, 0x70, 0x74,
533    0x78, 0x7C, 0x7F, 0x83, 0x87, 0x8B, 0x8E, 0x92,
534    0x96, 0x99, 0x9D, 0xA1, 0xA4, 0xA8, 0xAB, 0xAF,
535    0xB2, 0xB6, 0xB9, 0xBD, 0xC0, 0xC4, 0xC7, 0xCB,
536    0xCE, 0xD1, 0xD5, 0xD8, 0xDB, 0xDF, 0xE2, 0xE5,
537    0xE9, 0xEC, 0xEF, 0xF2, 0xF6, 0xF9, 0xFC, 0xFD
538};
539#endif
540
541static int xan_decode_frame(AVCodecContext *avctx, AVFrame *frame,
542                            int *got_frame, AVPacket *avpkt)
543{
544    const uint8_t *buf = avpkt->data;
545    int ret, buf_size = avpkt->size;
546    XanContext *s = avctx->priv_data;
547    GetByteContext ctx;
548    int tag = 0;
549
550    bytestream2_init(&ctx, buf, buf_size);
551    while (bytestream2_get_bytes_left(&ctx) > 8 && tag != VGA__TAG) {
552        unsigned *tmpptr;
553        uint32_t new_pal;
554        int size;
555        int i;
556        tag  = bytestream2_get_le32(&ctx);
557        size = bytestream2_get_be32(&ctx);
558        if (size < 0) {
559            av_log(avctx, AV_LOG_ERROR, "Invalid tag size %d\n", size);
560            return AVERROR_INVALIDDATA;
561        }
562        size = FFMIN(size, bytestream2_get_bytes_left(&ctx));
563        switch (tag) {
564        case PALT_TAG:
565            if (size < PALETTE_SIZE)
566                return AVERROR_INVALIDDATA;
567            if (s->palettes_count >= PALETTES_MAX)
568                return AVERROR_INVALIDDATA;
569            tmpptr = av_realloc_array(s->palettes,
570                                      s->palettes_count + 1, AVPALETTE_SIZE);
571            if (!tmpptr)
572                return AVERROR(ENOMEM);
573            s->palettes = tmpptr;
574            tmpptr += s->palettes_count * AVPALETTE_COUNT;
575            for (i = 0; i < PALETTE_COUNT; i++) {
576#if RUNTIME_GAMMA
577                int r = gamma_corr(bytestream2_get_byteu(&ctx));
578                int g = gamma_corr(bytestream2_get_byteu(&ctx));
579                int b = gamma_corr(bytestream2_get_byteu(&ctx));
580#else
581                int r = gamma_lookup[bytestream2_get_byteu(&ctx)];
582                int g = gamma_lookup[bytestream2_get_byteu(&ctx)];
583                int b = gamma_lookup[bytestream2_get_byteu(&ctx)];
584#endif
585                *tmpptr++ = (0xFFU << 24) | (r << 16) | (g << 8) | b;
586            }
587            s->palettes_count++;
588            break;
589        case SHOT_TAG:
590            if (size < 4)
591                return AVERROR_INVALIDDATA;
592            new_pal = bytestream2_get_le32(&ctx);
593            if (new_pal < s->palettes_count) {
594                s->cur_palette = new_pal;
595            } else
596                av_log(avctx, AV_LOG_ERROR, "Invalid palette selected\n");
597            break;
598        case VGA__TAG:
599            break;
600        default:
601            bytestream2_skip(&ctx, size);
602            break;
603        }
604    }
605    buf_size = bytestream2_get_bytes_left(&ctx);
606
607    if (s->palettes_count <= 0) {
608        av_log(s->avctx, AV_LOG_ERROR, "No palette found\n");
609        return AVERROR_INVALIDDATA;
610    }
611
612    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
613        return ret;
614
615    if (!s->frame_size)
616        s->frame_size = frame->linesize[0] * s->avctx->height;
617
618    memcpy(frame->data[1],
619           s->palettes + s->cur_palette * AVPALETTE_COUNT, AVPALETTE_SIZE);
620
621    s->buf = ctx.buffer;
622    s->size = buf_size;
623
624    if (xan_wc3_decode_frame(s, frame) < 0)
625        return AVERROR_INVALIDDATA;
626
627    av_frame_unref(s->last_frame);
628    if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
629        return ret;
630
631    *got_frame = 1;
632
633    /* always report that the buffer was completely consumed */
634    return buf_size;
635}
636
637const FFCodec ff_xan_wc3_decoder = {
638    .p.name         = "xan_wc3",
639    .p.long_name    = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"),
640    .p.type         = AVMEDIA_TYPE_VIDEO,
641    .p.id           = AV_CODEC_ID_XAN_WC3,
642    .priv_data_size = sizeof(XanContext),
643    .init           = xan_decode_init,
644    .close          = xan_decode_end,
645    FF_CODEC_DECODE_CB(xan_decode_frame),
646    .p.capabilities = AV_CODEC_CAP_DR1,
647    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
648};
649