RE: [PATCH v3 4/4] media: ti-vpe: Add support for SEQ_TB buffers

2014-12-02 Thread Devshatwar, Nikhil
 -Original Message-
 From: Hans Verkuil [mailto:hverk...@xs4all.nl]
 Sent: Monday, December 01, 2014 4:22 PM
 To: Devshatwar, Nikhil; linux-media@vger.kernel.org
 Subject: Re: [PATCH v3 4/4] media: ti-vpe: Add support for SEQ_TB
 buffers
 
 On 11/29/2014 11:27 AM, Nikhil Devshatwar wrote:
  The video source can generate the data in the SEQ_TB buffer format.
  In the case of TI SoC, the IVA_HD can generate the interlaced content
  in the SEQ_TB buffer format. This is the format where the top and
  bottom field data can be contained in a single buffer. For example,
  for NV12, interlaced format, the data in Y buffer will be arranged as
 Y-top followed by Y-bottom.
  And likewise for UV plane.
 
  Also, queueing one buffer of SEQ_TB is euivalent to queueing two
  different
 
 queueing - queuing
 euivalent - equivalent
 
  buffers for top and bottom fields. Driver needs to take care of this
  when handling source buffer lists.
 
  Signed-off-by: Nikhil Devshatwar nikhil...@ti.com
 
 Currently you are supporting SEQ_TB. Should SEQ_BT also be supported? I
 don't know if you are aware but NTSC transmits the bottom field before
 the top field, while PAL/SECAM transmit top before bottom.
 
 So for NTSC support having SEQ_BT might be useful. Up to you, though.
 
OK no problem
I think that should be easy to add
I will add this support and repost the patchset
 Regards,
 
   Hans
 
  ---
  Changes from v1:
   * Add check for valid field in qbuf ioctl
   * Fix issue with swapped fields
 
   drivers/media/platform/ti-vpe/vpe.c |  124
  ---
   1 file changed, 102 insertions(+), 22 deletions(-)
 
  diff --git a/drivers/media/platform/ti-vpe/vpe.c
  b/drivers/media/platform/ti-vpe/vpe.c
  index 6a96bbf..b53aea5 100644
  --- a/drivers/media/platform/ti-vpe/vpe.c
  +++ b/drivers/media/platform/ti-vpe/vpe.c
  @@ -319,9 +319,13 @@ struct vpe_q_data {  };
 
   /* vpe_q_data flag bits */
  -#defineQ_DATA_FRAME_1D (1  0)
  -#defineQ_DATA_MODE_TILED   (1  1)
  -#defineQ_DATA_INTERLACED   (1  2)
  +#defineQ_DATA_FRAME_1D (1  0)
  +#defineQ_DATA_MODE_TILED   (1  1)
  +#defineQ_DATA_INTERLACED_ALTERNATE (1  2)
  +#defineQ_DATA_INTERLACED_SEQ_TB(1  3)
  +
  +#define Q_IS_INTERLACED(Q_DATA_INTERLACED_ALTERNATE | \
  +   Q_DATA_INTERLACED_SEQ_TB)
 
   enum {
  Q_DATA_SRC = 0,
  @@ -647,7 +651,7 @@ static void set_us_coefficients(struct vpe_ctx
  *ctx)
 
  cp = us_coeffs[0].anchor_fid0_c0;
 
  -   if (s_q_data-flags  Q_DATA_INTERLACED)/* interlaced */
  +   if (s_q_data-flags  Q_IS_INTERLACED)  /* interlaced */
  cp += sizeof(us_coeffs[0]) / sizeof(*cp);
 
  end_cp = cp + sizeof(us_coeffs[0]) / sizeof(*cp); @@ -774,8
 +778,7
  @@ static void set_dei_regs(struct vpe_ctx *ctx)
   * for both progressive and interlace content in interlace bypass
 mode.
   * It has been recommended not to use progressive bypass mode.
   */
  -   if ((!ctx-deinterlacing  (s_q_data-flags 
 Q_DATA_INTERLACED)) ||
  -   !(s_q_data-flags  Q_DATA_INTERLACED)) {
  +   if (!(s_q_data-flags  Q_IS_INTERLACED) || !ctx-deinterlacing)
 {
  deinterlace = false;
  val = VPE_DEI_INTERLACE_BYPASS;
  }
  @@ -843,8 +846,8 @@ static int set_srcdst_params(struct vpe_ctx *ctx)
  ctx-sequence = 0;
  ctx-field = V4L2_FIELD_TOP;
 
  -   if ((s_q_data-flags  Q_DATA_INTERLACED) 
  -   !(d_q_data-flags  Q_DATA_INTERLACED)) {
  +   if ((s_q_data-flags  Q_IS_INTERLACED) 
  +   !(d_q_data-flags  Q_IS_INTERLACED)) {
  int bytes_per_line;
  const struct vpdma_data_format *mv =
  vpdma_misc_fmts[VPDMA_DATA_FMT_MV];
  @@ -1068,6 +1071,27 @@ static void add_in_dtd(struct vpe_ctx *ctx,
 int port)
  vpdma_fmt = fmt-vpdma_fmt[plane];
 
  dma_addr = vb2_dma_addr_plus_data_offset(vb, plane);
  +
  +   if (q_data-flags  Q_DATA_INTERLACED_SEQ_TB) {
  +   /*
  +* Use top or bottom field from same vb alternately
  +* f,f-1,f-2 = TBT when seq is even
  +* f,f-1,f-2 = BTB when seq is odd
  +*/
  +   field = (p_data-vb_index + (ctx-sequence % 2)) % 2;
  +
  +   if (field) {
  +   /* bottom field of a SEQ_TB buffer
  +* Skip the top field data by */
  +   int height = q_data-height / 2;
  +   int bpp = fmt-fourcc == V4L2_PIX_FMT_NV12 ?
  +   1 : (vpdma_fmt-depth  3);
  +   if (plane)
  +   height /= 2;
  +   dma_addr += q_data-width * height * bpp

Re: [PATCH v3 4/4] media: ti-vpe: Add support for SEQ_TB buffers

2014-12-01 Thread Hans Verkuil
On 11/29/2014 11:27 AM, Nikhil Devshatwar wrote:
 The video source can generate the data in the SEQ_TB buffer format.
 In the case of TI SoC, the IVA_HD can generate the interlaced content in
 the SEQ_TB buffer format. This is the format where the top and bottom field
 data can be contained in a single buffer. For example, for NV12, interlaced
 format, the data in Y buffer will be arranged as Y-top followed by Y-bottom.
 And likewise for UV plane.
 
 Also, queueing one buffer of SEQ_TB is euivalent to queueing two different

queueing - queuing 
euivalent - equivalent

 buffers for top and bottom fields. Driver needs to take care of this when
 handling source buffer lists.
 
 Signed-off-by: Nikhil Devshatwar nikhil...@ti.com

Currently you are supporting SEQ_TB. Should SEQ_BT also be supported? I don't
know if you are aware but NTSC transmits the bottom field before the top field,
while PAL/SECAM transmit top before bottom.

So for NTSC support having SEQ_BT might be useful. Up to you, though.

Regards,

Hans

 ---
 Changes from v1:
  * Add check for valid field in qbuf ioctl
  * Fix issue with swapped fields
 
  drivers/media/platform/ti-vpe/vpe.c |  124 
 ---
  1 file changed, 102 insertions(+), 22 deletions(-)
 
 diff --git a/drivers/media/platform/ti-vpe/vpe.c 
 b/drivers/media/platform/ti-vpe/vpe.c
 index 6a96bbf..b53aea5 100644
 --- a/drivers/media/platform/ti-vpe/vpe.c
 +++ b/drivers/media/platform/ti-vpe/vpe.c
 @@ -319,9 +319,13 @@ struct vpe_q_data {
  };
  
  /* vpe_q_data flag bits */
 -#define  Q_DATA_FRAME_1D (1  0)
 -#define  Q_DATA_MODE_TILED   (1  1)
 -#define  Q_DATA_INTERLACED   (1  2)
 +#define  Q_DATA_FRAME_1D (1  0)
 +#define  Q_DATA_MODE_TILED   (1  1)
 +#define  Q_DATA_INTERLACED_ALTERNATE (1  2)
 +#define  Q_DATA_INTERLACED_SEQ_TB(1  3)
 +
 +#define Q_IS_INTERLACED  (Q_DATA_INTERLACED_ALTERNATE | \
 + Q_DATA_INTERLACED_SEQ_TB)
  
  enum {
   Q_DATA_SRC = 0,
 @@ -647,7 +651,7 @@ static void set_us_coefficients(struct vpe_ctx *ctx)
  
   cp = us_coeffs[0].anchor_fid0_c0;
  
 - if (s_q_data-flags  Q_DATA_INTERLACED)/* interlaced */
 + if (s_q_data-flags  Q_IS_INTERLACED)  /* interlaced */
   cp += sizeof(us_coeffs[0]) / sizeof(*cp);
  
   end_cp = cp + sizeof(us_coeffs[0]) / sizeof(*cp);
 @@ -774,8 +778,7 @@ static void set_dei_regs(struct vpe_ctx *ctx)
* for both progressive and interlace content in interlace bypass mode.
* It has been recommended not to use progressive bypass mode.
*/
 - if ((!ctx-deinterlacing  (s_q_data-flags  Q_DATA_INTERLACED)) ||
 - !(s_q_data-flags  Q_DATA_INTERLACED)) {
 + if (!(s_q_data-flags  Q_IS_INTERLACED) || !ctx-deinterlacing) {
   deinterlace = false;
   val = VPE_DEI_INTERLACE_BYPASS;
   }
 @@ -843,8 +846,8 @@ static int set_srcdst_params(struct vpe_ctx *ctx)
   ctx-sequence = 0;
   ctx-field = V4L2_FIELD_TOP;
  
 - if ((s_q_data-flags  Q_DATA_INTERLACED) 
 - !(d_q_data-flags  Q_DATA_INTERLACED)) {
 + if ((s_q_data-flags  Q_IS_INTERLACED) 
 + !(d_q_data-flags  Q_IS_INTERLACED)) {
   int bytes_per_line;
   const struct vpdma_data_format *mv =
   vpdma_misc_fmts[VPDMA_DATA_FMT_MV];
 @@ -1068,6 +1071,27 @@ static void add_in_dtd(struct vpe_ctx *ctx, int port)
   vpdma_fmt = fmt-vpdma_fmt[plane];
  
   dma_addr = vb2_dma_addr_plus_data_offset(vb, plane);
 +
 + if (q_data-flags  Q_DATA_INTERLACED_SEQ_TB) {
 + /*
 +  * Use top or bottom field from same vb alternately
 +  * f,f-1,f-2 = TBT when seq is even
 +  * f,f-1,f-2 = BTB when seq is odd
 +  */
 + field = (p_data-vb_index + (ctx-sequence % 2)) % 2;
 +
 + if (field) {
 + /* bottom field of a SEQ_TB buffer
 +  * Skip the top field data by */
 + int height = q_data-height / 2;
 + int bpp = fmt-fourcc == V4L2_PIX_FMT_NV12 ?
 + 1 : (vpdma_fmt-depth  3);
 + if (plane)
 + height /= 2;
 + dma_addr += q_data-width * height * bpp;
 + }
 + }
 +
   if (!dma_addr) {
   vpe_err(ctx-dev,
   acquiring input buffer(%d) dma_addr failed\n,
 @@ -1122,9 +1146,22 @@ static void device_run(void *priv)
   struct vpe_ctx *ctx = priv;
   struct sc_data *sc = ctx-dev-sc;
   struct vpe_q_data *d_q_data = ctx-q_data[Q_DATA_DST];