linux/drivers/media/video
Mike Isely 66349b4e7a V4L/DVB (13169): bttv: Fix potential out-of-order field processing
There is a subtle interaction in the bttv driver which can result in
fields being repeatedly processed out of order.  This is a problem
specifically when running in V4L2_FIELD_ALTERNATE mode (probably the
most common case).

1. The determination of which fields are associated with which buffers
happens in videobuf, before the bttv driver gets a chance to queue the
corresponding DMA.  Thus by the point when the DMA is queued for a
given buffer, the algorithm has to do the queuing based on the
buffer's already assigned field type - not based on which field is
"next" in the video stream.

2. The driver normally tries to queue both the top and bottom fields
at the same time (see bttv_irq_next_video()).  It tries to sort out
top vs bottom by looking at the field type for the next 2 available
buffers and assigning them appropriately.

3. However the bttv driver *always* actually processes the top field
first.  There's even an interrupt set aside for specifically
recognizing when the top field has been processed so that it can be
marked done even while the bottom field is still being DMAed.

Given all of the above, if one gets into a situation where
bttv_irq_next_video() gets entered when the first available buffer has
been pre-associated as a bottom field, then the function is going to
process the buffers out of order.  That first available buffer will be
put into the bottom field slot and the buffer after that will be put
into the top field slot.  Problem is, since the top field is always
processed first by the driver, then that second buffer (the one after
the first available buffer) will be the first one to be finished.
Because of the strict fifo handling of all video buffers, then that
top field won't be seen by the app until after the bottom field is
also processed.  Worse still, the app will get back the
chronologically later bottom field first, *before* the top field is
received.  The buffer's timestamps will even be backwards.

While not fatal to most TV apps, this behavior can subtlely degrade
userspace deinterlacing (probably will cause jitter).  That's probably
why it has gone unnoticed.  But it will also cause serious problems if
the app in question discards all but the latest received buffer (a
latency minimizing tactic) - causing one field to only ever be
displayed since the other is now always late.  Unfortunately once you
get into this state, you're stuck this way - because having consumed
two buffers, now the next time around the "first" available buffer
will again be a bottom field and the same thing happens.

How can we get into this state?  In a perfect world, where there's
always a few free buffers queued to the driver, it should be
impossible.  However if something disrupts streaming, e.g. if the
userspace app can't queue free buffers fast enough for a moment due
perhaps to a CPU scheduling glitch, then the driver can get
momentarily starved and some number of fields will be dropped.  That's
OK.  But if an odd number of fields get dropped, then that "first"
available buffer might be the bottom field and now we're stuck...

This patch fixes that problem by deliberately only setting up a single
field for one frame if we don't get a top field as the first available
buffer.  By purposely skipping the other field, then we only handle a
single buffer thus bringing things back into proper sync (i.e. top
field first) for the next frame.  To do this we just drop the few
lines in bttv_irq_next_video() that attempt to set up the second
buffer when that second buffer isn't for the bottom field.

This is definitely a problem in when in V4L2_FIELD_ALTERNATE mode.  In
the other modes this change either has no effect or doesn't harm
things any further anyway.

Signed-off-by: Mike Isely <isely@pobox.com>
CC: stable@kernel.org
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2009-11-07 12:55:07 -02:00
..
au0828 V4L/DVB (12540): v4l: simplify v4l2_i2c_new_subdev and friends 2009-09-19 00:19:24 -03:00
bt8xx V4L/DVB (13169): bttv: Fix potential out-of-order field processing 2009-11-07 12:55:07 -02:00
cpia2 V4L/DVB: cleanup redundant tests on unsigned 2009-06-16 18:20:58 -03:00
cx18 V4L/DVB (12725): v4l: warn when desired devnodenr is in use & add _no_warn function 2009-09-19 00:19:34 -03:00
cx88 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2009-09-22 07:51:45 -07:00
cx231xx V4L/DVB (12540): v4l: simplify v4l2_i2c_new_subdev and friends 2009-09-19 00:19:24 -03:00
cx23885 V4L/DVB (13014): Add support for Compro VideoMate E800 (DVB-T part only) 2009-09-19 00:53:06 -03:00
cx25840 V4L/DVB (12613): cx25840: fix determining the firmware name 2009-09-12 12:19:52 -03:00
davinci V4L/DVB (12906d): V4L : vpif updates for DM6467 vpif capture driver 2009-09-19 00:19:40 -03:00
em28xx V4L/DVB (12540): v4l: simplify v4l2_i2c_new_subdev and friends 2009-09-19 00:19:24 -03:00
et61x251 const: mark struct vm_struct_operations 2009-09-27 11:39:25 -07:00
gspca V4L/DVB (13122): gscpa - stv06xx + ov518: dont discard every other frame 2009-11-07 12:55:05 -02:00
hdpvr V4L/DVB (12472): hdpvr-control: fix bad whitespaces 2009-09-12 12:19:02 -03:00
ivtv V4L/DVB (12725): v4l: warn when desired devnodenr is in use & add _no_warn function 2009-09-19 00:19:34 -03:00
ovcamchip V4L/DVB (11304): v4l2: remove v4l2_subdev_command calls where they are no longer needed. 2009-03-30 12:43:49 -03:00
pvrusb2 V4L/DVB (12540): v4l: simplify v4l2_i2c_new_subdev and friends 2009-09-19 00:19:24 -03:00
pwc V4L/DVB (12489): pwc - fix few use-after-free and memory leaks 2009-09-12 12:19:13 -03:00
saa7134 V4L/DVB (13011): Change tuner type of BeholdTV cards 2009-09-19 00:52:50 -03:00
saa7164 media: video: Fix build in saa7164 2009-09-22 18:58:17 -03:00
sn9c102 const: mark struct vm_struct_operations 2009-09-27 11:39:25 -07:00
usbvideo headers: smp_lock.h redux 2009-07-12 12:22:34 -07:00
usbvision headers: utsname.h redux 2009-09-23 18:13:10 -07:00
uvc const: mark struct vm_struct_operations 2009-09-27 11:39:25 -07:00
zc0301 const: mark struct vm_struct_operations 2009-09-27 11:39:25 -07:00
zoran const: mark struct vm_struct_operations 2009-09-27 11:39:25 -07:00
adv7170.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
adv7175.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
adv7180.c V4L/DVB (13019): video: initial support for ADV7180 2009-09-19 00:53:39 -03:00
adv7343_regs.h V4L/DVB (11743): Analog Devices ADV7343 video encoder driver 2009-06-16 18:20:59 -03:00
adv7343.c V4L/DVB (12201): adv7343: remove unused #include <linux/version.h> 2009-09-19 00:18:07 -03:00
arv.c
bt819.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
bt856.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
bt866.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
btcx-risc.c
btcx-risc.h
bw-qcam.c V4L/DVB (12438): Read buffer overflow 2009-08-13 20:39:14 -03:00
bw-qcam.h
c-qcam.c
cafe_ccic-regs.h
cafe_ccic.c const: mark struct vm_struct_operations 2009-09-27 11:39:25 -07:00
cpia_pp.c
cpia_usb.c
cpia.c headers: remove sched.h from poll.h 2009-10-04 15:05:10 -07:00
cpia.h
cs53l32a.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
cs5345.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
cs8420.h
cx2341x.c V4L/DVB (12104): ivtv/cx18: fix regression: class controls are no longer seen 2009-06-23 03:14:31 -03:00
dabusb.c Driver-Core: fix devnode callbacks for dabusb and industrialio 2009-09-21 07:36:33 -07:00
dabusb.h
font.h
hexium_gemini.c V4L/DVB: cleanup redundant tests on unsigned 2009-06-16 18:20:58 -03:00
hexium_orion.c V4L/DVB: cleanup redundant tests on unsigned 2009-06-16 18:20:58 -03:00
ibmmpeg2.h
indycam.c V4L/DVB (10866): saa7191, indycam: remove compat code. 2009-03-30 12:43:11 -03:00
indycam.h V4L/DVB (10861): vino/indycam/saa7191: convert to i2c modules to V4L2. 2009-03-30 12:43:10 -03:00
ir-kbd-i2c.c V4L/DVB (12595): common/ir: use a struct for keycode tables 2009-09-12 12:19:47 -03:00
Kconfig V4L/DVB (13019): video: initial support for ADV7180 2009-09-19 00:53:39 -03:00
ks0127.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
ks0127.h V4L/DVB (10730): v4l-dvb: cleanup obsolete references to v4l1 headers. 2009-03-30 12:42:59 -03:00
m52790.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
Makefile V4L/DVB (13019): video: initial support for ADV7180 2009-09-19 00:53:39 -03:00
meye.c headers: remove sched.h from interrupt.h 2009-10-11 11:20:58 -07:00
meye.h
msp3400-driver.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
msp3400-driver.h V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
msp3400-kthreads.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
mt9m001.c V4L/DVB (12536): soc-camera: remove .gain and .exposure struct soc_camera_device members 2009-09-19 00:19:20 -03:00
mt9m111.c V4L/DVB (12536): soc-camera: remove .gain and .exposure struct soc_camera_device members 2009-09-19 00:19:20 -03:00
mt9t031.c V4L/DVB (12536): soc-camera: remove .gain and .exposure struct soc_camera_device members 2009-09-19 00:19:20 -03:00
mt9v011.c V4L/DVB (12401): m9v011: add vflip/hflip controls to control mirror/upside down 2009-08-13 20:39:08 -03:00
mt9v011.h V4L/DVB (12340): mtv9v011: Add a missing chip version to the driver 2009-08-13 20:39:02 -03:00
mt9v022.c V4L/DVB (12536): soc-camera: remove .gain and .exposure struct soc_camera_device members 2009-09-19 00:19:20 -03:00
mx1_camera.c V4L/DVB (12536): soc-camera: remove .gain and .exposure struct soc_camera_device members 2009-09-19 00:19:20 -03:00
mx3_camera.c V4L/DVB (12534): soc-camera: V4L2 API compliant scaling (S_FMT) and cropping (S_CROP) 2009-09-19 00:19:17 -03:00
mxb.c V4L/DVB (12540): v4l: simplify v4l2_i2c_new_subdev and friends 2009-09-19 00:19:24 -03:00
mxb.h
omap24xxcam-dma.c
omap24xxcam.c V4L/DVB (11264): omap24xxcam: Remove buffer type check from vidioc_s/g_parm 2009-03-30 12:43:45 -03:00
omap24xxcam.h
ov511.c V4L/DVB (12083): ov511: remove ov518 usb id's from the driver 2009-06-23 03:13:16 -03:00
ov511.h V4L/DVB (11966): ov511: Fix unit_video parameter behavior 2009-06-16 19:07:40 -03:00
ov772x.c V4L/DVB (12536): soc-camera: remove .gain and .exposure struct soc_camera_device members 2009-09-19 00:19:20 -03:00
ov7670.c V4L/DVB (11117): ov7670: add support to get/set registers 2009-03-30 12:43:30 -03:00
pms.c
pxa_camera.c V4L/DVB (13131): pxa_camera: fix camera pixel format configuration 2009-11-07 12:55:06 -02:00
s2255drv.c headers: smp_lock.h redux 2009-07-12 12:22:34 -07:00
saa711x_regs.h
saa717x.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
saa5246a.c headers: smp_lock.h redux 2009-07-12 12:22:34 -07:00
saa5249.c headers: smp_lock.h redux 2009-07-12 12:22:34 -07:00
saa6588.c V4L/DVB (12215): saa6588: conform to the final RDS spec. 2009-09-12 12:17:31 -03:00
saa7110.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
saa7115.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
saa7121.h
saa7127.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
saa7146.h V4L/DVB (10907): avoid loading the entire videodev.h header on V4L2 drivers 2009-03-30 12:43:15 -03:00
saa7146reg.h
saa7185.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
saa7191.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
saa7191.h V4L/DVB (10861): vino/indycam/saa7191: convert to i2c modules to V4L2. 2009-03-30 12:43:10 -03:00
se401.c headers: smp_lock.h redux 2009-07-12 12:22:34 -07:00
se401.h V4L/DVB (11998): se401: Fix coding style 2009-06-16 19:07:54 -03:00
sh_mobile_ceu_camera.c V4L/DVB (13129): sh_mobile_ceu_camera: fix cropping for scaling clients 2009-11-07 12:55:06 -02:00
soc_camera_platform.c V4L/DVB (12580): soc-camera: remove now unneeded subdevice group ID assignments 2009-09-19 00:19:22 -03:00
soc_camera.c V4L/DVB (13132): fix use-after-free Oops, resulting from a driver-core API change 2009-11-07 12:55:07 -02:00
stk-sensor.c
stk-webcam.c const: mark struct vm_struct_operations 2009-09-27 11:39:25 -07:00
stk-webcam.h
stradis.c headers: smp_lock.h redux 2009-07-12 12:22:34 -07:00
stv680.c V4L/DVB (12369): stv680: kfree called before usb_kill_urb 2009-09-12 12:18:28 -03:00
stv680.h
tcm825x.c V4L/DVB (12111): tcm825x: remove incorrect __exit_p wrapper 2009-06-23 03:14:48 -03:00
tcm825x.h V4L/DVB (10628): V4L: Storage class should be before const qualifier 2009-03-30 12:42:48 -03:00
tda7432.c V4L/DVB (11564): tda7432: Delete old driver history 2009-06-16 18:20:36 -03:00
tda9840.c V4L/DVB (11372): v4l2: use old-style i2c API for kernels < 2.6.26 instead of < 2.6.22 2009-04-06 21:44:23 -03:00
tda9875.c V4L/DVB (11302): tda9875: remove legacy code for old-style i2c API 2009-03-30 12:43:48 -03:00
tea6415c.c V4L/DVB (11737): Drop stray references to i2c_probe 2009-06-16 18:20:58 -03:00
tea6415c.h V4L/DVB (10499): saa7146: convert saa7146 and mxb in particular to v4l2_subdev. 2009-03-30 12:42:42 -03:00
tea6420.c V4L/DVB (11737): Drop stray references to i2c_probe 2009-06-16 18:20:58 -03:00
tea6420.h V4L/DVB (10499): saa7146: convert saa7146 and mxb in particular to v4l2_subdev. 2009-03-30 12:42:42 -03:00
ths7303.c V4L/DVB (11742): TI THS7303 video amplifier driver code 2009-06-16 18:20:59 -03:00
tlv320aic23b.c V4L/DVB (11304): v4l2: remove v4l2_subdev_command calls where they are no longer needed. 2009-03-30 12:43:49 -03:00
tuner-core.c V4L/DVB (12964): tuner-core: add support for NXP TDA18271 without TDA829X demod 2009-09-19 00:16:01 -03:00
tvaudio.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
tveeprom.c V4L/DVB (12478): ARRAY_SIZE changes 2009-09-12 12:19:05 -03:00
tvp514x_regs.h V4L/DVB (12246): tvp514x: Migration to sub-device framework 2009-09-19 00:18:09 -03:00
tvp514x.c V4L/DVB (12247): tvp514x: formatting comments as per kernel documentation 2009-09-19 00:18:11 -03:00
tvp5150_reg.h
tvp5150.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
tw9910.c V4L/DVB (12536): soc-camera: remove .gain and .exposure struct soc_camera_device members 2009-09-19 00:19:20 -03:00
upd64031a.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
upd64083.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
v4l1-compat.c V4L/DVB (12948): v4l1-compat: fix VIDIOC_G_STD handling 2009-09-19 00:15:25 -03:00
v4l2-common.c V4L/DVB (12540): v4l: simplify v4l2_i2c_new_subdev and friends 2009-09-19 00:19:24 -03:00
v4l2-compat-ioctl32.c V4L/DVB (12549): v4l2: video device: Add FM TX controls default configurations 2009-09-12 12:19:19 -03:00
v4l2-dev.c V4L/DVB (12725): v4l: warn when desired devnodenr is in use & add _no_warn function 2009-09-19 00:19:34 -03:00
v4l2-device.c V4L/DVB (11936): Fix v4l2-device usage of i2c_unregister_device() 2009-06-16 19:07:26 -03:00
v4l2-int-device.c
v4l2-ioctl.c V4L/DVB (12543): v4l: introduce string control support. 2009-09-12 12:19:17 -03:00
videobuf-core.c headers: remove sched.h from interrupt.h 2009-10-11 11:20:58 -07:00
videobuf-dma-contig.c const: mark struct vm_struct_operations 2009-09-27 11:39:25 -07:00
videobuf-dma-sg.c headers: remove sched.h from interrupt.h 2009-10-11 11:20:58 -07:00
videobuf-dvb.c
videobuf-vmalloc.c const: mark struct vm_struct_operations 2009-09-27 11:39:25 -07:00
vino.c const: mark struct vm_struct_operations 2009-09-27 11:39:25 -07:00
vino.h
vivi.c V4L/DVB (12134): vivi: bug: don't assume that S_STD will be called before streaming 2009-07-05 10:05:10 -03:00
vp27smpx.c V4L/DVB (11370): v4l2-subdev: move s_std from tuner to core. 2009-04-06 21:44:22 -03:00
vpx3220.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
w9966.c V4L/DVB (10907): avoid loading the entire videodev.h header on V4L2 drivers 2009-03-30 12:43:15 -03:00
w9968cf_decoder.h
w9968cf_vpp.h
w9968cf.c V4L/DVB (12540): v4l: simplify v4l2_i2c_new_subdev and friends 2009-09-19 00:19:24 -03:00
w9968cf.h V4L/DVB (11377): v4l: increase version numbers of drivers converted to v4l2_subdev. 2009-04-06 21:44:26 -03:00
wm8739.c V4L/DVB (11304): v4l2: remove v4l2_subdev_command calls where they are no longer needed. 2009-03-30 12:43:49 -03:00
wm8775.c V4L/DVB (11380): v4l2-subdev: change s_routing prototype 2009-04-06 21:44:27 -03:00
zr364xx.c V4L/DVB (12326): zr364xx: error message when buffer is too small and code cleanup 2009-09-12 12:18:07 -03:00