diff options
Diffstat (limited to 'libavcodec/magicyuv.c')
-rw-r--r-- | libavcodec/magicyuv.c | 481 |
1 files changed, 399 insertions, 82 deletions
diff --git a/libavcodec/magicyuv.c b/libavcodec/magicyuv.c index 027143f..9c6e1ba 100644 --- a/libavcodec/magicyuv.c +++ b/libavcodec/magicyuv.c @@ -2,20 +2,20 @@ * MagicYUV decoder * Copyright (c) 2016 Paul B Mahol * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -23,14 +23,15 @@ #include <string.h> #include "libavutil/pixdesc.h" +#include "libavutil/qsort.h" #include "avcodec.h" -#include "bitstream.h" #include "bytestream.h" +#include "get_bits.h" #include "huffyuvdsp.h" #include "internal.h" +#include "lossless_videodsp.h" #include "thread.h" -#include "vlc.h" typedef struct Slice { uint32_t start; @@ -44,26 +45,33 @@ typedef enum Prediction { } Prediction; typedef struct HuffEntry { - uint8_t sym; + uint16_t sym; uint8_t len; uint32_t code; } HuffEntry; typedef struct MagicYUVContext { AVFrame *p; + int max; + int bps; int slice_height; int nb_slices; int planes; // number of encoded planes in bitstream int decorrelate; // postprocessing work + int color_matrix; // video color matrix + int flags; int interlaced; // video is interlaced uint8_t *buf; // pointer to AVPacket->data int hshift[4]; int vshift[4]; Slice *slices[4]; // slice bitstream positions for each plane unsigned int slices_size[4]; // slice sizes for each plane - uint8_t len[4][256]; // table of code lengths for each plane + uint8_t len[4][4096]; // table of code lengths for each plane VLC vlc[4]; // VLC for each plane - HuffYUVDSPContext hdsp; + int (*huff_build)(VLC *vlc, uint8_t *len); + int (*magy_decode_slice)(AVCodecContext *avctx, void *tdata, + int j, int threadnr); + LLVidDSPContext llviddsp; } MagicYUVContext; static int huff_cmp_len(const void *a, const void *b) @@ -72,6 +80,82 @@ static int huff_cmp_len(const void *a, const void *b) return (aa->len - bb->len) * 256 + aa->sym - bb->sym; } +static int huff_cmp_len10(const void *a, const void *b) +{ + const HuffEntry *aa = a, *bb = b; + return (aa->len - bb->len) * 1024 + aa->sym - bb->sym; +} + +static int huff_cmp_len12(const void *a, const void *b) +{ + const HuffEntry *aa = a, *bb = b; + return (aa->len - bb->len) * 4096 + aa->sym - bb->sym; +} + +static int huff_build10(VLC *vlc, uint8_t *len) +{ + HuffEntry he[1024]; + uint32_t codes[1024]; + uint8_t bits[1024]; + uint16_t syms[1024]; + uint32_t code; + int i; + + for (i = 0; i < 1024; i++) { + he[i].sym = 1023 - i; + he[i].len = len[i]; + if (len[i] == 0 || len[i] > 32) + return AVERROR_INVALIDDATA; + } + AV_QSORT(he, 1024, HuffEntry, huff_cmp_len10); + + code = 1; + for (i = 1023; i >= 0; i--) { + codes[i] = code >> (32 - he[i].len); + bits[i] = he[i].len; + syms[i] = he[i].sym; + code += 0x80000000u >> (he[i].len - 1); + } + + ff_free_vlc(vlc); + return ff_init_vlc_sparse(vlc, FFMIN(he[1023].len, 12), 1024, + bits, sizeof(*bits), sizeof(*bits), + codes, sizeof(*codes), sizeof(*codes), + syms, sizeof(*syms), sizeof(*syms), 0); +} + +static int huff_build12(VLC *vlc, uint8_t *len) +{ + HuffEntry he[4096]; + uint32_t codes[4096]; + uint8_t bits[4096]; + uint16_t syms[4096]; + uint32_t code; + int i; + + for (i = 0; i < 4096; i++) { + he[i].sym = 4095 - i; + he[i].len = len[i]; + if (len[i] == 0 || len[i] > 32) + return AVERROR_INVALIDDATA; + } + AV_QSORT(he, 4096, HuffEntry, huff_cmp_len12); + + code = 1; + for (i = 4095; i >= 0; i--) { + codes[i] = code >> (32 - he[i].len); + bits[i] = he[i].len; + syms[i] = he[i].sym; + code += 0x80000000u >> (he[i].len - 1); + } + + ff_free_vlc(vlc); + return ff_init_vlc_sparse(vlc, FFMIN(he[4095].len, 14), 4096, + bits, sizeof(*bits), sizeof(*bits), + codes, sizeof(*codes), sizeof(*codes), + syms, sizeof(*syms), sizeof(*syms), 0); +} + static int huff_build(VLC *vlc, uint8_t *len) { HuffEntry he[256]; @@ -84,8 +168,10 @@ static int huff_build(VLC *vlc, uint8_t *len) for (i = 0; i < 256; i++) { he[i].sym = 255 - i; he[i].len = len[i]; + if (len[i] == 0 || len[i] > 32) + return AVERROR_INVALIDDATA; } - qsort(he, 256, sizeof(HuffEntry), huff_cmp_len); + AV_QSORT(he, 256, HuffEntry, huff_cmp_len); code = 1; for (i = 255; i >= 0; i--) { @@ -102,38 +188,189 @@ static int huff_build(VLC *vlc, uint8_t *len) syms, sizeof(*syms), sizeof(*syms), 0); } +static void magicyuv_median_pred16(uint16_t *dst, const uint16_t *src1, + const uint16_t *diff, intptr_t w, + int *left, int *left_top, int max) +{ + int i; + uint16_t l, lt; + + l = *left; + lt = *left_top; + + for (i = 0; i < w; i++) { + l = mid_pred(l, src1[i], (l + src1[i] - lt)) + diff[i]; + l &= max; + lt = src1[i]; + dst[i] = l; + } + + *left = l; + *left_top = lt; +} + +static int magy_decode_slice10(AVCodecContext *avctx, void *tdata, + int j, int threadnr) +{ + MagicYUVContext *s = avctx->priv_data; + int interlaced = s->interlaced; + const int bps = s->bps; + const int max = s->max - 1; + AVFrame *p = s->p; + int i, k, x; + GetBitContext gb; + uint16_t *dst; + + for (i = 0; i < s->planes; i++) { + int left, lefttop, top; + int height = AV_CEIL_RSHIFT(FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height), s->vshift[i]); + int width = AV_CEIL_RSHIFT(avctx->coded_width, s->hshift[i]); + int sheight = AV_CEIL_RSHIFT(s->slice_height, s->vshift[i]); + ptrdiff_t fake_stride = (p->linesize[i] / 2) * (1 + interlaced); + ptrdiff_t stride = p->linesize[i] / 2; + int flags, pred; + int ret = init_get_bits8(&gb, s->buf + s->slices[i][j].start, + s->slices[i][j].size); + + if (ret < 0) + return ret; + + flags = get_bits(&gb, 8); + pred = get_bits(&gb, 8); + + dst = (uint16_t *)p->data[i] + j * sheight * stride; + if (flags & 1) { + for (k = 0; k < height; k++) { + for (x = 0; x < width; x++) + dst[x] = get_bits(&gb, bps); + + dst += stride; + } + } else { + for (k = 0; k < height; k++) { + for (x = 0; x < width; x++) { + int pix; + if (get_bits_left(&gb) <= 0) + return AVERROR_INVALIDDATA; + + pix = get_vlc2(&gb, s->vlc[i].table, s->vlc[i].bits, 3); + if (pix < 0) + return AVERROR_INVALIDDATA; + + dst[x] = max - pix; + } + dst += stride; + } + } + + switch (pred) { + case LEFT: + dst = (uint16_t *)p->data[i] + j * sheight * stride; + s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0); + dst += stride; + if (interlaced) { + s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0); + dst += stride; + } + for (k = 1 + interlaced; k < height; k++) { + s->llviddsp.add_left_pred_int16(dst, dst, max, width, dst[-fake_stride]); + dst += stride; + } + break; + case GRADIENT: + dst = (uint16_t *)p->data[i] + j * sheight * stride; + s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0); + dst += stride; + if (interlaced) { + s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0); + dst += stride; + } + for (k = 1 + interlaced; k < height; k++) { + top = dst[-fake_stride]; + left = top + dst[0]; + dst[0] = left & max; + for (x = 1; x < width; x++) { + top = dst[x - fake_stride]; + lefttop = dst[x - (fake_stride + 1)]; + left += top - lefttop + dst[x]; + dst[x] = left & max; + } + dst += stride; + } + break; + case MEDIAN: + dst = (uint16_t *)p->data[i] + j * sheight * stride; + s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0); + dst += stride; + if (interlaced) { + s->llviddsp.add_left_pred_int16(dst, dst, max, width, 0); + dst += stride; + } + lefttop = left = dst[0]; + for (k = 1 + interlaced; k < height; k++) { + magicyuv_median_pred16(dst, dst - fake_stride, dst, width, &left, &lefttop, max); + lefttop = left = dst[0]; + dst += stride; + } + break; + default: + avpriv_request_sample(avctx, "Unknown prediction: %d", pred); + } + } + + if (s->decorrelate) { + int height = FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height); + int width = avctx->coded_width; + uint16_t *r = (uint16_t *)p->data[0] + j * s->slice_height * p->linesize[0] / 2; + uint16_t *g = (uint16_t *)p->data[1] + j * s->slice_height * p->linesize[1] / 2; + uint16_t *b = (uint16_t *)p->data[2] + j * s->slice_height * p->linesize[2] / 2; + + for (i = 0; i < height; i++) { + for (k = 0; k < width; k++) { + b[k] = (b[k] + g[k]) & max; + r[k] = (r[k] + g[k]) & max; + } + b += p->linesize[0] / 2; + g += p->linesize[1] / 2; + r += p->linesize[2] / 2; + } + } + + return 0; +} + static int magy_decode_slice(AVCodecContext *avctx, void *tdata, int j, int threadnr) { MagicYUVContext *s = avctx->priv_data; int interlaced = s->interlaced; AVFrame *p = s->p; - int i, k, x; - BitstreamContext bc; + int i, k, x, min_width; + GetBitContext gb; uint8_t *dst; for (i = 0; i < s->planes; i++) { int left, lefttop, top; - int height = AV_CEIL_RSHIFT(FFMIN(s->slice_height, avctx->height - j * s->slice_height), s->vshift[i]); - int width = AV_CEIL_RSHIFT(avctx->width, s->hshift[i]); + int height = AV_CEIL_RSHIFT(FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height), s->vshift[i]); + int width = AV_CEIL_RSHIFT(avctx->coded_width, s->hshift[i]); int sheight = AV_CEIL_RSHIFT(s->slice_height, s->vshift[i]); ptrdiff_t fake_stride = p->linesize[i] * (1 + interlaced); ptrdiff_t stride = p->linesize[i]; int flags, pred; - int ret = bitstream_init8(&bc, s->buf + s->slices[i][j].start, - s->slices[i][j].size); + int ret = init_get_bits8(&gb, s->buf + s->slices[i][j].start, + s->slices[i][j].size); if (ret < 0) return ret; - flags = bitstream_read(&bc, 8); - pred = bitstream_read(&bc, 8); + flags = get_bits(&gb, 8); + pred = get_bits(&gb, 8); dst = p->data[i] + j * sheight * stride; if (flags & 1) { for (k = 0; k < height; k++) { for (x = 0; x < width; x++) - dst[x] = bitstream_read(&bc, 8); + dst[x] = get_bits(&gb, 8); dst += stride; } @@ -141,10 +378,10 @@ static int magy_decode_slice(AVCodecContext *avctx, void *tdata, for (k = 0; k < height; k++) { for (x = 0; x < width; x++) { int pix; - if (bitstream_bits_left(&bc) <= 0) + if (get_bits_left(&gb) <= 0) return AVERROR_INVALIDDATA; - pix = bitstream_read_vlc(&bc, s->vlc[i].table, s->vlc[i].bits, 3); + pix = get_vlc2(&gb, s->vlc[i].table, s->vlc[i].bits, 3); if (pix < 0) return AVERROR_INVALIDDATA; @@ -157,52 +394,52 @@ static int magy_decode_slice(AVCodecContext *avctx, void *tdata, switch (pred) { case LEFT: dst = p->data[i] + j * sheight * stride; - s->hdsp.add_hfyu_left_pred(dst, dst, width, 0); + s->llviddsp.add_left_pred(dst, dst, width, 0); dst += stride; if (interlaced) { - s->hdsp.add_hfyu_left_pred(dst, dst, width, 0); + s->llviddsp.add_left_pred(dst, dst, width, 0); dst += stride; } for (k = 1 + interlaced; k < height; k++) { - s->hdsp.add_hfyu_left_pred(dst, dst, width, dst[-fake_stride]); + s->llviddsp.add_left_pred(dst, dst, width, dst[-fake_stride]); dst += stride; } break; case GRADIENT: dst = p->data[i] + j * sheight * stride; - s->hdsp.add_hfyu_left_pred(dst, dst, width, 0); - left = lefttop = 0; + s->llviddsp.add_left_pred(dst, dst, width, 0); dst += stride; if (interlaced) { - s->hdsp.add_hfyu_left_pred(dst, dst, width, 0); - left = lefttop = 0; + s->llviddsp.add_left_pred(dst, dst, width, 0); dst += stride; } + min_width = FFMIN(width, 32); for (k = 1 + interlaced; k < height; k++) { top = dst[-fake_stride]; left = top + dst[0]; dst[0] = left; - for (x = 1; x < width; x++) { + for (x = 1; x < min_width; x++) { /* dsp need aligned 32 */ top = dst[x - fake_stride]; lefttop = dst[x - (fake_stride + 1)]; left += top - lefttop + dst[x]; dst[x] = left; } + if (width > 32) + s->llviddsp.add_gradient_pred(dst + 32, fake_stride, width - 32); dst += stride; } break; case MEDIAN: dst = p->data[i] + j * sheight * stride; - lefttop = left = dst[0]; - s->hdsp.add_hfyu_left_pred(dst, dst, width, 0); + s->llviddsp.add_left_pred(dst, dst, width, 0); dst += stride; if (interlaced) { - lefttop = left = dst[0]; - s->hdsp.add_hfyu_left_pred(dst, dst, width, 0); + s->llviddsp.add_left_pred(dst, dst, width, 0); dst += stride; } + lefttop = left = dst[0]; for (k = 1 + interlaced; k < height; k++) { - s->hdsp.add_hfyu_median_pred(dst, dst - fake_stride, + s->llviddsp.add_median_pred(dst, dst - fake_stride, dst, width, &left, &lefttop); lefttop = left = dst[0]; dst += stride; @@ -214,15 +451,15 @@ static int magy_decode_slice(AVCodecContext *avctx, void *tdata, } if (s->decorrelate) { - int height = FFMIN(s->slice_height, avctx->height - j * s->slice_height); - int width = avctx->width; + int height = FFMIN(s->slice_height, avctx->coded_height - j * s->slice_height); + int width = avctx->coded_width; uint8_t *b = p->data[0] + j * s->slice_height * p->linesize[0]; uint8_t *g = p->data[1] + j * s->slice_height * p->linesize[1]; uint8_t *r = p->data[2] + j * s->slice_height * p->linesize[2]; for (i = 0; i < height; i++) { - s->hdsp.add_bytes(b, g, width); - s->hdsp.add_bytes(r, g, width); + s->llviddsp.add_bytes(b, g, width); + s->llviddsp.add_bytes(r, g, width); b += p->linesize[0]; g += p->linesize[1]; r += p->linesize[2]; @@ -232,6 +469,46 @@ static int magy_decode_slice(AVCodecContext *avctx, void *tdata, return 0; } +static int build_huffman(AVCodecContext *avctx, GetBitContext *gbit, int max) +{ + MagicYUVContext *s = avctx->priv_data; + int i = 0, j = 0, k; + + memset(s->len, 0, sizeof(s->len)); + while (get_bits_left(gbit) >= 8) { + int b = get_bits(gbit, 1); + int x = get_bits(gbit, 7); + int l = get_bitsz(gbit, b * 8) + 1; + + for (k = 0; k < l; k++) + if (j + k < max) + s->len[i][j + k] = x; + + j += l; + if (j == max) { + j = 0; + if (s->huff_build(&s->vlc[i], s->len[i])) { + av_log(avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n"); + return AVERROR_INVALIDDATA; + } + i++; + if (i == s->planes) { + break; + } + } else if (j > max) { + av_log(avctx, AV_LOG_ERROR, "Invalid Huffman codes\n"); + return AVERROR_INVALIDDATA; + } + } + + if (i != s->planes) { + av_log(avctx, AV_LOG_ERROR, "Huffman tables too short\n"); + return AVERROR_INVALIDDATA; + } + + return 0; +} + static int magy_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { @@ -239,10 +516,10 @@ static int magy_decode_frame(AVCodecContext *avctx, void *data, ThreadFrame frame = { .f = data }; AVFrame *p = data; GetByteContext gbyte; - BitstreamContext bc; + GetBitContext gbit; uint32_t first_offset, offset, next_offset, header_size, slice_width; int width, height, format, version, table_size; - int ret, i, j, k; + int ret, i, j; bytestream2_init(&gbyte, avpkt->data, avpkt->size); if (bytestream2_get_le32(&gbyte) != MKTAG('M', 'A', 'G', 'Y')) @@ -266,6 +543,10 @@ static int magy_decode_frame(AVCodecContext *avctx, void *data, s->hshift[2] = s->vshift[2] = 0; s->decorrelate = 0; + s->max = 256; + s->bps = 8; + s->huff_build = huff_build; + s->magy_decode_slice = magy_decode_slice; format = bytestream2_get_byte(&gbyte); switch (format) { @@ -298,14 +579,64 @@ static int magy_decode_frame(AVCodecContext *avctx, void *data, case 0x6b: avctx->pix_fmt = AV_PIX_FMT_GRAY8; break; + case 0x6c: + avctx->pix_fmt = AV_PIX_FMT_YUV422P10; + s->hshift[1] = + s->hshift[2] = 1; + s->max = 1024; + s->huff_build = huff_build10; + s->magy_decode_slice = magy_decode_slice10; + s->bps = 10; + break; + case 0x6d: + avctx->pix_fmt = AV_PIX_FMT_GBRP10; + s->decorrelate = 1; + s->max = 1024; + s->huff_build = huff_build10; + s->magy_decode_slice = magy_decode_slice10; + s->bps = 10; + break; + case 0x6e: + avctx->pix_fmt = AV_PIX_FMT_GBRAP10; + s->decorrelate = 1; + s->max = 1024; + s->huff_build = huff_build10; + s->magy_decode_slice = magy_decode_slice10; + s->bps = 10; + break; + case 0x6f: + avctx->pix_fmt = AV_PIX_FMT_GBRP12; + s->decorrelate = 1; + s->max = 4096; + s->huff_build = huff_build12; + s->magy_decode_slice = magy_decode_slice10; + s->bps = 12; + break; + case 0x70: + avctx->pix_fmt = AV_PIX_FMT_GBRAP12; + s->decorrelate = 1; + s->max = 4096; + s->huff_build = huff_build12; + s->magy_decode_slice = magy_decode_slice10; + s->bps = 12; + break; + case 0x73: + avctx->pix_fmt = AV_PIX_FMT_GRAY10; + s->max = 1024; + s->huff_build = huff_build10; + s->magy_decode_slice = magy_decode_slice10; + s->bps = 10; + break; default: avpriv_request_sample(avctx, "Format 0x%X", format); return AVERROR_PATCHWELCOME; } s->planes = av_pix_fmt_count_planes(avctx->pix_fmt); - bytestream2_skip(&gbyte, 2); - s->interlaced = !!(bytestream2_get_byte(&gbyte) & 2); + bytestream2_skip(&gbyte, 1); + s->color_matrix = bytestream2_get_byte(&gbyte); + s->flags = bytestream2_get_byte(&gbyte); + s->interlaced = !!(s->flags & 2); bytestream2_skip(&gbyte, 3); width = bytestream2_get_le32(&gbyte); @@ -315,12 +646,12 @@ static int magy_decode_frame(AVCodecContext *avctx, void *data, return ret; slice_width = bytestream2_get_le32(&gbyte); - if (slice_width != width) { + if (slice_width != avctx->coded_width) { avpriv_request_sample(avctx, "Slice width %"PRIu32, slice_width); return AVERROR_PATCHWELCOME; } s->slice_height = bytestream2_get_le32(&gbyte); - if (s->slice_height <= 0 || s->slice_height > INT_MAX - height) { + if (s->slice_height <= 0 || s->slice_height > INT_MAX - avctx->coded_height) { av_log(avctx, AV_LOG_ERROR, "invalid slice height: %d\n", s->slice_height); return AVERROR_INVALIDDATA; @@ -328,7 +659,7 @@ static int magy_decode_frame(AVCodecContext *avctx, void *data, bytestream2_skip(&gbyte, 4); - s->nb_slices = (height + s->slice_height - 1) / s->slice_height; + s->nb_slices = (avctx->coded_height + s->slice_height - 1) / s->slice_height; if (s->nb_slices > INT_MAX / sizeof(Slice)) { av_log(avctx, AV_LOG_ERROR, "invalid number of slices: %d\n", s->nb_slices); @@ -371,41 +702,13 @@ static int magy_decode_frame(AVCodecContext *avctx, void *data, if (table_size < 2) return AVERROR_INVALIDDATA; - ret = bitstream_init8(&bc, avpkt->data + bytestream2_tell(&gbyte), table_size); + ret = init_get_bits8(&gbit, avpkt->data + bytestream2_tell(&gbyte), table_size); if (ret < 0) return ret; - memset(s->len, 0, sizeof(s->len)); - j = i = 0; - while (bitstream_bits_left(&bc) >= 8) { - int b = bitstream_read(&bc, 4); - int x = bitstream_read(&bc, 4); - int l = bitstream_read(&bc, b) + 1; - - for (k = 0; k < l; k++) - if (j + k < 256) - s->len[i][j + k] = x; - - j += l; - if (j == 256) { - j = 0; - if (huff_build(&s->vlc[i], s->len[i])) { - av_log(avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n"); - return AVERROR_INVALIDDATA; - } - i++; - if (i == s->planes) { - break; - } - } else if (j > 256) { - return AVERROR_INVALIDDATA; - } - } - - if (i != s->planes) { - av_log(avctx, AV_LOG_ERROR, "Huffman tables too short\n"); - return AVERROR_INVALIDDATA; - } + ret = build_huffman(avctx, &gbit, s->max); + if (ret < 0) + return ret; p->pict_type = AV_PICTURE_TYPE_I; p->key_frame = 1; @@ -415,12 +718,26 @@ static int magy_decode_frame(AVCodecContext *avctx, void *data, s->buf = avpkt->data; s->p = p; - avctx->execute2(avctx, magy_decode_slice, NULL, NULL, s->nb_slices); - - if (avctx->pix_fmt == AV_PIX_FMT_GBRP || - avctx->pix_fmt == AV_PIX_FMT_GBRAP) { + avctx->execute2(avctx, s->magy_decode_slice, NULL, NULL, s->nb_slices); + + if (avctx->pix_fmt == AV_PIX_FMT_GBRP || + avctx->pix_fmt == AV_PIX_FMT_GBRAP || + avctx->pix_fmt == AV_PIX_FMT_GBRP10 || + avctx->pix_fmt == AV_PIX_FMT_GBRAP10|| + avctx->pix_fmt == AV_PIX_FMT_GBRAP12|| + avctx->pix_fmt == AV_PIX_FMT_GBRP12) { FFSWAP(uint8_t*, p->data[0], p->data[1]); FFSWAP(int, p->linesize[0], p->linesize[1]); + } else { + switch (s->color_matrix) { + case 1: + p->colorspace = AVCOL_SPC_BT470BG; + break; + case 2: + p->colorspace = AVCOL_SPC_BT709; + break; + } + p->color_range = (s->flags & 4) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; } *got_frame = 1; @@ -446,7 +763,7 @@ static int magy_init_thread_copy(AVCodecContext *avctx) static av_cold int magy_decode_init(AVCodecContext *avctx) { MagicYUVContext *s = avctx->priv_data; - ff_huffyuvdsp_init(&s->hdsp); + ff_llviddsp_init(&s->llviddsp); return 0; } |