[MPlayer-dev-eng] [PATCH] v4l2: prevent divide by zero

Németh Márton nm127 at freemail.hu
Sat Aug 14 14:22:41 CEST 2010


In case of PAC7302 based webcam the VIDIOC_G_PARM ioctl for V4L2_BUF_TYPE_VIDEO_CAPTURE
type may return parm.parm.capture.timeperframe = { 0, 0 } at stream/tvi_v4l2.c::getstd().
This is response is a valid response because V4L2 specification states: "Drivers
support this function only when they set the V4L2_CAP_TIMEPERFRAME flag in the capability
field." [1] This driver has no such capability.

The problem only arrives later when the there is an attempt to use the value and
try to divide by zero.

References:
[1] Video for Linux Two API Specification, Revision 0.24, struct v4l2_captureparm
http://v4l2spec.bytesex.org/spec/r11680.htm#V4L2-CAPTUREPARM

Signed-off-by: Márton Németh <nm127 at freemail.hu>
---

$ gdb ./mencoder
GNU gdb (GDB) 7.0.1-debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/nmarci/src/mplayer/mplayer/mencoder...done.
(gdb) set args tv:// -tv driver=v4l2 -ovc lavc -o test.avi
(gdb) run
Starting program: /home/nmarci/src/mplayer/mplayer/mencoder tv:// -tv driver=v4l2 -ovc lavc -o test.avi
[Thread debugging using libthread_db enabled]
MEncoder SVN-r31961-4.4.4 (C) 2000-2010 MPlayer Team
success: format: 9  data: 0x0 - 0x0
TV file format detected.
Selected driver: v4l2
 name: Video 4 Linux 2 input
 author: Martin Olschewski <olschewski at zpr.uni-koeln.de>
 comment: first try, more to come ;-)
v4l2: your device driver does not support VIDIOC_G_STD ioctl, VIDIOC_G_PARM was used instead.
Selected device: USB Camera (093a:2626)
 Capabilities:  video capture  read/write  streaming
 supported norms:
 inputs: 0 = pac7311;
 Current input: 0
 Current format: RGB24
tv.c: norm_from_string(pal): Bogus norm parameter, setting default.
v4l2: ioctl enum norm failed: Invalid argument
Error: Cannot set norm!
Selected input hasn't got a tuner!
v4l2: Cannot get fps
Audio block size too low, setting to 16384!

Program received signal SIGFPE, Arithmetic exception.
start (priv=0x8dbffd8) at stream/tvi_v4l2.c:1473
1473                                                   priv->standard.frameperiod.numerator
(gdb) bt
#0  start (priv=0x8dbffd8) at stream/tvi_v4l2.c:1473
#1  0x0824c2c1 in demux_open_tv (demuxer=0x8dbf218) at stream/tv.c:819
#2  0x08135753 in demux_open_stream (stream=<value optimized out>, file_format=<value optimized out>,
    force=<value optimized out>, audio_id=-1, video_id=-1, dvdsub_id=-1, filename=0x8daa508 "tv://")
    at libmpdemux/demuxer.c:985
#3  0x081359e3 in demux_open (vs=0x8dbd1b0, file_format=9, audio_id=<value optimized out>, video_id=-1, dvdsub_id=-1,
    filename=0x8daa508 "tv://") at libmpdemux/demuxer.c:1191
#4  0x080b1944 in main (argc=8, argv=0xbffff614) at mencoder.c:737
(gdb) print priv
$1 = (priv_t *) 0x8dbffd8
(gdb) print *priv
$2 = {video_dev = 0x8dc0368 "/dev/video0", video_fd = 5, vbi_dev = 0x0, vbi_fd = 0, vbi_bufsize = 0, vbi_shutdown = 0,
  vbi_grabber_thread = 0, priv_vbi = 0x0, mp_format = 842094169, capability = {
    driver = "pac7311\000\000\000\000\000\000\000\000",
    card = "USB Camera (093a:2626)\000\000\000\000\000\000\000\000\000",
    bus_info = "usb-0000:00:1d.1-1", '\000' <repeats 13 times>, version = 132864, capabilities = 83886081, reserved = {
      0, 0, 0, 0}}, input = {index = 0, name = "pac7311", '\000' <repeats 24 times>, type = 2, audioset = 0, tuner = 0,
    std = 0, status = 0, reserved = {0, 0, 0, 0}}, format = {type = V4L2_BUF_TYPE_VIDEO_CAPTURE, fmt = {pix = {
        width = 640, height = 480, pixelformat = 842094169, field = V4L2_FIELD_NONE, bytesperline = 640,
        sizeimage = 460800, colorspace = V4L2_COLORSPACE_JPEG, priv = 0}, win = {w = {left = 640, top = 480,
          width = 842094169, height = 1}, field = 640, chromakey = 460800, clips = 0x7, clipcount = 0, bitmap = 0x0,
        global_alpha = 0 '\000'}, vbi = {sampling_rate = 640, offset = 480, samples_per_line = 842094169,
        sample_format = 1, start = {640, 460800}, count = {7, 0}, flags = 0, reserved = {0, 0}}, sliced = {
        service_set = 640, service_lines = {{0, 480, 0, 22105, 12849, 1, 0, 640, 0, 2048, 7, 7, 0 <repeats 12 times>}, {
            0 <repeats 24 times>}}, io_size = 0, reserved = {0, 0}},
      raw_data = "\200\002\000\000\340\001\000\000YV12\001\000\000\000\200\002\000\000\000\b\a\000\a", '\000' <repeats 174 times>}}, standard = {index = 0, id =
0, name = '\000' <repeats 23 times>, frameperiod = {numerator = 0,
      denominator = 0}, framelines = 0, reserved = {0, 0, 0, 0}}, tuner = {index = 0, name = '\000' <repeats 31 times>,
    type = 0, capability = 0, rangelow = 0, rangehigh = 0, rxsubchans = 0, audmode = 0, signal = 0, afc = 0, reserved = {
      0, 0, 0, 0}}, map = 0x0, mapcount = 0, frames = 0, first_frame = 0, curr_frame = 0, streamon = 0,
  audio_grabber_thread = 0, skew_mutex = {__data = {__lock = 0, __count = 0, __owner = 0, __kind = 0, __nusers = 0, {
        __spins = 0, __list = {__next = 0x0}}}, __size = '\000' <repeats 23 times>, __align = 0}, first = 0,
  immediate_mode = 0, video_buffer_size_max = 1140, video_buffer_size_current = 0, video_ringbuffer = 0x0,
  video_head = 0, video_tail = 0, video_cnt = 0, video_grabber_thread = 0, video_buffer_mutex = {__data = {__lock = 0,
      __count = 0, __owner = 0, __kind = 0, __nusers = 0, {__spins = 0, __list = {__next = 0x0}}},
    __size = '\000' <repeats 23 times>, __align = 0}, audio_dev = 0x0, audio_in = {type = 2, setup = 1,
    req_channels = 2, req_samplerate = 44100, channels = 2, samplerate = 44100, blocksize = 16384, bytes_per_sample = 2,
    samplesize = 16, oss = {device = 0x8dc21c8 "/dev/dsp", audio_fd = 6}}, audio_start_time = 0,
  audio_buffer_size = 485, aud_skew_cnt = 16, audio_ringbuffer = 0xb6cbf008 "", audio_skew_buffer = 0x8dc21d8,
  audio_skew_delta_buffer = 0x8dc2260, audio_head = 0, audio_tail = 0, audio_cnt = 0, audio_skew = 0,
  audio_skew_factor = 0, audio_skew_measure_time = 0, audio_drop = 0, shutdown = 0, audio_initialized = 1,
  audio_secs_per_block = 0.09287981859410431, audio_usecs_per_block = 92879, audio_skew_total = 0,
  audio_skew_delta_total = 0, audio_recv_blocks_total = 0, audio_sent_blocks_total = 0, audio_mutex = {__data = {
      __lock = 0, __count = 0, __owner = 0, __kind = 0, __nusers = 0, {__spins = 0, __list = {__next = 0x0}}},
    __size = '\000' <repeats 23 times>, __align = 0}, audio_insert_null_samples = 0, audio_null_blocks_inserted = 0,
  dropped_frames_timeshift = 0, dropped_frames_compensated = 0, tv_param = 0x8dbd0f0}
(gdb)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: v4l2_prevent_divide_by_zero.patch
Type: text/x-diff
Size: 1194 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/attachments/20100814/52c51ae9/attachment.patch>


More information about the MPlayer-dev-eng mailing list