drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c
Extension
.c
Size
6051 bytes
Lines
216
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

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));
}

Annotation

Implementation Notes