Commit ad0ebb96 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

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: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 78e92006
This diff is collapsed.
This diff is collapsed.
...@@ -26,12 +26,12 @@ ...@@ -26,12 +26,12 @@
#define _EM28XX_H #define _EM28XX_H
#include <linux/videodev2.h> #include <linux/videodev2.h>
#include <media/videobuf-vmalloc.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <media/ir-kbd-i2c.h> #include <media/ir-kbd-i2c.h>
#define UNSET -1
/* maximum number of em28xx boards */ /* maximum number of em28xx boards */
#define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */ #define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */
...@@ -81,31 +81,69 @@ ...@@ -81,31 +81,69 @@
/* time in msecs to wait for i2c writes to finish */ /* time in msecs to wait for i2c writes to finish */
#define EM2800_I2C_WRITE_TIMEOUT 20 #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 { enum em28xx_stream_state {
STREAM_OFF, STREAM_OFF,
STREAM_INTERRUPT, STREAM_INTERRUPT,
STREAM_ON, STREAM_ON,
}; };
/* frames */ struct em28xx_usb_isoc_ctl {
struct em28xx_frame_t { /* max packet size of isoc transaction */
void *bufmem; int max_pkt_size;
struct v4l2_buffer buf;
enum em28xx_frame_state state; /* 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; struct list_head frame;
unsigned long vma_use_count;
int top_field; 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 */ /* io methods */
...@@ -255,10 +293,6 @@ struct em28xx { ...@@ -255,10 +293,6 @@ struct em28xx {
int mute; int mute;
int volume; int volume;
/* frame properties */ /* 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 width; /* current frame width */
int height; /* current frame height */ int height; /* current frame height */
int frame_size; /* current frame size */ int frame_size; /* current frame size */
...@@ -277,7 +311,6 @@ struct em28xx { ...@@ -277,7 +311,6 @@ struct em28xx {
/* states */ /* states */
enum em28xx_dev_state state; enum em28xx_dev_state state;
enum em28xx_stream_state stream;
enum em28xx_io_method io; enum em28xx_io_method io;
struct work_struct request_module_wk; struct work_struct request_module_wk;
...@@ -292,6 +325,11 @@ struct em28xx { ...@@ -292,6 +325,11 @@ struct em28xx {
unsigned char eedata[256]; unsigned char eedata[256];
/* Isoc control struct */
struct em28xx_dmaqueue vidq;
struct em28xx_usb_isoc_ctl isoc_ctl;
spinlock_t slock;
/* usb transfer */ /* usb transfer */
struct usb_device *udev; /* the usb device */ struct usb_device *udev; /* the usb device */
int alt; /* alternate */ int alt; /* alternate */
...@@ -315,6 +353,12 @@ struct em28xx_fh { ...@@ -315,6 +353,12 @@ struct em28xx_fh {
struct em28xx *dev; struct em28xx *dev;
unsigned int stream_on:1; /* Locks streams */ unsigned int stream_on:1; /* Locks streams */
int radio; int radio;
unsigned int width, height;
struct videobuf_queue vb_vidq;
struct em28xx_fmt *fmt;
enum v4l2_buf_type type;
}; };
struct em28xx_ops { struct em28xx_ops {
...@@ -351,8 +395,6 @@ int em28xx_colorlevels_set_default(struct em28xx *dev); ...@@ -351,8 +395,6 @@ int em28xx_colorlevels_set_default(struct em28xx *dev);
int em28xx_capture_start(struct em28xx *dev, int start); int em28xx_capture_start(struct em28xx *dev, int start);
int em28xx_outfmt_set_yuv422(struct em28xx *dev); int em28xx_outfmt_set_yuv422(struct em28xx *dev);
int em28xx_resolution_set(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); int em28xx_set_alternate(struct em28xx *dev);
/* Provided by em28xx-video.c */ /* Provided by em28xx-video.c */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment