diff options
author | Bastien Nocera <hadess@users.sourceforge.net> | 2003-01-31 17:56:35 +0000 |
---|---|---|
committer | Bastien Nocera <hadess@users.sourceforge.net> | 2003-01-31 17:56:35 +0000 |
commit | 4489eaee57861208aeaa15640bcf9a1c235509c9 (patch) | |
tree | dc12cc498538e60d278a9688b0215a311cf90e58 | |
parent | f000f1b8a8ff2c42293873c150cb2f8a3fe95c70 (diff) | |
download | xine-lib-4489eaee57861208aeaa15640bcf9a1c235509c9.tar.gz xine-lib-4489eaee57861208aeaa15640bcf9a1c235509c9.tar.bz2 |
fix the v4l plugin for lower resolution devices (webcam)
CVS patchset: 4066
CVS date: 2003/01/31 17:56:35
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | src/input/input_v4l.c | 94 |
2 files changed, 61 insertions, 34 deletions
@@ -1,6 +1,7 @@ xine-lib (1-beta5) * new AV sync strategy (audio resample) for DXR3 users * improved fb driver with zero copy + * fix the v4l plugin for lower resolution devices (webcam) xine-lib (1-beta4) * http input fixes diff --git a/src/input/input_v4l.c b/src/input/input_v4l.c index 4da1523c5..60acf1ce3 100644 --- a/src/input/input_v4l.c +++ b/src/input/input_v4l.c @@ -41,12 +41,18 @@ #include "input_plugin.h" #define NUM_FRAMES 10 -#define GRAB_WIDTH 768 -#define GRAB_HEIGHT 576 -/* -#define GRAB_WIDTH 384 -#define GRAB_HEIGHT 288 -*/ + +#define NUM_RESOLUTIONS 5 +static struct { + int width; + int height; +} resolutions[NUM_RESOLUTIONS] = { + { 768, 576 }, + { 640, 480 }, + { 384, 288 }, + { 320, 240 }, + { 160, 120 }, +}; /* #define LOG @@ -278,14 +284,15 @@ static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *strea /* v4l_input_class_t *cls = (v4l_input_class_t *) cls_gen; */ v4l_input_plugin_t *this; - int i, ret; + int i, j, ret, found; char *mrl = strdup(data); #ifdef LOG printf ("input_v4l: trying to open '%s'\n", mrl); #endif + found = 0; - if (strncasecmp (mrl, "v4l://", 6)) { + if (strncasecmp (mrl, "v4l:", 4)) { free (mrl); return NULL; } @@ -301,24 +308,6 @@ static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *strea pthread_mutex_init (&this->frames_lock, NULL); pthread_cond_init (&this->frame_freed, NULL); - for (i=0; i<NUM_FRAMES; i++) { - - buf_element_t *frame; - - frame = xine_xmalloc (sizeof (buf_element_t)); - - frame->decoder_info[0] = GRAB_WIDTH; - frame->decoder_info[1] = GRAB_HEIGHT; - frame->content = xine_xmalloc (frame->decoder_info[0] * frame->decoder_info[1] * 3 / 2); - frame->type = BUF_VIDEO_YUV_FRAMES; - - frame->source = this; - frame->free_buffer = store_frame; - frame->extra_info = xine_xmalloc(sizeof(extra_info_t)); - - store_frame (frame); - } - this->video_fd = open("/dev/video0", O_RDWR); if (this->video_fd < 0) { printf ("input_v4l: cannot open v4l device\n"); @@ -337,6 +326,44 @@ static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *strea free(this); return NULL; } + + /* figure out the resolution */ + for (j=0; j<NUM_RESOLUTIONS; j++) + { + if (resolutions[j].width < this->video_cap.maxwidth + && resolutions[j].height < this->video_cap.maxheight) + { + found = 1; + break; + } + } + + if (found == 0 || resolutions[j].width < this->video_cap.minwidth + || resolutions[j].height < this->video_cap.minheight) + { + printf ("input_v4l: grab device does not support any preset resolutions"); + free(this); + return NULL; + } + + for (i=0; i<NUM_FRAMES; i++) { + + buf_element_t *frame; + + frame = xine_xmalloc (sizeof (buf_element_t)); + + frame->decoder_info[0] = resolutions[j].width; + frame->decoder_info[1] = resolutions[j].height; + frame->content = xine_xmalloc (frame->decoder_info[0] * frame->decoder_info[1] * 3 / 2); + frame->type = BUF_VIDEO_YUV_FRAMES; + + frame->source = this; + frame->free_buffer = store_frame; + frame->extra_info = xine_xmalloc(sizeof(extra_info_t)); + + store_frame (frame); + } + /* unmute audio */ ioctl(this->video_fd, VIDIOCGAUDIO, &this->audio); memcpy(&this->audio_saved, &this->audio, sizeof(this->audio)); @@ -395,18 +422,18 @@ static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *strea return NULL; } this->gb_frame = 0; - + /* start to grab the first frame */ this->gb_buf.frame = (this->gb_frame + 1) % this->gb_buffers.frames; - this->gb_buf.height = GRAB_HEIGHT; - this->gb_buf.width = GRAB_WIDTH; + this->gb_buf.height = resolutions[j].height; + this->gb_buf.width = resolutions[j].width; this->gb_buf.format = VIDEO_PALETTE_YUV420P; - + ret = ioctl(this->video_fd, VIDIOCMCAPTURE, &this->gb_buf); if (ret < 0 && errno != EAGAIN) { /* try YUV422 */ this->gb_buf.format = VIDEO_PALETTE_YUV422; - + ret = ioctl(this->video_fd, VIDIOCMCAPTURE, &this->gb_buf); } else printf ("input_v4l: YUV420 should work\n"); @@ -427,14 +454,13 @@ static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *strea switch(this->frame_format) { case VIDEO_PALETTE_YUV420P: - this->frame_size = ( GRAB_WIDTH * GRAB_HEIGHT * 3) / 2; + this->frame_size = ( resolutions[j].width * resolutions[j].height * 3) / 2; break; case VIDEO_PALETTE_YUV422: - this->frame_size = GRAB_WIDTH * GRAB_HEIGHT * 2; + this->frame_size = resolutions[j].width * resolutions[j].height * 2; break; } - this->start_time=0; this->input_plugin.get_capabilities = v4l_plugin_get_capabilities; |