@@ -898,15 +898,14 @@ static struct vpe_ctx *file2ctx(struct file *file)
static int job_ready(void *priv)
{
struct vpe_ctx *ctx = priv;
- int needed = ctx->bufs_per_job;
- if (ctx->deinterlacing && ctx->src_vbs[2] == NULL)
- needed += 2; /* need additional two most recent fields */
-
- if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) < needed)
- return 0;
-
- if (v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) < needed)
+ /*
+ * This check is needed as this might be called directly from driver
+ * When called by m2m framework, this will always satisfy, but when
+ * called from vpe_irq, this might fail. (src stream with zero buffers)
+ */
+ if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) <= 0 ||
+ v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) <= 0)
return 0;
return 1;
@@ -1116,19 +1115,20 @@ static void device_run(void *priv)
struct sc_data *sc = ctx->dev->sc;
struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST];
- if (ctx->deinterlacing && ctx->src_vbs[2] == NULL) {
- ctx->src_vbs[2] = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
- WARN_ON(ctx->src_vbs[2] == NULL);
- ctx->src_vbs[1] = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
- WARN_ON(ctx->src_vbs[1] == NULL);
- }
-
ctx->src_vbs[0] = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
WARN_ON(ctx->src_vbs[0] == NULL);
ctx->dst_vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
WARN_ON(ctx->dst_vb == NULL);
if (ctx->deinterlacing) {
+
+ if (ctx->src_vbs[2] == NULL) {
+ ctx->src_vbs[2] = ctx->src_vbs[0];
+ WARN_ON(ctx->src_vbs[2] == NULL);
+ ctx->src_vbs[1] = ctx->src_vbs[0];
+ WARN_ON(ctx->src_vbs[1] == NULL);
+ }
+
/*
* we have output the first 2 frames through line average, we
* now switch to EDI de-interlacer
@@ -1348,7 +1348,7 @@ static irqreturn_t vpe_irq(int irq_vpe, void *data)
}
ctx->bufs_completed++;
- if (ctx->bufs_completed < ctx->bufs_per_job) {
+ if (ctx->bufs_completed < ctx->bufs_per_job && job_ready(ctx)) {
device_run(ctx);
goto handled;
}