drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec.c
Extension
.c
Size
30051 bytes
Lines
1042
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 (!vb2_is_streaming(src_vq)) {
			mtk_v4l2_vdec_dbg(1, ctx, "Output stream is off. No need to flush.");
			return 0;
		}
		if (!vb2_is_streaming(dst_vq)) {
			mtk_v4l2_vdec_dbg(1, ctx, "Capture stream is off. No need to flush.");
			return 0;
		}
		v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf.vb);
		v4l2_m2m_try_schedule(ctx->m2m_ctx);
		break;

	case V4L2_DEC_CMD_START:
		vb2_clear_last_buffer_dequeued(dst_vq);
		break;

	default:
		return -EINVAL;
	}

	return 0;
}

static int stateless_try_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd)
{
	return v4l2_m2m_ioctl_stateless_try_decoder_cmd(file, priv, cmd);
}

static int stateless_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd)
{
	struct mtk_vcodec_dec_ctx *ctx = file_to_dec_ctx(file);
	int ret;

	ret = v4l2_m2m_ioctl_stateless_try_decoder_cmd(file, priv, cmd);
	if (ret)
		return ret;

	mtk_v4l2_vdec_dbg(3, ctx, "decoder cmd=%u", cmd->cmd);
	switch (cmd->cmd) {
	case V4L2_DEC_CMD_FLUSH:
		/*
		 * If the flag of the output buffer is equals V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF,
		 * this command will prevent dequeueing the capture buffer containing the last
		 * decoded frame. Or do nothing
		 */
		break;
	default:
		mtk_v4l2_vdec_err(ctx, "invalid stateless decoder cmd=%u", cmd->cmd);
		return -EINVAL;
	}

	return 0;
}

static int vidioc_try_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd)
{
	struct mtk_vcodec_dec_ctx *ctx = file_to_dec_ctx(file);

	if (ctx->dev->vdec_pdata->uses_stateless_api)
		return stateless_try_decoder_cmd(file, priv, cmd);

	return stateful_try_decoder_cmd(file, priv, cmd);
}

static int vidioc_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd)
{
	struct mtk_vcodec_dec_ctx *ctx = file_to_dec_ctx(file);

	if (ctx->dev->vdec_pdata->uses_stateless_api)
		return stateless_decoder_cmd(file, priv, cmd);

	return stateful_decoder_cmd(file, priv, cmd);
}

void mtk_vdec_unlock(struct mtk_vcodec_dec_ctx *ctx)
{
	mutex_unlock(&ctx->dev->dec_mutex[ctx->hw_id]);
}

void mtk_vdec_lock(struct mtk_vcodec_dec_ctx *ctx)
{
	mutex_lock(&ctx->dev->dec_mutex[ctx->hw_id]);
}

void mtk_vcodec_dec_release(struct mtk_vcodec_dec_ctx *ctx)
{
	vdec_if_deinit(ctx);
	ctx->state = MTK_STATE_FREE;
}

Annotation

Implementation Notes