[FFmpeg-devel] [PATCH] avcodec: add Actimagine VX video decoder

Andreas Rheinhardt andreas.rheinhardt at gmail.com
Mon Mar 15 20:47:10 EET 2021


Florian Nouwt:
> I applied the few changes you suggested. I moved the shared tables to
> h264_cavlc_data.c. Am I supposed to share the actual vlc tables (such
> as "static VLC_TYPE coeff_token_vlc_tables[520+332+280+256][2];")
> which are generated by actimagine_init_static respectively
> ff_h264_decode_init_vlc as well?
> 
Yes, please.


> Op ma 15 mrt. 2021 om 16:10 schreef Florian Nouwt <fnouwt2 at gmail.com>:
>>
>> Signed-off-by: Florian Nouwt <fnouwt2 at gmail.com>
>> ---
>>  Changelog                    |    1 +
>>  configure                    |    1 +
>>  doc/general_contents.texi    |    2 +
>>  libavcodec/Makefile          |    3 +-
>>  libavcodec/actimagine.c      | 1523 ++++++++++++++++++++++++++++++++++
>>  libavcodec/allcodecs.c       |    1 +
>>  libavcodec/codec_desc.c      |    7 +
>>  libavcodec/codec_id.h        |    1 +
>>  libavcodec/h264_cavlc.c      |  135 +--
>>  libavcodec/h264_cavlc_data.c |  140 ++++
>>  libavcodec/h264_cavlc_data.h |   33 +
>>  libavcodec/version.h         |    2 +-
>>  libavformat/riff.c           |    2 +
>>  13 files changed, 1723 insertions(+), 128 deletions(-)
>>  create mode 100644 libavcodec/actimagine.c
>>  create mode 100644 libavcodec/h264_cavlc_data.c
>>  create mode 100644 libavcodec/h264_cavlc_data.h
>>
>> diff --git a/Changelog b/Changelog
>> index a96e350e09..8807f3dcb3 100644
>> --- a/Changelog
>> +++ b/Changelog
>> @@ -83,6 +83,7 @@ version <next>:
>>  - msad video filter
>>  - gophers protocol
>>  - RIST protocol via librist
>> +- Actimagine VX video decoder
>>
>>
>>  version 4.3:
>> diff --git a/configure b/configure
>> index f0ac719d2d..10a07da95f 100755
>> --- a/configure
>> +++ b/configure
>> @@ -2662,6 +2662,7 @@ ac3_fixed_decoder_select="ac3_parser ac3dsp bswapdsp mdct"
>>  ac3_encoder_select="ac3dsp audiodsp mdct me_cmp"
>>  ac3_fixed_encoder_select="ac3dsp audiodsp mdct me_cmp"
>>  acelp_kelvin_decoder_select="audiodsp"
>> +actimagine_decoder_select="bswapdsp golomb"
>>  adpcm_g722_decoder_select="g722dsp"
>>  adpcm_g722_encoder_select="g722dsp"
>>  aic_decoder_select="golomb idctdsp"
>> diff --git a/doc/general_contents.texi b/doc/general_contents.texi
>> index 33ece6e884..d4261386fc 100644
>> --- a/doc/general_contents.texi
>> +++ b/doc/general_contents.texi
>> @@ -807,6 +807,8 @@ following image formats are supported:
>>  @item 8088flex TMV           @tab     @tab  X
>>  @item A64 multicolor         @tab  X  @tab
>>      @tab Creates video suitable to be played on a commodore 64 (multicolor mode).
>> + at item Actimagine VX Video    @tab     @tab  X
>> +    @tab fourcc: vxs1, VXS1
>>  @item Amazing Studio PAF Video @tab     @tab  X
>>  @item American Laser Games MM  @tab    @tab X
>>      @tab Used in games like Mad Dog McCree.
>> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
>> index 81cc16471b..1b90c66925 100644
>> --- a/libavcodec/Makefile
>> +++ b/libavcodec/Makefile
>> @@ -182,6 +182,7 @@ OBJS-$(CONFIG_AC3_ENCODER)             += ac3enc_float.o ac3enc.o ac3tab.o \
>>  OBJS-$(CONFIG_AC3_FIXED_ENCODER)       += ac3enc_fixed.o ac3enc.o ac3tab.o ac3.o kbdwin.o
>>  OBJS-$(CONFIG_AC3_MF_ENCODER)          += mfenc.o mf_utils.o
>>  OBJS-$(CONFIG_ACELP_KELVIN_DECODER)    += g729dec.o lsp.o celp_math.o celp_filters.o acelp_filters.o acelp_pitch_delay.o acelp_vectors.o g729postfilter.o
>> +OBJS-$(CONFIG_ACTIMAGINE_DECODER)      += actimagine.o h264_cavlc_data.o
>>  OBJS-$(CONFIG_AGM_DECODER)             += agm.o
>>  OBJS-$(CONFIG_AIC_DECODER)             += aic.o
>>  OBJS-$(CONFIG_ALAC_DECODER)            += alac.o alac_data.o alacdsp.o
>> @@ -367,7 +368,7 @@ OBJS-$(CONFIG_H264_DECODER)            += h264dec.o h264_cabac.o h264_cavlc.o \
>>                                            h264_direct.o h264_loopfilter.o  \
>>                                            h264_mb.o h264_picture.o \
>>                                            h264_refs.o h264_sei.o \
>> -                                          h264_slice.o h264data.o
>> +                                          h264_slice.o h264data.o h264_cavlc_data.o
>>  OBJS-$(CONFIG_H264_AMF_ENCODER)        += amfenc_h264.o
>>  OBJS-$(CONFIG_H264_CUVID_DECODER)      += cuviddec.o
>>  OBJS-$(CONFIG_H264_MEDIACODEC_DECODER) += mediacodecdec.o
>> diff --git a/libavcodec/actimagine.c b/libavcodec/actimagine.c
>> new file mode 100644
>> index 0000000000..f495426869
>> --- /dev/null
>> +++ b/libavcodec/actimagine.c
>> @@ -0,0 +1,1523 @@
>> +/*
>> + * Actimagine VX Video decoder
>> + * Copyright (c) 2021 Florian Nouwt
>> + *
>> + * This file is part of FFmpeg.
>> + *
>> + * 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.
>> + *
>> + * 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 FFmpeg; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>> + */
>> +
>> +#include <inttypes.h>
>> +
>> +#include "libavutil/avassert.h"
>> +#include "libavutil/thread.h"
>> +
>> +#include "avcodec.h"
>> +#include "bytestream.h"
>> +#include "bswapdsp.h"
>> +#include "get_bits.h"
>> +#include "golomb.h"
>> +#include "internal.h"
>> +#include "h264_cavlc_data.h"
>> +
>> +static const uint8_t predict_dc_shift_tab[] = {1, 2, 3, 0, 4};
>> +
>> +static const uint8_t zigzag4x4_tab[] =
>> +{
>> +    0x00, 0x04, 0x01, 0x02, 0x05, 0x08, 0x0C, 0x09,
>> +    0x06, 0x03, 0x07, 0x0A, 0x0D, 0x0E, 0x0B, 0x0F
>> +};
>> +
>> +static const uint8_t quant4x4_tab[][8] =
>> +{
>> +    { 0x0A, 0x0D, 0x0A, 0x0D, 0x0D, 0x10, 0x0D, 0x10 },
>> +    { 0x0B, 0x0E, 0x0B, 0x0E, 0x0E, 0x12, 0x0E, 0x12 },
>> +    { 0x0D, 0x10, 0x0D, 0x10, 0x10, 0x14, 0x10, 0x14 },
>> +    { 0x0E, 0x12, 0x0E, 0x12, 0x12, 0x17, 0x12, 0x17 },
>> +    { 0x10, 0x14, 0x10, 0x14, 0x14, 0x19, 0x14, 0x19 },
>> +    { 0x12, 0x17, 0x12, 0x17, 0x17, 0x1D, 0x17, 0x1D }
>> +};
>> +
>> +static const uint8_t old_mb_mode_remap_tab[] =
>> +{
>> +     1,  2,  0,  4,  7,  3, 11, 15,  9,  5, 14,  6,
>> +    12, 13,  8, 16, 23, 10, 22, 19, 20, 17, 21, 18
>> +};
>> +
>> +static const uint8_t residu_mask_old_tab[] =
>> +{
>> +    0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x03, 0x05,
>> +    0x0A, 0x0C, 0x0F, 0x1F, 0x07, 0x0B, 0x0D, 0x0E,
>> +    0x06, 0x09, 0x13, 0x15, 0x1A, 0x1C, 0x11, 0x12,
>> +    0x14, 0x18, 0x17, 0x1B, 0x1D, 0x1E, 0x16, 0x19
>> +};
>> +
>> +static const uint8_t residu_mask_new_tab[] =
>> +{
>> +    0x00, 0x08, 0x04, 0x02, 0x01, 0x1F, 0x0F, 0x0A,
>> +    0x05, 0x0C, 0x03, 0x10, 0x0E, 0x0D, 0x0B, 0x07,
>> +    0x09, 0x06, 0x1E, 0x1B, 0x1A, 0x1D, 0x17, 0x15,
>> +    0x18, 0x12, 0x11, 0x1C, 0x14, 0x13, 0x16, 0x19
>> +};
>> +
>> +static const int cavlc_suffix_len_update_tab[] =
>> +{
>> +    2, 5, 11, 23, 47, 32768
>> +};
>> +
>> +static const uint8_t coeff_token_table_index[17] =
>> +{
>> +    0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3
>> +};
>> +
>> +typedef struct MVec {
>> +    int x, y;
>> +} MVec;
>> +
>> +typedef struct ActimagineContext {
>> +    AVFrame *cur_frame;
>> +    AVFrame *ref_frames[3];
>> +    int      ref_frame_count;
>> +
>> +    int version;
>> +    int quantizer;
>> +    int avi;
>> +
>> +    GetBitContext gb;
>> +
>> +    uint8_t *bitstream;
>> +    int bitstream_size;
>> +
>> +    int qtab[2][4];
>> +
>> +    uint8_t pred4_cache[5][5];
>> +
>> +    MVec *vectors;
>> +    int   vectors_stride;
>> +
>> +    uint8_t *total_coeff_y;
>> +    int      total_coeff_y_stride;
>> +
>> +    uint8_t *total_coeff_uv;
>> +    int      total_coeff_uv_stride;
>> +
>> +    BswapDSPContext bdsp;
>> +} ActimagineContext;
>> +
>> +static VLC coeff_token_vlc[4];
>> +static VLC_TYPE coeff_token_vlc_tables[520+332+280+256][2];
>> +static const int coeff_token_vlc_tables_size[4]={520,332,280,256};
>> +
>> +static VLC total_zeros_vlc[15+1];
>> +static VLC_TYPE total_zeros_vlc_tables[15][512][2];
>> +static const int total_zeros_vlc_tables_size = 512;
>> +
>> +static VLC run_vlc[6+1];
>> +static VLC_TYPE run_vlc_tables[6][8][2];
>> +static const int run_vlc_tables_size = 8;
>> +
>> +static VLC run7_vlc;
>> +static VLC_TYPE run7_vlc_table[96][2];
>> +static const int run7_vlc_table_size = 96;
>> +
>> +#define COEFF_TOKEN_VLC_BITS    8
>> +#define TOTAL_ZEROS_VLC_BITS    9
>> +#define RUN_VLC_BITS            3
>> +#define RUN7_VLC_BITS           6
>> +
>> +#define PIXEL_REF(s, ref, plane, x, y)\
>> +    ((s)->ref_frames[(ref)]->data[(plane)]\
>> +        [(y) * (s)->ref_frames[(ref)]->linesize[(plane)] + (x)])
>> +
>> +#define PIXEL_CUR(s, plane, x, y)\
>> +    ((s)->cur_frame->data[(plane)]\
>> +        [(y) * (s)->cur_frame->linesize[(plane)] + (x)])
>> +
>> +#define PREDICT2(a,b)       (((a) + (b) + 1) >> 1)
>> +#define PREDICT3(a,b,c)     (((a) + 2 * (b) + (c) + 2) >> 2)
>> +
>> +#define VX_VERSION_INVALID  -1
>> +#define VX_VERSION_OLD       0
>> +#define VX_VERSION_NEW       1
>> +
>> +static av_cold void actimagine_init_static(void)
>> +{
>> +    // all these tables are equal to the ones used for h264 cavlc
>> +    int offset = 0;
>> +    for (int i = 0; i < 4; i++) {
>> +        coeff_token_vlc[i].table = coeff_token_vlc_tables + offset;
>> +        coeff_token_vlc[i].table_allocated = coeff_token_vlc_tables_size[i];
>> +        init_vlc(&coeff_token_vlc[i], COEFF_TOKEN_VLC_BITS, 4 * 17,
>> +                 &ff_h264_cavlc_coeff_token_len [i][0], 1, 1,
>> +                 &ff_h264_cavlc_coeff_token_bits[i][0], 1, 1,
>> +                 INIT_VLC_USE_NEW_STATIC);
>> +        offset += coeff_token_vlc_tables_size[i];
>> +    }
>> +    /*
>> +     * This is a one time safety check to make sure that
>> +     * the packed static coeff_token_vlc table sizes
>> +     * were initialized correctly.
>> +     */
>> +    av_assert0(offset == FF_ARRAY_ELEMS(coeff_token_vlc_tables));
>> +
>> +    for (int i = 0; i < 15; i++) {
>> +        total_zeros_vlc[i + 1].table = total_zeros_vlc_tables[i];
>> +        total_zeros_vlc[i + 1].table_allocated = total_zeros_vlc_tables_size;
>> +        init_vlc(&total_zeros_vlc[i + 1],
>> +                 TOTAL_ZEROS_VLC_BITS, 16,
>> +                 &ff_h264_cavlc_total_zeros_len [i][0], 1, 1,
>> +                 &ff_h264_cavlc_total_zeros_bits[i][0], 1, 1,
>> +                 INIT_VLC_USE_NEW_STATIC);
>> +    }
>> +
>> +    for (int i = 0; i < 6; i++) {
>> +        run_vlc[i + 1].table = run_vlc_tables[i];
>> +        run_vlc[i + 1].table_allocated = run_vlc_tables_size;
>> +        init_vlc(&run_vlc[i + 1],
>> +                 RUN_VLC_BITS, 7,
>> +                 &ff_h264_cavlc_run_len [i][0], 1, 1,
>> +                 &ff_h264_cavlc_run_bits[i][0], 1, 1,
>> +                 INIT_VLC_USE_NEW_STATIC);
>> +    }
>> +
>> +    run7_vlc.table = run7_vlc_table,
>> +    run7_vlc.table_allocated = run7_vlc_table_size;
>> +    init_vlc(&run7_vlc, RUN7_VLC_BITS, 16,
>> +             &ff_h264_cavlc_run_len [6][0], 1, 1,
>> +             &ff_h264_cavlc_run_bits[6][0], 1, 1,
>> +             INIT_VLC_USE_NEW_STATIC);
>> +}
>> +
>> +static int setup_qtables(AVCodecContext *avctx, int quantizer)
>> +{
>> +    int qx, qy;
>> +    ActimagineContext *s = avctx->priv_data;
>> +
>> +    if (quantizer < 12 || quantizer > 161)
>> +        return AVERROR_INVALIDDATA;
>> +
>> +    s->quantizer = quantizer;
>> +
>> +    qx = quantizer % 6;
>> +    qy = quantizer / 6;
>> +
>> +    for (int i = 0; i < 2; i++)
>> +        for (int j = 0; j < 4; j++)
>> +            s->qtab[i][j] = quant4x4_tab[qx][4 * i + j] << qy;
>> +
>> +    return 0;
>> +}
>> +
>> +static av_cold int actimagine_init(AVCodecContext *avctx)
>> +{
>> +    int vectors_size;
>> +    int total_coeff_y_size;
>> +    int total_coeff_uv_size;
>> +    static AVOnce init_static_once = AV_ONCE_INIT;
>> +    ActimagineContext *s = avctx->priv_data;
>> +
>> +    if (avctx->width & 15 || avctx->height & 15) {
>> +        av_log(avctx, AV_LOG_ERROR, "width/height not multiple of 16\n");
>> +        return AVERROR_INVALIDDATA;
>> +    }
>> +
>> +    ff_bswapdsp_init(&s->bdsp);
>> +
>> +    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
>> +    avctx->color_range = AVCOL_RANGE_JPEG;
>> +    avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
>> +    // the color space of this video format is not supported currently
>> +    // it is a yuv approximation that can be converted back to rgb using bitshifts
>> +    // r = y + (v << 1)
>> +    // g = y - (u >> 1) - v
>> +    // b = y + (u << 1)
>> +    avctx->colorspace = AVCOL_SPC_NB;
>> +
>> +    // predict4 cache
>> +    for (int i = 0; i < 5; i++)
>> +        for (int j = 0; j < 5; j++)
>> +            s->pred4_cache[i][j] = 9;
>> +
>> +    // motion vector cache
>> +    s->vectors_stride = (avctx->width >> 4) + 2;
>> +    vectors_size = ((avctx->height >> 4) + 1) * s->vectors_stride;
>> +    s->vectors = av_calloc(vectors_size, sizeof(MVec));
>> +    if (!s->vectors)
>> +        return AVERROR(ENOMEM);
>> +
>> +    // total dct coefficient cache for luma
>> +    s->total_coeff_y_stride = (avctx->width >> 2) + 1;
>> +    total_coeff_y_size = ((avctx->height >> 2) + 1) * s->total_coeff_y_stride;
>> +    s->total_coeff_y = av_mallocz(total_coeff_y_size);
>> +    if (!s->total_coeff_y)
>> +        return AVERROR(ENOMEM);
>> +
>> +    // total dct coefficient cache for chroma
>> +    s->total_coeff_uv_stride = (avctx->width >> 3) + 1;
>> +    total_coeff_uv_size = ((avctx->height >> 3) + 1) * s->total_coeff_uv_stride;
>> +    s->total_coeff_uv = av_mallocz(total_coeff_uv_size);
>> +    if (!s->total_coeff_uv)
>> +        return AVERROR(ENOMEM);
>> +
>> +    s->ref_frame_count = 0;
>> +    for (int i = 0; i < 3; i++) {
>> +        s->ref_frames[i] = av_frame_alloc();
>> +        if (!s->ref_frames[i])
>> +            return AVERROR(ENOMEM);
>> +    }
>> +    s->cur_frame = av_frame_alloc();
>> +    if (!s->cur_frame)
>> +        return AVERROR(ENOMEM);
>> +
>> +    s->version = VX_VERSION_INVALID;
>> +    s->quantizer = -1;
>> +    s->avi = 0;
>> +
>> +    // when the source is an avi file, the quantizer is stored in the extradata
>> +    if (avctx->extradata_size == 4)
>> +        if (!setup_qtables(avctx, AV_RL32(avctx->extradata)))
>> +            s->avi = 1;
>> +
>> +    ff_thread_once(&init_static_once, actimagine_init_static);
>> +
>> +    return 0;
>> +}
>> +
>> +static void clear_total_coeff(AVCodecContext *avctx, int x, int y, int w, int h)
>> +{
>> +    ActimagineContext *s = avctx->priv_data;
>> +
>> +    // luma
>> +    uint8_t *total_coeff = &s->total_coeff_y[
>> +        ((y >> 2) + 1) * s->total_coeff_y_stride + (x >> 2) + 1];
>> +
>> +    for (int y2 = 0; y2 < (h >> 2); y2++)
>> +        for (int x2 = 0; x2 < (w >> 2); x2++)
>> +            total_coeff[y2 * s->total_coeff_y_stride + x2] = 0;
>> +
>> +    // chroma
>> +    total_coeff = &s->total_coeff_uv[
>> +        ((y >> 3) + 1) * s->total_coeff_uv_stride + (x >> 3) + 1];
>> +
>> +    for (int y2 = 0; y2 < (h >> 3); y2++)
>> +        for (int x2 = 0; x2 < (w >> 3); x2++)
>> +            total_coeff[y2 * s->total_coeff_uv_stride + x2] = 0;
>> +}
>> +
>> +static void predict_plane_intern(AVCodecContext *avctx, int x, int y,
>> +                                 int w, int h, int plane)
>> +{
>> +    ActimagineContext *s = avctx->priv_data;
>> +    if (w == 1 && h == 1)
>> +        return;
>> +    if (w == 1 && h != 1) {
>> +        uint8_t top    = PIXEL_CUR(s, plane, x, y - 1);
>> +        uint8_t bottom = PIXEL_CUR(s, plane, x, y + h - 1);
>> +        PIXEL_CUR(s, plane, x, y + (h >> 1) - 1) = (top + bottom) >> 1;
>> +        predict_plane_intern(avctx, x, y, 1, h >> 1, plane);
>> +        predict_plane_intern(avctx, x, y + (h >> 1), 1, h >> 1, plane);
>> +    } else if (w != 1 && h == 1) {
>> +        uint8_t left  = PIXEL_CUR(s, plane, x - 1, y);
>> +        uint8_t right = PIXEL_CUR(s, plane, x + w - 1, y);
>> +        PIXEL_CUR(s, plane, x + (w >> 1) - 1, y) = (left + right) >> 1;
>> +        predict_plane_intern(avctx, x, y, w >> 1, 1, plane);
>> +        predict_plane_intern(avctx, x + (w >> 1), y, w >> 1, 1, plane);
>> +    } else {
>> +        uint8_t bottom_left  = PIXEL_CUR(s, plane, x - 1, y + h - 1);
>> +        uint8_t top_right    = PIXEL_CUR(s, plane, x + w - 1, y - 1);
>> +        uint8_t bottom_right = PIXEL_CUR(s, plane, x + w - 1, y + h - 1);
>> +        uint8_t bottom_center = (bottom_left + bottom_right) >> 1;
>> +        uint8_t center_right = (top_right + bottom_right) >> 1;
>> +        PIXEL_CUR(s, plane, x + (w >> 1) - 1, y + h - 1) = bottom_center;
>> +        PIXEL_CUR(s, plane, x + w - 1, y + (h >> 1) - 1) = center_right;
>> +        if ((w == 4 || w == 16) ^ (h == 4 || h == 16)) {
>> +            uint8_t center_left = PIXEL_CUR(s, plane, x - 1, y + (h >> 1) - 1);
>> +            PIXEL_CUR(s, plane, x + (w >> 1) - 1, y + (h >> 1) - 1)
>> +                = (center_left + center_right) >> 1;
>> +        } else {
>> +            uint8_t top_center = PIXEL_CUR(s, plane, x + (w >> 1) - 1, y - 1);
>> +            PIXEL_CUR(s, plane, x + (w >> 1) - 1, y + (h >> 1) - 1)
>> +                = (top_center + bottom_center) >> 1;
>> +        }
>> +        predict_plane_intern(avctx, x, y, w >> 1, h >> 1, plane);
>> +        predict_plane_intern(avctx, x + (w >> 1), y, w >> 1, h >> 1, plane);
>> +        predict_plane_intern(avctx, x, y + (h >> 1), w >> 1, h >> 1, plane);
>> +        predict_plane_intern(avctx, x + (w >> 1), y + (h >> 1), w >> 1, h >> 1,
>> +                             plane);
>> +    }
>> +}
>> +
>> +static void predict_plane(AVCodecContext *avctx, int x, int y, int w, int h,
>> +                          int plane, int param)
>> +{
>> +    ActimagineContext *s = avctx->priv_data;
>> +    uint8_t bottom_left = PIXEL_CUR(s, plane, x - 1, y + h - 1);
>> +    uint8_t top_right   = PIXEL_CUR(s, plane, x + w - 1, y - 1);
>> +    PIXEL_CUR(s, plane, x + w - 1, y + h - 1)
>> +        = ((bottom_left + top_right + 1) >> 1) + param;
>> +    predict_plane_intern(avctx, x, y, w, h, plane);
>> +}
>> +
>> +static int predict_mb_plane(AVCodecContext *avctx, int x, int y, int w, int h)
>> +{
>> +    ActimagineContext *s = avctx->priv_data;
>> +    GetBitContext *gb = &s->gb;
>> +    // y
>> +    int param = get_se_golomb(gb);
>> +    if (param < -(1 << 16) || param >= (1 << 16)) {
>> +        av_log(avctx, AV_LOG_ERROR, "invalid plane param\n");
>> +        return AVERROR_INVALIDDATA;
>> +    }
>> +    predict_plane(avctx, x, y, w, h, 0, param << 1);
>> +
>> +    // u
>> +    param = get_se_golomb(gb);
>> +    if (param < -(1 << 16) || param >= (1 << 16)) {
>> +        av_log(avctx, AV_LOG_ERROR, "invalid plane param\n");
>> +        return AVERROR_INVALIDDATA;
>> +    }
>> +    predict_plane(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 1, param << 1);
>> +
>> +    // v
>> +    param = get_se_golomb(gb);
>> +    if (param < -(1 << 16) || param >= (1 << 16)) {
>> +        av_log(avctx, AV_LOG_ERROR, "invalid plane param\n");
>> +        return AVERROR_INVALIDDATA;
>> +    }
>> +    predict_plane(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 2, param << 1);
>> +
>> +    return 0;
>> +}
>> +
>> +static void predict_horizontal(AVCodecContext *avctx, int x, int y,
>> +                               int w, int h, int plane)
>> +{
>> +    ActimagineContext *s = avctx->priv_data;
>> +    for (int y2 = 0; y2 < h; y2++) {
>> +        uint8_t pixel = PIXEL_CUR(s, plane, x - 1, y + y2);
>> +        for (int x2 = 0; x2 < w; x2++)
>> +            PIXEL_CUR(s, plane, x + x2, y + y2) = pixel;
>> +    }
>> +}
>> +
>> +static void predict_vertical(AVCodecContext *avctx, int x, int y,
>> +                             int w, int h, int plane)
>> +{
>> +    ActimagineContext *s = avctx->priv_data;
>> +    for (int y2 = 0; y2 < h; y2++)
>> +        for (int x2 = 0; x2 < w; x2++)
>> +            PIXEL_CUR(s, plane, x + x2, y + y2)
>> +                = PIXEL_CUR(s, plane, x + x2, y - 1);
>> +}
>> +
>> +static void predict_dc(AVCodecContext *avctx, int x, int y, int w, int h,
>> +                       int plane)
>> +{
>> +    uint8_t dc;
>> +    ActimagineContext *s = avctx->priv_data;
>> +    if (x != 0 && y != 0) {
>> +        int sum_h, sum_v;
>> +        sum_h = w >> 1;
>> +        for (int x2 = 0; x2 < w; x2++)
>> +            sum_h += PIXEL_CUR(s, plane, x + x2, y - 1);
>> +        sum_h >>= predict_dc_shift_tab[w >> 2];
>> +
>> +        sum_v = h >> 1;
>> +        for (int y2 = 0; y2 < h; y2++)
>> +            sum_v += PIXEL_CUR(s, plane, x - 1, y + y2);
>> +        sum_v >>= predict_dc_shift_tab[h >> 2];
>> +
>> +        dc = (sum_h + sum_v + 1) >> 1;
>> +    } else if (x == 0 && y != 0) {
>> +        int sum = w >> 1;
>> +        for (int x2 = 0; x2 < w; x2++)
>> +            sum += PIXEL_CUR(s, plane, x + x2, y - 1);
>> +        dc = sum >> predict_dc_shift_tab[w >> 2];
>> +    } else if (x != 0 && y == 0) {
>> +        int sum = h >> 1;
>> +        for (int y2 = 0; y2 < h; y2++)
>> +            sum += PIXEL_CUR(s, plane, x - 1, y + y2);
>> +        dc = sum >> predict_dc_shift_tab[h >> 2];
>> +    } else
>> +        dc = 128;
>> +
>> +    for (int y2 = 0; y2 < h; y2++)
>> +        for (int x2 = 0; x2 < w; x2++)
>> +            PIXEL_CUR(s, plane, x + x2, y + y2) = dc;
>> +}
>> +
>> +static int predict_notile_uv(AVCodecContext *avctx, int x, int y, int w, int h)
>> +{
>> +    ActimagineContext *s = avctx->priv_data;
>> +    GetBitContext *gb = &s->gb;
>> +    int mode_uv = get_ue_golomb_31(gb);
>> +    switch (mode_uv) {
>> +    case 0:// dc
>> +        predict_dc(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 1);
>> +        predict_dc(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 2);
>> +        break;
>> +    case 1:// horizontal
>> +        predict_horizontal(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 1);
>> +        predict_horizontal(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 2);
>> +        break;
>> +    case 2:// vertical
>> +        predict_vertical(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 1);
>> +        predict_vertical(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 2);
>> +        break;
>> +    case 3:// plane
>> +        predict_plane(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 1, 0);
>> +        predict_plane(avctx, x >> 1, y >> 1, w >> 1, h >> 1, 2, 0);
>> +        break;
>> +    default:
>> +        av_log(avctx, AV_LOG_ERROR, "invalid predict notile uv mode\n");
>> +        return AVERROR_INVALIDDATA;
>> +    }
>> +    return 0;
>> +}
>> +
>> +static int predict_notile(AVCodecContext *avctx, int x, int y, int w, int h)
>> +{
>> +    ActimagineContext *s = avctx->priv_data;
>> +    GetBitContext *gb = &s->gb;
>> +    int mode_y = get_ue_golomb_31(gb);
>> +    switch (mode_y) {
>> +    case 0:// vertical
>> +        predict_vertical(avctx, x, y, w, h, 0);
>> +        break;
>> +    case 1:// horizontal
>> +        predict_horizontal(avctx, x, y, w, h, 0);
>> +        break;
>> +    case 2:// dc
>> +        predict_dc(avctx, x, y, w, h, 0);
>> +        break;
>> +    case 3:// plane
>> +        predict_plane(avctx, x, y, w, h, 0, 0);
>> +        break;
>> +    default:
>> +        av_log(avctx, AV_LOG_ERROR, "invalid predict notile y mode\n");
>> +        return AVERROR_INVALIDDATA;
>> +    }
>> +    return predict_notile_uv(avctx, x, y, w, h);
>> +}
>> +
>> +// slightly different from the common dc prediction method
>> +static void predict4_dc(AVCodecContext *avctx, int x, int y)
>> +{
>> +    uint8_t dc;
>> +    ActimagineContext *s = avctx->priv_data;
>> +    if (x == 0 && y == 0)
>> +        dc = 128;
>> +    else {
>> +        int sum   = 0;
>> +        int shift = 1;
>> +
>> +        if (x != 0) {
>> +            shift++;
>> +            for (int y2 = 0; y2 < 4; y2++)
>> +                sum += PIXEL_CUR(s, 0, x - 1, y + y2);
>> +            sum += 2;
>> +        }
>> +
>> +        if (y != 0) {
>> +            shift++;
>> +            for (int x2 = 0; x2 < 4; x2++)
>> +                sum += PIXEL_CUR(s, 0, x + x2, y - 1);
>> +            sum += 2;
>> +        }
>> +
>> +        dc = sum >> shift;
>> +    }
>> +
>> +    for (int y2 = 0; y2 < 4; y2++)
>> +        for (int x2 = 0; x2 < 4; x2++)
>> +            PIXEL_CUR(s, 0, x + x2, y + y2) = dc;
>> +}
>> +
>> +static void predict4_diagonal_down_left(AVCodecContext *avctx, int x, int y)
>> +{
>> +    uint8_t val;
>> +    ActimagineContext *s = avctx->priv_data;
>> +
>> +    uint8_t a = PIXEL_CUR(s, 0, x + 0, y - 1);
>> +    uint8_t b = PIXEL_CUR(s, 0, x + 1, y - 1);
>> +    uint8_t c = PIXEL_CUR(s, 0, x + 2, y - 1);
>> +    uint8_t d = PIXEL_CUR(s, 0, x + 3, y - 1);
>> +    uint8_t e = PIXEL_CUR(s, 0, x + 4, y - 1);
>> +    uint8_t f = PIXEL_CUR(s, 0, x + 5, y - 1);
>> +    uint8_t g = PIXEL_CUR(s, 0, x + 6, y - 1);
>> +    uint8_t h = PIXEL_CUR(s, 0, x + 7, y - 1);
>> +
>> +    PIXEL_CUR(s, 0, x, y) = PREDICT3(a, b, c);
>> +
>> +    val = PREDICT3(b, c, d);
>> +    PIXEL_CUR(s, 0, x + 1, y + 0) = val;
>> +    PIXEL_CUR(s, 0, x + 0, y + 1) = val;
>> +
>> +    val = PREDICT3(c, d, e);
>> +    PIXEL_CUR(s, 0, x + 2, y + 0) = val;
>> +    PIXEL_CUR(s, 0, x + 1, y + 1) = val;
>> +    PIXEL_CUR(s, 0, x + 0, y + 2) = val;
>> +
>> +    val = PREDICT3(d, e, f);
>> +    PIXEL_CUR(s, 0, x + 3, y + 0) = val;
>> +    PIXEL_CUR(s, 0, x + 2, y + 1) = val;
>> +    PIXEL_CUR(s, 0, x + 1, y + 2) = val;
>> +    PIXEL_CUR(s, 0, x + 0, y + 3) = val;
>> +
>> +    val = PREDICT3(e, f, g);
>> +    PIXEL_CUR(s, 0, x + 3, y + 1) = val;
>> +    PIXEL_CUR(s, 0, x + 2, y + 2) = val;
>> +    PIXEL_CUR(s, 0, x + 1, y + 3) = val;
>> +
>> +    val = PREDICT3(f, g, h);
>> +    PIXEL_CUR(s, 0, x + 3, y + 2) = val;
>> +    PIXEL_CUR(s, 0, x + 2, y + 3) = val;
>> +
>> +    PIXEL_CUR(s, 0, x + 3, y + 3) = PREDICT3(g, h, h);
>> +}
>> +
>> +static void predict4_diagonal_down_right(AVCodecContext *avctx, int x, int y)
>> +{
>> +    uint8_t val;
>> +    ActimagineContext *s = avctx->priv_data;
>> +
>> +    uint8_t a = PIXEL_CUR(s, 0, x + 0, y - 1);
>> +    uint8_t b = PIXEL_CUR(s, 0, x + 1, y - 1);
>> +    uint8_t c = PIXEL_CUR(s, 0, x + 2, y - 1);
>> +    uint8_t d = PIXEL_CUR(s, 0, x + 3, y - 1);
>> +
>> +    uint8_t i = PIXEL_CUR(s, 0, x - 1, y + 0);
>> +    uint8_t j = PIXEL_CUR(s, 0, x - 1, y + 1);
>> +    uint8_t k = PIXEL_CUR(s, 0, x - 1, y + 2);
>> +    uint8_t l = PIXEL_CUR(s, 0, x - 1, y + 3);
>> +
>> +    uint8_t m = PIXEL_CUR(s, 0, x - 1, y - 1);
>> +
>> +    PIXEL_CUR(s, 0, x + 0, y + 3) = PREDICT3(j, k, l);
>> +
>> +    val = PREDICT3(i, j, k);
>> +    PIXEL_CUR(s, 0, x + 0, y + 2) = val;
>> +    PIXEL_CUR(s, 0, x + 1, y + 3) = val;
>> +
>> +    val = PREDICT3(m, i, j);
>> +    PIXEL_CUR(s, 0, x + 0, y + 1) = val;
>> +    PIXEL_CUR(s, 0, x + 1, y + 2) = val;
>> +    PIXEL_CUR(s, 0, x + 2, y + 3) = val;
>> +
>> +    val = PREDICT3(i, m, a);
>> +    PIXEL_CUR(s, 0, x + 0, y + 0) = val;
>> +    PIXEL_CUR(s, 0, x + 1, y + 1) = val;
>> +    PIXEL_CUR(s, 0, x + 2, y + 2) = val;
>> +    PIXEL_CUR(s, 0, x + 3, y + 3) = val;
>> +
>> +    val = PREDICT3(m, a, b);
>> +    PIXEL_CUR(s, 0, x + 1, y + 0) = val;
>> +    PIXEL_CUR(s, 0, x + 2, y + 1) = val;
>> +    PIXEL_CUR(s, 0, x + 3, y + 2) = val;
>> +
>> +    val = PREDICT3(a, b, c);
>> +    PIXEL_CUR(s, 0, x + 2, y + 0) = val;
>> +    PIXEL_CUR(s, 0, x + 3, y + 1) = val;
>> +
>> +    PIXEL_CUR(s, 0, x + 3, y + 0) = PREDICT3(b, c, d);
>> +}
>> +
>> +static void predict4_vertical_right(AVCodecContext *avctx, int x, int y)
>> +{
>> +    uint8_t val;
>> +    ActimagineContext *s = avctx->priv_data;
>> +
>> +    uint8_t a = PIXEL_CUR(s, 0, x + 0, y - 1);
>> +    uint8_t b = PIXEL_CUR(s, 0, x + 1, y - 1);
>> +    uint8_t c = PIXEL_CUR(s, 0, x + 2, y - 1);
>> +    uint8_t d = PIXEL_CUR(s, 0, x + 3, y - 1);
>> +
>> +    uint8_t i = PIXEL_CUR(s, 0, x - 1, y + 0);
>> +    uint8_t j = PIXEL_CUR(s, 0, x - 1, y + 1);
>> +    uint8_t k = PIXEL_CUR(s, 0, x - 1, y + 2);
>> +
>> +    uint8_t m = PIXEL_CUR(s, 0, x - 1, y - 1);
>> +
>> +    PIXEL_CUR(s, 0, x + 0, y + 3) = PREDICT3(i, j, k);
>> +    PIXEL_CUR(s, 0, x + 0, y + 2) = PREDICT3(m, i, j);
>> +
>> +    val = PREDICT3(a, m, i);
>> +    PIXEL_CUR(s, 0, x + 0, y + 1) = val;
>> +    PIXEL_CUR(s, 0, x + 1, y + 3) = val;
>> +
>> +    val = PREDICT2(a, m);
>> +    PIXEL_CUR(s, 0, x + 0, y + 0) = val;
>> +    PIXEL_CUR(s, 0, x + 1, y + 2) = val;
>> +
>> +    val = PREDICT3(b, a, m);
>> +    PIXEL_CUR(s, 0, x + 1, y + 1) = val;
>> +    PIXEL_CUR(s, 0, x + 2, y + 3) = val;
>> +
>> +    val = PREDICT2(b, a);
>> +    PIXEL_CUR(s, 0, x + 1, y + 0) = val;
>> +    PIXEL_CUR(s, 0, x + 2, y + 2) = val;
>> +
>> +    val = PREDICT3(c, b, a);
>> +    PIXEL_CUR(s, 0, x + 2, y + 1) = val;
>> +    PIXEL_CUR(s, 0, x + 3, y + 3) = val;
>> +
>> +    val = PREDICT2(c, b);
>> +    PIXEL_CUR(s, 0, x + 2, y + 0) = val;
>> +    PIXEL_CUR(s, 0, x + 3, y + 2) = val;
>> +
>> +    PIXEL_CUR(s, 0, x + 3, y + 1) = PREDICT3(d, c, b);
>> +    PIXEL_CUR(s, 0, x + 3, y + 0) = PREDICT2(d, c);
>> +}
>> +
>> +static void predict4_horizontal_down(AVCodecContext *avctx, int x, int y)
>> +{
>> +    uint8_t val;
>> +    ActimagineContext *s = avctx->priv_data;
>> +
>> +    uint8_t a = PIXEL_CUR(s, 0, x + 0, y - 1);
>> +    uint8_t b = PIXEL_CUR(s, 0, x + 1, y - 1);
>> +    uint8_t c = PIXEL_CUR(s, 0, x + 2, y - 1);
>> +
>> +    uint8_t i = PIXEL_CUR(s, 0, x - 1, y + 0);
>> +    uint8_t j = PIXEL_CUR(s, 0, x - 1, y + 1);
>> +    uint8_t k = PIXEL_CUR(s, 0, x - 1, y + 2);
>> +    uint8_t l = PIXEL_CUR(s, 0, x - 1, y + 3);
>> +
>> +    uint8_t m = PIXEL_CUR(s, 0, x - 1, y - 1);
>> +
>> +    PIXEL_CUR(s, 0, x + 0, y + 3) = PREDICT2(k, l);
>> +    PIXEL_CUR(s, 0, x + 1, y + 3) = PREDICT3(j, k, l);
>> +
>> +    val = PREDICT2(j, k);
>> +    PIXEL_CUR(s, 0, x + 0, y + 2) = val;
>> +    PIXEL_CUR(s, 0, x + 2, y + 3) = val;
>> +
>> +    val = PREDICT3(i, j, k);
>> +    PIXEL_CUR(s, 0, x + 1, y + 2) = val;
>> +    PIXEL_CUR(s, 0, x + 3, y + 3) = val;
>> +
>> +    val = PREDICT2(i, j);
>> +    PIXEL_CUR(s, 0, x + 0, y + 1) = val;
>> +    PIXEL_CUR(s, 0, x + 2, y + 2) = val;
>> +
>> +    val = PREDICT3(m, i, j);
>> +    PIXEL_CUR(s, 0, x + 1, y + 1) = val;
>> +    PIXEL_CUR(s, 0, x + 3, y + 2) = val;
>> +
>> +    val = PREDICT2(i, m);
>> +    PIXEL_CUR(s, 0, x + 0, y + 0) = val;
>> +    PIXEL_CUR(s, 0, x + 2, y + 1) = val;
>> +
>> +    val = PREDICT3(i, m, a);
>> +    PIXEL_CUR(s, 0, x + 1, y + 0) = val;
>> +    PIXEL_CUR(s, 0, x + 3, y + 1) = val;
>> +
>> +    PIXEL_CUR(s, 0, x + 2, y + 0) = PREDICT3(m, a, b);
>> +    PIXEL_CUR(s, 0, x + 3, y + 0) = PREDICT3(a, b, c);
>> +}
>> +
>> +static void predict4_vertical_left(AVCodecContext *avctx, int x, int y)
>> +{
>> +    uint8_t val;
>> +    ActimagineContext *s = avctx->priv_data;
>> +
>> +    uint8_t a = PIXEL_CUR(s, 0, x + 0, y - 1);
>> +    uint8_t b = PIXEL_CUR(s, 0, x + 1, y - 1);
>> +    uint8_t c = PIXEL_CUR(s, 0, x + 2, y - 1);
>> +    uint8_t d = PIXEL_CUR(s, 0, x + 3, y - 1);
>> +    uint8_t e = PIXEL_CUR(s, 0, x + 4, y - 1);
>> +    uint8_t f = PIXEL_CUR(s, 0, x + 5, y - 1);
>> +    uint8_t g = PIXEL_CUR(s, 0, x + 6, y - 1);
>> +
>> +    PIXEL_CUR(s, 0, x + 3, y + 3) = PREDICT3(e, f, g);
>> +    PIXEL_CUR(s, 0, x + 3, y + 2) = PREDICT2(e, f);
>> +
>> +    val = PREDICT3(d, e, f);
>> +    PIXEL_CUR(s, 0, x + 3, y + 1) = val;
>> +    PIXEL_CUR(s, 0, x + 2, y + 3) = val;
>> +
>> +    val = PREDICT2(d, e);
>> +    PIXEL_CUR(s, 0, x + 3, y + 0) = val;
>> +    PIXEL_CUR(s, 0, x + 2, y + 2) = val;
>> +
>> +    val = PREDICT3(c, d, e);
>> +    PIXEL_CUR(s, 0, x + 2, y + 1) = val;
>> +    PIXEL_CUR(s, 0, x + 1, y + 3) = val;
>> +
>> +    val = PREDICT2(c, d);
>> +    PIXEL_CUR(s, 0, x + 2, y + 0) = val;
>> +    PIXEL_CUR(s, 0, x + 1, y + 2) = val;
>> +
>> +    val = PREDICT3(b, c, d);
>> +    PIXEL_CUR(s, 0, x + 1, y + 1) = val;
>> +    PIXEL_CUR(s, 0, x + 0, y + 3) = val;
>> +
>> +    val = PREDICT2(b, c);
>> +    PIXEL_CUR(s, 0, x + 1, y + 0) = val;
>> +    PIXEL_CUR(s, 0, x + 0, y + 2) = val;
>> +
>> +    PIXEL_CUR(s, 0, x + 0, y + 1) = PREDICT3(a, b, c);
>> +    PIXEL_CUR(s, 0, x + 0, y + 0) = PREDICT2(a, b);
>> +}
>> +
>> +static void predict4_horizontal_up(AVCodecContext *avctx, int x, int y)
>> +{
>> +    ActimagineContext *s = avctx->priv_data;
>> +
>> +    uint8_t i = PIXEL_CUR(s, 0, x - 1, y + 0);
>> +    uint8_t j = PIXEL_CUR(s, 0, x - 1, y + 1);
>> +    uint8_t k = PIXEL_CUR(s, 0, x - 1, y + 2);
>> +    uint8_t l = PIXEL_CUR(s, 0, x - 1, y + 3);
>> +
>> +    PIXEL_CUR(s, 0, x + 0, y + 0) = PREDICT2(i, j);
>> +    PIXEL_CUR(s, 0, x + 1, y + 0) = PREDICT3(i, j, k);
>> +    PIXEL_CUR(s, 0, x + 2, y + 0) = PREDICT2(j, k);
>> +    PIXEL_CUR(s, 0, x + 3, y + 0) = PREDICT3(j, k, l);
>> +
>> +    PIXEL_CUR(s, 0, x + 0, y + 1) = PREDICT2(j, k);
>> +    PIXEL_CUR(s, 0, x + 1, y + 1) = PREDICT3(j, k, l);
>> +    PIXEL_CUR(s, 0, x + 2, y + 1) = PREDICT2(k, l);
>> +    PIXEL_CUR(s, 0, x + 3, y + 1) = PREDICT3(k, l, l);
>> +
>> +    PIXEL_CUR(s, 0, x + 0, y + 2) = PREDICT2(k, l);
>> +    PIXEL_CUR(s, 0, x + 1, y + 2) = PREDICT3(k, l, l);
>> +    PIXEL_CUR(s, 0, x + 2, y + 2) = l;
>> +    PIXEL_CUR(s, 0, x + 3, y + 2) = l;
>> +
>> +    PIXEL_CUR(s, 0, x + 0, y + 3) = l;
>> +    PIXEL_CUR(s, 0, x + 1, y + 3) = l;
>> +    PIXEL_CUR(s, 0, x + 2, y + 3) = l;
>> +    PIXEL_CUR(s, 0, x + 3, y + 3) = l;
>> +}
>> +
>> +static int predict4(AVCodecContext *avctx, int x, int y, int w, int h)
>> +{
>> +    ActimagineContext *s = avctx->priv_data;
>> +    GetBitContext *gb = &s->gb;
>> +    for (int y2 = 0; y2 < h >> 2; y2++) {
>> +        for (int x2 = 0; x2 < w >> 2; x2++) {
>> +            uint8_t mode = FFMIN(s->pred4_cache[1 + y2 - 1][1 + x2],
>> +                                 s->pred4_cache[1 + y2][1 + x2 - 1]);
>> +            if (mode == 9)// if invalid predict dc
>> +                mode = 2;
>> +
>> +            if (!get_bits1(gb)) {
>> +                uint8_t val = get_bits(gb, 3);
>> +                if (val >= mode)
>> +                    val++;
>> +                mode = val;
>> +            }
>> +
>> +            s->pred4_cache[1 + y2][1 + x2] = mode;
>> +
>> +            switch (mode) {
>> +            case 0:// vertical
>> +                predict_vertical(avctx, x + x2 * 4, y + y2 * 4, 4, 4, 0);
>> +                break;
>> +            case 1:// horizontal
>> +                predict_horizontal(avctx, x + x2 * 4, y + y2 * 4, 4, 4, 0);
>> +                break;
>> +            case 2:// dc
>> +                predict4_dc(avctx, x + x2 * 4, y + y2 * 4);
>> +                break;
>> +            case 3:// diagonal-down-left
>> +                predict4_diagonal_down_left(avctx, x + x2 * 4, y + y2 * 4);
>> +                break;
>> +            case 4:// diagonal-down-right
>> +                predict4_diagonal_down_right(avctx, x + x2 * 4, y + y2 * 4);
>> +                break;
>> +            case 5:// vertical-right
>> +                predict4_vertical_right(avctx, x + x2 * 4, y + y2 * 4);
>> +                break;
>> +            case 6:// horizontal-down
>> +                predict4_horizontal_down(avctx, x + x2 * 4, y + y2 * 4);
>> +                break;
>> +            case 7:// vertical-left
>> +                predict4_vertical_left(avctx, x + x2 * 4, y + y2 * 4);
>> +                break;
>> +            case 8:// horizontal-up
>> +                predict4_horizontal_up(avctx, x + x2 * 4, y + y2 * 4);
>> +                break;
>> +            default:
>> +                av_log(avctx, AV_LOG_ERROR, "invalid predict4 mode\n");
>> +                return AVERROR_INVALIDDATA;
>> +            }
>> +        }
>> +    }
>> +    return predict_notile_uv(avctx, x, y, w, h);
>> +}
>> +
>> +static void decode_dct(AVCodecContext *avctx, int x, int y, int plane,
>> +                       const int* level)
>> +{
>> +    int a, b, c, d, e, f;
>> +    int dct[16];
>> +    int tmp[16];
>> +    ActimagineContext *s = avctx->priv_data;
>> +
>> +    // dezigzag
>> +    for (int i = 0; i < 16; i++)
>> +        dct[zigzag4x4_tab[i]] = level[i];
>> +
>> +    // dequantize
>> +    for (int i = 0; i < 2; i++) {
>> +        for (int j = 0; j < 4; j++) {
>> +            dct[4 * j + i]     *= s->qtab[i][j];
>> +            dct[4 * j + i + 2] *= s->qtab[i][j];
>> +        }
>> +    }
>> +
>> +    dct[0] += 32;// rounding
>> +
>> +    for (int i = 0; i < 4; i++) {
>> +        a = dct[i * 4 + 0];
>> +        b = dct[i * 4 + 1];
>> +        c = dct[i * 4 + 2];
>> +        d = dct[i * 4 + 3];
>> +        a += c;
>> +        c = a - c * 2;
>> +        e = (b >> 1) - d;
>> +        f = b + (d >> 1);
>> +        tmp[ 0 + i] = a + f;
>> +        tmp[ 4 + i] = c + e;
>> +        tmp[ 8 + i] = c - e;
>> +        tmp[12 + i] = a - f;
>> +    }
>> +
>> +    for (int i = 0; i < 4; i++) {
>> +        a = tmp[i * 4 + 0];
>> +        b = tmp[i * 4 + 1];
>> +        c = tmp[i * 4 + 2];
>> +        d = tmp[i * 4 + 3];
>> +        a += c;
>> +        c =  a - c * 2;
>> +        e  = (b >> 1) - d;
>> +        f = b + (d >> 1);
>> +        PIXEL_CUR(s, plane, x + 0, y + i)
>> +            = av_clip_uint8(PIXEL_CUR(s, plane, x + 0, y + i) + ((a + f) >> 6));
>> +        PIXEL_CUR(s, plane, x + 1, y + i)
>> +            = av_clip_uint8(PIXEL_CUR(s, plane, x + 1, y + i) + ((c + e) >> 6));
>> +        PIXEL_CUR(s, plane, x + 2, y + i)
>> +            = av_clip_uint8(PIXEL_CUR(s, plane, x + 2, y + i) + ((c - e) >> 6));
>> +        PIXEL_CUR(s, plane, x + 3, y + i)
>> +            = av_clip_uint8(PIXEL_CUR(s, plane, x + 3, y + i) + ((a - f) >> 6));
>> +    }
>> +}
>> +
>> +static void decode_residu_cavlc(AVCodecContext *avctx, int x, int y, int plane,
>> +                                int nc, uint8_t *out_total_coeff)
>> +{
>> +    int level[16];
>> +    int coeff_token, total_coeff, trailing_ones, i, zeros_left, suffix_length;
>> +    ActimagineContext *s = avctx->priv_data;
>> +    GetBitContext *gb = &s->gb;
>> +
>> +    coeff_token = get_vlc2(gb, coeff_token_vlc[coeff_token_table_index[nc]].table,
>> +                           COEFF_TOKEN_VLC_BITS, 2);
>> +    trailing_ones = coeff_token & 3;
>> +    total_coeff   = coeff_token >> 2;
>> +
>> +    *out_total_coeff = total_coeff;
>> +    if (total_coeff == 0)
>> +        return;
>> +
>> +    av_assert2(total_coeff <= 16);
>> +
>> +    i = 15;
>> +    if (total_coeff != 16) {
>> +        int trailing_zeros;
>> +        zeros_left = get_vlc2(gb, total_zeros_vlc[total_coeff].table,
>> +                              TOTAL_ZEROS_VLC_BITS, 1);
>> +        trailing_zeros = 16 - (total_coeff + zeros_left);
>> +        while(trailing_zeros-- > 0)
>> +            level[i--] = 0;
>> +    } else
>> +        zeros_left = 0;
>> +
>> +    suffix_length = 0;
>> +    while (1) {
>> +        int level_suffix, level_code, run_before;
>> +        if (trailing_ones > 0) {
>> +            trailing_ones--;
>> +            level[i--] = get_bits1(gb) ? -1 : 1;
>> +        } else {
>> +            int level_prefix = 0;
>> +            while (!get_bits1(gb))
>> +                level_prefix++;
>> +
>> +            if (level_prefix == 15)
>> +                level_suffix = get_bits(gb, 11);
>> +            else
>> +                level_suffix = suffix_length == 0 ? 0 : get_bits(gb, suffix_length);
>> +
>> +            level_code = level_suffix + (level_prefix << suffix_length);
>> +
>> +            if (level_code > cavlc_suffix_len_update_tab[suffix_length])
>> +                suffix_length++;
>> +
>> +            level_code++;
>> +            if (get_bits1(gb))
>> +                level_code = -level_code;
>> +            level[i--] = level_code;
>> +        }
>> +
>> +        if (--total_coeff == 0)
>> +            break;
>> +
>> +        if (zeros_left == 0)
>> +            continue;
>> +
>> +        if(zeros_left < 7)
>> +            run_before = get_vlc2(gb, run_vlc[zeros_left].table, RUN_VLC_BITS, 1);
>> +        else
>> +            run_before = get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2);
>> +        zeros_left -= run_before;
>> +        while(run_before-- > 0)
>> +            level[i--] = 0;
>> +    }
>> +
>> +    while(zeros_left-- > 0)
>> +        level[i--] = 0;
>> +
>> +    decode_dct(avctx, x, y, plane, level);
>> +}
>> +
>> +static int decode_residu_blocks(AVCodecContext *avctx, int x, int y,
>> +                                int w, int h)
>> +{
>> +    ActimagineContext *s = avctx->priv_data;
>> +    GetBitContext *gb = &s->gb;
>> +    uint8_t *total_coeff_y = &s->total_coeff_y[
>> +        ((y >> 2) + 1) * s->total_coeff_y_stride + (x >> 2) + 1];
>> +    uint8_t *total_coeff_uv = &s->total_coeff_uv[
>> +        ((y >> 3) + 1) * s->total_coeff_uv_stride + (x >> 3) + 1];
>> +    for (int y2 = 0; y2 < h >> 3; y2++) {
>> +        for (int x2 = 0; x2 < w >> 3; x2++) {
>> +            uint8_t residu_mask;
>> +            int code = get_ue_golomb_31(gb);
>> +            if (code > 0x1F) {
>> +                av_log(avctx, AV_LOG_ERROR, "invalid residu mask code\n");
>> +                return AVERROR_INVALIDDATA;
>> +            }
>> +            if (s->version == VX_VERSION_OLD)
>> +                residu_mask = residu_mask_old_tab[code];
>> +            else
>> +                residu_mask = residu_mask_new_tab[code];
>> +
>> +            if (residu_mask & 1) {
>> +                int nc = (total_coeff_y[-1] +
>> +                          total_coeff_y[-s->total_coeff_y_stride] + 1) >> 1;
>> +                decode_residu_cavlc(avctx, x + x2 * 8, y + y2 * 8, 0, nc,
>> +                                    &total_coeff_y[0]);
>> +            } else
>> +                total_coeff_y[0] = 0;
>> +
>> +            if (residu_mask & 2) {
>> +                int nc = (total_coeff_y[0] +
>> +                          total_coeff_y[-s->total_coeff_y_stride + 1] + 1) >> 1;
>> +                decode_residu_cavlc(avctx, x + x2 * 8 + 4, y + y2 * 8, 0, nc,
>> +                                    &total_coeff_y[1]);
>> +            } else
>> +                total_coeff_y[1] = 0;
>> +
>> +            if (residu_mask & 4) {
>> +                int nc = (total_coeff_y[s->total_coeff_y_stride - 1] +
>> +                          total_coeff_y[0] + 1) >> 1;
>> +                decode_residu_cavlc(avctx, x + x2 * 8, y + y2 * 8 + 4, 0, nc,
>> +                                    &total_coeff_y[s->total_coeff_y_stride]);
>> +            } else
>> +                total_coeff_y[s->total_coeff_y_stride] = 0;
>> +
>> +            if (residu_mask & 8) {
>> +                int nc = (total_coeff_y[s->total_coeff_y_stride] +
>> +                          total_coeff_y[1] + 1) >> 1;
>> +                decode_residu_cavlc(
>> +                    avctx, x + x2 * 8 + 4, y + y2 * 8 + 4, 0, nc,
>> +                    &total_coeff_y[s->total_coeff_y_stride + 1]);
>> +            } else
>> +                total_coeff_y[s->total_coeff_y_stride + 1] = 0;
>> +
>> +            if (residu_mask & 16) {
>> +                uint8_t total_coeff_u, total_coeff_v;
>> +                int nc = (total_coeff_uv[-1] +
>> +                          total_coeff_uv[-s->total_coeff_uv_stride] + 1) >> 1;
>> +                decode_residu_cavlc(avctx, (x + x2 * 8) >> 1, (y + y2 * 8) >> 1,
>> +                                    1, nc, &total_coeff_u);
>> +                decode_residu_cavlc(avctx, (x + x2 * 8) >> 1, (y + y2 * 8) >> 1,
>> +                                    2, nc, &total_coeff_v);
>> +                total_coeff_uv[0] = (total_coeff_u + total_coeff_v + 1) >> 1;
>> +            } else
>> +                total_coeff_uv[0] = 0;
>> +
>> +            total_coeff_y += 2;
>> +            total_coeff_uv++;
>> +        }
>> +        total_coeff_y  += (s->total_coeff_y_stride << 1) - (w >> 2);
>> +        total_coeff_uv += s->total_coeff_uv_stride - (w >> 3);
>> +    }
>> +    return 0;
>> +}
>> +
>> +static int predict_inter(AVCodecContext *avctx, int x, int y, int w, int h,
>> +                          const MVec *predVec, int has_delta, int ref_frame)
>> +{
>> +    ActimagineContext *s = avctx->priv_data;
>> +    GetBitContext *gb = &s->gb;
>> +    MVec vec = *predVec;
>> +
>> +    if (ref_frame >= s->ref_frame_count) {
>> +        av_log(avctx, AV_LOG_ERROR, "reference to unavailable frame\n");
>> +        return AVERROR_INVALIDDATA;
>> +    }
>> +
>> +    s->cur_frame->pict_type = AV_PICTURE_TYPE_P;
>> +    s->cur_frame->key_frame = 0;
>> +
>> +    if (has_delta) {
>> +        vec.x += (unsigned)get_se_golomb(gb);
>> +        vec.y += (unsigned)get_se_golomb(gb);
>> +    }
>> +
>> +    if (vec.x >= INT_MAX || vec.y >= INT_MAX)
>> +        return AVERROR_INVALIDDATA;
>> +
>> +    s->vectors[(1 + (y >> 4)) * s->vectors_stride + 1 + (x >> 4)] = vec;
>> +
>> +    if (x + vec.x < 0 || x + vec.x + w > avctx->width ||
>> +        y + vec.y < 0 || y + vec.y + h > avctx->height) {
>> +        av_log(avctx, AV_LOG_ERROR, "motion vector out of bounds\n");
>> +        return AVERROR_INVALIDDATA;
>> +    }
>> +
>> +    // luma
>> +    for (int y2 = 0; y2 < h; y2++)
>> +        for (int x2 = 0; x2 < w; x2++)
>> +            PIXEL_CUR(s, 0, x + x2, y + y2)
>> +                = PIXEL_REF(s, ref_frame, 0, x + x2 + vec.x, y + y2 + vec.y);
>> +
>> +    // chroma
>> +    for (int y2 = 0; y2 < (h >> 1); y2++) {
>> +        for (int x2 = 0; x2 < (w >> 1); x2++) {
>> +            // u
>> +            PIXEL_CUR(s, 1, (x >> 1) + x2, (y >> 1) + y2)
>> +                = PIXEL_REF(s, ref_frame, 1, (x >> 1) + x2 + (vec.x >> 1),
>> +                            (y >> 1) + y2 + (vec.y >> 1));
>> +            // v
>> +            PIXEL_CUR(s, 2, (x >> 1) + x2, (y >> 1) + y2)
>> +                = PIXEL_REF(s, ref_frame, 2, (x >> 1) + x2 + (vec.x >> 1),
>> +                            (y >> 1) + y2 + (vec.y >> 1));
>> +        }
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static int predict_inter_dc(AVCodecContext *avctx, int x, int y, int w, int h)
>> +{
>> +    int dx, dy, dc_y, dc_u, dc_v;
>> +    ActimagineContext *s = avctx->priv_data;
>> +    GetBitContext *gb = &s->gb;
>> +
>> +    if (s->ref_frame_count == 0) {
>> +        av_log(avctx, AV_LOG_ERROR, "reference to unavailable frame\n");
>> +        return AVERROR_INVALIDDATA;
>> +    }
>> +
>> +    dx   = get_se_golomb(gb);
>> +    dy   = get_se_golomb(gb);
>> +
>> +    if (x + dx < 0 || x + dx + w > avctx->width ||
>> +        y + dy < 0 || y + dy + h > avctx->height) {
>> +        av_log(avctx, AV_LOG_ERROR, "motion vector out of bounds\n");
>> +        return AVERROR_INVALIDDATA;
>> +    }
>> +
>> +    dc_y = get_se_golomb(gb);
>> +    if (dc_y < -(1<<16) || dc_y >= (1 << 16)) {
>> +        av_log(avctx, AV_LOG_ERROR, "invalid dc offset\n");
>> +        return AVERROR_INVALIDDATA;
>> +    }
>> +    dc_y <<= 1;
>> +
>> +    dc_u = get_se_golomb(gb);
>> +    if (dc_u < -(1<<16) || dc_u >= (1 << 16)) {
>> +        av_log(avctx, AV_LOG_ERROR, "invalid dc offset\n");
>> +        return AVERROR_INVALIDDATA;
>> +    }
>> +    dc_u <<= 1;
>> +
>> +    dc_v = get_se_golomb(gb);
>> +    if (dc_v < -(1<<16) || dc_v >= (1 << 16)) {
>> +        av_log(avctx, AV_LOG_ERROR, "invalid dc offset\n");
>> +        return AVERROR_INVALIDDATA;
>> +    }
>> +    dc_v <<= 1;
>> +
>> +    s->cur_frame->pict_type = AV_PICTURE_TYPE_P;
>> +    s->cur_frame->key_frame = 0;
>> +
>> +    // luma
>> +    for (int y2 = 0; y2 < h; y2++)
>> +        for (int x2 = 0; x2 < w; x2++)
>> +            PIXEL_CUR(s, 0, x + x2, y + y2) = av_clip_uint8(
>> +                PIXEL_REF(s, 0, 0, x + x2 + dx, y + y2 + dy) + dc_y);
>> +
>> +    // chroma
>> +    for (int y2 = 0; y2 < (h >> 1); y2++) {
>> +        for (int x2 = 0; x2 < (w >> 1); x2++) {
>> +            PIXEL_CUR(s, 1, (x >> 1) + x2, (y >> 1) + y2) = av_clip_uint8(
>> +                PIXEL_REF(s, 0, 1, (x >> 1) + x2 + (dx >> 1),
>> +                          (y >> 1) + y2 + (dy >> 1)) + dc_u);
>> +            PIXEL_CUR(s, 2, (x >> 1) + x2, (y >> 1) + y2) = av_clip_uint8(
>> +                PIXEL_REF(s, 0, 2, (x >> 1) + x2 + (dx >> 1),
>> +                          (y >> 1) + y2 + (dy >> 1)) + dc_v);
>> +        }
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static int decode_mb(AVCodecContext *avctx, int x, int y, int w, int h,
>> +                     const MVec *predVec)
>> +{
>> +    ActimagineContext *s = avctx->priv_data;
>> +    GetBitContext *gb = &s->gb;
>> +    int ret = 0;
>> +
>> +    int mode = get_ue_golomb_31(gb);
>> +    if (s->version == VX_VERSION_OLD)
>> +        mode = old_mb_mode_remap_tab[mode];
>> +
>> +    switch (mode) {
>> +    case 0:// v-split, no residu
>> +        if (w == 2) {
>> +            av_log(avctx, AV_LOG_ERROR, "invalid macroblock mode\n");
>> +            return AVERROR_INVALIDDATA;
>> +        }
>> +        if ((ret = decode_mb(avctx, x, y, w >> 1, h, predVec)) < 0)
>> +            return ret;
>> +        if ((ret = decode_mb(avctx, x + (w >> 1), y, w >> 1, h, predVec)) < 0)
>> +            return ret;
>> +        if (w == 8 && (h == 8 || h == 16))
>> +            clear_total_coeff(avctx, x, y, w, h);
>> +        break;
>> +    case 1:// no delta, no residu, ref 0
>> +        if ((ret = predict_inter(avctx, x, y, w, h, predVec, 0, 0)) < 0)
>> +            return ret;
>> +        if ((w == 8 || w == 16) && (h == 8 || h == 16))
>> +            clear_total_coeff(avctx, x, y, w, h);
>> +        break;
>> +    case 2:// h-split, no residu
>> +        if (h == 2) {
>> +            av_log(avctx, AV_LOG_ERROR, "invalid macroblock mode\n");
>> +            return AVERROR_INVALIDDATA;
>> +        }
>> +        if ((ret = decode_mb(avctx, x, y, w, h >> 1, predVec)) < 0)
>> +            return ret;
>> +        if ((ret = decode_mb(avctx, x, y + (h >> 1), w, h >> 1, predVec)) < 0)
>> +            return ret;
>> +        if ((w == 8 || w == 16) && h == 8)
>> +            clear_total_coeff(avctx, x, y, w, h);
>> +        break;
>> +    case 3:// unpredicted delta ref0 + dc offset, no residu
>> +        if ((ret = predict_inter_dc(avctx, x, y, w, h)) < 0)
>> +            return ret;
>> +        if ((w == 8 || w == 16) && (h == 8 || h == 16))
>> +            clear_total_coeff(avctx, x, y, w, h);
>> +        break;
>> +    case 4:// delta, no residu, ref 0
>> +    case 5:// delta, no residu, ref 1
>> +    case 6:// delta, no residu, ref 2
>> +        if ((ret = predict_inter(avctx, x, y, w, h, predVec, 1, mode - 4)) < 0)
>> +            return ret;
>> +        if ((w == 8 || w == 16) && (h == 8 || h == 16))
>> +            clear_total_coeff(avctx, x, y, w, h);
>> +        break;
>> +    case 7:// plane, no residu
>> +        if ((ret = predict_mb_plane(avctx, x, y, w, h)) < 0)
>> +            return ret;
>> +        if ((w == 8 || w == 16) && (h == 8 || h == 16))
>> +            clear_total_coeff(avctx, x, y, w, h);
>> +        break;
>> +    case 8:// v-split, residu
>> +        if (w == 2) {
>> +            av_log(avctx, AV_LOG_ERROR, "invalid macroblock mode\n");
>> +            return AVERROR_INVALIDDATA;
>> +        }
>> +        if ((ret = decode_mb(avctx, x, y, w >> 1, h, predVec)) < 0)
>> +            return ret;
>> +        if ((ret = decode_mb(avctx, x + (w >> 1), y, w >> 1, h, predVec)) < 0)
>> +            return ret;
>> +        if ((ret = decode_residu_blocks(avctx, x, y, w, h)) < 0)
>> +            return ret;
>> +        break;
>> +    case 9:// no delta, no residu, ref 1
>> +        if ((ret = predict_inter(avctx, x, y, w, h, predVec, 0, 1)) < 0)
>> +            return ret;
>> +        if ((w == 8 || w == 16) && (h == 8 || h == 16))
>> +            clear_total_coeff(avctx, x, y, w, h);
>> +        break;
>> +    case 10:// unpredicted delta ref0 + dc offset, residu
>> +        if ((ret = predict_inter_dc(avctx, x, y, w, h)) < 0)
>> +            return ret;
>> +        if ((ret = decode_residu_blocks(avctx, x, y, w, h)) < 0)
>> +            return ret;
>> +        break;
>> +    case 11:// predict notile, no residu
>> +        if ((ret = predict_notile(avctx, x, y, w, h)) < 0)
>> +            return ret;
>> +        if ((w == 8 || w == 16) && (h == 8 || h == 16))
>> +            clear_total_coeff(avctx, x, y, w, h);
>> +        break;
>> +    case 12:// no delta, residu, ref 0
>> +        if ((ret = predict_inter(avctx, x, y, w, h, predVec, 0, 0)) < 0)
>> +            return ret;
>> +        if ((ret = decode_residu_blocks(avctx, x, y, w, h)) < 0)
>> +            return ret;
>> +        break;
>> +    case 13:// h-split, residu
>> +        if (h == 2) {
>> +            av_log(avctx, AV_LOG_ERROR, "invalid macroblock mode\n");
>> +            return AVERROR_INVALIDDATA;
>> +        }
>> +        if ((ret = decode_mb(avctx, x, y, w, h >> 1, predVec)) < 0)
>> +            return ret;
>> +        if ((ret = decode_mb(avctx, x, y + (h >> 1), w, h >> 1, predVec)) < 0)
>> +            return ret;
>> +        if ((ret = decode_residu_blocks(avctx, x, y, w, h)) < 0)
>> +            return ret;
>> +        break;
>> +    case 14:// no delta, no residu, ref 2
>> +        if ((ret = predict_inter(avctx, x, y, w, h, predVec, 0, 2)) < 0)
>> +            return ret;
>> +        if ((w == 8 || w == 16) && (h == 8 || h == 16))
>> +            clear_total_coeff(avctx, x, y, w, h);
>> +        break;
>> +    case 15:// predict4, no residu
>> +        if ((ret = predict4(avctx, x, y, w, h)) < 0)
>> +            return ret;
>> +        if ((w == 8 || w == 16) && (h == 8 || h == 16))
>> +            clear_total_coeff(avctx, x, y, w, h);
>> +        break;
>> +    case 16:// delta, residu, ref 0
>> +    case 17:// delta, residu, ref 1
>> +    case 18:// delta, residu, ref 2
>> +        if ((ret = predict_inter(avctx, x, y, w, h, predVec, 1, mode - 16)) < 0)
>> +            return ret;
>> +        if ((ret = decode_residu_blocks(avctx, x, y, w, h)) < 0)
>> +            return ret;
>> +        break;
>> +    case 19:// predict4, residu
>> +        if ((ret = predict4(avctx, x, y, w, h)) < 0)
>> +            return ret;
>> +        if ((ret = decode_residu_blocks(avctx, x, y, w, h)) < 0)
>> +            return ret;
>> +        break;
>> +    case 20:// no delta, residu, ref 1
>> +    case 21:// no delta, residu, ref 2
>> +        if ((ret = predict_inter(avctx, x, y, w, h, predVec, 0, mode - 20 + 1)) < 0)
>> +            return ret;
>> +        if ((ret = decode_residu_blocks(avctx, x, y, w, h)) < 0)
>> +            return ret;
>> +        break;
>> +    case 22:// predict notile, residu
>> +        if ((ret = predict_notile(avctx, x, y, w, h)) < 0)
>> +            return ret;
>> +        if ((ret = decode_residu_blocks(avctx, x, y, w, h)) < 0)
>> +            return ret;
>> +        break;
>> +    case 23:// plane, residu
>> +        if ((ret = predict_mb_plane(avctx, x, y, w, h)) < 0)
>> +            return ret;
>> +        if ((ret = decode_residu_blocks(avctx, x, y, w, h)) < 0)
>> +            return ret;
>> +        break;
>> +    default:
>> +        av_log(avctx, AV_LOG_ERROR, "invalid macroblock mode\n");
>> +        return AVERROR_INVALIDDATA;
>> +    }
>> +    return 0;
>> +}
>> +
>> +static int detect_format(AVCodecContext *avctx)
>> +{
>> +    // assume the new format, if any incorrect decisions are made for the
>> +    // first macroblock of a keyframe (ref, non-dc prediction) then it must be
>> +    // the old format
>> +    ActimagineContext *s = avctx->priv_data;
>> +    GetBitContext *gb = &s->gb;
>> +    int w = 16;
>> +    int h = 16;
>> +    while (1) {
>> +        int mode = get_ue_golomb_31(gb);
>> +        if (mode == 0 || mode == 8) { // v-split
>> +            if (w == 2) // too many splits
>> +                return VX_VERSION_OLD;
>> +            w >>= 1;
>> +            continue;
>> +        } else if (mode == 2 || mode == 13) { // h-split
>> +            if (h == 2) // too many splits
>> +                return VX_VERSION_OLD;
>> +            h >>= 1;
>> +            continue;
>> +        } else if (mode == 11 || mode == 22) { // predict notile
>> +            if (get_ue_golomb_31(gb) != 2) // mode_y != dc
>> +                return VX_VERSION_OLD;
>> +            if (get_ue_golomb_31(gb) != 0) // mode_uv != dc
>> +                return VX_VERSION_OLD;
>> +            break; //we should have enough evidence now
>> +        } else if (mode == 15 || mode == 19) { // predict4
>> +            // initial prediction is always dc
>> +            // we don't expect that prediction to be wrong
>> +            if (!get_bits1(gb))
>> +                return VX_VERSION_OLD;
>> +            break; //we should have enough evidence now
>> +        } else // inter prediction, plane or any other value
>> +            return VX_VERSION_OLD;
>> +    }
>> +    return VX_VERSION_NEW;
>> +}
>> +
>> +static int actimagine_decode(AVCodecContext *avctx, void *data,
>> +                            int *got_frame, AVPacket *pkt)
>> +{
>> +    MVec *vectors;
>> +    int ret;
>> +    ActimagineContext *s = avctx->priv_data;
>> +    GetBitContext *gb = &s->gb;
>> +    AVFrame *frame = s->cur_frame;
>> +
>> +    // in avi files the frames start with a 32 bit number that seems to
>> +    // indicate the total number of bits
>> +    int offset = s->avi ? 4 : 0;
>> +
>> +    av_fast_padded_malloc(&s->bitstream, &s->bitstream_size,
>> +                          pkt->size);
>> +
>> +    if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0)
>> +        return ret;
>> +
>> +    s->bdsp.bswap16_buf((uint16_t *)s->bitstream, (uint16_t *)pkt->data,
>> +                        (pkt->size + 1) >> 1);
>> +
>> +    ret = init_get_bits8(gb, s->bitstream + offset,
>> +                         FFALIGN(pkt->size - offset, 2));
>> +    if (ret < 0)
>> +        return ret;
>> +
>> +    // determine the bitstream version if this was not done yet
>> +    if (s->version == VX_VERSION_INVALID) {
>> +        if (s->ref_frame_count != 0) {
>> +            av_log(avctx, AV_LOG_ERROR, "can't determine version on p frame\n");
>> +            return AVERROR_INVALIDDATA;
>> +        }
>> +        s->version = detect_format(avctx);
>> +
>> +        // reinit bitreader
>> +        ret = init_get_bits8(gb, s->bitstream + offset,
>> +                             FFALIGN(pkt->size - offset, 2));
>> +        if (ret < 0)
>> +            return ret;
>> +    }
>> +
>> +    vectors = s->vectors + s->vectors_stride + 1;
>> +
>> +    frame->pict_type = AV_PICTURE_TYPE_I;
>> +    frame->key_frame = 1;
>> +
>> +    if (s->quantizer == -1) {
>> +        av_log(avctx, AV_LOG_ERROR, "no quantizer setup\n");
>> +        return AVERROR_INVALIDDATA;
>> +    }
>> +
>> +    for (int y = 0; y < avctx->height; y += 16) {
>> +        MVec *vec_cur = vectors;
>> +        for (int x = 0; x < avctx->width; x += 16) {
>> +            MVec predVec;
>> +            vec_cur[0].x = 0;
>> +            vec_cur[0].y = 0;
>> +            predVec.x = mid_pred(vec_cur[-1].x, vec_cur[-s->vectors_stride].x,
>> +                                 vec_cur[-s->vectors_stride + 1].x);
>> +            predVec.y = mid_pred(vec_cur[-1].y, vec_cur[-s->vectors_stride].y,
>> +                                 vec_cur[-s->vectors_stride + 1].y);
>> +            if ((ret = decode_mb(avctx, x, y, 16, 16, &predVec)) < 0)
>> +                return ret;
>> +            vec_cur++;
>> +        }
>> +        vectors += s->vectors_stride;
>> +    }
>> +
>> +    if (s->ref_frame_count == 3)
>> +        av_frame_unref(s->ref_frames[2]);
>> +
>> +    s->cur_frame = s->ref_frames[2];
>> +    s->ref_frames[2] = s->ref_frames[1];
>> +    s->ref_frames[1] = s->ref_frames[0];
>> +    s->ref_frames[0] = frame;
>> +
>> +    if (s->ref_frame_count < 3)
>> +        s->ref_frame_count++;
>> +
>> +    if ((ret = av_frame_ref(data, frame)) < 0)
>> +        return ret;
>> +    *got_frame = 1;
>> +
>> +    return 0;
>> +}
>> +
>> +static void actimagine_flush(AVCodecContext *avctx)
>> +{
>> +    ActimagineContext *s = avctx->priv_data;
>> +
>> +    for (int i = 0; i < 3; i++)
>> +        av_frame_unref(s->ref_frames[i]);
>> +
>> +    s->ref_frame_count = 0;
>> +}
>> +
>> +static av_cold int actimagine_close(AVCodecContext *avctx)
>> +{
>> +    ActimagineContext *s = avctx->priv_data;
>> +
>> +    av_freep(&s->vectors);
>> +    s->vectors_stride = 0;
>> +    av_freep(&s->total_coeff_y);
>> +    s->total_coeff_y_stride = 0;
>> +    av_freep(&s->total_coeff_uv);
>> +    s->total_coeff_uv_stride = 0;
>> +
>> +    av_freep(&s->bitstream);
>> +    s->bitstream_size = 0;
>> +
>> +    for (int i = 0; i < 3; i++)
>> +        av_frame_free(&s->ref_frames[i]);
>> +    av_frame_free(&s->cur_frame);
>> +
>> +    return 0;
>> +}
>> +
>> +AVCodec ff_actimagine_decoder = {
>> +    .name           = "actimagine",
>> +    .long_name      = NULL_IF_CONFIG_SMALL("Actimagine VX Video"),
>> +    .type           = AVMEDIA_TYPE_VIDEO,
>> +    .id             = AV_CODEC_ID_ACTIMAGINE,
>> +    .priv_data_size = sizeof(ActimagineContext),
>> +    .init           = actimagine_init,
>> +    .decode         = actimagine_decode,
>> +    .flush          = actimagine_flush,
>> +    .close          = actimagine_close,
>> +    .capabilities   = AV_CODEC_CAP_DR1,
>> +    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
>> +};
>> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
>> index 2e9a3581de..10809f3492 100644
>> --- a/libavcodec/allcodecs.c
>> +++ b/libavcodec/allcodecs.c
>> @@ -32,6 +32,7 @@
>>  extern AVCodec ff_a64multi_encoder;
>>  extern AVCodec ff_a64multi5_encoder;
>>  extern AVCodec ff_aasc_decoder;
>> +extern AVCodec ff_actimagine_decoder;
>>  extern AVCodec ff_aic_decoder;
>>  extern AVCodec ff_alias_pix_encoder;
>>  extern AVCodec ff_alias_pix_decoder;
>> diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
>> index 17f8a14044..65d96c21af 100644
>> --- a/libavcodec/codec_desc.c
>> +++ b/libavcodec/codec_desc.c
>> @@ -1856,6 +1856,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
>>          .long_name = NULL_IF_CONFIG_SMALL("Digital Pictures SGA Video"),
>>          .props     = AV_CODEC_PROP_LOSSY,
>>      },
>> +    {
>> +        .id        = AV_CODEC_ID_ACTIMAGINE,
>> +        .type      = AVMEDIA_TYPE_VIDEO,
>> +        .name      = "actimagine",
>> +        .long_name = NULL_IF_CONFIG_SMALL("Actimagine VX Video"),
>> +        .props     = AV_CODEC_PROP_LOSSY,
>> +    },
>>
>>      /* various PCM "codecs" */
>>      {
>> diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
>> index ab7bc68ee2..a4b3f3955d 100644
>> --- a/libavcodec/codec_id.h
>> +++ b/libavcodec/codec_id.h
>> @@ -307,6 +307,7 @@ enum AVCodecID {
>>      AV_CODEC_ID_CRI,
>>      AV_CODEC_ID_SIMBIOSIS_IMX,
>>      AV_CODEC_ID_SGA_VIDEO,
>> +    AV_CODEC_ID_ACTIMAGINE,
>>
>>      /* various PCM "codecs" */
>>      AV_CODEC_ID_FIRST_AUDIO = 0x10000,     ///< A dummy id pointing at the start of audio codecs
>> diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c
>> index 9f5f692331..642fb2659d 100644
>> --- a/libavcodec/h264_cavlc.c
>> +++ b/libavcodec/h264_cavlc.c
>> @@ -36,6 +36,7 @@
>>  #include "golomb.h"
>>  #include "mpegutils.h"
>>  #include "libavutil/avassert.h"
>> +#include "h264_cavlc_data.h"
>>
>>
>>  static const uint8_t golomb_to_inter_cbp_gray[16]={
>> @@ -86,104 +87,6 @@ static const uint8_t chroma422_dc_coeff_token_bits[4*9]={
>>    7,   5,  4, 4,
>>  };
>>
>> -static const uint8_t coeff_token_len[4][4*17]={
>> -{
>> -     1, 0, 0, 0,
>> -     6, 2, 0, 0,     8, 6, 3, 0,     9, 8, 7, 5,    10, 9, 8, 6,
>> -    11,10, 9, 7,    13,11,10, 8,    13,13,11, 9,    13,13,13,10,
>> -    14,14,13,11,    14,14,14,13,    15,15,14,14,    15,15,15,14,
>> -    16,15,15,15,    16,16,16,15,    16,16,16,16,    16,16,16,16,
>> -},
>> -{
>> -     2, 0, 0, 0,
>> -     6, 2, 0, 0,     6, 5, 3, 0,     7, 6, 6, 4,     8, 6, 6, 4,
>> -     8, 7, 7, 5,     9, 8, 8, 6,    11, 9, 9, 6,    11,11,11, 7,
>> -    12,11,11, 9,    12,12,12,11,    12,12,12,11,    13,13,13,12,
>> -    13,13,13,13,    13,14,13,13,    14,14,14,13,    14,14,14,14,
>> -},
>> -{
>> -     4, 0, 0, 0,
>> -     6, 4, 0, 0,     6, 5, 4, 0,     6, 5, 5, 4,     7, 5, 5, 4,
>> -     7, 5, 5, 4,     7, 6, 6, 4,     7, 6, 6, 4,     8, 7, 7, 5,
>> -     8, 8, 7, 6,     9, 8, 8, 7,     9, 9, 8, 8,     9, 9, 9, 8,
>> -    10, 9, 9, 9,    10,10,10,10,    10,10,10,10,    10,10,10,10,
>> -},
>> -{
>> -     6, 0, 0, 0,
>> -     6, 6, 0, 0,     6, 6, 6, 0,     6, 6, 6, 6,     6, 6, 6, 6,
>> -     6, 6, 6, 6,     6, 6, 6, 6,     6, 6, 6, 6,     6, 6, 6, 6,
>> -     6, 6, 6, 6,     6, 6, 6, 6,     6, 6, 6, 6,     6, 6, 6, 6,
>> -     6, 6, 6, 6,     6, 6, 6, 6,     6, 6, 6, 6,     6, 6, 6, 6,
>> -}
>> -};
>> -
>> -static const uint8_t coeff_token_bits[4][4*17]={
>> -{
>> -     1, 0, 0, 0,
>> -     5, 1, 0, 0,     7, 4, 1, 0,     7, 6, 5, 3,     7, 6, 5, 3,
>> -     7, 6, 5, 4,    15, 6, 5, 4,    11,14, 5, 4,     8,10,13, 4,
>> -    15,14, 9, 4,    11,10,13,12,    15,14, 9,12,    11,10,13, 8,
>> -    15, 1, 9,12,    11,14,13, 8,     7,10, 9,12,     4, 6, 5, 8,
>> -},
>> -{
>> -     3, 0, 0, 0,
>> -    11, 2, 0, 0,     7, 7, 3, 0,     7,10, 9, 5,     7, 6, 5, 4,
>> -     4, 6, 5, 6,     7, 6, 5, 8,    15, 6, 5, 4,    11,14,13, 4,
>> -    15,10, 9, 4,    11,14,13,12,     8,10, 9, 8,    15,14,13,12,
>> -    11,10, 9,12,     7,11, 6, 8,     9, 8,10, 1,     7, 6, 5, 4,
>> -},
>> -{
>> -    15, 0, 0, 0,
>> -    15,14, 0, 0,    11,15,13, 0,     8,12,14,12,    15,10,11,11,
>> -    11, 8, 9,10,     9,14,13, 9,     8,10, 9, 8,    15,14,13,13,
>> -    11,14,10,12,    15,10,13,12,    11,14, 9,12,     8,10,13, 8,
>> -    13, 7, 9,12,     9,12,11,10,     5, 8, 7, 6,     1, 4, 3, 2,
>> -},
>> -{
>> -     3, 0, 0, 0,
>> -     0, 1, 0, 0,     4, 5, 6, 0,     8, 9,10,11,    12,13,14,15,
>> -    16,17,18,19,    20,21,22,23,    24,25,26,27,    28,29,30,31,
>> -    32,33,34,35,    36,37,38,39,    40,41,42,43,    44,45,46,47,
>> -    48,49,50,51,    52,53,54,55,    56,57,58,59,    60,61,62,63,
>> -}
>> -};
>> -
>> -static const uint8_t total_zeros_len[16][16]= {
>> -    {1,3,3,4,4,5,5,6,6,7,7,8,8,9,9,9},
>> -    {3,3,3,3,3,4,4,4,4,5,5,6,6,6,6},
>> -    {4,3,3,3,4,4,3,3,4,5,5,6,5,6},
>> -    {5,3,4,4,3,3,3,4,3,4,5,5,5},
>> -    {4,4,4,3,3,3,3,3,4,5,4,5},
>> -    {6,5,3,3,3,3,3,3,4,3,6},
>> -    {6,5,3,3,3,2,3,4,3,6},
>> -    {6,4,5,3,2,2,3,3,6},
>> -    {6,6,4,2,2,3,2,5},
>> -    {5,5,3,2,2,2,4},
>> -    {4,4,3,3,1,3},
>> -    {4,4,2,1,3},
>> -    {3,3,1,2},
>> -    {2,2,1},
>> -    {1,1},
>> -};
>> -
>> -static const uint8_t total_zeros_bits[16][16]= {
>> -    {1,3,2,3,2,3,2,3,2,3,2,3,2,3,2,1},
>> -    {7,6,5,4,3,5,4,3,2,3,2,3,2,1,0},
>> -    {5,7,6,5,4,3,4,3,2,3,2,1,1,0},
>> -    {3,7,5,4,6,5,4,3,3,2,2,1,0},
>> -    {5,4,3,7,6,5,4,3,2,1,1,0},
>> -    {1,1,7,6,5,4,3,2,1,1,0},
>> -    {1,1,5,4,3,3,2,1,1,0},
>> -    {1,1,1,3,3,2,2,1,0},
>> -    {1,0,1,3,2,1,1,1},
>> -    {1,0,1,3,2,1,1},
>> -    {0,1,1,2,1,3},
>> -    {0,1,1,1,1},
>> -    {0,1,1,1},
>> -    {0,1,1},
>> -    {0,1},
>> -};
>> -
>>  static const uint8_t chroma_dc_total_zeros_len[3][4]= {
>>      { 1, 2, 3, 3,},
>>      { 1, 2, 2, 0,},
>> @@ -216,26 +119,6 @@ static const uint8_t chroma422_dc_total_zeros_bits[7][8]= {
>>      { 0, 1 },
>>  };
>>
>> -static const uint8_t run_len[7][16]={
>> -    {1,1},
>> -    {1,2,2},
>> -    {2,2,2,2},
>> -    {2,2,2,3,3},
>> -    {2,2,3,3,3,3},
>> -    {2,3,3,3,3,3,3},
>> -    {3,3,3,3,3,3,3,4,5,6,7,8,9,10,11},
>> -};
>> -
>> -static const uint8_t run_bits[7][16]={
>> -    {1,0},
>> -    {1,1,0},
>> -    {3,2,1,0},
>> -    {3,2,1,1,0},
>> -    {3,2,3,2,1,0},
>> -    {3,0,1,3,2,5,4},
>> -    {7,6,5,4,3,2,1,1,1,1,1,1,1,1,1},
>> -};
>> -
>>  static VLC coeff_token_vlc[4];
>>  static VLC_TYPE coeff_token_vlc_tables[520+332+280+256][2];
>>  static const int coeff_token_vlc_tables_size[4]={520,332,280,256};
>> @@ -347,8 +230,8 @@ av_cold void ff_h264_decode_init_vlc(void)
>>          coeff_token_vlc[i].table = coeff_token_vlc_tables + offset;
>>          coeff_token_vlc[i].table_allocated = coeff_token_vlc_tables_size[i];
>>          init_vlc(&coeff_token_vlc[i], COEFF_TOKEN_VLC_BITS, 4*17,
>> -                 &coeff_token_len [i][0], 1, 1,
>> -                 &coeff_token_bits[i][0], 1, 1,
>> +                 &ff_h264_cavlc_coeff_token_len [i][0], 1, 1,
>> +                 &ff_h264_cavlc_coeff_token_bits[i][0], 1, 1,
>>                   INIT_VLC_USE_NEW_STATIC);
>>          offset += coeff_token_vlc_tables_size[i];
>>      }
>> @@ -384,8 +267,8 @@ av_cold void ff_h264_decode_init_vlc(void)
>>          total_zeros_vlc[i + 1].table_allocated = total_zeros_vlc_tables_size;
>>          init_vlc(&total_zeros_vlc[i + 1],
>>                   TOTAL_ZEROS_VLC_BITS, 16,
>> -                 &total_zeros_len [i][0], 1, 1,
>> -                 &total_zeros_bits[i][0], 1, 1,
>> +                 &ff_h264_cavlc_total_zeros_len [i][0], 1, 1,
>> +                 &ff_h264_cavlc_total_zeros_bits[i][0], 1, 1,
>>                   INIT_VLC_USE_NEW_STATIC);
>>      }
>>
>> @@ -394,15 +277,15 @@ av_cold void ff_h264_decode_init_vlc(void)
>>          run_vlc[i + 1].table_allocated = run_vlc_tables_size;
>>          init_vlc(&run_vlc[i + 1],
>>                   RUN_VLC_BITS, 7,
>> -                 &run_len [i][0], 1, 1,
>> -                 &run_bits[i][0], 1, 1,
>> +                 &ff_h264_cavlc_run_len [i][0], 1, 1,
>> +                 &ff_h264_cavlc_run_bits[i][0], 1, 1,
>>                   INIT_VLC_USE_NEW_STATIC);
>>      }
>>      run7_vlc.table = run7_vlc_table;
>>      run7_vlc.table_allocated = run7_vlc_table_size;
>>      init_vlc(&run7_vlc, RUN7_VLC_BITS, 16,
>> -             &run_len [6][0], 1, 1,
>> -             &run_bits[6][0], 1, 1,
>> +             &ff_h264_cavlc_run_len [6][0], 1, 1,
>> +             &ff_h264_cavlc_run_bits[6][0], 1, 1,
>>               INIT_VLC_USE_NEW_STATIC);
>>
>>      init_cavlc_level_tab();
>> diff --git a/libavcodec/h264_cavlc_data.c b/libavcodec/h264_cavlc_data.c
>> new file mode 100644
>> index 0000000000..d18ab1954c
>> --- /dev/null
>> +++ b/libavcodec/h264_cavlc_data.c
>> @@ -0,0 +1,140 @@
>> +/*
>> + * H.264 cavlc tables
>> + * Copyright (c) 2003 Michael Niedermayer <michaelni at gmx.at>
>> + *
>> + * This file is part of FFmpeg.
>> + *
>> + * 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.
>> + *
>> + * 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 FFmpeg; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>> + */
>> +
>> +#include "h264_cavlc_data.h"
>> +
>> +const uint8_t ff_h264_cavlc_coeff_token_len[4][4*17]={
>> +{
>> +     1, 0, 0, 0,
>> +     6, 2, 0, 0,     8, 6, 3, 0,     9, 8, 7, 5,    10, 9, 8, 6,
>> +    11,10, 9, 7,    13,11,10, 8,    13,13,11, 9,    13,13,13,10,
>> +    14,14,13,11,    14,14,14,13,    15,15,14,14,    15,15,15,14,
>> +    16,15,15,15,    16,16,16,15,    16,16,16,16,    16,16,16,16,
>> +},
>> +{
>> +     2, 0, 0, 0,
>> +     6, 2, 0, 0,     6, 5, 3, 0,     7, 6, 6, 4,     8, 6, 6, 4,
>> +     8, 7, 7, 5,     9, 8, 8, 6,    11, 9, 9, 6,    11,11,11, 7,
>> +    12,11,11, 9,    12,12,12,11,    12,12,12,11,    13,13,13,12,
>> +    13,13,13,13,    13,14,13,13,    14,14,14,13,    14,14,14,14,
>> +},
>> +{
>> +     4, 0, 0, 0,
>> +     6, 4, 0, 0,     6, 5, 4, 0,     6, 5, 5, 4,     7, 5, 5, 4,
>> +     7, 5, 5, 4,     7, 6, 6, 4,     7, 6, 6, 4,     8, 7, 7, 5,
>> +     8, 8, 7, 6,     9, 8, 8, 7,     9, 9, 8, 8,     9, 9, 9, 8,
>> +    10, 9, 9, 9,    10,10,10,10,    10,10,10,10,    10,10,10,10,
>> +},
>> +{
>> +     6, 0, 0, 0,
>> +     6, 6, 0, 0,     6, 6, 6, 0,     6, 6, 6, 6,     6, 6, 6, 6,
>> +     6, 6, 6, 6,     6, 6, 6, 6,     6, 6, 6, 6,     6, 6, 6, 6,
>> +     6, 6, 6, 6,     6, 6, 6, 6,     6, 6, 6, 6,     6, 6, 6, 6,
>> +     6, 6, 6, 6,     6, 6, 6, 6,     6, 6, 6, 6,     6, 6, 6, 6,
>> +}
>> +};
>> +
>> +const uint8_t ff_h264_cavlc_coeff_token_bits[4][4*17]={
>> +{
>> +     1, 0, 0, 0,
>> +     5, 1, 0, 0,     7, 4, 1, 0,     7, 6, 5, 3,     7, 6, 5, 3,
>> +     7, 6, 5, 4,    15, 6, 5, 4,    11,14, 5, 4,     8,10,13, 4,
>> +    15,14, 9, 4,    11,10,13,12,    15,14, 9,12,    11,10,13, 8,
>> +    15, 1, 9,12,    11,14,13, 8,     7,10, 9,12,     4, 6, 5, 8,
>> +},
>> +{
>> +     3, 0, 0, 0,
>> +    11, 2, 0, 0,     7, 7, 3, 0,     7,10, 9, 5,     7, 6, 5, 4,
>> +     4, 6, 5, 6,     7, 6, 5, 8,    15, 6, 5, 4,    11,14,13, 4,
>> +    15,10, 9, 4,    11,14,13,12,     8,10, 9, 8,    15,14,13,12,
>> +    11,10, 9,12,     7,11, 6, 8,     9, 8,10, 1,     7, 6, 5, 4,
>> +},
>> +{
>> +    15, 0, 0, 0,
>> +    15,14, 0, 0,    11,15,13, 0,     8,12,14,12,    15,10,11,11,
>> +    11, 8, 9,10,     9,14,13, 9,     8,10, 9, 8,    15,14,13,13,
>> +    11,14,10,12,    15,10,13,12,    11,14, 9,12,     8,10,13, 8,
>> +    13, 7, 9,12,     9,12,11,10,     5, 8, 7, 6,     1, 4, 3, 2,
>> +},
>> +{
>> +     3, 0, 0, 0,
>> +     0, 1, 0, 0,     4, 5, 6, 0,     8, 9,10,11,    12,13,14,15,
>> +    16,17,18,19,    20,21,22,23,    24,25,26,27,    28,29,30,31,
>> +    32,33,34,35,    36,37,38,39,    40,41,42,43,    44,45,46,47,
>> +    48,49,50,51,    52,53,54,55,    56,57,58,59,    60,61,62,63,
>> +}
>> +};
>> +
>> +const uint8_t ff_h264_cavlc_total_zeros_len[16][16]= {
>> +    {1,3,3,4,4,5,5,6,6,7,7,8,8,9,9,9},
>> +    {3,3,3,3,3,4,4,4,4,5,5,6,6,6,6},
>> +    {4,3,3,3,4,4,3,3,4,5,5,6,5,6},
>> +    {5,3,4,4,3,3,3,4,3,4,5,5,5},
>> +    {4,4,4,3,3,3,3,3,4,5,4,5},
>> +    {6,5,3,3,3,3,3,3,4,3,6},
>> +    {6,5,3,3,3,2,3,4,3,6},
>> +    {6,4,5,3,2,2,3,3,6},
>> +    {6,6,4,2,2,3,2,5},
>> +    {5,5,3,2,2,2,4},
>> +    {4,4,3,3,1,3},
>> +    {4,4,2,1,3},
>> +    {3,3,1,2},
>> +    {2,2,1},
>> +    {1,1},
>> +};
>> +
>> +const uint8_t ff_h264_cavlc_total_zeros_bits[16][16]= {
>> +    {1,3,2,3,2,3,2,3,2,3,2,3,2,3,2,1},
>> +    {7,6,5,4,3,5,4,3,2,3,2,3,2,1,0},
>> +    {5,7,6,5,4,3,4,3,2,3,2,1,1,0},
>> +    {3,7,5,4,6,5,4,3,3,2,2,1,0},
>> +    {5,4,3,7,6,5,4,3,2,1,1,0},
>> +    {1,1,7,6,5,4,3,2,1,1,0},
>> +    {1,1,5,4,3,3,2,1,1,0},
>> +    {1,1,1,3,3,2,2,1,0},
>> +    {1,0,1,3,2,1,1,1},
>> +    {1,0,1,3,2,1,1},
>> +    {0,1,1,2,1,3},
>> +    {0,1,1,1,1},
>> +    {0,1,1,1},
>> +    {0,1,1},
>> +    {0,1},
>> +};
>> +
>> +const uint8_t ff_h264_cavlc_run_len[7][16]={
>> +    {1,1},
>> +    {1,2,2},
>> +    {2,2,2,2},
>> +    {2,2,2,3,3},
>> +    {2,2,3,3,3,3},
>> +    {2,3,3,3,3,3,3},
>> +    {3,3,3,3,3,3,3,4,5,6,7,8,9,10,11},
>> +};
>> +
>> +const uint8_t ff_h264_cavlc_run_bits[7][16]={
>> +    {1,0},
>> +    {1,1,0},
>> +    {3,2,1,0},
>> +    {3,2,1,1,0},
>> +    {3,2,3,2,1,0},
>> +    {3,0,1,3,2,5,4},
>> +    {7,6,5,4,3,2,1,1,1,1,1,1,1,1,1},
>> +};
>> diff --git a/libavcodec/h264_cavlc_data.h b/libavcodec/h264_cavlc_data.h
>> new file mode 100644
>> index 0000000000..f20453fa26
>> --- /dev/null
>> +++ b/libavcodec/h264_cavlc_data.h
>> @@ -0,0 +1,33 @@
>> +/*
>> + * This file is part of FFmpeg.
>> + *
>> + * 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.
>> + *
>> + * 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 FFmpeg; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>> + */
>> +
>> +#ifndef AVCODEC_H264_CAVLC_DATA_H
>> +#define AVCODEC_H264_CAVLC_DATA_H
>> +
>> +#include <stdint.h>
>> +
>> +extern const uint8_t ff_h264_cavlc_coeff_token_len[4][4*17];
>> +extern const uint8_t ff_h264_cavlc_coeff_token_bits[4][4*17];
>> +
>> +extern const uint8_t ff_h264_cavlc_total_zeros_len[16][16];
>> +extern const uint8_t ff_h264_cavlc_total_zeros_bits[16][16];
>> +
>> +extern const uint8_t ff_h264_cavlc_run_len[7][16];
>> +extern const uint8_t ff_h264_cavlc_run_bits[7][16];
>> +
>> +#endif /* AVCODEC_H264_CAVLC_DATA_H */
>> diff --git a/libavcodec/version.h b/libavcodec/version.h
>> index 4299ad4239..f992e1b36e 100644
>> --- a/libavcodec/version.h
>> +++ b/libavcodec/version.h
>> @@ -28,7 +28,7 @@
>>  #include "libavutil/version.h"
>>
>>  #define LIBAVCODEC_VERSION_MAJOR  58
>> -#define LIBAVCODEC_VERSION_MINOR 131
>> +#define LIBAVCODEC_VERSION_MINOR 132
>>  #define LIBAVCODEC_VERSION_MICRO 100
>>
>>  #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
>> diff --git a/libavformat/riff.c b/libavformat/riff.c
>> index 270ff7c024..5d5cfe16b0 100644
>> --- a/libavformat/riff.c
>> +++ b/libavformat/riff.c
>> @@ -496,6 +496,8 @@ const AVCodecTag ff_codec_bmp_tags[] = {
>>      { AV_CODEC_ID_MVHA,         MKTAG('M', 'V', 'H', 'A') },
>>      { AV_CODEC_ID_MV30,         MKTAG('M', 'V', '3', '0') },
>>      { AV_CODEC_ID_NOTCHLC,      MKTAG('n', 'l', 'c', '1') },
>> +    { AV_CODEC_ID_ACTIMAGINE,   MKTAG('V', 'X', 'S', '1') },
>> +    { AV_CODEC_ID_ACTIMAGINE,   MKTAG('v', 'x', 's', '1') },
>>      { AV_CODEC_ID_NONE,         0 }
>>  };
>>
>> --
>> 2.17.1
>>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
> 



More information about the ffmpeg-devel mailing list