cf2a4afbf67febad0a81df83c374312d833a9e1a
[ffmpeg.git] / libavcodec / prosumer.c
1 /*
2  * Brooktree ProSumer Video decoder
3  * Copyright (c) 2018 Paul B Mahol
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 <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include "libavutil/imgutils.h"
27 #include "libavutil/internal.h"
28 #include "libavutil/intreadwrite.h"
29 #include "libavutil/mem.h"
30
31 #include "avcodec.h"
32 #include "bytestream.h"
33 #include "internal.h"
34
35 typedef struct ProSumerContext {
36     GetByteContext gb;
37     PutByteContext pb;
38
39     unsigned stride;
40     unsigned size;
41     uint32_t lut[0x10000];
42     uint8_t *table_b;
43     uint8_t *decbuffer;
44 } ProSumerContext;
45
46 #define PAIR(high, low) (((uint64_t)(high) << 32) | low)
47
48 static int decompress(GetByteContext *gb, int size, PutByteContext *pb, const uint32_t *lut)
49 {
50     int pos, idx, cnt, fill;
51     uint32_t a, b, c;
52
53     bytestream2_skip(gb, 32);
54     cnt = 4;
55     a = bytestream2_get_le32(gb);
56     idx = a >> 20;
57     b = lut[2 * idx];
58
59     while (1) {
60         if (((b & 0xFF00u) != 0x8000u) || (b & 0xFFu)) {
61             if ((b & 0xFF00u) != 0x8000u) {
62                 bytestream2_put_le16(pb, b);
63             } else if (b & 0xFFu) {
64                 idx = 0;
65                 for (int i = 0; i < (b & 0xFFu); i++)
66                     bytestream2_put_le32(pb, 0);
67             }
68             c = b >> 16;
69             if (c & 0xFF00u) {
70                 c = (((c >> 8) & 0xFFu) | (c & 0xFF00)) & 0xF00F;
71                 fill = lut[2 * idx + 1];
72                 if ((c & 0xFF00u) == 0x1000) {
73                     bytestream2_put_le16(pb, fill);
74                     c &= 0xFFFF00FFu;
75                 } else {
76                     bytestream2_put_le32(pb, fill);
77                     c &= 0xFFFF00FFu;
78                 }
79             }
80             while (c) {
81                 a <<= 4;
82                 cnt--;
83                 if (!cnt) {
84                     if (bytestream2_get_bytes_left(gb) <= 0) {
85                         if (!a)
86                             return 0;
87                         cnt = 4;
88                     } else {
89                         pos = bytestream2_tell(gb) ^ 2;
90                         bytestream2_seek(gb, pos, SEEK_SET);
91                         AV_WN16(&a, bytestream2_peek_le16(gb));
92                         pos = pos ^ 2;
93                         bytestream2_seek(gb, pos, SEEK_SET);
94                         bytestream2_skip(gb, 2);
95                         cnt = 4;
96                     }
97                 }
98                 c--;
99             }
100             idx = a >> 20;
101             b = lut[2 * idx];
102             continue;
103         }
104         idx = 2;
105         while (idx) {
106             a <<= 4;
107             cnt--;
108             if (cnt) {
109                 idx--;
110                 continue;
111             }
112             if (bytestream2_get_bytes_left(gb) <= 0) {
113                 if (a) {
114                     cnt = 4;
115                     idx--;
116                     continue;
117                 }
118                 return 0;
119             }
120             pos = bytestream2_tell(gb) ^ 2;
121             bytestream2_seek(gb, pos, SEEK_SET);
122             AV_WN16(&a, bytestream2_peek_le16(gb));
123             pos = pos ^ 2;
124             bytestream2_seek(gb, pos, SEEK_SET);
125             bytestream2_skip(gb, 2);
126             cnt = 4;
127             idx--;
128         }
129         b = PAIR(4, a) >> 16;
130     }
131
132     return 0;
133 }
134
135 static void do_shift(uint32_t *dst, int offset, uint32_t *src, int stride, int height)
136 {
137     uint32_t x = (0x7F7F7F7F >> 1) & 0x7F7F7F7F;
138
139     dst += offset >> 2;
140
141     for (int i = 0; i < height; i++) {
142         for (int j = 0; j < stride >> 2; j++) {
143             dst[j] = (((src[j] >> 3) + (x & dst[j])) << 3) & 0xFCFCFCFC;
144         }
145
146         dst += stride >> 2;
147         src += stride >> 2;
148     }
149 }
150
151 static int decode_frame(AVCodecContext *avctx, void *data,
152                         int *got_frame, AVPacket *avpkt)
153 {
154     ProSumerContext *s = avctx->priv_data;
155     AVFrame * const frame = data;
156     int ret;
157
158     if (avpkt->size <= 32)
159         return AVERROR_INVALIDDATA;
160
161     memset(s->decbuffer, 0, s->size);
162     bytestream2_init(&s->gb, avpkt->data, avpkt->size);
163     bytestream2_init_writer(&s->pb, s->decbuffer, s->size);
164
165     decompress(&s->gb, AV_RL32(avpkt->data + 28) >> 1, &s->pb, s->lut);
166     do_shift((uint32_t *)s->decbuffer, 0, (uint32_t *)s->table_b, s->stride, 1);
167     do_shift((uint32_t *)s->decbuffer, s->stride, (uint32_t *)s->decbuffer, s->stride, avctx->height - 1);
168
169     ret = ff_get_buffer(avctx, frame, 0);
170     if (ret < 0)
171         return ret;
172
173     for (int i = avctx->height - 1; i >= 0 ; i--) {
174         uint8_t *y = &frame->data[0][i * frame->linesize[0]];
175         uint8_t *u = &frame->data[1][i * frame->linesize[1]];
176         uint8_t *v = &frame->data[2][i * frame->linesize[2]];
177         uint8_t *src = s->decbuffer + (avctx->height - 1 - i) * s->stride;
178
179         for (int j = 0; j < avctx->width; j += 8) {
180             *(u++) = *src++;
181             *(y++) = *src++;
182             *(v++) = *src++;
183             *(y++) = *src++;
184
185             *(u++) = *src++;
186             *(y++) = *src++;
187             *(v++) = *src++;
188             *(y++) = *src++;
189
190             *(y++) = *src++;
191             *(y++) = *src++;
192             *(y++) = *src++;
193             *(y++) = *src++;
194         }
195     }
196
197     frame->pict_type = AV_PICTURE_TYPE_I;
198     frame->key_frame = 1;
199     *got_frame = 1;
200
201     return avpkt->size;
202 }
203
204 static const uint32_t table[] = {
205     0x0000, 0x10000001, 0x0101, 0x20000001, 0x0202, 0x30000001, 0xFFFF, 0x40000001, 0xFEFE, 0x50000001,
206     0x0001, 0x70000001, 0x0100, 0x80000001, 0x00FF, 0x90000001, 0xFF00, 0xA0000001, 0x8001, 0x60000001,
207     0x8002, 0xB0000001, 0xFCFC, 0x01000002, 0x0404, 0x03000002, 0x0002, 0xD3000002, 0xFEFC, 0x02000002,
208     0xFCFE, 0x04000002, 0xFEFF, 0xD2000002, 0x0808, 0x06000002, 0xFFFE, 0x05000002, 0x0402, 0xC0000002,
209     0x0204, 0xC1000002, 0xF8F8, 0xC3000002, 0x0201, 0xC4000002, 0x0102, 0xC6000002, 0x0804, 0xF3000002,
210     0x0408, 0xE0000002, 0xF8FC, 0xE1000002, 0xFCF8, 0xC7000002, 0x00FE, 0xD0000002, 0xFE00, 0xD4000002,
211     0xFF01, 0xD5000002, 0x01FF, 0xD6000002, 0x0200, 0xD7000002, 0xFCFF, 0xE2000002, 0x0104, 0xE3000002,
212     0xF0F0, 0xE5000002, 0x0401, 0xE7000002, 0x02FE, 0xF0000002, 0xFE02, 0xF1000002, 0xFE01, 0xF2000002,
213     0x01FE, 0xF4000002, 0xFF02, 0xF5000002, 0x02FF, 0xF6000002, 0x8003, 0xC2000002, 0x8004, 0x07000002,
214     0x8005, 0xD1000002, 0x8006, 0xC5000002, 0x8007, 0xE6000002, 0x8008, 0xE4000002, 0x8009, 0xF7000002,
215     0xFC02, 0x08000003, 0xFE04, 0x08100003, 0xFC00, 0x08200003, 0x02FC, 0x08300003, 0x1010, 0x08400003,
216     0x00FC, 0x08500003, 0x0004, 0x08600003, 0x0400, 0x08700003, 0xFFFC, 0x08800003, 0x1008, 0x08900003,
217     0x0810, 0x08A00003, 0x0802, 0x08B00003, 0x0208, 0x08C00003, 0xFEF8, 0x08D00003, 0xFC01, 0x08E00003,
218     0x04FF, 0x08F00003, 0xF8FE, 0x09000003, 0xFC04, 0x09100003, 0x04FC, 0x09200003, 0xFF04, 0x09300003,
219     0x01FC, 0x09400003, 0xF0F8, 0x09500003, 0xF8F0, 0x09600003, 0x04FE, 0x09700003, 0xF0FC, 0x09800003,
220     0x0008, 0x09900003, 0x08FE, 0x09A00003, 0x01F8, 0x09B00003, 0x0800, 0x09C00003, 0x08FC, 0x09D00003,
221     0xFE08, 0x09E00003, 0xFC08, 0x09F00003, 0xF800, 0x0A000003, 0x0108, 0x0A100003, 0xF802, 0x0A200003,
222     0x0801, 0x0A300003, 0x00F8, 0x0A400003, 0xF804, 0x0A500003, 0xF8FF, 0x0A600003, 0xFFF8, 0x0A700003,
223     0x04F8, 0x0A800003, 0x02F8, 0x0A900003, 0x1004, 0x0AA00003, 0x08F8, 0x0AB00003, 0xF808, 0x0AC00003,
224     0x0410, 0x0AD00003, 0xFF08, 0x0AE00003, 0x08FF, 0x0AF00003, 0xFCF0, 0x0B000003, 0xF801, 0x0B100003,
225     0xE0F0, 0x0B200003, 0xF3F3, 0x0B300003, 0xF0E0, 0x0B400003, 0xFAFA, 0x0B500003, 0xF7F7, 0x0B600003,
226     0xFEF0, 0x0B700003, 0xF0FE, 0x0B800003, 0xE9E9, 0x0B900003, 0xF9F9, 0x0BA00003, 0x2020, 0x0BB00003,
227     0xE0E0, 0x0BC00003, 0x02F0, 0x0BD00003, 0x04F0, 0x0BE00003, 0x2010, 0x0BF00003, 0xECEC, 0x0C000003,
228     0xEFEF, 0x0C100003, 0x1020, 0x0C200003, 0xF5F5, 0x0C300003, 0xF4F4, 0x0C400003, 0xEDED, 0x0C500003,
229     0xEAEA, 0x0C600003, 0xFBFB, 0x0C700003, 0x1002, 0x0C800003, 0xF2F2, 0x0C900003, 0xF6F6, 0x0CA00003,
230     0xF1F1, 0x0CB00003, 0xFDFD, 0x0CC00003, 0x0210, 0x0CD00003, 0x10FF, 0x0CE00003, 0xFDFE, 0x0CF00003,
231     0x10F8, 0x0D000003, 0x1000, 0x0D100003, 0xF001, 0x0D200003, 0x1001, 0x0D300003, 0x0010, 0x0D400003,
232     0x10FE, 0x0D500003, 0xEBEB, 0x0D600003, 0xFE10, 0x0D700003, 0x0110, 0x0D800003, 0xF000, 0x0D900003,
233     0x08F0, 0x0DA00003, 0x01F0, 0x0DB00003, 0x0303, 0x0DC00003, 0x00F0, 0x0DD00003, 0xF002, 0x0DE00003,
234     0x10FC, 0x0DF00003, 0xFC10, 0x0E000003, 0xF0FF, 0x0E100003, 0xEEEE, 0x0E200003, 0xF004, 0x0E300003,
235     0xFFF0, 0x0E400003, 0xF7F8, 0x0E500003, 0xF3F2, 0x0E600003, 0xF9FA, 0x0E700003, 0x0820, 0x0E800003,
236     0x0302, 0x0E900003, 0xE0F8, 0x0EA00003, 0x0505, 0x0EB00003, 0x2008, 0x0EC00003, 0xE8E8, 0x0ED00003,
237     0x0403, 0x0EE00003, 0xFBFC, 0x0EF00003, 0xFCFD, 0x0F000003, 0xFBFA, 0x0F100003, 0x0203, 0x0F200003,
238     0xFCFB, 0x0F300003, 0x0304, 0x0F400003, 0xF810, 0x0F500003, 0xFF10, 0x0F600003, 0xF008, 0x0F700003,
239     0xFEFD, 0x0F800003, 0xF7F6, 0x0F900003, 0xF2F1, 0x0FA00003, 0xF3F4, 0x0FB00003, 0xEDEC, 0x0FC00003,
240     0xF4F1, 0x0FD00003, 0xF5F6, 0x0FE00003, 0xF0F1, 0x0FF00003, 0xF9F8, 0xC8000003, 0x10F0, 0xC8100003,
241     0xF2F3, 0xC8200003, 0xF7F9, 0xC8300003, 0xF6F5, 0xC8400003, 0xF0EF, 0xC8500003, 0xF4F5, 0xC8600003,
242     0xF6F7, 0xC8700003, 0xFAF9, 0xC8800003, 0x0405, 0xC8900003, 0xF8F9, 0xC8A00003, 0xFAFB, 0xC8B00003,
243     0xF1F0, 0xC8C00003, 0xF4F3, 0xC8D00003, 0xF1F2, 0xC8E00003, 0xF8E0, 0xC8F00003, 0xF8F7, 0xC9000003,
244     0xFDFC, 0xC9100003, 0xF8FA, 0xC9200003, 0xFAF6, 0xC9300003, 0xEEEF, 0xC9400003, 0xF5F7, 0xC9500003,
245     0xFDFB, 0xC9600003, 0xF4F6, 0xC9700003, 0xFCFA, 0xC9800003, 0xECED, 0xC9900003, 0xF0F3, 0xC9A00003,
246     0xF3F1, 0xC9B00003, 0xECEB, 0xC9C00003, 0xEDEE, 0xC9D00003, 0xF9F7, 0xC9E00003, 0x0420, 0xC9F00003,
247     0xEBEA, 0xCA000003, 0xF0F4, 0xCA100003, 0xF3F5, 0xCA200003, 0xFAF7, 0xCA300003, 0x0301, 0xCA400003,
248     0xF3F7, 0xCA500003, 0xF7F3, 0xCA600003, 0xEFF0, 0xCA700003, 0xF9F6, 0xCA800003, 0xEFEE, 0xCA900003,
249     0xF4F7, 0xCAA00003, 0x0504, 0xCAB00003, 0xF5F4, 0xCAC00003, 0xF1F3, 0xCAD00003, 0xEBEE, 0xCAE00003,
250     0xF2F5, 0xCAF00003, 0xF3EF, 0xCB000003, 0xF5F1, 0xCB100003, 0xF9F3, 0xCB200003, 0xEDF0, 0xCB300003,
251     0xEEF1, 0xCB400003, 0xF6F9, 0xCB500003, 0xF8FB, 0xCB600003, 0xF010, 0xCB700003, 0xF2F6, 0xCB800003,
252     0xF4ED, 0xCB900003, 0xF7FB, 0xCBA00003, 0xF8F3, 0xCBB00003, 0xEDEB, 0xCBC00003, 0xF0F2, 0xCBD00003,
253     0xF2F9, 0xCBE00003, 0xF8F1, 0xCBF00003, 0xFAFC, 0xCC000003, 0xFBF8, 0xCC100003, 0xF6F0, 0xCC200003,
254     0xFAF8, 0xCC300003, 0x0103, 0xCC400003, 0xF3F6, 0xCC500003, 0xF4F9, 0xCC600003, 0xF7F2, 0xCC700003,
255     0x2004, 0xCC800003, 0xF2F0, 0xCC900003, 0xF4F2, 0xCCA00003, 0xEEED, 0xCCB00003, 0xFCE0, 0xCCC00003,
256     0xEAE9, 0xCCD00003, 0xEAEB, 0xCCE00003, 0xF6F4, 0xCCF00003, 0xFFFD, 0xCD000003, 0xE9EA, 0xCD100003,
257     0xF1F4, 0xCD200003, 0xF6EF, 0xCD300003, 0xF6F8, 0xCD400003, 0xF8F6, 0xCD500003, 0xEFF2, 0xCD600003,
258     0xEFF1, 0xCD700003, 0xF7F1, 0xCD800003, 0xFBFD, 0xCD900003, 0xFEF6, 0xCDA00003, 0xFFF7, 0xCDB00003,
259     0x0605, 0xCDC00003, 0xF0F5, 0xCDD00003, 0xF0FA, 0xCDE00003, 0xF1F9, 0xCDF00003, 0xF2FC, 0xCE000003,
260     0xF7EE, 0xCE100003, 0xF7F5, 0xCE200003, 0xF9FC, 0xCE300003, 0xFAF5, 0xCE400003, 0xFBF1, 0xCE500003,
261     0xF1EF, 0xCE600003, 0xF1FA, 0xCE700003, 0xF4F8, 0xCE800003, 0xF7F0, 0xCE900003, 0xF7F4, 0xCEA00003,
262     0xF7FC, 0xCEB00003, 0xF9FB, 0xCEC00003, 0xFAF1, 0xCED00003, 0xFBF9, 0xCEE00003, 0xFDFF, 0xCEF00003,
263     0xE0FC, 0xCF000003, 0xEBEC, 0xCF100003, 0xEDEF, 0xCF200003, 0xEFED, 0xCF300003, 0xF1F6, 0xCF400003,
264     0xF2F7, 0xCF500003, 0xF3EE, 0xCF600003, 0xF3F8, 0xCF700003, 0xF5F2, 0xCF800003, 0xF8F2, 0xCF900003,
265     0xF9F1, 0xCFA00003, 0xF9F2, 0xCFB00003, 0xFBEF, 0xCFC00003, 0x00FD, 0xCFD00003, 0xECEE, 0xCFE00003,
266     0xF2EF, 0xCFF00003, 0xF2F8, 0xD8000003, 0xF5F0, 0xD8100003, 0xF6F2, 0xD8200003, 0xFCF7, 0xD8300003,
267     0xFCF9, 0xD8400003, 0x0506, 0xD8500003, 0xEEEC, 0xD8600003, 0xF0F6, 0xD8700003, 0xF2F4, 0xD8800003,
268     0xF6F1, 0xD8900003, 0xF8F5, 0xD8A00003, 0xF9F4, 0xD8B00003, 0xFBF7, 0xD8C00003, 0x0503, 0xD8D00003,
269     0xEFEC, 0xD8E00003, 0xF3F0, 0xD8F00003, 0xF4F0, 0xD9000003, 0xF5F3, 0xD9100003, 0xF6F3, 0xD9200003,
270     0xF7FA, 0xD9300003, 0x800A, 0xD9400003, 0x800B, 0xD9500003, 0x800C, 0xD9600003, 0x800D, 0xD9700003,
271     0x800E, 0xD9800003, 0x800F, 0xD9900003, 0x8010, 0xD9A00003, 0x8011, 0xD9B00003, 0x8012, 0xD9C00003,
272     0x8013, 0xD9D00003, 0x8014, 0xD9E00003, 0x8015, 0xD9F00003, 0x8016, 0xDA000003, 0x8017, 0xDA100003,
273     0x8018, 0xDA200003, 0x8019, 0xDA300003, 0x801A, 0xDA400003, 0x801B, 0xDA500003, 0x801C, 0xDA600003,
274     0x801D, 0xDA700003, 0x801E, 0xDA800003, 0x801F, 0xDA900003, 0x8020, 0xDAA00003, 0x8021, 0xDAB00003,
275     0x8022, 0xDAC00003, 0x8023, 0xDAD00003, 0x8024, 0xDAE00003, 0x8025, 0xDAF00003, 0x8026, 0xDB000003,
276     0x8027, 0xDB100003, 0x8028, 0xDB200003, 0x8029, 0xDB300003, 0x802A, 0xDB400003, 0x802B, 0xDB500003,
277     0x802C, 0xDB600003, 0x802D, 0xDB700003, 0x802E, 0xDB800003, 0x802F, 0xDB900003, 0x80FF, 0xDBA00003,
278     0x0001
279 };
280
281 static void fill_elements(uint32_t idx, uint32_t shift, int size, uint32_t *e0, uint32_t *e1)
282 {
283     uint32_t b, h = idx << (32 - shift);
284
285     for (int i = 0; i < size; i++) {
286         b = 4 * (table[2 * i + 1] & 0xF);
287         if (shift >= b && (h & (0xFFF00000u << (12 - b))) == (table[2 * i + 1] & 0xFFFF0000u)) {
288             if (table[2 * i] >> 8 == 0x80u) {
289                 return;
290             } else {
291                 *e1 = table[2 * i];
292                 *e0 = (*e0 & 0xFFFFFFu) | (((12 + b - shift) & 0xFFFFFFFCu | 0x40u) << 22);
293                 shift -= b;
294                 h <<= b;
295                 break;
296             }
297         }
298     }
299     for (int i = 0; i < size; i++) {
300         b = 4 * (table[2 * i + 1] & 0xF);
301         if (shift >= b && (h & (0xFFF00000u << (12 - b))) == (table[2 * i + 1] & 0xFFFF0000u)) {
302             if (table[2 * i] >> 8 == 0x80u) {
303                 return;
304             } else {
305                 *e1 |= table[2 * i] << 16;
306                 *e0 = (*e0 & 0xFFFFFFu) | (((12 + b - shift) & 0xFFFFFFFCu | 0x80u) << 22);
307                 break;
308             }
309         }
310     }
311 }
312
313 static void fill_lut(uint32_t *lut)
314 {
315     for (int i = 1; i < FF_ARRAY_ELEMS(table); i += 2) {
316         uint32_t a = table[i];
317         uint32_t b = a & 0xFFu;
318         uint32_t c, d, e;
319
320         c = (b << 16) | table[i-1];
321         d = 4 * (3 - b);
322         e = (((0xFFF00000u << d) & a) >> 20) & 0xFFF;
323         if (d <= 0) {
324             lut[2 * e] = c;
325             lut[2 * e + 1] = 0;
326         } else {
327             for (int j = 0; j < 1 << d; j++) {
328                 uint32_t f = 0xFFFFFFFFu;
329                 c &= 0xFFFFFFu;
330                 if ((c & 0xFF00u) != 0x8000u)
331                     fill_elements(j, d, 365, &c, &f);
332                 lut[2 * e + 2 * j] = c;
333                 lut[2 * e + 2 * j + 1] = f;
334             }
335         }
336     }
337
338     for (int i = 0; i < 32; i += 2) {
339         lut[i  ] = 0x68000;
340         lut[i+1] = 0;
341     }
342 }
343
344 static av_cold int decode_init(AVCodecContext *avctx)
345 {
346     ProSumerContext *s = avctx->priv_data;
347
348     s->stride = 3LL * FFALIGN(avctx->width, 8) >> 1;
349     s->size = avctx->height * s->stride;
350
351     avctx->pix_fmt = AV_PIX_FMT_YUV411P;
352
353     s->table_b = av_malloc(s->stride);
354     s->decbuffer = av_malloc(s->size);
355     if (!s->table_b || !s->decbuffer)
356         return AVERROR(ENOMEM);
357     memset(s->table_b, 0x80u, s->stride);
358
359     fill_lut(s->lut);
360
361     return 0;
362 }
363
364 static av_cold int decode_close(AVCodecContext *avctx)
365 {
366     ProSumerContext *s = avctx->priv_data;
367
368     av_freep(&s->table_b);
369     av_freep(&s->decbuffer);
370
371     return 0;
372 }
373
374 AVCodec ff_prosumer_decoder = {
375     .name           = "prosumer",
376     .long_name      = NULL_IF_CONFIG_SMALL("Brooktree ProSumer Video"),
377     .type           = AVMEDIA_TYPE_VIDEO,
378     .id             = AV_CODEC_ID_PROSUMER,
379     .priv_data_size = sizeof(ProSumerContext),
380     .init           = decode_init,
381     .decode         = decode_frame,
382     .close          = decode_close,
383     .capabilities   = AV_CODEC_CAP_DR1,
384     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
385                       FF_CODEC_CAP_INIT_CLEANUP,
386 };