avcodec/wmaprodec: cleanup extradata dumping
[ffmpeg.git] / libavcodec / magicyuv.c
1 /*
2  * MagicYUV decoder
3  * Copyright (c) 2016 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 <stdlib.h>
23 #include <string.h>
24
25 #include "libavutil/pixdesc.h"
26 #include "libavutil/qsort.h"
27
28 #include "avcodec.h"
29 #include "bytestream.h"
30 #include "get_bits.h"
31 #include "huffyuvdsp.h"
32 #include "internal.h"
33 #include "lossless_videodsp.h"
34 #include "thread.h"
35
36 typedef struct Slice {
37     uint32_t start;
38     uint32_t size;
39 } Slice;
40
41 typedef enum Prediction {
42     LEFT = 1,
43     GRADIENT,
44     MEDIAN,
45 } Prediction;
46
47 typedef struct HuffEntry {
48     uint16_t sym;
49     uint8_t  len;
50     uint32_t code;
51 } HuffEntry;
52
53 typedef struct MagicYUVContext {
54     AVFrame          *p;
55     int               max;
56     int               slice_height;
57     int               nb_slices;
58     int               planes;         // number of encoded planes in bitstream
59     int               decorrelate;    // postprocessing work
60     int               interlaced;     // video is interlaced
61     uint8_t          *buf;            // pointer to AVPacket->data
62     int               hshift[4];
63     int               vshift[4];
64     Slice            *slices[4];      // slice bitstream positions for each plane
65     unsigned int      slices_size[4]; // slice sizes for each plane
66     uint8_t           len[4][1024];   // table of code lengths for each plane
67     VLC               vlc[4];         // VLC for each plane
68     int (*huff_build)(VLC *vlc, uint8_t *len);
69     int (*magy_decode_slice)(AVCodecContext *avctx, void *tdata,
70                              int j, int threadnr);
71     HuffYUVDSPContext hdsp;
72     LLVidDSPContext   llviddsp;
73 } MagicYUVContext;
74
75 static int huff_cmp_len(const void *a, const void *b)
76 {
77     const HuffEntry *aa = a, *bb = b;
78     return (aa->len - bb->len) * 256 + aa->sym - bb->sym;
79 }
80
81 static int huff_cmp_len10(const void *a, const void *b)
82 {
83     const HuffEntry *aa = a, *bb = b;
84     return (aa->len - bb->len) * 1024 + aa->sym - bb->sym;
85 }
86
87 static int huff_build10(VLC *vlc, uint8_t *len)
88 {
89     HuffEntry he[1024];
90     uint32_t codes[1024];
91     uint8_t bits[1024];
92     uint16_t syms[1024];
93     uint32_t code;
94     int i;
95
96     for (i = 0; i < 1024; i++) {
97         he[i].sym = 1023 - i;
98         he[i].len = len[i];
99     }
100     AV_QSORT(he, 1024, HuffEntry, huff_cmp_len10);
101
102     code = 1;
103     for (i = 1023; i >= 0; i--) {
104         codes[i] = code >> (32 - he[i].len);
105         bits[i]  = he[i].len;
106         syms[i]  = he[i].sym;
107         code += 0x80000000u >> (he[i].len - 1);
108     }
109
110     ff_free_vlc(vlc);
111     return ff_init_vlc_sparse(vlc, FFMIN(he[1023].len, 12), 1024,
112                               bits,  sizeof(*bits),  sizeof(*bits),
113                               codes, sizeof(*codes), sizeof(*codes),
114                               syms,  sizeof(*syms),  sizeof(*syms), 0);
115 }
116
117 static int huff_build(VLC *vlc, uint8_t *len)
118 {
119     HuffEntry he[256];
120     uint32_t codes[256];
121     uint8_t bits[256];
122     uint8_t syms[256];
123     uint32_t code;
124     int i;
125
126     for (i = 0; i < 256; i++) {
127         he[i].sym = 255 - i;
128         he[i].len = len[i];
129     }
130     AV_QSORT(he, 256, HuffEntry, huff_cmp_len);
131
132     code = 1;
133     for (i = 255; i >= 0; i--) {
134         codes[i] = code >> (32 - he[i].len);
135         bits[i]  = he[i].len;
136         syms[i]  = he[i].sym;
137         code += 0x80000000u >> (he[i].len - 1);
138     }
139
140     ff_free_vlc(vlc);
141     return ff_init_vlc_sparse(vlc, FFMIN(he[255].len, 12), 256,
142                               bits,  sizeof(*bits),  sizeof(*bits),
143                               codes, sizeof(*codes), sizeof(*codes),
144                               syms,  sizeof(*syms),  sizeof(*syms), 0);
145 }
146
147 static void magicyuv_median_pred10(uint16_t *dst, const uint16_t *src1,
148                                    const uint16_t *diff, intptr_t w,
149                                    int *left, int *left_top)
150 {
151     int i;
152     uint16_t l, lt;
153
154     l  = *left;
155     lt = *left_top;
156
157     for (i = 0; i < w; i++) {
158         l      = mid_pred(l, src1[i], (l + src1[i] - lt)) + diff[i];
159         l     &= 0x3FF;
160         lt     = src1[i];
161         dst[i] = l;
162     }
163
164     *left     = l;
165     *left_top = lt;
166 }
167
168 static int magy_decode_slice10(AVCodecContext *avctx, void *tdata,
169                                int j, int threadnr)
170 {
171     MagicYUVContext *s = avctx->priv_data;
172     int interlaced = s->interlaced;
173     AVFrame *p = s->p;
174     int i, k, x;
175     GetBitContext gb;
176     uint16_t *dst;
177
178     for (i = 0; i < s->planes; i++) {
179         int left, lefttop, top;
180         int height = AV_CEIL_RSHIFT(FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height), s->vshift[i]);
181         int width = AV_CEIL_RSHIFT(avctx->coded_width, s->hshift[i]);
182         int sheight = AV_CEIL_RSHIFT(s->slice_height, s->vshift[i]);
183         ptrdiff_t fake_stride = (p->linesize[i] / 2) * (1 + interlaced);
184         ptrdiff_t stride = p->linesize[i] / 2;
185         int flags, pred;
186         int ret = init_get_bits8(&gb, s->buf + s->slices[i][j].start,
187                                  s->slices[i][j].size);
188
189         if (ret < 0)
190             return ret;
191
192         flags = get_bits(&gb, 8);
193         pred  = get_bits(&gb, 8);
194
195         dst = (uint16_t *)p->data[i] + j * sheight * stride;
196         if (flags & 1) {
197             for (k = 0; k < height; k++) {
198                 for (x = 0; x < width; x++)
199                     dst[x] = get_bits(&gb, 10);
200
201                 dst += stride;
202             }
203         } else {
204             for (k = 0; k < height; k++) {
205                 for (x = 0; x < width; x++) {
206                     int pix;
207                     if (get_bits_left(&gb) <= 0)
208                         return AVERROR_INVALIDDATA;
209
210                     pix = get_vlc2(&gb, s->vlc[i].table, s->vlc[i].bits, 3);
211                     if (pix < 0)
212                         return AVERROR_INVALIDDATA;
213
214                     dst[x] = 1023 - pix;
215                 }
216                 dst += stride;
217             }
218         }
219
220         switch (pred) {
221         case LEFT:
222             dst = (uint16_t *)p->data[i] + j * sheight * stride;
223             s->llviddsp.add_hfyu_left_pred_int16(dst, dst, 1023, width, 0);
224             dst += stride;
225             if (interlaced) {
226                 s->llviddsp.add_hfyu_left_pred_int16(dst, dst, 1023, width, 0);
227                 dst += stride;
228             }
229             for (k = 1 + interlaced; k < height; k++) {
230                 s->llviddsp.add_hfyu_left_pred_int16(dst, dst, 1023, width, dst[-fake_stride]);
231                 dst += stride;
232             }
233             break;
234         case GRADIENT:
235             dst = (uint16_t *)p->data[i] + j * sheight * stride;
236             s->llviddsp.add_hfyu_left_pred_int16(dst, dst, 1023, width, 0);
237             left = lefttop = 0;
238             dst += stride;
239             if (interlaced) {
240                 s->llviddsp.add_hfyu_left_pred_int16(dst, dst, 1023, width, 0);
241                 left = lefttop = 0;
242                 dst += stride;
243             }
244             for (k = 1 + interlaced; k < height; k++) {
245                 top = dst[-fake_stride];
246                 left = top + dst[0];
247                 dst[0] = left & 0x3FF;
248                 for (x = 1; x < width; x++) {
249                     top = dst[x - fake_stride];
250                     lefttop = dst[x - (fake_stride + 1)];
251                     left += top - lefttop + dst[x];
252                     dst[x] = left & 0x3FF;
253                 }
254                 dst += stride;
255             }
256             break;
257         case MEDIAN:
258             dst = (uint16_t *)p->data[i] + j * sheight * stride;
259             lefttop = left = dst[0];
260             s->llviddsp.add_hfyu_left_pred_int16(dst, dst, 1023, width, 0);
261             dst += stride;
262             if (interlaced) {
263                 lefttop = left = dst[0];
264                 s->llviddsp.add_hfyu_left_pred_int16(dst, dst, 1023, width, 0);
265                 dst += stride;
266             }
267             for (k = 1 + interlaced; k < height; k++) {
268                 magicyuv_median_pred10(dst, dst - fake_stride, dst, width, &left, &lefttop);
269                 lefttop = left = dst[0];
270                 dst += stride;
271             }
272             break;
273         default:
274             avpriv_request_sample(avctx, "Unknown prediction: %d", pred);
275         }
276     }
277
278     if (s->decorrelate) {
279         int height = FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height);
280         int width = avctx->coded_width;
281         uint16_t *r = (uint16_t *)p->data[0] + j * s->slice_height * p->linesize[0] / 2;
282         uint16_t *g = (uint16_t *)p->data[1] + j * s->slice_height * p->linesize[1] / 2;
283         uint16_t *b = (uint16_t *)p->data[2] + j * s->slice_height * p->linesize[2] / 2;
284
285         for (i = 0; i < height; i++) {
286             for (k = 0; k < width; k++) {
287                 b[k] = (b[k] + g[k]) & 0x3FF;
288                 r[k] = (r[k] + g[k]) & 0x3FF;
289             }
290             b += p->linesize[0] / 2;
291             g += p->linesize[1] / 2;
292             r += p->linesize[2] / 2;
293         }
294     }
295
296     return 0;
297 }
298
299 static int magy_decode_slice(AVCodecContext *avctx, void *tdata,
300                              int j, int threadnr)
301 {
302     MagicYUVContext *s = avctx->priv_data;
303     int interlaced = s->interlaced;
304     AVFrame *p = s->p;
305     int i, k, x;
306     GetBitContext gb;
307     uint8_t *dst;
308
309     for (i = 0; i < s->planes; i++) {
310         int left, lefttop, top;
311         int height = AV_CEIL_RSHIFT(FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height), s->vshift[i]);
312         int width = AV_CEIL_RSHIFT(avctx->coded_width, s->hshift[i]);
313         int sheight = AV_CEIL_RSHIFT(s->slice_height, s->vshift[i]);
314         ptrdiff_t fake_stride = p->linesize[i] * (1 + interlaced);
315         ptrdiff_t stride = p->linesize[i];
316         int flags, pred;
317         int ret = init_get_bits8(&gb, s->buf + s->slices[i][j].start,
318                                  s->slices[i][j].size);
319
320         if (ret < 0)
321             return ret;
322
323         flags = get_bits(&gb, 8);
324         pred  = get_bits(&gb, 8);
325
326         dst = p->data[i] + j * sheight * stride;
327         if (flags & 1) {
328             for (k = 0; k < height; k++) {
329                 for (x = 0; x < width; x++)
330                     dst[x] = get_bits(&gb, 8);
331
332                 dst += stride;
333             }
334         } else {
335             for (k = 0; k < height; k++) {
336                 for (x = 0; x < width; x++) {
337                     int pix;
338                     if (get_bits_left(&gb) <= 0)
339                         return AVERROR_INVALIDDATA;
340
341                     pix = get_vlc2(&gb, s->vlc[i].table, s->vlc[i].bits, 3);
342                     if (pix < 0)
343                         return AVERROR_INVALIDDATA;
344
345                     dst[x] = 255 - pix;
346                 }
347                 dst += stride;
348             }
349         }
350
351         switch (pred) {
352         case LEFT:
353             dst = p->data[i] + j * sheight * stride;
354             s->hdsp.add_hfyu_left_pred(dst, dst, width, 0);
355             dst += stride;
356             if (interlaced) {
357                 s->hdsp.add_hfyu_left_pred(dst, dst, width, 0);
358                 dst += stride;
359             }
360             for (k = 1 + interlaced; k < height; k++) {
361                 s->hdsp.add_hfyu_left_pred(dst, dst, width, dst[-fake_stride]);
362                 dst += stride;
363             }
364             break;
365         case GRADIENT:
366             dst = p->data[i] + j * sheight * stride;
367             s->hdsp.add_hfyu_left_pred(dst, dst, width, 0);
368             left = lefttop = 0;
369             dst += stride;
370             if (interlaced) {
371                 s->hdsp.add_hfyu_left_pred(dst, dst, width, 0);
372                 left = lefttop = 0;
373                 dst += stride;
374             }
375             for (k = 1 + interlaced; k < height; k++) {
376                 top = dst[-fake_stride];
377                 left = top + dst[0];
378                 dst[0] = left;
379                 for (x = 1; x < width; x++) {
380                     top = dst[x - fake_stride];
381                     lefttop = dst[x - (fake_stride + 1)];
382                     left += top - lefttop + dst[x];
383                     dst[x] = left;
384                 }
385                 dst += stride;
386             }
387             break;
388         case MEDIAN:
389             dst = p->data[i] + j * sheight * stride;
390             lefttop = left = dst[0];
391             s->hdsp.add_hfyu_left_pred(dst, dst, width, 0);
392             dst += stride;
393             if (interlaced) {
394                 lefttop = left = dst[0];
395                 s->hdsp.add_hfyu_left_pred(dst, dst, width, 0);
396                 dst += stride;
397             }
398             for (k = 1 + interlaced; k < height; k++) {
399                 s->hdsp.add_hfyu_median_pred(dst, dst - fake_stride,
400                                              dst, width, &left, &lefttop);
401                 lefttop = left = dst[0];
402                 dst += stride;
403             }
404             break;
405         default:
406             avpriv_request_sample(avctx, "Unknown prediction: %d", pred);
407         }
408     }
409
410     if (s->decorrelate) {
411         int height = FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height);
412         int width = avctx->coded_width;
413         uint8_t *b = p->data[0] + j * s->slice_height * p->linesize[0];
414         uint8_t *g = p->data[1] + j * s->slice_height * p->linesize[1];
415         uint8_t *r = p->data[2] + j * s->slice_height * p->linesize[2];
416
417         for (i = 0; i < height; i++) {
418             s->hdsp.add_bytes(b, g, width);
419             s->hdsp.add_bytes(r, g, width);
420             b += p->linesize[0];
421             g += p->linesize[1];
422             r += p->linesize[2];
423         }
424     }
425
426     return 0;
427 }
428
429 static int build_huffman(AVCodecContext *avctx, GetBitContext *gbit, int max)
430 {
431     MagicYUVContext *s = avctx->priv_data;
432     int i = 0, j = 0, k;
433
434     memset(s->len, 0, sizeof(s->len));
435     while (get_bits_left(gbit) >= 8) {
436         int b = get_bits(gbit, 4);
437         int x = get_bits(gbit, 4);
438         int l = get_bitsz(gbit, b) + 1;
439
440         for (k = 0; k < l; k++)
441             if (j + k < max)
442                 s->len[i][j + k] = x;
443
444         j += l;
445         if (j == max) {
446             j = 0;
447             if (s->huff_build(&s->vlc[i], s->len[i])) {
448                 av_log(avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n");
449                 return AVERROR_INVALIDDATA;
450             }
451             i++;
452             if (i == s->planes) {
453                 break;
454             }
455         } else if (j > max) {
456             return AVERROR_INVALIDDATA;
457         }
458     }
459
460     if (i != s->planes) {
461         av_log(avctx, AV_LOG_ERROR, "Huffman tables too short\n");
462         return AVERROR_INVALIDDATA;
463     }
464
465     return 0;
466 }
467
468 static int magy_decode_frame(AVCodecContext *avctx, void *data,
469                              int *got_frame, AVPacket *avpkt)
470 {
471     MagicYUVContext *s = avctx->priv_data;
472     ThreadFrame frame = { .f = data };
473     AVFrame *p = data;
474     GetByteContext gbyte;
475     GetBitContext gbit;
476     uint32_t first_offset, offset, next_offset, header_size, slice_width;
477     int width, height, format, version, table_size;
478     int ret, i, j;
479
480     bytestream2_init(&gbyte, avpkt->data, avpkt->size);
481     if (bytestream2_get_le32(&gbyte) != MKTAG('M', 'A', 'G', 'Y'))
482         return AVERROR_INVALIDDATA;
483
484     header_size = bytestream2_get_le32(&gbyte);
485     if (header_size < 32 || header_size >= avpkt->size) {
486         av_log(avctx, AV_LOG_ERROR,
487                "header or packet too small %"PRIu32"\n", header_size);
488         return AVERROR_INVALIDDATA;
489     }
490
491     version = bytestream2_get_byte(&gbyte);
492     if (version != 7) {
493         avpriv_request_sample(avctx, "Version %d", version);
494         return AVERROR_PATCHWELCOME;
495     }
496
497     s->hshift[1] =
498     s->vshift[1] =
499     s->hshift[2] =
500     s->vshift[2] = 0;
501     s->decorrelate = 0;
502     s->max = 256;
503     s->huff_build = huff_build;
504     s->magy_decode_slice = magy_decode_slice;
505
506     format = bytestream2_get_byte(&gbyte);
507     switch (format) {
508     case 0x65:
509         avctx->pix_fmt = AV_PIX_FMT_GBRP;
510         s->decorrelate = 1;
511         break;
512     case 0x66:
513         avctx->pix_fmt = AV_PIX_FMT_GBRAP;
514         s->decorrelate = 1;
515         break;
516     case 0x67:
517         avctx->pix_fmt = AV_PIX_FMT_YUV444P;
518         break;
519     case 0x68:
520         avctx->pix_fmt = AV_PIX_FMT_YUV422P;
521         s->hshift[1] =
522         s->hshift[2] = 1;
523         break;
524     case 0x69:
525         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
526         s->hshift[1] =
527         s->vshift[1] =
528         s->hshift[2] =
529         s->vshift[2] = 1;
530         break;
531     case 0x6a:
532         avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
533         break;
534     case 0x6b:
535         avctx->pix_fmt = AV_PIX_FMT_GRAY8;
536         break;
537     case 0x6c:
538         avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
539         s->hshift[1] =
540         s->hshift[2] = 1;
541         s->max = 1024;
542         s->huff_build = huff_build10;
543         s->magy_decode_slice = magy_decode_slice10;
544         break;
545     case 0x6d:
546         avctx->pix_fmt = AV_PIX_FMT_GBRP10;
547         s->decorrelate = 1;
548         s->max = 1024;
549         s->huff_build = huff_build10;
550         s->magy_decode_slice = magy_decode_slice10;
551         break;
552     case 0x6e:
553         avctx->pix_fmt = AV_PIX_FMT_GBRAP10;
554         s->decorrelate = 1;
555         s->max = 1024;
556         s->huff_build = huff_build10;
557         s->magy_decode_slice = magy_decode_slice10;
558         break;
559     case 0x73:
560         avctx->pix_fmt = AV_PIX_FMT_GRAY10;
561         s->max = 1024;
562         s->huff_build = huff_build10;
563         s->magy_decode_slice = magy_decode_slice10;
564         break;
565     default:
566         avpriv_request_sample(avctx, "Format 0x%X", format);
567         return AVERROR_PATCHWELCOME;
568     }
569     s->planes = av_pix_fmt_count_planes(avctx->pix_fmt);
570
571     bytestream2_skip(&gbyte, 2);
572     s->interlaced = !!(bytestream2_get_byte(&gbyte) & 2);
573     bytestream2_skip(&gbyte, 3);
574
575     width  = bytestream2_get_le32(&gbyte);
576     height = bytestream2_get_le32(&gbyte);
577     ret = ff_set_dimensions(avctx, width, height);
578     if (ret < 0)
579         return ret;
580
581     slice_width = bytestream2_get_le32(&gbyte);
582     if (slice_width != avctx->coded_width) {
583         avpriv_request_sample(avctx, "Slice width %"PRIu32, slice_width);
584         return AVERROR_PATCHWELCOME;
585     }
586     s->slice_height = bytestream2_get_le32(&gbyte);
587     if (s->slice_height <= 0 || s->slice_height > INT_MAX - avctx->coded_height) {
588         av_log(avctx, AV_LOG_ERROR,
589                "invalid slice height: %d\n", s->slice_height);
590         return AVERROR_INVALIDDATA;
591     }
592
593     bytestream2_skip(&gbyte, 4);
594
595     s->nb_slices = (avctx->coded_height + s->slice_height - 1) / s->slice_height;
596     if (s->nb_slices > INT_MAX / sizeof(Slice)) {
597         av_log(avctx, AV_LOG_ERROR,
598                "invalid number of slices: %d\n", s->nb_slices);
599         return AVERROR_INVALIDDATA;
600     }
601
602     for (i = 0; i < s->planes; i++) {
603         av_fast_malloc(&s->slices[i], &s->slices_size[i], s->nb_slices * sizeof(Slice));
604         if (!s->slices[i])
605             return AVERROR(ENOMEM);
606
607         offset = bytestream2_get_le32(&gbyte);
608         if (offset >= avpkt->size - header_size)
609             return AVERROR_INVALIDDATA;
610
611         if (i == 0)
612             first_offset = offset;
613
614         for (j = 0; j < s->nb_slices - 1; j++) {
615             s->slices[i][j].start = offset + header_size;
616
617             next_offset = bytestream2_get_le32(&gbyte);
618             if (next_offset <= offset || next_offset >= avpkt->size - header_size)
619                 return AVERROR_INVALIDDATA;
620
621             s->slices[i][j].size = next_offset - offset;
622             offset = next_offset;
623         }
624
625         s->slices[i][j].start = offset + header_size;
626         s->slices[i][j].size  = avpkt->size - s->slices[i][j].start;
627     }
628
629     if (bytestream2_get_byte(&gbyte) != s->planes)
630         return AVERROR_INVALIDDATA;
631
632     bytestream2_skip(&gbyte, s->nb_slices * s->planes);
633
634     table_size = header_size + first_offset - bytestream2_tell(&gbyte);
635     if (table_size < 2)
636         return AVERROR_INVALIDDATA;
637
638     ret = init_get_bits8(&gbit, avpkt->data + bytestream2_tell(&gbyte), table_size);
639     if (ret < 0)
640         return ret;
641
642     ret = build_huffman(avctx, &gbit, s->max);
643     if (ret < 0)
644         return ret;
645
646     p->pict_type = AV_PICTURE_TYPE_I;
647     p->key_frame = 1;
648
649     if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
650         return ret;
651
652     s->buf = avpkt->data;
653     s->p = p;
654     avctx->execute2(avctx, s->magy_decode_slice, NULL, NULL, s->nb_slices);
655
656     if (avctx->pix_fmt == AV_PIX_FMT_GBRP   ||
657         avctx->pix_fmt == AV_PIX_FMT_GBRAP  ||
658         avctx->pix_fmt == AV_PIX_FMT_GBRP10 ||
659         avctx->pix_fmt == AV_PIX_FMT_GBRAP10) {
660         FFSWAP(uint8_t*, p->data[0], p->data[1]);
661         FFSWAP(int, p->linesize[0], p->linesize[1]);
662     }
663
664     *got_frame = 1;
665
666     return avpkt->size;
667 }
668
669 #if HAVE_THREADS
670 static int magy_init_thread_copy(AVCodecContext *avctx)
671 {
672     MagicYUVContext *s = avctx->priv_data;
673     int i;
674
675     for (i = 0; i < FF_ARRAY_ELEMS(s->slices); i++) {
676         s->slices[i] = NULL;
677         s->slices_size[i] = 0;
678     }
679
680     return 0;
681 }
682 #endif
683
684 static av_cold int magy_decode_init(AVCodecContext *avctx)
685 {
686     MagicYUVContext *s = avctx->priv_data;
687     ff_huffyuvdsp_init(&s->hdsp);
688     ff_llviddsp_init(&s->llviddsp, avctx);
689     return 0;
690 }
691
692 static av_cold int magy_decode_end(AVCodecContext *avctx)
693 {
694     MagicYUVContext * const s = avctx->priv_data;
695     int i;
696
697     for (i = 0; i < FF_ARRAY_ELEMS(s->slices); i++) {
698         av_freep(&s->slices[i]);
699         s->slices_size[i] = 0;
700         ff_free_vlc(&s->vlc[i]);
701     }
702
703     return 0;
704 }
705
706 AVCodec ff_magicyuv_decoder = {
707     .name             = "magicyuv",
708     .long_name        = NULL_IF_CONFIG_SMALL("MagicYUV video"),
709     .type             = AVMEDIA_TYPE_VIDEO,
710     .id               = AV_CODEC_ID_MAGICYUV,
711     .priv_data_size   = sizeof(MagicYUVContext),
712     .init             = magy_decode_init,
713     .init_thread_copy = ONLY_IF_THREADS_ENABLED(magy_init_thread_copy),
714     .close            = magy_decode_end,
715     .decode           = magy_decode_frame,
716     .capabilities     = AV_CODEC_CAP_DR1 |
717                         AV_CODEC_CAP_FRAME_THREADS |
718                         AV_CODEC_CAP_SLICE_THREADS,
719     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE,
720 };