summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Nocera <hadess@users.sourceforge.net>2003-01-31 17:56:35 +0000
committerBastien Nocera <hadess@users.sourceforge.net>2003-01-31 17:56:35 +0000
commit4489eaee57861208aeaa15640bcf9a1c235509c9 (patch)
treedc12cc498538e60d278a9688b0215a311cf90e58
parentf000f1b8a8ff2c42293873c150cb2f8a3fe95c70 (diff)
downloadxine-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--ChangeLog1
-rw-r--r--src/input/input_v4l.c94
2 files changed, 61 insertions, 34 deletions
diff --git a/ChangeLog b/ChangeLog
index 08e5e7c2c..c2ca4a136 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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;