drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c
Extension
.c
Size
58961 bytes
Lines
1869
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 (inst->src_fmt.num_planes == 1) {
			frame_buf.buf_y =
				vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
			frame_buf.buf_cb = frame_buf.buf_y + luma_size;
			frame_buf.buf_cr = frame_buf.buf_cb + chroma_size;
		} else if (inst->src_fmt.num_planes == 2) {
			frame_buf.buf_y =
				vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
			frame_buf.buf_cb =
				vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 1);
			frame_buf.buf_cr = frame_buf.buf_cb + chroma_size;
		} else if (inst->src_fmt.num_planes == 3) {
			frame_buf.buf_y =
				vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
			frame_buf.buf_cb =
				vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 1);
			frame_buf.buf_cr =
				vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 2);
		}
		frame_buf.stride = stride;
		pic_param.src_idx = src_buf->vb2_buf.index;
	}

	pic_param.source_frame = &frame_buf;
	pic_param.code_option.implicit_header_encode = 1;
	pic_param.code_option.encode_aud = inst->encode_aud;
	ret = wave5_vpu_enc_start_one_frame(inst, &pic_param, fail_res);
	if (ret) {
		if (*fail_res == WAVE5_SYSERR_QUEUEING_FAIL)
			return -EINVAL;

		dev_dbg(inst->dev->dev, "%s: wave5_vpu_enc_start_one_frame fail: %d\n",
			__func__, ret);
		src_buf = v4l2_m2m_src_buf_remove(m2m_ctx);
		if (!src_buf) {
			dev_dbg(inst->dev->dev,
				"%s: Removing src buf failed, the queue is empty\n",
				__func__);
			return -EINVAL;
		}
		dst_buf = v4l2_m2m_dst_buf_remove(m2m_ctx);
		if (!dst_buf) {
			dev_dbg(inst->dev->dev,
				"%s: Removing dst buf failed, the queue is empty\n",
				__func__);
			return -EINVAL;
		}
		switch_state(inst, VPU_INST_STATE_STOP);
		dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
		v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
		v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
	} else {
		dev_dbg(inst->dev->dev, "%s: wave5_vpu_enc_start_one_frame success\n",
			__func__);
	}

	return 0;
}

static void wave5_vpu_enc_finish_encode(struct vpu_instance *inst)
{
	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
	int ret;
	struct enc_output_info enc_output_info;
	struct vb2_v4l2_buffer *src_buf = NULL;
	struct vb2_v4l2_buffer *dst_buf = NULL;

	ret = wave5_vpu_enc_get_output_info(inst, &enc_output_info);
	if (ret) {
		dev_dbg(inst->dev->dev,
			"%s: vpu_enc_get_output_info fail: %d  reason: %u | info: %u\n",
			__func__, ret, enc_output_info.error_reason, enc_output_info.warn_info);
		return;
	}

	dev_dbg(inst->dev->dev,
		"%s: pic_type %i recon_idx %i src_idx %i pic_byte %u pts %llu\n",
		__func__,  enc_output_info.pic_type, enc_output_info.recon_frame_index,
		enc_output_info.enc_src_idx, enc_output_info.enc_pic_byte, enc_output_info.pts);

	if (enc_output_info.enc_src_idx >= 0) {
		src_buf = v4l2_m2m_src_buf_remove_by_idx(m2m_ctx, enc_output_info.enc_src_idx);
		if (!src_buf) {
			dev_warn(inst->dev->dev, "%s: no source buffer found\n", __func__);
		} else {
			inst->timestamp = src_buf->vb2_buf.timestamp;
			v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
		}
	}

Annotation

Implementation Notes