aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2015-03-09 11:03:52 -0400
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-04-02 19:54:24 -0400
commitddcaee9dd4c00174db8ddf913c87ddf3773c446e (patch)
tree109e70f27a21d9d914ba7a64d15d68fd7e1c172d
parent96c76efae3211c7b798553602d3165b4ea34aa95 (diff)
[media] vivid: add support for single buffer planar formats
Make vivid aware of the difference of planes and buffers. Note that this does not yet add support for hor/vert downsampled formats. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
-rw-r--r--drivers/media/platform/vivid/vivid-core.h2
-rw-r--r--drivers/media/platform/vivid/vivid-kthread-cap.c54
-rw-r--r--drivers/media/platform/vivid/vivid-vid-cap.c58
-rw-r--r--drivers/media/platform/vivid/vivid-vid-common.c2
-rw-r--r--drivers/media/platform/vivid/vivid-vid-out.c68
5 files changed, 105 insertions, 79 deletions
diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h
index bcefd19f25ca..9e15aee9a52e 100644
--- a/drivers/media/platform/vivid/vivid-core.h
+++ b/drivers/media/platform/vivid/vivid-core.h
@@ -334,7 +334,7 @@ struct vivid_dev {
334 u32 ycbcr_enc_out; 334 u32 ycbcr_enc_out;
335 u32 quantization_out; 335 u32 quantization_out;
336 u32 service_set_out; 336 u32 service_set_out;
337 u32 bytesperline_out[TPG_MAX_PLANES]; 337 unsigned bytesperline_out[TPG_MAX_PLANES];
338 unsigned tv_field_out; 338 unsigned tv_field_out;
339 unsigned tv_audio_output; 339 unsigned tv_audio_output;
340 bool vbi_out_have_wss; 340 bool vbi_out_have_wss;
diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c b/drivers/media/platform/vivid/vivid-kthread-cap.c
index 9976d4523366..22e17847e67f 100644
--- a/drivers/media/platform/vivid/vivid-kthread-cap.c
+++ b/drivers/media/platform/vivid/vivid-kthread-cap.c
@@ -229,6 +229,20 @@ static void vivid_precalc_copy_rects(struct vivid_dev *dev)
229 dev->loop_vid_overlay_cap.left, dev->loop_vid_overlay_cap.top); 229 dev->loop_vid_overlay_cap.left, dev->loop_vid_overlay_cap.top);
230} 230}
231 231
232static void *plane_vaddr(struct tpg_data *tpg, struct vivid_buffer *buf,
233 unsigned p, unsigned bpl[TPG_MAX_PLANES], unsigned h)
234{
235 unsigned i;
236 void *vbuf;
237
238 if (p == 0 || tpg_g_buffers(tpg) > 1)
239 return vb2_plane_vaddr(&buf->vb, p);
240 vbuf = vb2_plane_vaddr(&buf->vb, 0);
241 for (i = 0; i < p; i++)
242 vbuf += bpl[i] * h / tpg->vdownsampling[i];
243 return vbuf;
244}
245
232static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf, 246static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf,
233 struct vivid_buffer *vid_cap_buf) 247 struct vivid_buffer *vid_cap_buf)
234{ 248{
@@ -269,8 +283,10 @@ static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf,
269 283
270 vid_cap_buf->vb.v4l2_buf.field = vid_out_buf->vb.v4l2_buf.field; 284 vid_cap_buf->vb.v4l2_buf.field = vid_out_buf->vb.v4l2_buf.field;
271 285
272 voutbuf = vb2_plane_vaddr(&vid_out_buf->vb, p) + 286 voutbuf = plane_vaddr(tpg, vid_out_buf, p,
273 vid_out_buf->vb.v4l2_planes[p].data_offset; 287 dev->bytesperline_out, dev->fmt_out_rect.height);
288 if (p < dev->fmt_out->buffers)
289 voutbuf += vid_out_buf->vb.v4l2_planes[p].data_offset;
274 voutbuf += dev->loop_vid_out.left * pixsize + dev->loop_vid_out.top * stride_out; 290 voutbuf += dev->loop_vid_out.left * pixsize + dev->loop_vid_out.top * stride_out;
275 vcapbuf += dev->compose_cap.left * pixsize + dev->compose_cap.top * stride_cap; 291 vcapbuf += dev->compose_cap.left * pixsize + dev->compose_cap.top * stride_cap;
276 292
@@ -395,6 +411,7 @@ update_vid_out_y:
395 411
396static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf) 412static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf)
397{ 413{
414 struct tpg_data *tpg = &dev->tpg;
398 unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1; 415 unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1;
399 unsigned line_height = 16 / factor; 416 unsigned line_height = 16 / factor;
400 bool is_tv = vivid_is_sdtv_cap(dev); 417 bool is_tv = vivid_is_sdtv_cap(dev);
@@ -436,28 +453,29 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf)
436 } else { 453 } else {
437 buf->vb.v4l2_buf.field = dev->field_cap; 454 buf->vb.v4l2_buf.field = dev->field_cap;
438 } 455 }
439 tpg_s_field(&dev->tpg, buf->vb.v4l2_buf.field, 456 tpg_s_field(tpg, buf->vb.v4l2_buf.field,
440 dev->field_cap == V4L2_FIELD_ALTERNATE); 457 dev->field_cap == V4L2_FIELD_ALTERNATE);
441 tpg_s_perc_fill_blank(&dev->tpg, dev->must_blank[buf->vb.v4l2_buf.index]); 458 tpg_s_perc_fill_blank(tpg, dev->must_blank[buf->vb.v4l2_buf.index]);
442 459
443 vivid_precalc_copy_rects(dev); 460 vivid_precalc_copy_rects(dev);
444 461
445 for (p = 0; p < tpg_g_planes(&dev->tpg); p++) { 462 for (p = 0; p < tpg_g_planes(tpg); p++) {
446 void *vbuf = vb2_plane_vaddr(&buf->vb, p); 463 void *vbuf = plane_vaddr(tpg, buf, p,
464 tpg->bytesperline, tpg->buf_height);
447 465
448 /* 466 /*
449 * The first plane of a multiplanar format has a non-zero 467 * The first plane of a multiplanar format has a non-zero
450 * data_offset. This helps testing whether the application 468 * data_offset. This helps testing whether the application
451 * correctly supports non-zero data offsets. 469 * correctly supports non-zero data offsets.
452 */ 470 */
453 if (dev->fmt_cap->data_offset[p]) { 471 if (p < tpg_g_buffers(tpg) && dev->fmt_cap->data_offset[p]) {
454 memset(vbuf, dev->fmt_cap->data_offset[p] & 0xff, 472 memset(vbuf, dev->fmt_cap->data_offset[p] & 0xff,
455 dev->fmt_cap->data_offset[p]); 473 dev->fmt_cap->data_offset[p]);
456 vbuf += dev->fmt_cap->data_offset[p]; 474 vbuf += dev->fmt_cap->data_offset[p];
457 } 475 }
458 tpg_calc_text_basep(&dev->tpg, basep, p, vbuf); 476 tpg_calc_text_basep(tpg, basep, p, vbuf);
459 if (!is_loop || vivid_copy_buffer(dev, p, vbuf, buf)) 477 if (!is_loop || vivid_copy_buffer(dev, p, vbuf, buf))
460 tpg_fillbuffer(&dev->tpg, vivid_get_std_cap(dev), p, vbuf); 478 tpg_fill_plane_buffer(tpg, vivid_get_std_cap(dev), p, vbuf);
461 } 479 }
462 dev->must_blank[buf->vb.v4l2_buf.index] = false; 480 dev->must_blank[buf->vb.v4l2_buf.index] = false;
463 481
@@ -476,12 +494,12 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf)
476 (dev->field_cap == V4L2_FIELD_ALTERNATE) ? 494 (dev->field_cap == V4L2_FIELD_ALTERNATE) ?
477 (buf->vb.v4l2_buf.field == V4L2_FIELD_TOP ? 495 (buf->vb.v4l2_buf.field == V4L2_FIELD_TOP ?
478 " top" : " bottom") : ""); 496 " top" : " bottom") : "");
479 tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); 497 tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
480 } 498 }
481 if (dev->osd_mode == 0) { 499 if (dev->osd_mode == 0) {
482 snprintf(str, sizeof(str), " %dx%d, input %d ", 500 snprintf(str, sizeof(str), " %dx%d, input %d ",
483 dev->src_rect.width, dev->src_rect.height, dev->input); 501 dev->src_rect.width, dev->src_rect.height, dev->input);
484 tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); 502 tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
485 503
486 gain = v4l2_ctrl_g_ctrl(dev->gain); 504 gain = v4l2_ctrl_g_ctrl(dev->gain);
487 mutex_lock(dev->ctrl_hdl_user_vid.lock); 505 mutex_lock(dev->ctrl_hdl_user_vid.lock);
@@ -491,38 +509,38 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf)
491 dev->contrast->cur.val, 509 dev->contrast->cur.val,
492 dev->saturation->cur.val, 510 dev->saturation->cur.val,
493 dev->hue->cur.val); 511 dev->hue->cur.val);
494 tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); 512 tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
495 snprintf(str, sizeof(str), 513 snprintf(str, sizeof(str),
496 " autogain %d, gain %3d, alpha 0x%02x ", 514 " autogain %d, gain %3d, alpha 0x%02x ",
497 dev->autogain->cur.val, gain, dev->alpha->cur.val); 515 dev->autogain->cur.val, gain, dev->alpha->cur.val);
498 mutex_unlock(dev->ctrl_hdl_user_vid.lock); 516 mutex_unlock(dev->ctrl_hdl_user_vid.lock);
499 tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); 517 tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
500 mutex_lock(dev->ctrl_hdl_user_aud.lock); 518 mutex_lock(dev->ctrl_hdl_user_aud.lock);
501 snprintf(str, sizeof(str), 519 snprintf(str, sizeof(str),
502 " volume %3d, mute %d ", 520 " volume %3d, mute %d ",
503 dev->volume->cur.val, dev->mute->cur.val); 521 dev->volume->cur.val, dev->mute->cur.val);
504 mutex_unlock(dev->ctrl_hdl_user_aud.lock); 522 mutex_unlock(dev->ctrl_hdl_user_aud.lock);
505 tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); 523 tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
506 mutex_lock(dev->ctrl_hdl_user_gen.lock); 524 mutex_lock(dev->ctrl_hdl_user_gen.lock);
507 snprintf(str, sizeof(str), " int32 %d, int64 %lld, bitmask %08x ", 525 snprintf(str, sizeof(str), " int32 %d, int64 %lld, bitmask %08x ",
508 dev->int32->cur.val, 526 dev->int32->cur.val,
509 *dev->int64->p_cur.p_s64, 527 *dev->int64->p_cur.p_s64,
510 dev->bitmask->cur.val); 528 dev->bitmask->cur.val);
511 tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); 529 tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
512 snprintf(str, sizeof(str), " boolean %d, menu %s, string \"%s\" ", 530 snprintf(str, sizeof(str), " boolean %d, menu %s, string \"%s\" ",
513 dev->boolean->cur.val, 531 dev->boolean->cur.val,
514 dev->menu->qmenu[dev->menu->cur.val], 532 dev->menu->qmenu[dev->menu->cur.val],
515 dev->string->p_cur.p_char); 533 dev->string->p_cur.p_char);
516 tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); 534 tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
517 snprintf(str, sizeof(str), " integer_menu %lld, value %d ", 535 snprintf(str, sizeof(str), " integer_menu %lld, value %d ",
518 dev->int_menu->qmenu_int[dev->int_menu->cur.val], 536 dev->int_menu->qmenu_int[dev->int_menu->cur.val],
519 dev->int_menu->cur.val); 537 dev->int_menu->cur.val);
520 mutex_unlock(dev->ctrl_hdl_user_gen.lock); 538 mutex_unlock(dev->ctrl_hdl_user_gen.lock);
521 tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); 539 tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
522 if (dev->button_pressed) { 540 if (dev->button_pressed) {
523 dev->button_pressed--; 541 dev->button_pressed--;
524 snprintf(str, sizeof(str), " button pressed!"); 542 snprintf(str, sizeof(str), " button pressed!");
525 tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); 543 tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
526 } 544 }
527 } 545 }
528 546
diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c
index 4d50961f35c2..1d9ea2d9d61a 100644
--- a/drivers/media/platform/vivid/vivid-vid-cap.c
+++ b/drivers/media/platform/vivid/vivid-vid-cap.c
@@ -100,7 +100,7 @@ static int vid_cap_queue_setup(struct vb2_queue *vq, const struct v4l2_format *f
100 unsigned sizes[], void *alloc_ctxs[]) 100 unsigned sizes[], void *alloc_ctxs[])
101{ 101{
102 struct vivid_dev *dev = vb2_get_drv_priv(vq); 102 struct vivid_dev *dev = vb2_get_drv_priv(vq);
103 unsigned planes = tpg_g_planes(&dev->tpg); 103 unsigned buffers = tpg_g_buffers(&dev->tpg);
104 unsigned h = dev->fmt_cap_rect.height; 104 unsigned h = dev->fmt_cap_rect.height;
105 unsigned p; 105 unsigned p;
106 106
@@ -133,39 +133,36 @@ static int vid_cap_queue_setup(struct vb2_queue *vq, const struct v4l2_format *f
133 mp = &fmt->fmt.pix_mp; 133 mp = &fmt->fmt.pix_mp;
134 /* 134 /*
135 * Check if the number of planes in the specified format match 135 * Check if the number of planes in the specified format match
136 * the number of planes in the current format. You can't mix that. 136 * the number of buffers in the current format. You can't mix that.
137 */ 137 */
138 if (mp->num_planes != planes) 138 if (mp->num_planes != buffers)
139 return -EINVAL; 139 return -EINVAL;
140 vfmt = vivid_get_format(dev, mp->pixelformat); 140 vfmt = vivid_get_format(dev, mp->pixelformat);
141 for (p = 0; p < planes; p++) { 141 for (p = 0; p < buffers; p++) {
142 sizes[p] = mp->plane_fmt[p].sizeimage; 142 sizes[p] = mp->plane_fmt[p].sizeimage;
143 if (sizes[0] < tpg_g_bytesperline(&dev->tpg, 0) * h + 143 if (sizes[p] < tpg_g_line_width(&dev->tpg, p) * h +
144 vfmt->data_offset[p]) 144 vfmt->data_offset[p])
145 return -EINVAL; 145 return -EINVAL;
146 } 146 }
147 } else { 147 } else {
148 for (p = 0; p < planes; p++) 148 for (p = 0; p < buffers; p++)
149 sizes[p] = tpg_g_bytesperline(&dev->tpg, p) * h + 149 sizes[p] = tpg_g_line_width(&dev->tpg, p) * h +
150 dev->fmt_cap->data_offset[p]; 150 dev->fmt_cap->data_offset[p];
151 } 151 }
152 152
153 if (vq->num_buffers + *nbuffers < 2) 153 if (vq->num_buffers + *nbuffers < 2)
154 *nbuffers = 2 - vq->num_buffers; 154 *nbuffers = 2 - vq->num_buffers;
155 155
156 *nplanes = planes; 156 *nplanes = buffers;
157 157
158 /* 158 /*
159 * videobuf2-vmalloc allocator is context-less so no need to set 159 * videobuf2-vmalloc allocator is context-less so no need to set
160 * alloc_ctxs array. 160 * alloc_ctxs array.
161 */ 161 */
162 162
163 if (planes == 2) 163 dprintk(dev, 1, "%s: count=%d\n", __func__, *nbuffers);
164 dprintk(dev, 1, "%s, count=%d, sizes=%u, %u\n", __func__, 164 for (p = 0; p < buffers; p++)
165 *nbuffers, sizes[0], sizes[1]); 165 dprintk(dev, 1, "%s: size[%u]=%u\n", __func__, p, sizes[p]);
166 else
167 dprintk(dev, 1, "%s, count=%d, size=%u\n", __func__,
168 *nbuffers, sizes[0]);
169 166
170 return 0; 167 return 0;
171} 168}
@@ -174,7 +171,7 @@ static int vid_cap_buf_prepare(struct vb2_buffer *vb)
174{ 171{
175 struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); 172 struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
176 unsigned long size; 173 unsigned long size;
177 unsigned planes = tpg_g_planes(&dev->tpg); 174 unsigned buffers = tpg_g_buffers(&dev->tpg);
178 unsigned p; 175 unsigned p;
179 176
180 dprintk(dev, 1, "%s\n", __func__); 177 dprintk(dev, 1, "%s\n", __func__);
@@ -190,8 +187,8 @@ static int vid_cap_buf_prepare(struct vb2_buffer *vb)
190 dev->buf_prepare_error = false; 187 dev->buf_prepare_error = false;
191 return -EINVAL; 188 return -EINVAL;
192 } 189 }
193 for (p = 0; p < planes; p++) { 190 for (p = 0; p < buffers; p++) {
194 size = tpg_g_bytesperline(&dev->tpg, p) * dev->fmt_cap_rect.height + 191 size = tpg_g_line_width(&dev->tpg, p) * dev->fmt_cap_rect.height +
195 dev->fmt_cap->data_offset[p]; 192 dev->fmt_cap->data_offset[p];
196 193
197 if (vb2_plane_size(vb, p) < size) { 194 if (vb2_plane_size(vb, p) < size) {
@@ -532,11 +529,11 @@ int vivid_g_fmt_vid_cap(struct file *file, void *priv,
532 mp->colorspace = vivid_colorspace_cap(dev); 529 mp->colorspace = vivid_colorspace_cap(dev);
533 mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); 530 mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev);
534 mp->quantization = vivid_quantization_cap(dev); 531 mp->quantization = vivid_quantization_cap(dev);
535 mp->num_planes = dev->fmt_cap->planes; 532 mp->num_planes = dev->fmt_cap->buffers;
536 for (p = 0; p < mp->num_planes; p++) { 533 for (p = 0; p < mp->num_planes; p++) {
537 mp->plane_fmt[p].bytesperline = tpg_g_bytesperline(&dev->tpg, p); 534 mp->plane_fmt[p].bytesperline = tpg_g_bytesperline(&dev->tpg, p);
538 mp->plane_fmt[p].sizeimage = 535 mp->plane_fmt[p].sizeimage =
539 mp->plane_fmt[p].bytesperline * mp->height + 536 tpg_g_line_width(&dev->tpg, p) * mp->height +
540 dev->fmt_cap->data_offset[p]; 537 dev->fmt_cap->data_offset[p];
541 } 538 }
542 return 0; 539 return 0;
@@ -602,18 +599,19 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv,
602 599
603 /* This driver supports custom bytesperline values */ 600 /* This driver supports custom bytesperline values */
604 601
605 /* Calculate the minimum supported bytesperline value */ 602 mp->num_planes = fmt->buffers;
606 bytesperline = (mp->width * fmt->bit_depth[0]) >> 3;
607 /* Calculate the maximum supported bytesperline value */
608 max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->bit_depth[0]) >> 3;
609 mp->num_planes = fmt->planes;
610 for (p = 0; p < mp->num_planes; p++) { 603 for (p = 0; p < mp->num_planes; p++) {
604 /* Calculate the minimum supported bytesperline value */
605 bytesperline = (mp->width * fmt->bit_depth[p]) >> 3;
606 /* Calculate the maximum supported bytesperline value */
607 max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->bit_depth[p]) >> 3;
608
611 if (pfmt[p].bytesperline > max_bpl) 609 if (pfmt[p].bytesperline > max_bpl)
612 pfmt[p].bytesperline = max_bpl; 610 pfmt[p].bytesperline = max_bpl;
613 if (pfmt[p].bytesperline < bytesperline) 611 if (pfmt[p].bytesperline < bytesperline)
614 pfmt[p].bytesperline = bytesperline; 612 pfmt[p].bytesperline = bytesperline;
615 pfmt[p].sizeimage = pfmt[p].bytesperline * mp->height + 613 pfmt[p].sizeimage = tpg_calc_line_width(&dev->tpg, p, pfmt[p].bytesperline) *
616 fmt->data_offset[p]; 614 mp->height + fmt->data_offset[p];
617 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved)); 615 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved));
618 } 616 }
619 mp->colorspace = vivid_colorspace_cap(dev); 617 mp->colorspace = vivid_colorspace_cap(dev);
@@ -633,6 +631,7 @@ int vivid_s_fmt_vid_cap(struct file *file, void *priv,
633 struct vb2_queue *q = &dev->vb_vid_cap_q; 631 struct vb2_queue *q = &dev->vb_vid_cap_q;
634 int ret = vivid_try_fmt_vid_cap(file, priv, f); 632 int ret = vivid_try_fmt_vid_cap(file, priv, f);
635 unsigned factor = 1; 633 unsigned factor = 1;
634 unsigned p;
636 unsigned i; 635 unsigned i;
637 636
638 if (ret < 0) 637 if (ret < 0)
@@ -735,16 +734,15 @@ int vivid_s_fmt_vid_cap(struct file *file, void *priv,
735 dev->fmt_cap_rect.width = mp->width; 734 dev->fmt_cap_rect.width = mp->width;
736 dev->fmt_cap_rect.height = mp->height; 735 dev->fmt_cap_rect.height = mp->height;
737 tpg_s_buf_height(&dev->tpg, mp->height); 736 tpg_s_buf_height(&dev->tpg, mp->height);
738 tpg_s_bytesperline(&dev->tpg, 0, mp->plane_fmt[0].bytesperline); 737 tpg_s_fourcc(&dev->tpg, dev->fmt_cap->fourcc);
739 if (tpg_g_planes(&dev->tpg) > 1) 738 for (p = 0; p < tpg_g_buffers(&dev->tpg); p++)
740 tpg_s_bytesperline(&dev->tpg, 1, mp->plane_fmt[1].bytesperline); 739 tpg_s_bytesperline(&dev->tpg, p, mp->plane_fmt[p].bytesperline);
741 dev->field_cap = mp->field; 740 dev->field_cap = mp->field;
742 if (dev->field_cap == V4L2_FIELD_ALTERNATE) 741 if (dev->field_cap == V4L2_FIELD_ALTERNATE)
743 tpg_s_field(&dev->tpg, V4L2_FIELD_TOP, true); 742 tpg_s_field(&dev->tpg, V4L2_FIELD_TOP, true);
744 else 743 else
745 tpg_s_field(&dev->tpg, dev->field_cap, false); 744 tpg_s_field(&dev->tpg, dev->field_cap, false);
746 tpg_s_crop_compose(&dev->tpg, &dev->crop_cap, &dev->compose_cap); 745 tpg_s_crop_compose(&dev->tpg, &dev->crop_cap, &dev->compose_cap);
747 tpg_s_fourcc(&dev->tpg, dev->fmt_cap->fourcc);
748 if (vivid_is_sdtv_cap(dev)) 746 if (vivid_is_sdtv_cap(dev))
749 dev->tv_field_cap = mp->field; 747 dev->tv_field_cap = mp->field;
750 tpg_update_mv_step(&dev->tpg); 748 tpg_update_mv_step(&dev->tpg);
diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c
index 7a02aef0bdaa..0f93fea5d56d 100644
--- a/drivers/media/platform/vivid/vivid-vid-common.c
+++ b/drivers/media/platform/vivid/vivid-vid-common.c
@@ -234,7 +234,7 @@ const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat)
234 for (k = 0; k < ARRAY_SIZE(vivid_formats); k++) { 234 for (k = 0; k < ARRAY_SIZE(vivid_formats); k++) {
235 fmt = &vivid_formats[k]; 235 fmt = &vivid_formats[k];
236 if (fmt->fourcc == pixelformat) 236 if (fmt->fourcc == pixelformat)
237 if (fmt->planes == 1 || dev->multiplanar) 237 if (fmt->buffers == 1 || dev->multiplanar)
238 return fmt; 238 return fmt;
239 } 239 }
240 240
diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c
index 9cf036cfd3fb..eeafb6c93c64 100644
--- a/drivers/media/platform/vivid/vivid-vid-out.c
+++ b/drivers/media/platform/vivid/vivid-vid-out.c
@@ -36,9 +36,14 @@ static int vid_out_queue_setup(struct vb2_queue *vq, const struct v4l2_format *f
36 unsigned sizes[], void *alloc_ctxs[]) 36 unsigned sizes[], void *alloc_ctxs[])
37{ 37{
38 struct vivid_dev *dev = vb2_get_drv_priv(vq); 38 struct vivid_dev *dev = vb2_get_drv_priv(vq);
39 unsigned planes = dev->fmt_out->planes; 39 const struct vivid_fmt *vfmt = dev->fmt_out;
40 unsigned planes = vfmt->buffers;
40 unsigned h = dev->fmt_out_rect.height; 41 unsigned h = dev->fmt_out_rect.height;
41 unsigned size = dev->bytesperline_out[0] * h; 42 unsigned size = dev->bytesperline_out[0] * h;
43 unsigned p;
44
45 for (p = vfmt->buffers; p < vfmt->planes; p++)
46 size += dev->bytesperline_out[p] * h;
42 47
43 if (dev->field_out == V4L2_FIELD_ALTERNATE) { 48 if (dev->field_out == V4L2_FIELD_ALTERNATE) {
44 /* 49 /*
@@ -74,21 +79,16 @@ static int vid_out_queue_setup(struct vb2_queue *vq, const struct v4l2_format *f
74 if (mp->num_planes != planes) 79 if (mp->num_planes != planes)
75 return -EINVAL; 80 return -EINVAL;
76 sizes[0] = mp->plane_fmt[0].sizeimage; 81 sizes[0] = mp->plane_fmt[0].sizeimage;
77 if (planes == 2) { 82 if (sizes[0] < size)
78 sizes[1] = mp->plane_fmt[1].sizeimage;
79 if (sizes[0] < dev->bytesperline_out[0] * h ||
80 sizes[1] < dev->bytesperline_out[1] * h)
81 return -EINVAL;
82 } else if (sizes[0] < size) {
83 return -EINVAL; 83 return -EINVAL;
84 for (p = 1; p < planes; p++) {
85 sizes[p] = mp->plane_fmt[p].sizeimage;
86 if (sizes[p] < dev->bytesperline_out[p] * h)
87 return -EINVAL;
84 } 88 }
85 } else { 89 } else {
86 if (planes == 2) { 90 for (p = 0; p < planes; p++)
87 sizes[0] = dev->bytesperline_out[0] * h; 91 sizes[p] = p ? dev->bytesperline_out[p] * h : size;
88 sizes[1] = dev->bytesperline_out[1] * h;
89 } else {
90 sizes[0] = size;
91 }
92 } 92 }
93 93
94 if (vq->num_buffers + *nbuffers < 2) 94 if (vq->num_buffers + *nbuffers < 2)
@@ -101,12 +101,9 @@ static int vid_out_queue_setup(struct vb2_queue *vq, const struct v4l2_format *f
101 * alloc_ctxs array. 101 * alloc_ctxs array.
102 */ 102 */
103 103
104 if (planes == 2) 104 dprintk(dev, 1, "%s: count=%d\n", __func__, *nbuffers);
105 dprintk(dev, 1, "%s, count=%d, sizes=%u, %u\n", __func__, 105 for (p = 0; p < planes; p++)
106 *nbuffers, sizes[0], sizes[1]); 106 dprintk(dev, 1, "%s: size[%u]=%u\n", __func__, p, sizes[p]);
107 else
108 dprintk(dev, 1, "%s, count=%d, size=%u\n", __func__,
109 *nbuffers, sizes[0]);
110 return 0; 107 return 0;
111} 108}
112 109
@@ -222,7 +219,7 @@ const struct vb2_ops vivid_vid_out_qops = {
222void vivid_update_format_out(struct vivid_dev *dev) 219void vivid_update_format_out(struct vivid_dev *dev)
223{ 220{
224 struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt; 221 struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt;
225 unsigned size; 222 unsigned size, p;
226 223
227 switch (dev->output_type[dev->output]) { 224 switch (dev->output_type[dev->output]) {
228 case SVID: 225 case SVID:
@@ -269,9 +266,9 @@ void vivid_update_format_out(struct vivid_dev *dev)
269 if (V4L2_FIELD_HAS_T_OR_B(dev->field_out)) 266 if (V4L2_FIELD_HAS_T_OR_B(dev->field_out))
270 dev->crop_out.height /= 2; 267 dev->crop_out.height /= 2;
271 dev->fmt_out_rect = dev->crop_out; 268 dev->fmt_out_rect = dev->crop_out;
272 dev->bytesperline_out[0] = (dev->sink_rect.width * dev->fmt_out->bit_depth[0]) / 8; 269 for (p = 0; p < dev->fmt_out->planes; p++)
273 if (dev->fmt_out->planes == 2) 270 dev->bytesperline_out[p] =
274 dev->bytesperline_out[1] = (dev->sink_rect.width * dev->fmt_out->bit_depth[0]) / 8; 271 (dev->sink_rect.width * dev->fmt_out->bit_depth[p]) / 8;
275} 272}
276 273
277/* Map the field to something that is valid for the current output */ 274/* Map the field to something that is valid for the current output */
@@ -315,21 +312,27 @@ int vivid_g_fmt_vid_out(struct file *file, void *priv,
315{ 312{
316 struct vivid_dev *dev = video_drvdata(file); 313 struct vivid_dev *dev = video_drvdata(file);
317 struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp; 314 struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;
315 const struct vivid_fmt *fmt = dev->fmt_out;
318 unsigned p; 316 unsigned p;
319 317
320 mp->width = dev->fmt_out_rect.width; 318 mp->width = dev->fmt_out_rect.width;
321 mp->height = dev->fmt_out_rect.height; 319 mp->height = dev->fmt_out_rect.height;
322 mp->field = dev->field_out; 320 mp->field = dev->field_out;
323 mp->pixelformat = dev->fmt_out->fourcc; 321 mp->pixelformat = fmt->fourcc;
324 mp->colorspace = dev->colorspace_out; 322 mp->colorspace = dev->colorspace_out;
325 mp->ycbcr_enc = dev->ycbcr_enc_out; 323 mp->ycbcr_enc = dev->ycbcr_enc_out;
326 mp->quantization = dev->quantization_out; 324 mp->quantization = dev->quantization_out;
327 mp->num_planes = dev->fmt_out->planes; 325 mp->num_planes = fmt->buffers;
328 for (p = 0; p < mp->num_planes; p++) { 326 for (p = 0; p < mp->num_planes; p++) {
329 mp->plane_fmt[p].bytesperline = dev->bytesperline_out[p]; 327 mp->plane_fmt[p].bytesperline = dev->bytesperline_out[p];
330 mp->plane_fmt[p].sizeimage = 328 mp->plane_fmt[p].sizeimage =
331 mp->plane_fmt[p].bytesperline * mp->height; 329 mp->plane_fmt[p].bytesperline * mp->height;
332 } 330 }
331 for (p = fmt->buffers; p < fmt->planes; p++) {
332 unsigned stride = dev->bytesperline_out[p];
333
334 mp->plane_fmt[0].sizeimage += stride * mp->height;
335 }
333 return 0; 336 return 0;
334} 337}
335 338
@@ -391,7 +394,7 @@ int vivid_try_fmt_vid_out(struct file *file, void *priv,
391 bytesperline = (mp->width * fmt->bit_depth[0]) >> 3; 394 bytesperline = (mp->width * fmt->bit_depth[0]) >> 3;
392 /* Calculate the maximum supported bytesperline value */ 395 /* Calculate the maximum supported bytesperline value */
393 max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->bit_depth[0]) >> 3; 396 max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->bit_depth[0]) >> 3;
394 mp->num_planes = fmt->planes; 397 mp->num_planes = fmt->buffers;
395 for (p = 0; p < mp->num_planes; p++) { 398 for (p = 0; p < mp->num_planes; p++) {
396 if (pfmt[p].bytesperline > max_bpl) 399 if (pfmt[p].bytesperline > max_bpl)
397 pfmt[p].bytesperline = max_bpl; 400 pfmt[p].bytesperline = max_bpl;
@@ -400,6 +403,9 @@ int vivid_try_fmt_vid_out(struct file *file, void *priv,
400 pfmt[p].sizeimage = pfmt[p].bytesperline * mp->height; 403 pfmt[p].sizeimage = pfmt[p].bytesperline * mp->height;
401 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved)); 404 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved));
402 } 405 }
406 for (p = fmt->buffers; p < fmt->planes; p++)
407 pfmt[0].sizeimage += (pfmt[0].bytesperline * fmt->bit_depth[p]) /
408 fmt->bit_depth[0];
403 mp->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 409 mp->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
404 mp->quantization = V4L2_QUANTIZATION_DEFAULT; 410 mp->quantization = V4L2_QUANTIZATION_DEFAULT;
405 if (vivid_is_svid_out(dev)) { 411 if (vivid_is_svid_out(dev)) {
@@ -431,6 +437,7 @@ int vivid_s_fmt_vid_out(struct file *file, void *priv,
431 struct vb2_queue *q = &dev->vb_vid_out_q; 437 struct vb2_queue *q = &dev->vb_vid_out_q;
432 int ret = vivid_try_fmt_vid_out(file, priv, f); 438 int ret = vivid_try_fmt_vid_out(file, priv, f);
433 unsigned factor = 1; 439 unsigned factor = 1;
440 unsigned p;
434 441
435 if (ret < 0) 442 if (ret < 0)
436 return ret; 443 return ret;
@@ -526,9 +533,12 @@ int vivid_s_fmt_vid_out(struct file *file, void *priv,
526 533
527 dev->fmt_out_rect.width = mp->width; 534 dev->fmt_out_rect.width = mp->width;
528 dev->fmt_out_rect.height = mp->height; 535 dev->fmt_out_rect.height = mp->height;
529 dev->bytesperline_out[0] = mp->plane_fmt[0].bytesperline; 536 for (p = 0; p < mp->num_planes; p++)
530 if (mp->num_planes > 1) 537 dev->bytesperline_out[p] = mp->plane_fmt[p].bytesperline;
531 dev->bytesperline_out[1] = mp->plane_fmt[1].bytesperline; 538 for (p = dev->fmt_out->buffers; p < dev->fmt_out->planes; p++)
539 dev->bytesperline_out[p] =
540 (dev->bytesperline_out[0] * dev->fmt_out->bit_depth[p]) /
541 dev->fmt_out->bit_depth[0];
532 dev->field_out = mp->field; 542 dev->field_out = mp->field;
533 if (vivid_is_svid_out(dev)) 543 if (vivid_is_svid_out(dev))
534 dev->tv_field_out = mp->field; 544 dev->tv_field_out = mp->field;