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