summaryrefslogtreecommitdiffstats
path: root/drivers/media/video/bt8xx
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-11-12 10:59:04 +1100
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-11-12 10:59:04 +1100
commit0526484aa345adbf790d1201a6f5d09be0a648a3 (patch)
tree8da37ac2858a960e80dc59ebc4afc460935724f4 /drivers/media/video/bt8xx
parente0ea8b2c0677e6cc44a0e5b867be48867f91de5b (diff)
parentaa021baa3295fa6e3f367d80f8955dd5176656eb (diff)
Merge commit 'origin/master' into next
Diffstat (limited to 'drivers/media/video/bt8xx')
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 939d1e51297..a6724019c66 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -1299,7 +1299,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
tvnorm = &bttv_tvnorms[norm];
- if (!memcmp(&bttv_tvnorms[btv->tvnorm].cropcap, &tvnorm->cropcap,
+ if (memcmp(&bttv_tvnorms[btv->tvnorm].cropcap, &tvnorm->cropcap,
sizeof (tvnorm->cropcap))) {
bttv_crop_reset(&btv->crop[0], norm);
btv->crop[1] = btv->crop[0]; /* current = default */
@@ -3800,11 +3800,34 @@ bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set)
if (!V4L2_FIELD_HAS_BOTH(item->vb.field) &&
(item->vb.queue.next != &btv->capture)) {
item = list_entry(item->vb.queue.next, struct bttv_buffer, vb.queue);
+ /* Mike Isely <isely@pobox.com> - Only check
+ * and set up the bottom field in the logic
+ * below. Don't ever do the top field. This
+ * of course means that if we set up the
+ * bottom field in the above code that we'll
+ * actually skip a field. But that's OK.
+ * Having processed only a single buffer this
+ * time, then the next time around the first
+ * available buffer should be for a top field.
+ * That will then cause us here to set up a
+ * top then a bottom field in the normal way.
+ * The alternative to this understanding is
+ * that we set up the second available buffer
+ * as a top field, but that's out of order
+ * since this driver always processes the top
+ * field first - the effect will be the two
+ * buffers being returned in the wrong order,
+ * with the second buffer also being delayed
+ * by one field time (owing to the fifo nature
+ * of videobuf). Worse still, we'll be stuck
+ * doing fields out of order now every time
+ * until something else causes a field to be
+ * dropped. By effectively forcing a field to
+ * drop this way then we always get back into
+ * sync within a single frame time. (Out of
+ * order fields can screw up deinterlacing
+ * algorithms.) */
if (!V4L2_FIELD_HAS_BOTH(item->vb.field)) {
- if (NULL == set->top &&
- V4L2_FIELD_TOP == item->vb.field) {
- set->top = item;
- }
if (NULL == set->bottom &&
V4L2_FIELD_BOTTOM == item->vb.field) {
set->bottom = item;