diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2015-03-09 11:03:52 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-04-02 19:54:24 -0400 |
commit | ddcaee9dd4c00174db8ddf913c87ddf3773c446e (patch) | |
tree | 109e70f27a21d9d914ba7a64d15d68fd7e1c172d | |
parent | 96c76efae3211c7b798553602d3165b4ea34aa95 (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.h | 2 | ||||
-rw-r--r-- | drivers/media/platform/vivid/vivid-kthread-cap.c | 54 | ||||
-rw-r--r-- | drivers/media/platform/vivid/vivid-vid-cap.c | 58 | ||||
-rw-r--r-- | drivers/media/platform/vivid/vivid-vid-common.c | 2 | ||||
-rw-r--r-- | drivers/media/platform/vivid/vivid-vid-out.c | 68 |
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 | ||
232 | static 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 | |||
232 | static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf, | 246 | static 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 | ||
396 | static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf) | 412 | static 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 = { | |||
222 | void vivid_update_format_out(struct vivid_dev *dev) | 219 | void 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; |