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