|
@@ -592,7 +592,7 @@ static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx)
|
|
|
return 1;
|
|
|
/* context is ready to encode a frame */
|
|
|
if ((ctx->state == MFCINST_RUNNING ||
|
|
|
- ctx->state == MFCINST_HEAD_PARSED) &&
|
|
|
+ ctx->state == MFCINST_HEAD_PRODUCED) &&
|
|
|
ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)
|
|
|
return 1;
|
|
|
/* context is ready to encode remaining frames */
|
|
@@ -649,6 +649,7 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
|
|
|
struct s5p_mfc_enc_params *p = &ctx->enc_params;
|
|
|
struct s5p_mfc_buf *dst_mb;
|
|
|
unsigned long flags;
|
|
|
+ unsigned int enc_pb_count;
|
|
|
|
|
|
if (p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) {
|
|
|
spin_lock_irqsave(&dev->irqlock, flags);
|
|
@@ -661,18 +662,19 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
|
|
|
vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE);
|
|
|
spin_unlock_irqrestore(&dev->irqlock, flags);
|
|
|
}
|
|
|
- if (IS_MFCV6(dev)) {
|
|
|
- ctx->state = MFCINST_HEAD_PARSED; /* for INIT_BUFFER cmd */
|
|
|
- } else {
|
|
|
+
|
|
|
+ if (!IS_MFCV6(dev)) {
|
|
|
ctx->state = MFCINST_RUNNING;
|
|
|
if (s5p_mfc_ctx_ready(ctx))
|
|
|
set_work_bit_irqsave(ctx);
|
|
|
s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
|
|
|
- }
|
|
|
-
|
|
|
- if (IS_MFCV6(dev))
|
|
|
- ctx->dpb_count = s5p_mfc_hw_call(dev->mfc_ops,
|
|
|
+ } else {
|
|
|
+ enc_pb_count = s5p_mfc_hw_call(dev->mfc_ops,
|
|
|
get_enc_dpb_count, dev);
|
|
|
+ if (ctx->pb_count < enc_pb_count)
|
|
|
+ ctx->pb_count = enc_pb_count;
|
|
|
+ ctx->state = MFCINST_HEAD_PRODUCED;
|
|
|
+ }
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -717,9 +719,9 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
|
|
|
|
|
|
slice_type = s5p_mfc_hw_call(dev->mfc_ops, get_enc_slice_type, dev);
|
|
|
strm_size = s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev);
|
|
|
- mfc_debug(2, "Encoded slice type: %d", slice_type);
|
|
|
- mfc_debug(2, "Encoded stream size: %d", strm_size);
|
|
|
- mfc_debug(2, "Display order: %d",
|
|
|
+ mfc_debug(2, "Encoded slice type: %d\n", slice_type);
|
|
|
+ mfc_debug(2, "Encoded stream size: %d\n", strm_size);
|
|
|
+ mfc_debug(2, "Display order: %d\n",
|
|
|
mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT));
|
|
|
spin_lock_irqsave(&dev->irqlock, flags);
|
|
|
if (slice_type >= 0) {
|
|
@@ -1055,15 +1057,13 @@ static int vidioc_reqbufs(struct file *file, void *priv,
|
|
|
}
|
|
|
ctx->capture_state = QUEUE_BUFS_REQUESTED;
|
|
|
|
|
|
- if (!IS_MFCV6(dev)) {
|
|
|
- ret = s5p_mfc_hw_call(ctx->dev->mfc_ops,
|
|
|
- alloc_codec_buffers, ctx);
|
|
|
- if (ret) {
|
|
|
- mfc_err("Failed to allocate encoding buffers\n");
|
|
|
- reqbufs->count = 0;
|
|
|
- ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
|
|
|
- return -ENOMEM;
|
|
|
- }
|
|
|
+ ret = s5p_mfc_hw_call(ctx->dev->mfc_ops,
|
|
|
+ alloc_codec_buffers, ctx);
|
|
|
+ if (ret) {
|
|
|
+ mfc_err("Failed to allocate encoding buffers\n");
|
|
|
+ reqbufs->count = 0;
|
|
|
+ ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
|
|
|
+ return -ENOMEM;
|
|
|
}
|
|
|
} else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
|
|
|
if (ctx->output_state != QUEUE_FREE) {
|
|
@@ -1071,6 +1071,19 @@ static int vidioc_reqbufs(struct file *file, void *priv,
|
|
|
ctx->output_state);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
+
|
|
|
+ if (IS_MFCV6(dev)) {
|
|
|
+ /* Check for min encoder buffers */
|
|
|
+ if (ctx->pb_count &&
|
|
|
+ (reqbufs->count < ctx->pb_count)) {
|
|
|
+ reqbufs->count = ctx->pb_count;
|
|
|
+ mfc_debug(2, "Minimum %d output buffers needed\n",
|
|
|
+ ctx->pb_count);
|
|
|
+ } else {
|
|
|
+ ctx->pb_count = reqbufs->count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
|
|
|
if (ret != 0) {
|
|
|
mfc_err("error in vb2_reqbufs() for E(S)\n");
|
|
@@ -1533,14 +1546,14 @@ int vidioc_encoder_cmd(struct file *file, void *priv,
|
|
|
|
|
|
spin_lock_irqsave(&dev->irqlock, flags);
|
|
|
if (list_empty(&ctx->src_queue)) {
|
|
|
- mfc_debug(2, "EOS: empty src queue, entering finishing state");
|
|
|
+ mfc_debug(2, "EOS: empty src queue, entering finishing state\n");
|
|
|
ctx->state = MFCINST_FINISHING;
|
|
|
if (s5p_mfc_ctx_ready(ctx))
|
|
|
set_work_bit_irqsave(ctx);
|
|
|
spin_unlock_irqrestore(&dev->irqlock, flags);
|
|
|
s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
|
|
|
} else {
|
|
|
- mfc_debug(2, "EOS: marking last buffer of stream");
|
|
|
+ mfc_debug(2, "EOS: marking last buffer of stream\n");
|
|
|
buf = list_entry(ctx->src_queue.prev,
|
|
|
struct s5p_mfc_buf, list);
|
|
|
if (buf->flags & MFC_BUF_FLAG_USED)
|
|
@@ -1609,9 +1622,9 @@ static int check_vb_with_fmt(struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb)
|
|
|
mfc_err("failed to get plane cookie\n");
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
- mfc_debug(2, "index: %d, plane[%d] cookie: 0x%08zx",
|
|
|
- vb->v4l2_buf.index, i,
|
|
|
- vb2_dma_contig_plane_dma_addr(vb, i));
|
|
|
+ mfc_debug(2, "index: %d, plane[%d] cookie: 0x%08zx\n",
|
|
|
+ vb->v4l2_buf.index, i,
|
|
|
+ vb2_dma_contig_plane_dma_addr(vb, i));
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
@@ -1760,11 +1773,27 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
|
|
|
struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
|
|
|
struct s5p_mfc_dev *dev = ctx->dev;
|
|
|
|
|
|
- v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
|
|
|
+ if (IS_MFCV6(dev) && (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) {
|
|
|
+
|
|
|
+ if ((ctx->state == MFCINST_GOT_INST) &&
|
|
|
+ (dev->curr_ctx == ctx->num) && dev->hw_lock) {
|
|
|
+ s5p_mfc_wait_for_done_ctx(ctx,
|
|
|
+ S5P_MFC_R2H_CMD_SEQ_DONE_RET,
|
|
|
+ 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ctx->src_bufs_cnt < ctx->pb_count) {
|
|
|
+ mfc_err("Need minimum %d OUTPUT buffers\n",
|
|
|
+ ctx->pb_count);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/* If context is ready then dev = work->data;schedule it to run */
|
|
|
if (s5p_mfc_ctx_ready(ctx))
|
|
|
set_work_bit_irqsave(ctx);
|
|
|
s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1920,6 +1949,7 @@ int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx)
|
|
|
if (controls[i].is_volatile && ctx->ctrls[i])
|
|
|
ctx->ctrls[i]->flags |= V4L2_CTRL_FLAG_VOLATILE;
|
|
|
}
|
|
|
+ v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
|
|
|
return 0;
|
|
|
}
|
|
|
|