void (*irq_clear)(struct cedrus_ctx *ctx);
void (*irq_disable)(struct cedrus_ctx *ctx);
enum cedrus_irq_status (*irq_status)(struct cedrus_ctx *ctx);
- void (*setup)(struct cedrus_ctx *ctx, struct cedrus_run *run);
+ int (*setup)(struct cedrus_ctx *ctx, struct cedrus_run *run);
int (*start)(struct cedrus_ctx *ctx);
void (*stop)(struct cedrus_ctx *ctx);
void (*trigger)(struct cedrus_ctx *ctx);
struct cedrus_dev *dev = ctx->dev;
struct cedrus_run run = {};
struct media_request *src_req;
+ int error;
run.src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
run.dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
cedrus_dst_format_set(dev, &ctx->dst_fmt);
- dev->dec_ops[ctx->current_codec]->setup(ctx, &run);
+ error = dev->dec_ops[ctx->current_codec]->setup(ctx, &run);
+ if (error)
+ v4l2_err(&ctx->dev->v4l2_dev,
+ "Failed to setup decoding job: %d\n", error);
/* Complete request(s) controls if needed. */
if (src_req)
v4l2_ctrl_request_complete(src_req, &ctx->hdl);
- dev->dec_ops[ctx->current_codec]->trigger(ctx);
-
- /* Start the watchdog timer. */
- schedule_delayed_work(&dev->watchdog_work,
- msecs_to_jiffies(2000));
+ /* Trigger decoding if setup went well, bail out otherwise. */
+ if (!error) {
+ dev->dec_ops[ctx->current_codec]->trigger(ctx);
+
+ /* Start the watchdog timer. */
+ schedule_delayed_work(&dev->watchdog_work,
+ msecs_to_jiffies(2000));
+ } else {
+ v4l2_m2m_buf_done_and_job_finish(ctx->dev->m2m_dev,
+ ctx->fh.m2m_ctx,
+ VB2_BUF_STATE_ERROR);
+ }
}
reg & ~VE_H264_CTRL_INT_MASK);
}
-static void cedrus_h264_setup(struct cedrus_ctx *ctx,
- struct cedrus_run *run)
+static int cedrus_h264_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
{
struct cedrus_dev *dev = ctx->dev;
cedrus_write_frame_list(ctx, run);
cedrus_set_params(ctx, run);
+
+ return 0;
}
static int cedrus_h264_start(struct cedrus_ctx *ctx)
return 0;
}
-static void cedrus_h265_setup(struct cedrus_ctx *ctx,
- struct cedrus_run *run)
+static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
{
struct cedrus_dev *dev = ctx->dev;
const struct v4l2_ctrl_hevc_sps *sps;
GFP_KERNEL, DMA_ATTR_NO_KERNEL_MAPPING);
if (!ctx->codec.h265.mv_col_buf) {
ctx->codec.h265.mv_col_buf_size = 0;
- // TODO: Abort the process here.
- return;
+ return -ENOMEM;
}
}
/* Enable appropriate interruptions. */
cedrus_write(dev, VE_DEC_H265_CTRL, VE_DEC_H265_CTRL_IRQ_MASK);
+
+ return 0;
}
static int cedrus_h265_start(struct cedrus_ctx *ctx)
cedrus_write(dev, VE_DEC_MPEG_CTRL, reg);
}
-static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
+static int cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
{
const struct v4l2_ctrl_mpeg2_sequence *seq;
const struct v4l2_ctrl_mpeg2_picture *pic;
VE_DEC_MPEG_CTRL_MC_CACHE_EN;
cedrus_write(dev, VE_DEC_MPEG_CTRL, reg);
+
+ return 0;
}
static void cedrus_mpeg2_trigger(struct cedrus_ctx *ctx)
reg & ~VE_H264_CTRL_INT_MASK);
}
-static void cedrus_vp8_setup(struct cedrus_ctx *ctx,
- struct cedrus_run *run)
+static int cedrus_vp8_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
{
const struct v4l2_ctrl_vp8_frame *slice = run->vp8.frame_params;
struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q;
ctx->codec.vp8.last_sharpness_level =
slice->lf.sharpness_level;
}
+
+ return 0;
}
static int cedrus_vp8_start(struct cedrus_ctx *ctx)