X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=libavcodec%2Fmagicyuv.c;h=3f6348b531ed6cfa21981083a044b33d51a0f189;hb=2b01b7918beebe7b392ebf255f887e396a59e4c6;hp=634d45ca4809930f9ef760b8e039519c1070996d;hpb=55e5af3c03898ffbac352fe4af83208fa4129c71;p=platform%2Fupstream%2Fffmpeg.git diff --git a/libavcodec/magicyuv.c b/libavcodec/magicyuv.c index 634d45c..3f6348b 100644 --- a/libavcodec/magicyuv.c +++ b/libavcodec/magicyuv.c @@ -29,12 +29,13 @@ #include "avcodec.h" #include "bytestream.h" #include "codec_internal.h" +#include "decode.h" #include "get_bits.h" -#include "huffyuvdsp.h" -#include "internal.h" #include "lossless_videodsp.h" #include "thread.h" +#define VLC_BITS 12 + typedef struct Slice { uint32_t start; uint32_t size; @@ -68,15 +69,20 @@ typedef struct MagicYUVContext { Slice *slices[4]; // slice bitstream positions for each plane unsigned int slices_size[4]; // slice sizes for each plane VLC vlc[4]; // VLC for each plane + VLC_MULTI multi[4]; // Buffer for joint VLC data int (*magy_decode_slice)(AVCodecContext *avctx, void *tdata, int j, int threadnr); LLVidDSPContext llviddsp; + HuffEntry he[1 << 14]; + uint8_t len[1 << 14]; } MagicYUVContext; -static int huff_build(const uint8_t len[], uint16_t codes_pos[33], - VLC *vlc, int nb_elems, void *logctx) +static int huff_build(AVCodecContext *avctx, + const uint8_t len[], uint16_t codes_pos[33], + VLC *vlc, VLC_MULTI *multi, int nb_elems, void *logctx) { - HuffEntry he[4096]; + MagicYUVContext *s = avctx->priv_data; + HuffEntry *he = s->he; for (int i = 31; i > 0; i--) codes_pos[i] += codes_pos[i + 1]; @@ -84,8 +90,9 @@ static int huff_build(const uint8_t len[], uint16_t codes_pos[33], for (unsigned i = nb_elems; i-- > 0;) he[--codes_pos[len[i]]] = (HuffEntry){ len[i], i }; - ff_free_vlc(vlc); - return ff_init_vlc_from_lengths(vlc, FFMIN(he[0].len, 12), nb_elems, + ff_vlc_free(vlc); + ff_vlc_free_multi(multi); + return ff_vlc_init_multi_from_lengths(vlc, multi, FFMIN(he[0].len, VLC_BITS), nb_elems, nb_elems, &he[0].len, sizeof(he[0]), &he[0].sym, sizeof(he[0]), sizeof(he[0].sym), 0, 0, logctx); @@ -112,10 +119,25 @@ static void magicyuv_median_pred16(uint16_t *dst, const uint16_t *src1, *left_top = lt; } +#define READ_PLANE(dst, plane, b, c) \ +{ \ + x = 0; \ + for (; CACHED_BITSTREAM_READER && x < width-c && get_bits_left(&gb) > 0;) {\ + ret = get_vlc_multi(&gb, (uint8_t *)dst + x * b, multi, \ + vlc, vlc_bits, 3); \ + if (ret <= 0) \ + return AVERROR_INVALIDDATA; \ + x += ret; \ + } \ + for (; x < width && get_bits_left(&gb) > 0; x++) \ + dst[x] = get_vlc2(&gb, vlc, vlc_bits, 3); \ + dst += stride; \ +} + static int magy_decode_slice10(AVCodecContext *avctx, void *tdata, int j, int threadnr) { - MagicYUVContext *s = avctx->priv_data; + const MagicYUVContext *s = avctx->priv_data; int interlaced = s->interlaced; const int bps = s->bps; const int max = s->max - 1; @@ -131,6 +153,9 @@ static int magy_decode_slice10(AVCodecContext *avctx, void *tdata, 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; + const VLC_MULTI_ELEM *const multi = s->multi[i].table; + const VLCElem *const vlc = s->vlc[i].table; + const int vlc_bits = s->vlc[i].bits; int flags, pred; int ret = init_get_bits8(&gb, s->buf + s->slices[i][j].start, s->slices[i][j].size); @@ -152,20 +177,8 @@ static int magy_decode_slice10(AVCodecContext *avctx, void *tdata, 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] = pix; - } - dst += stride; - } + for (k = 0; k < height; k++) + READ_PLANE(dst, i, 2, 3) } switch (pred) { @@ -247,7 +260,7 @@ static int magy_decode_slice10(AVCodecContext *avctx, void *tdata, static int magy_decode_slice(AVCodecContext *avctx, void *tdata, int j, int threadnr) { - MagicYUVContext *s = avctx->priv_data; + const MagicYUVContext *s = avctx->priv_data; int interlaced = s->interlaced; AVFrame *p = s->p; int i, k, x, min_width; @@ -262,6 +275,9 @@ static int magy_decode_slice(AVCodecContext *avctx, void *tdata, ptrdiff_t fake_stride = p->linesize[i] * (1 + interlaced); ptrdiff_t stride = p->linesize[i]; const uint8_t *slice = s->buf + s->slices[i][j].start; + const VLC_MULTI_ELEM *const multi = s->multi[i].table; + const VLCElem *const vlc = s->vlc[i].table; + const int vlc_bits = s->vlc[i].bits; int flags, pred; flags = bytestream_get_byte(&slice); @@ -281,20 +297,8 @@ static int magy_decode_slice(AVCodecContext *avctx, void *tdata, if (ret < 0) return ret; - 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] = pix; - } - dst += stride; - } + for (k = 0; k < height; k++) + READ_PLANE(dst, i, 1, 7) } switch (pred) { @@ -380,7 +384,7 @@ static int build_huffman(AVCodecContext *avctx, const uint8_t *table, { MagicYUVContext *s = avctx->priv_data; GetByteContext gb; - uint8_t len[4096]; + uint8_t *len = s->len; uint16_t length_count[33] = { 0 }; int i = 0, j = 0, k; @@ -408,7 +412,7 @@ static int build_huffman(AVCodecContext *avctx, const uint8_t *table, if (j == max) { j = 0; - if (huff_build(len, length_count, &s->vlc[i], max, avctx)) { + if (huff_build(avctx, len, length_count, &s->vlc[i], &s->multi[i], max, avctx)) { av_log(avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n"); return AVERROR_INVALIDDATA; } @@ -525,6 +529,16 @@ static int magy_decode_frame(AVCodecContext *avctx, AVFrame *p, s->decorrelate = 1; s->bps = 12; break; + case 0x71: + avctx->pix_fmt = AV_PIX_FMT_GBRP14; + s->decorrelate = 1; + s->bps = 14; + break; + case 0x72: + avctx->pix_fmt = AV_PIX_FMT_GBRAP14; + s->decorrelate = 1; + s->bps = 14; + break; case 0x73: avctx->pix_fmt = AV_PIX_FMT_GRAY10; s->bps = 10; @@ -638,7 +652,7 @@ static int magy_decode_frame(AVCodecContext *avctx, AVFrame *p, return ret; p->pict_type = AV_PICTURE_TYPE_I; - p->key_frame = 1; + p->flags |= AV_FRAME_FLAG_KEY; if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0) return ret; @@ -652,7 +666,9 @@ static int magy_decode_frame(AVCodecContext *avctx, AVFrame *p, 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) { + avctx->pix_fmt == AV_PIX_FMT_GBRAP14|| + avctx->pix_fmt == AV_PIX_FMT_GBRP12|| + avctx->pix_fmt == AV_PIX_FMT_GBRP14) { FFSWAP(uint8_t*, p->data[0], p->data[1]); FFSWAP(int, p->linesize[0], p->linesize[1]); } else { @@ -687,7 +703,8 @@ static av_cold int magy_decode_end(AVCodecContext *avctx) for (i = 0; i < FF_ARRAY_ELEMS(s->slices); i++) { av_freep(&s->slices[i]); s->slices_size[i] = 0; - ff_free_vlc(&s->vlc[i]); + ff_vlc_free(&s->vlc[i]); + ff_vlc_free_multi(&s->multi[i]); } return 0; @@ -695,7 +712,7 @@ static av_cold int magy_decode_end(AVCodecContext *avctx) const FFCodec ff_magicyuv_decoder = { .p.name = "magicyuv", - .p.long_name = NULL_IF_CONFIG_SMALL("MagicYUV video"), + CODEC_LONG_NAME("MagicYUV video"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_MAGICYUV, .priv_data_size = sizeof(MagicYUVContext), @@ -705,5 +722,4 @@ const FFCodec ff_magicyuv_decoder = { .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, };