// SPDX-License-Identifier: GPL-2.0
/*
* Rockchip Video Decoder H264 backend
*
* Copyright (C) 2019 Collabora, Ltd.
* Boris Brezillon <boris.brezillon@collabora.com>
*
* Copyright (C) 2016 Rockchip Electronics Co., Ltd.
* Jeffy Chen <jeffy.chen@rock-chips.com>
*/
#include <media/v4l2-h264.h>
#include <media/v4l2-mem2mem.h>
#include "rkvdec.h"
#include "rkvdec-regs.h"
/* Size with u32 units. */
#define RKV_CABAC_INIT_BUFFER_SIZE (3680 + 128)
#define RKV_RPS_SIZE ((128 + 128) / 4)
#define RKV_ERROR_INFO_SIZE (256 * 144 * 4)
#define RKVDEC_NUM_REFLIST 3
struct rkvdec_h264_scaling_list {
u8 scaling_list_4x4[6][16];
u8 scaling_list_8x8[6][64];
u8 padding[128];
};
struct rkvdec_sps_pps_packet {
u32 info[8];
};
struct rkvdec_ps_field {
u16 offset;
u8 len;
};
#define PS_FIELD(_offset, _len) \
((struct rkvdec_ps_field){ _offset, _len })
#define SEQ_PARAMETER_SET_ID PS_FIELD(0, 4)
#define PROFILE_IDC PS_FIELD(4, 8)
#define CONSTRAINT_SET3_FLAG PS_FIELD(12, 1)
#define CHROMA_FORMAT_IDC PS_FIELD(13, 2)
#define BIT_DEPTH_LUMA PS_FIELD(15, 3)
#define BIT_DEPTH_CHROMA PS_FIELD(18, 3)
#define QPPRIME_Y_ZERO_TRANSFORM_BYPASS_FLAG PS_FIELD(21, 1)
#define LOG2_MAX_FRAME_NUM_MINUS4 PS_FIELD(22, 4)
#define MAX_NUM_REF_FRAMES PS_FIELD(26, 5)
#define PIC_ORDER_CNT_TYPE PS_FIELD(31, 2)
#define LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4 PS_FIELD(33, 4)
#define DELTA_PIC_ORDER_ALWAYS_ZERO_FLAG PS_FIELD(37, 1)
#define PIC_WIDTH_IN_MBS PS_FIELD(38, 9)
#define PIC_HEIGHT_IN_MBS PS_FIELD(47, 9)
#define FRAME_MBS_ONLY_FLAG PS_FIELD(56, 1)
#define MB_ADAPTIVE_FRAME_FIELD_FLAG PS_FIELD(57, 1)
#define DIRECT_8X8_INFERENCE_FLAG PS_FIELD(58, 1)
#define MVC_EXTENSION_ENABLE PS_FIELD(59, 1)
#define NUM_VIEWS PS_FIELD(60, 2)
#define VIEW_ID(i) PS_FIELD(62 + ((i) * 10), 10)
#define NUM_ANCHOR_REFS_L(i) PS_FIELD(82 + ((i) * 11), 1)
#define ANCHOR_REF_L(i) PS_FIELD(83 + ((i) * 11), 10)
#define NUM_NON_ANCHOR_REFS_L(i) PS_FIELD(104 + ((i) * 11), 1)
#define NON_ANCHOR_REFS_L(i) PS_FIELD(105 + ((i) * 11), 10)
#define PIC_PARAMETER_SET_ID PS_FIELD(128, 8)
#define PPS_SEQ_PARAMETER_SET_ID PS_FIELD(136, 5)
#define ENTROPY_CODING_MODE_FLAG PS_FIELD(141, 1)
#define BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT_FLAG PS_FIELD(142, 1)
#define NUM_REF_IDX_L_DEFAULT_ACTIVE_MINUS1(i) PS_FIELD(143 + ((i) * 5), 5)
#define WEIGHTED_PRED_FLAG PS_FIELD(153, 1)
#define WEIGHTED_BIPRED_IDC PS_FIELD(154, 2)
#define PIC_INIT_QP_MINUS26 PS_FIELD(156, 7)
#define PIC_INIT_QS_MINUS26 PS_FIELD(163, 6)
#define CHROMA_QP_INDEX_OFFSET PS_FIELD(169, 5)
#define DEBLOCKING_FILTER_CONTROL_PRESENT_FLAG PS_FIELD(174, 1)
#define CONSTRAINED_INTRA_PRED_FLAG PS_FIELD(175, 1)
#define REDUNDANT_PIC_CNT_PRESENT PS_FIELD(176, 1)
#define TRANSFORM_8X8_MODE_FLAG PS_FIELD(177, 1)
#define SECOND_CHROMA_QP_INDEX_OFFSET PS_FIELD(178, 5)
#define SCALING_LIST_ENABLE_FLAG PS_FIELD(183, 1)
#define SCALING_LIST_ADDRESS PS_FIELD(184, 32)
#define IS_LONG_TERM(i) PS_FIELD(216 + (i), 1)
#define DPB_OFFS(i, j) (288 + ((j) * 32 * 7) + ((i) * 7))
#define DPB_INFO(i, j) PS_FIELD(DPB_OFFS(i, j), 5)
#define BOTTOM_FLAG(i, j) PS_FIELD(DPB_OFFS(i, j) + 5, 1)
#define VIEW_INDEX_OFF(i, j) PS_FIELD(DPB_OFFS(i, j) + 6, 1)
/* Data structure describing auxiliary buffer format. */
struct rkvdec_h264_priv_tbl {
s8 cabac_table[4][464][2];
struct rkvdec_h264_scaling_list scaling_list;
u32 rps[RKV_RPS_SIZE];
struct rkvdec_sps_pps_packet param_set[256];
u8 err_info[RKV_ERROR_INFO_SIZE];
};
#define RKVDEC_H264_DPB_SIZE 16
struct rkvdec_h264_reflists {
u8 p[RKVDEC_H264_DPB_SIZE];
u8 b0[RKVDEC_H264_DPB_SIZE];
u8 b1[RKVDEC_H264_DPB_SIZE];
u8 num_valid;
};
struct rkvdec_h264_run {
struct rkvdec_run base;
const struct v4l2_ctrl_h264_decode_params *decode_params;
const struct v4l2_ctrl_h264_sps *sps;
const struct v4l2_ctrl_h264_pps *pps;
const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix;
};
struct rkvdec_h264_ctx {
struct rkvdec_aux_buf priv_tbl;
struct rkvdec_h264_reflists reflists;
};
#define CABAC_ENTRY(ctxidx, idc0_m, idc0_n, idc1_m, idc1_n, \
idc2_m, idc2_n, intra_m, intra_n) \
[0][(ctxidx)] = {idc0_m, idc0_n}, \
[1][(ctxidx)] = {idc1_m, idc1_n}, \
[2][(ctxidx)] = {idc2_m, idc2_n}, \
[3][(ctxidx)] = {intra_m, intra_n}
/*
* Constant CABAC table.
* Built from the tables described in section '9.3.1.1 Initialisation process
* for context variables' of the H264 spec.
*/
static const s8 rkvdec_h264_cabac_table[4][464][2] = {
/* Table 9-12 – Values of variables m and n for ctxIdx from 0 to 10 */
CABAC_ENTRY(0, 20, -15, 20, -15, 20, -15, 20, -15),
CABAC_ENTRY(1, 2, 54, 2, 54, 2, 54, 2, 54),
CABAC_ENTRY(2, 3, 74, 3, 74, 3, 74, 3, 74),
CABAC_ENTRY(3, 20, -15, 20, -15, 20, -15, 20, -15),
CABAC_ENTRY(4, 2, 54, 2, 54, 2, 54, 2, 54),
CABAC_ENTRY(5, 3, 74, 3, 74, 3, 74, 3, 74),
CABAC_ENTRY(6, -28, 127, -28, 127, -28, 127, -28, 127),
CABAC_ENTRY(7, -23, 104, -23, 104, -23, 104, -23, 104),