/*
 * VP9 compatible video decoder
 *
 * Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
 * Copyright (C) 2013 Clément Bœsch <u pkh me>
 *
 * 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_VP9DEC_H
#define AVCODEC_VP9DEC_H

#include <stddef.h>
#include <stdint.h>
#include <stdatomic.h>

#include "libavutil/buffer.h"
#include "libavutil/mem_internal.h"
#include "libavutil/thread.h"
#include "libavutil/internal.h"

#include "vp9.h"
#include "vp9dsp.h"
#include "vp9shared.h"

#define REF_INVALID_SCALE 0xFFFF

enum MVJoint {
    MV_JOINT_ZERO,
    MV_JOINT_H,
    MV_JOINT_V,
    MV_JOINT_HV,
};

typedef struct ProbContext {
    uint8_t y_mode[4][9];
    uint8_t uv_mode[10][9];
    uint8_t filter[4][2];
    uint8_t mv_mode[7][3];
    uint8_t intra[4];
    uint8_t comp[5];
    uint8_t single_ref[5][2];
    uint8_t comp_ref[5];
    uint8_t tx32p[2][3];
    uint8_t tx16p[2][2];
    uint8_t tx8p[2];
    uint8_t skip[3];
    uint8_t mv_joint[3];
    struct {
        uint8_t sign;
        uint8_t classes[10];
        uint8_t class0;
        uint8_t bits[10];
        uint8_t class0_fp[2][3];
        uint8_t fp[3];
        uint8_t class0_hp;
        uint8_t hp;
    } mv_comp[2];
    uint8_t partition[4][4][3];
} ProbContext;

typedef struct VP9Filter {
    uint8_t level[8 * 8];
    uint8_t /* bit=col */ mask[2 /* 0=y, 1=uv */][2 /* 0=col, 1=row */]
                              [8 /* rows */][4 /* 0=16, 1=8, 2=4, 3=inner4 */];
} VP9Filter;

typedef struct VP9Block {
    uint8_t seg_id, intra, comp, ref[2], mode[4], uvmode, skip;
    enum FilterMode filter;
    VP56mv mv[4 /* b_idx */][2 /* ref */];
    enum BlockSize bs;
    enum TxfmMode tx, uvtx;
    enum BlockLevel bl;
    enum BlockPartition bp;
} VP9Block;

typedef struct VP9TileData VP9TileData;

typedef struct VP9Context {
    VP9SharedContext s;
    VP9TileData *td;

    VP9DSPContext dsp;
    VideoDSPContext vdsp;
    GetBitContext gb;
    VP56RangeCoder c;
    int pass, active_tile_cols;

#if HAVE_THREADS
    pthread_mutex_t progress_mutex;
    pthread_cond_t progress_cond;
    atomic_int *entries;
    unsigned pthread_init_cnt;
#endif

    uint8_t ss_h, ss_v;
    uint8_t last_bpp, bpp_index, bytesperpixel;
    uint8_t last_keyframe;
    // sb_cols/rows, rows/cols and last_fmt are used for allocating all internal
    // arrays, and are thus per-thread. w/h and gf_fmt are synced between threads
    // and are therefore per-stream. pix_fmt represents the value in the header
    // of the currently processed frame.
    int w, h;
    enum AVPixelFormat pix_fmt, last_fmt, gf_fmt;
    unsigned sb_cols, sb_rows, rows, cols;
    ThreadFrame next_refs[8];

    struct {
        uint8_t lim_lut[64];
        uint8_t mblim_lut[64];
    } filter_lut;
    struct {
        ProbContext p;
        uint8_t coef[4][2][2][6][6][3];
    } prob_ctx[4];
    struct {
        ProbContext p;
        uint8_t coef[4][2][2][6][6][11];
    } prob;

    // contextual (above) cache
    uint8_t *above_partition_ctx;
    uint8_t *above_mode_ctx;
    // FIXME maybe merge some of the below in a flags field?
    uint8_t *above_y_nnz_ctx;
    uint8_t *above_uv_nnz_ctx[2];
    uint8_t *above_skip_ctx; // 1bit
    uint8_t *above_txfm_ctx; // 2bit
    uint8_t *above_segpred_ctx; // 1bit
    uint8_t *above_intra_ctx; // 1bit
    uint8_t *above_comp_ctx; // 1bit
    uint8_t *above_ref_ctx; // 2bit
    uint8_t *above_filter_ctx;
    VP56mv (*above_mv_ctx)[2];

    // whole-frame cache
    uint8_t *intra_pred_data[3];
    VP9Filter *lflvl;

    // block reconstruction intermediates
    int block_alloc_using_2pass;
    uint16_t mvscale[3][2];
    uint8_t mvstep[3][2];

    // frame specific buffer pools
    AVBufferPool *frame_extradata_pool;
    int frame_extradata_pool_size;
} VP9Context;

struct VP9TileData {
    //VP9Context should be const, but because of the threading API(generates
    //a lot of warnings) it's not.
    VP9Context *s;
    VP56RangeCoder *c_b;
    VP56RangeCoder *c;
    int row, row7, col, col7;
    uint8_t *dst[3];
    ptrdiff_t y_stride, uv_stride;
    VP9Block *b_base, *b;
    unsigned tile_col_start;

    struct {
        unsigned y_mode[4][10];
        unsigned uv_mode[10][10];
        unsigned filter[4][3];
        unsigned mv_mode[7][4];
        unsigned intra[4][2];
        unsigned comp[5][2];
        unsigned single_ref[5][2][2];
        unsigned comp_ref[5][2];
        unsigned tx32p[2][4];
        unsigned tx16p[2][3];
        unsigned tx8p[2][2];
        unsigned skip[3][2];
        unsigned mv_joint[4];
        struct {
            unsigned sign[2];
            unsigned classes[11];
            unsigned class0[2];
            unsigned bits[10][2];
            unsigned class0_fp[2][4];
            unsigned fp[4];
            unsigned class0_hp[2];
            unsigned hp[2];
        } mv_comp[2];
        unsigned partition[4][4][4];
        unsigned coef[4][2][2][6][6][3];
        unsigned eob[4][2][2][6][6][2];
    } counts;

    // whole-frame cache
    DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135 * 144 * 2];

    // contextual (left) cache
    DECLARE_ALIGNED(16, uint8_t, left_y_nnz_ctx)[16];
    DECLARE_ALIGNED(16, uint8_t, left_mode_ctx)[16];
    DECLARE_ALIGNED(16, VP56mv, left_mv_ctx)[16][2];
    DECLARE_ALIGNED(16, uint8_t, left_uv_nnz_ctx)[2][16];
    DECLARE_ALIGNED(8, uint8_t, left_partition_ctx)[8];
    DECLARE_ALIGNED(8, uint8_t, left_skip_ctx)[8];
    DECLARE_ALIGNED(8, uint8_t, left_txfm_ctx)[8];
    DECLARE_ALIGNED(8, uint8_t, left_segpred_ctx)[8];
    DECLARE_ALIGNED(8, uint8_t, left_intra_ctx)[8];
    DECLARE_ALIGNED(8, uint8_t, left_comp_ctx)[8];
    DECLARE_ALIGNED(8, uint8_t, left_ref_ctx)[8];
    DECLARE_ALIGNED(8, uint8_t, left_filter_ctx)[8];
    // block reconstruction intermediates
    DECLARE_ALIGNED(32, uint8_t, tmp_y)[64 * 64 * 2];
    DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][64 * 64 * 2];
    struct { int x, y; } min_mv, max_mv;
    int16_t *block_base, *block, *uvblock_base[2], *uvblock[2];
    uint8_t *eob_base, *uveob_base[2], *eob, *uveob[2];

    // error message
    int error_info;
    struct {
        unsigned int row:13;
        unsigned int col:13;
        unsigned int block_size_idx_x:2;
        unsigned int block_size_idx_y:2;
    } *block_structure;
    unsigned int nb_block_structure;
};

void ff_vp9_fill_mv(VP9TileData *td, VP56mv *mv, int mode, int sb);

void ff_vp9_adapt_probs(VP9Context *s);

void ff_vp9_decode_block(VP9TileData *td, int row, int col,
                         VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff,
                         enum BlockLevel bl, enum BlockPartition bp);

void ff_vp9_loopfilter_sb(AVCodecContext *avctx, VP9Filter *lflvl,
                          int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff);

void ff_vp9_intra_recon_8bpp(VP9TileData *td,
                             ptrdiff_t y_off, ptrdiff_t uv_off);
void ff_vp9_intra_recon_16bpp(VP9TileData *td,
                              ptrdiff_t y_off, ptrdiff_t uv_off);
void ff_vp9_inter_recon_8bpp(VP9TileData *td);
void ff_vp9_inter_recon_16bpp(VP9TileData *td);

#endif /* AVCODEC_VP9DEC_H */
