RE: [PATCH v2] [media] s5p-mfc: Modify encoder buffer alloc sequence

2013-03-27 Thread Kamil Debski
Hi,

 From: Arun Kumar K [mailto:arun...@samsung.com]
 Sent: Tuesday, March 26, 2013 8:28 AM
 
 MFC v6 needs minimum number of output buffers to be queued for encoder
 depending on the stream type and profile.
 For achieving this the sequence for allocating buffers at the encoder
 is modified similar to that of decoder.
 The new sequence is as follows:
 
 1) Set format on CAPTURE plane
 2) REQBUF on CAPTURE
 3) QBUFS and STREAMON on CAPTURE
 4) G_CTRL to get minimum buffers for OUTPUT plane
 5) REQBUF on OUTPUT with the minimum buffers given by driver

I don't like the idea of changing the encoding sequence. What if the old
applications rely on a particular sequence?

I see the problem you are addressing, but let's explore other options.
MFC v6 sets the minimum number of buffers needed after the header is
generated, v5 did not provide such information at all. 

Also using the variables dpb_count and state HEAD_PARSED seems odd. I guess
that you did reuse the existing variable and state. But the naming used now
is definitely misleading. DPB stands for decoded picture buffer.

I suggest adding a new variable epb_count, or changing dpb_count to pb_count
everywhere would be a good idea. Actually I like the latter more. In case of
HEAD_PARSED I suggest adding a HEAD_PRODUCED state.
 
 This also fixes the crash happeninig during multi instance encoder-
 decoder simultaneous run due to memory allocation happening from
 interrupt context.

Could you explain this problem more? What was the reason and how did you fix
it?

Also a small inline comment/question below.

 
 Signed-off-by: Arun Kumar K arun...@samsung.com
 ---
 Changes from v1
 - Corrected the commit message as pointed out by John Sheu.
   http://www.spinics.net/lists/linux-media/msg61477.html
 ---
  drivers/media/platform/s5p-mfc/s5p_mfc_enc.c|   98
 +++
  drivers/media/platform/s5p-mfc/s5p_mfc_opr.h|1 +
  drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c |7 ++
  drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c |   95 +--
 ---
  4 files changed, 147 insertions(+), 54 deletions(-)
 
 diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
 b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
 index 4f6b553..46ca986 100644
 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
 +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
 @@ -557,6 +557,16 @@ static struct mfc_control controls[] = {
   .step = 1,
   .default_value = 0,
   },
 + {
 + .id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT,
 + .type = V4L2_CTRL_TYPE_INTEGER,
 + .name = Minimum number of output bufs,
 + .minimum = 1,
 + .maximum = 32,
 + .step = 1,
 + .default_value = 1,
 + .is_volatile = 1,
 + },
  };
 
  #define NUM_CTRLS ARRAY_SIZE(controls)
 @@ -661,18 +671,17 @@ 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))
 + } else {
   ctx-dpb_count = s5p_mfc_hw_call(dev-mfc_ops,
   get_enc_dpb_count, dev);
 + ctx-state = MFCINST_HEAD_PARSED;
 + }
 
   return 0;
  }
 @@ -1055,15 +1064,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,12 +1078,35
 @@ static int vidioc_reqbufs(struct file *file, void *priv,
   ctx-output_state);
   return -EINVAL;

Re: [PATCH v2] [media] s5p-mfc: Modify encoder buffer alloc sequence

2013-03-27 Thread Arun Kumar K
Hi Kamil,

Thank you for the review.
Please find my response inline.

On Wed, Mar 27, 2013 at 4:54 PM, Kamil Debski k.deb...@samsung.com wrote:
 Hi,

 From: Arun Kumar K [mailto:arun...@samsung.com]
 Sent: Tuesday, March 26, 2013 8:28 AM

 MFC v6 needs minimum number of output buffers to be queued for encoder
 depending on the stream type and profile.
 For achieving this the sequence for allocating buffers at the encoder
 is modified similar to that of decoder.
 The new sequence is as follows:

 1) Set format on CAPTURE plane
 2) REQBUF on CAPTURE
 3) QBUFS and STREAMON on CAPTURE
 4) G_CTRL to get minimum buffers for OUTPUT plane
 5) REQBUF on OUTPUT with the minimum buffers given by driver

 I don't like the idea of changing the encoding sequence. What if the old
 applications rely on a particular sequence?

 I see the problem you are addressing, but let's explore other options.
 MFC v6 sets the minimum number of buffers needed after the header is
 generated, v5 did not provide such information at all.

Yes. The only other way I can see without making this sequence change is
to always keep the maximum number of buffers needed in worst case scenario.
But this is not the optimal solution. You have any other suggestion?


 Also using the variables dpb_count and state HEAD_PARSED seems odd. I guess
 that you did reuse the existing variable and state. But the naming used now
 is definitely misleading. DPB stands for decoded picture buffer.

 I suggest adding a new variable epb_count, or changing dpb_count to pb_count
 everywhere would be a good idea. Actually I like the latter more. In case of
 HEAD_PARSED I suggest adding a HEAD_PRODUCED state.

Ok I will make these changes. But still the encoding sequence will
remain modified.


 This also fixes the crash happeninig during multi instance encoder-
 decoder simultaneous run due to memory allocation happening from
 interrupt context.

 Could you explain this problem more? What was the reason and how did you fix
 it?

Earlier case, the function s5p_mfc_run_init_enc_buffers() which allocates
encoder scratch buffer was called in the try_run during state HEAD_PARSED.
If only one instance encoder is running, the allocation happens in
reqbufs which calls
try_run. But if multi-instance encoder/decoder is running, the try_run
called from
reqbuf can return due to HW lock. This will cause the function which allocates
memory to be called from interrupt context which generated crash.

Now it is modified such as the memory  allocation part happens from
reqbuf directly
and then it calls try_run which only sends the command to firmware.


 Also a small inline comment/question below.


 Signed-off-by: Arun Kumar K arun...@samsung.com
 ---
 Changes from v1
 - Corrected the commit message as pointed out by John Sheu.
   http://www.spinics.net/lists/linux-media/msg61477.html
 ---
  drivers/media/platform/s5p-mfc/s5p_mfc_enc.c|   98
 +++
  drivers/media/platform/s5p-mfc/s5p_mfc_opr.h|1 +
  drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c |7 ++
  drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c |   95 +--
 ---
  4 files changed, 147 insertions(+), 54 deletions(-)

 diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
 b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
 index 4f6b553..46ca986 100644
 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
 +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
 @@ -557,6 +557,16 @@ static struct mfc_control controls[] = {
   .step = 1,
   .default_value = 0,
   },
 + {
 + .id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT,
 + .type = V4L2_CTRL_TYPE_INTEGER,
 + .name = Minimum number of output bufs,
 + .minimum = 1,
 + .maximum = 32,
 + .step = 1,
 + .default_value = 1,
 + .is_volatile = 1,
 + },
  };

  #define NUM_CTRLS ARRAY_SIZE(controls)
 @@ -661,18 +671,17 @@ 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))
 + } else {
   ctx-dpb_count = s5p_mfc_hw_call(dev-mfc_ops,
   get_enc_dpb_count, dev);
 + ctx-state = MFCINST_HEAD_PARSED;
 + }

   return 0;
  }
 @@ -1055,15 +1064,13 @@ static int vidioc_reqbufs(struct file *file,
 void *priv,
   }
   ctx-capture_state = QUEUE_BUFS_REQUESTED;

 - if (!IS_MFCV6(dev)) {
 - ret =