diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-13 14:37:52 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-24 14:08:00 -0300 |
commit | ad0ebb96c220c461386e9a765fca3daf5590d01e (patch) | |
tree | 4c13c24682703cbb94f415eb944c573ac0835ccc /drivers/media/video/em28xx/em28xx.h | |
parent | 78e92006f410a4044f8c1760c25ac9d11d259aa2 (diff) |
V4L/DVB (7540): em28xx: convert to use videobuf-vmalloc
The usage of videobuf-vmalloc allows to cleanup em28xx logic.
Also, it reduced its size by about 5.42% on i386 arch (and about 7.5% on x86_64):
39113 4876 40 44029 abfd old/em28xx.ko
36731 4868 40 41639 a2a7 /home/v4l/master/v4l/em28xx.ko
Also, the preliminary tests, made on a single core 1.5 MHz Centrino showed
that CPU usage reduced from 42%-75% to 28%-33% (reports from "top") command.
A test with time command presented an even better result:
This is the performance tests I did, running code_example to get 1,000 frames
@29.995 Hz (about 35 seconds of stream), tested on a i386 machine, running at
1,5GHz:
The old driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:34.21: 8.22s User time, 25.16s Kernel time, 97% CPU used
The videobuf-based driver:
$ time -f "%E: %Us User time, %Ss Kernel time, %P CPU used" ./capture_example
0:35.36: 0.01s User time, 0.05s Kernel time, 0% CPU used
Conclusion:
The time consumption to receive the stream where reduced from about 33.38
seconds to 0.05 seconds.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/em28xx/em28xx.h')
-rw-r--r-- | drivers/media/video/em28xx/em28xx.h | 94 |
1 files changed, 68 insertions, 26 deletions
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 04e0e48ecabe..dd18ceb30a43 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -26,12 +26,12 @@ #define _EM28XX_H #include <linux/videodev2.h> +#include <media/videobuf-vmalloc.h> + #include <linux/i2c.h> #include <linux/mutex.h> #include <media/ir-kbd-i2c.h> -#define UNSET -1 - /* maximum number of em28xx boards */ #define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */ @@ -81,31 +81,69 @@ /* time in msecs to wait for i2c writes to finish */ #define EM2800_I2C_WRITE_TIMEOUT 20 -/* the various frame states */ -enum em28xx_frame_state { - F_UNUSED = 0, - F_QUEUED, - F_GRABBING, - F_DONE, - F_ERROR, -}; - -/* stream states */ enum em28xx_stream_state { STREAM_OFF, STREAM_INTERRUPT, STREAM_ON, }; -/* frames */ -struct em28xx_frame_t { - void *bufmem; - struct v4l2_buffer buf; - enum em28xx_frame_state state; +struct em28xx_usb_isoc_ctl { + /* max packet size of isoc transaction */ + int max_pkt_size; + + /* number of allocated urbs */ + int num_bufs; + + /* urb for isoc transfers */ + struct urb **urb; + + /* transfer buffers for isoc transfer */ + char **transfer_buffer; + + /* Last buffer command and region */ + u8 cmd; + int pos, size, pktsize; + + /* Last field: ODD or EVEN? */ + int field; + + /* Stores incomplete commands */ + u32 tmp_buf; + int tmp_buf_len; + + /* Stores already requested buffers */ + struct em28xx_buffer *buf; + + /* Stores the number of received fields */ + int nfields; +}; + +struct em28xx_fmt { + char *name; + u32 fourcc; /* v4l2 format id */ +}; + +/* buffer for one video frame */ +struct em28xx_buffer { + /* common v4l buffer stuff -- must be first */ + struct videobuf_buffer vb; + + struct em28xx_fmt *fmt; + struct list_head frame; - unsigned long vma_use_count; int top_field; - int fieldbytesused; + int receiving; +}; + +struct em28xx_dmaqueue { + struct list_head active; + struct list_head queued; + struct timer_list timeout; + + wait_queue_head_t wq; + + /* Counters to control buffer fill */ + int pos; }; /* io methods */ @@ -255,10 +293,6 @@ struct em28xx { int mute; int volume; /* frame properties */ - struct em28xx_frame_t frame[EM28XX_NUM_FRAMES]; /* list of frames */ - int num_frames; /* number of frames currently in use */ - unsigned int frame_count; /* total number of transfered frames */ - struct em28xx_frame_t *frame_current; /* the frame that is being filled */ int width; /* current frame width */ int height; /* current frame height */ int frame_size; /* current frame size */ @@ -277,7 +311,6 @@ struct em28xx { /* states */ enum em28xx_dev_state state; - enum em28xx_stream_state stream; enum em28xx_io_method io; struct work_struct request_module_wk; @@ -292,6 +325,11 @@ struct em28xx { unsigned char eedata[256]; + /* Isoc control struct */ + struct em28xx_dmaqueue vidq; + struct em28xx_usb_isoc_ctl isoc_ctl; + spinlock_t slock; + /* usb transfer */ struct usb_device *udev; /* the usb device */ int alt; /* alternate */ @@ -315,6 +353,12 @@ struct em28xx_fh { struct em28xx *dev; unsigned int stream_on:1; /* Locks streams */ int radio; + + unsigned int width, height; + struct videobuf_queue vb_vidq; + struct em28xx_fmt *fmt; + + enum v4l2_buf_type type; }; struct em28xx_ops { @@ -351,8 +395,6 @@ int em28xx_colorlevels_set_default(struct em28xx *dev); int em28xx_capture_start(struct em28xx *dev, int start); int em28xx_outfmt_set_yuv422(struct em28xx *dev); int em28xx_resolution_set(struct em28xx *dev); -int em28xx_init_isoc(struct em28xx *dev); -void em28xx_uninit_isoc(struct em28xx *dev); int em28xx_set_alternate(struct em28xx *dev); /* Provided by em28xx-video.c */ |