| Author | Tokens | Token Proportion | Commits | Commit Proportion |
|---|---|---|---|---|
| Detlev Casanova | 742 | 73.39% | 3 | 33.33% |
| Boris Brezillon | 179 | 17.71% | 1 | 11.11% |
| Jonas Karlman | 69 | 6.82% | 1 | 11.11% |
| Nicolas Dufresne | 11 | 1.09% | 2 | 22.22% |
| Ezequiel García | 10 | 0.99% | 2 | 22.22% |
| Total | 1011 | 9 |
// SPDX-License-Identifier: GPL-2.0 /* * Rockchip video decoder h264 common functions * * Copyright (C) 2025 Collabora, Ltd. * Detlev Casanova <detlev.casanova@collabora.com> * * 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 <linux/v4l2-common.h> #include <media/v4l2-h264.h> #include <media/v4l2-mem2mem.h> #include "rkvdec.h" #include "rkvdec-h264-common.h" #define RKVDEC_NUM_REFLIST 3 void lookup_ref_buf_idx(struct rkvdec_ctx *ctx, struct rkvdec_h264_run *run) { const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params; u32 i; for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) { struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; const struct v4l2_h264_dpb_entry *dpb = run->decode_params->dpb; struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q; struct vb2_buffer *buf = NULL; if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) { buf = vb2_find_buffer(cap_q, dpb[i].reference_ts); if (!buf) pr_debug("No buffer for reference_ts %llu", dpb[i].reference_ts); } run->ref_buf[i] = buf; } } void assemble_hw_rps(struct v4l2_h264_reflist_builder *builder, struct rkvdec_h264_run *run, struct rkvdec_h264_reflists *reflists, struct rkvdec_rps *hw_rps) { const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params; const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb; u32 i, j; memset(hw_rps, 0, sizeof(*hw_rps)); /* * Assign an invalid pic_num if DPB entry at that position is inactive. * If we assign 0 in that position hardware will treat that as a real * reference picture with pic_num 0, triggering output picture * corruption. */ for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) { if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) continue; rkvdec_set_bw_field(hw_rps->info, RPS_FRAME_NUM(i), builder->refs[i].frame_num); } for (j = 0; j < RKVDEC_NUM_REFLIST; j++) { for (i = 0; i < builder->num_valid; i++) { struct v4l2_h264_reference *ref; bool dpb_valid; bool bottom; switch (j) { case 0: ref = &reflists->p[i]; break; case 1: ref = &reflists->b0[i]; break; case 2: ref = &reflists->b1[i]; break; } if (WARN_ON(ref->index >= ARRAY_SIZE(dec_params->dpb))) continue; dpb_valid = !!(run->ref_buf[ref->index]); bottom = ref->fields == V4L2_H264_BOTTOM_FIELD_REF; rkvdec_set_bw_field(hw_rps->info, RPS_ENTRY_DPB_INFO(j, i), ref->index | (dpb_valid << 4)); rkvdec_set_bw_field(hw_rps->info, RPS_ENTRY_BOTTOM_FLAG(j, i), bottom); } } } void assemble_hw_scaling_list(struct rkvdec_h264_run *run, struct rkvdec_h264_scaling_list *scaling_list) { const struct v4l2_ctrl_h264_scaling_matrix *scaling = run->scaling_matrix; const struct v4l2_ctrl_h264_pps *pps = run->pps; if (!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT)) return; BUILD_BUG_ON(sizeof(scaling_list->scaling_list_4x4) != sizeof(scaling->scaling_list_4x4)); BUILD_BUG_ON(sizeof(scaling_list->scaling_list_8x8) != sizeof(scaling->scaling_list_8x8)); memcpy(scaling_list->scaling_list_4x4, scaling->scaling_list_4x4, sizeof(scaling->scaling_list_4x4)); memcpy(scaling_list->scaling_list_8x8, scaling->scaling_list_8x8, sizeof(scaling->scaling_list_8x8)); } #define RKVDEC_H264_MAX_DEPTH_IN_BYTES 2 int rkvdec_h264_adjust_fmt(struct rkvdec_ctx *ctx, struct v4l2_format *f) { struct v4l2_pix_format_mplane *fmt = &f->fmt.pix_mp; fmt->num_planes = 1; if (!fmt->plane_fmt[0].sizeimage) fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height * RKVDEC_H264_MAX_DEPTH_IN_BYTES; return 0; } enum rkvdec_image_fmt rkvdec_h264_get_image_fmt(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl) { const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps; if (ctrl->id != V4L2_CID_STATELESS_H264_SPS) return RKVDEC_IMG_FMT_ANY; if (sps->bit_depth_luma_minus8 == 0) { if (sps->chroma_format_idc == 2) return RKVDEC_IMG_FMT_422_8BIT; else return RKVDEC_IMG_FMT_420_8BIT; } else if (sps->bit_depth_luma_minus8 == 2) { if (sps->chroma_format_idc == 2) return RKVDEC_IMG_FMT_422_10BIT; else return RKVDEC_IMG_FMT_420_10BIT; } return RKVDEC_IMG_FMT_ANY; } int rkvdec_h264_validate_sps(struct rkvdec_ctx *ctx, const struct v4l2_ctrl_h264_sps *sps) { unsigned int width, height; if (sps->chroma_format_idc > 2) /* Only 4:0:0, 4:2:0 and 4:2:2 are supported */ return -EINVAL; if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8) /* Luma and chroma bit depth mismatch */ return -EINVAL; if (sps->bit_depth_luma_minus8 != 0 && sps->bit_depth_luma_minus8 != 2) /* Only 8-bit and 10-bit is supported */ return -EINVAL; width = (sps->pic_width_in_mbs_minus1 + 1) * 16; height = (sps->pic_height_in_map_units_minus1 + 1) * 16; /* * When frame_mbs_only_flag is not set, this is field height, * which is half the final height (see (7-18) in the * specification) */ if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)) height *= 2; if (width > ctx->coded_fmt.fmt.pix_mp.width || height > ctx->coded_fmt.fmt.pix_mp.height) return -EINVAL; return 0; } void rkvdec_h264_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_h264_run *run) { struct v4l2_ctrl *ctrl; ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, V4L2_CID_STATELESS_H264_DECODE_PARAMS); run->decode_params = ctrl ? ctrl->p_cur.p : NULL; ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, V4L2_CID_STATELESS_H264_SPS); run->sps = ctrl ? ctrl->p_cur.p : NULL; ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, V4L2_CID_STATELESS_H264_PPS); run->pps = ctrl ? ctrl->p_cur.p : NULL; ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, V4L2_CID_STATELESS_H264_SCALING_MATRIX); run->scaling_matrix = ctrl ? ctrl->p_cur.p : NULL; rkvdec_run_preamble(ctx, &run->base); }
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1