summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/input/input_v4l2.c132
1 files changed, 42 insertions, 90 deletions
diff --git a/src/input/input_v4l2.c b/src/input/input_v4l2.c
index 20cf4f8b6..1e6da1e78 100644
--- a/src/input/input_v4l2.c
+++ b/src/input/input_v4l2.c
@@ -29,9 +29,9 @@
#define LOG
-#include <xine/input_plugin.h>
-#include <xine/xine_plugin.h>
-#include <xine/xine_internal.h>
+#include "input_plugin.h"
+#include "xine_plugin.h"
+#include "xine_internal.h"
#include <string.h>
#include <sys/types.h>
@@ -43,10 +43,17 @@
#include <errno.h>
#ifdef HAVE_LIBV4L2_H
-#include <libv4l2.h>
+# include <libv4l2.h>
#else
-#include <sys/ioctl.h>
+# include <unistd.h>
+# include <sys/ioctl.h>
+# define v4l2_open(f,d) open(f,d)
+# define v4l2_ioctl(f,c,a) ioctl(f,c,a)
+# define v4l2_mmap(p,l,d,m,f,o) mmap(p,l,d,m,f,o)
+# define v4l2_munmap(s,l) munmap(s,l)
+# define v4l2_close(f) close(f)
#endif
+
typedef struct {
void *start;
size_t length;
@@ -82,27 +89,19 @@ typedef struct {
v4l2_radio_t* radio;
} v4l2_input_plugin_t;
-void v4l2_input_enqueue_video_buffer(v4l2_input_plugin_t *this, int idx);
-void v4l2_input_dequeue_video_buffer(v4l2_input_plugin_t *this, buf_element_t *input);
-int v4l2_input_setup_video_streaming(v4l2_input_plugin_t *this);
+static void v4l2_input_enqueue_video_buffer(v4l2_input_plugin_t *this, int idx);
+static void v4l2_input_dequeue_video_buffer(v4l2_input_plugin_t *this, buf_element_t *input);
+static int v4l2_input_setup_video_streaming(v4l2_input_plugin_t *this);
-int v4l2_input_open(input_plugin_t *this_gen) {
+static int v4l2_input_open(input_plugin_t *this_gen) {
v4l2_input_plugin_t *this = (v4l2_input_plugin_t*) this_gen;
lprintf("Opening %s\n", this->mrl);
-#ifdef HAVE_LIBV4L2_H
this->fd = v4l2_open(this->mrl, O_RDWR);
-#else
- this->fd = open(this->mrl, O_RDWR);
-#endif
if (this->fd) {
/* TODO: Clean up this mess */
this->events = xine_event_new_queue(this->stream);
-#ifdef HAVE_LIBV4L2_H
v4l2_ioctl(this->fd, VIDIOC_QUERYCAP, &(this->cap));
-#else
- ioctl(this->fd, VIDIOC_QUERYCAP, &(this->cap));
-#endif
if (this->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
this->video = malloc(sizeof(v4l2_video_t));
this->video->headerSent = 0;
@@ -133,7 +132,7 @@ int v4l2_input_open(input_plugin_t *this_gen) {
}
}
-int v4l2_input_setup_video_streaming(v4l2_input_plugin_t *this) {
+static int v4l2_input_setup_video_streaming(v4l2_input_plugin_t *this) {
this->video->bufcount = 0;
struct v4l2_requestbuffers reqbuf;
unsigned int i;
@@ -142,18 +141,14 @@ int v4l2_input_setup_video_streaming(v4l2_input_plugin_t *this) {
reqbuf.memory = V4L2_MEMORY_MMAP;
reqbuf.count = 25;
-#ifdef HAVE_LIBV4L2_H
if (-1 == v4l2_ioctl(this->fd, VIDIOC_REQBUFS, &reqbuf)) {
-#else
- if (-1 == ioctl(this->fd, VIDIOC_REQBUFS, &reqbuf)) {
-#endif
lprintf("Buffer request failed. Is streaming supported?\n");
return 0;
}
-
+
this->video->bufcount = reqbuf.count;
lprintf("Got %i buffers for stremaing.\n", reqbuf.count);
-
+
this->video->buffers = calloc(this->video->bufcount, sizeof(buffer_data));
_x_assert(this->video->buffers);
for (i = 0;i < this->video->bufcount;i++) {
@@ -162,37 +157,22 @@ int v4l2_input_setup_video_streaming(v4l2_input_plugin_t *this) {
buffer.type = reqbuf.type;
buffer.memory = reqbuf.memory;
buffer.index = i;
-
-#ifdef HAVE_LIBV4L2_H
+
if (-1 == v4l2_ioctl(this->fd, VIDIOC_QUERYBUF, &buffer)) {
-#else
- if (-1 == ioctl(this->fd, VIDIOC_QUERYBUF, &buffer)) {
-#endif
lprintf("Couldn't allocate buffer %i\n", i);
return 0;
}
-
+
this->video->buffers[i].length = buffer.length;
-#ifdef HAVE_LIBV4L2_H
this->video->buffers[i].start = (void*)v4l2_mmap(NULL, buffer.length,
PROT_READ | PROT_WRITE,
MAP_SHARED,
this->fd, buffer.m.offset);
-#else
- this->video->buffers[i].start = (void*)mmap(NULL, buffer.length,
- PROT_READ | PROT_WRITE,
- MAP_SHARED,
- this->fd, buffer.m.offset);
-#endif
if (MAP_FAILED == this->video->buffers[i].start) {
lprintf("Couldn't mmap buffer %i\n", i);
int j;
for(j = 0;j<i;j++) {
-#ifdef HAVE_LIBV4L2_H
v4l2_munmap(this->video->buffers[i].start, this->video->buffers[i].length);
-#else
- munmap(this->video->buffers[i].start, this->video->buffers[i].length);
-#endif
}
free(this->video->buffers);
this->video->bufcount = 0;
@@ -200,31 +180,23 @@ int v4l2_input_setup_video_streaming(v4l2_input_plugin_t *this) {
}
v4l2_input_enqueue_video_buffer(this, i);
}
-
+
struct v4l2_format fmt;
memset(&fmt, 0, sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
/* TODO: Other formats? MPEG support? */
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
-#ifdef HAVE_LIBV4L2_H
v4l2_ioctl(this->fd, VIDIOC_S_FMT, &fmt);
-#else
- ioctl(this->fd, VIDIOC_S_FMT, &fmt);
-#endif
this->video->resolution.width = fmt.fmt.pix.width;
this->video->resolution.height = fmt.fmt.pix.height;
-#ifdef HAVE_LIBV4L2_H
if (-1 == v4l2_ioctl(this->fd, VIDIOC_STREAMON, &reqbuf.type)) {
-#else
- if (-1 == ioctl(this->fd, VIDIOC_STREAMON, &reqbuf.type)) {
-#endif
lprintf("Couldn't start streaming: %s\n", strerror(errno));
return 0;
}
return 1;
}
-buf_element_t* v4l2_input_read_block(input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t len) {
+static buf_element_t* v4l2_input_read_block(input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t len) {
lprintf("Reading block\n");
v4l2_input_plugin_t *this = (v4l2_input_plugin_t*)this_gen;
buf_element_t *buf = fifo->buffer_pool_alloc(fifo);
@@ -235,7 +207,7 @@ buf_element_t* v4l2_input_read_block(input_plugin_t *this_gen, fifo_buffer_t *fi
lprintf("Sending video header\n");
xine_bmiheader bih;
bih.biSize = sizeof(xine_bmiheader);
- /* HACK: Why do I need to do this and why is it magic? */
+ /* HACK: Why do I need to do this and why is it magic? */
bih.biWidth = this->video->resolution.width*2;
bih.biHeight = this->video->resolution.height*2;
lprintf("Getting size of %ix%i\n", this->video->resolution.width, this->video->resolution.height);
@@ -253,94 +225,74 @@ buf_element_t* v4l2_input_read_block(input_plugin_t *this_gen, fifo_buffer_t *fi
return buf;
}
-uint32_t v4l2_input_blocksize(input_plugin_t *this_gen) {
+static uint32_t v4l2_input_blocksize(input_plugin_t *this_gen) {
/* HACK */
return 0;
v4l2_input_plugin_t *this = (v4l2_input_plugin_t*)this_gen;
if (this->video->headerSent) {
- lprintf("Returning block size of %i\n",this->video->buffers[0].length);
+ lprintf("Returning block size of %zu\n",this->video->buffers[0].length);
return this->video->buffers[0].length;
} else {
- lprintf("Returning block size of %i\n",sizeof(xine_bmiheader));
+ lprintf("Returning block size of %zu\n",sizeof(xine_bmiheader));
return sizeof(xine_bmiheader);
}
}
-void v4l2_input_dequeue_video_buffer(v4l2_input_plugin_t *this, buf_element_t *output) {
+static void v4l2_input_dequeue_video_buffer(v4l2_input_plugin_t *this, buf_element_t *output) {
struct v4l2_buffer buf;
memset(&buf, 0, sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
output->content = output->mem;
-#ifdef HAVE_LIBV4L2_H
v4l2_ioctl(this->fd, VIDIOC_DQBUF, &buf);
-#else
- ioctl(this->fd, VIDIOC_DQBUF, &buf);
-#endif
output->decoder_flags = BUF_FLAG_FRAME_START|BUF_FLAG_FRAME_END;
xine_fast_memcpy(output->content, this->video->buffers[buf.index].start, this->video->buffers[buf.index].length);
output->type = BUF_VIDEO_YUY2;
v4l2_input_enqueue_video_buffer(this, buf.index);
}
-void v4l2_input_enqueue_video_buffer(v4l2_input_plugin_t *this, int idx) {
+static void v4l2_input_enqueue_video_buffer(v4l2_input_plugin_t *this, int idx) {
struct v4l2_buffer buf;
memset(&buf, 0, sizeof(buf));
buf.index = idx;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
-#ifdef HAVE_LIBV4L2_H
v4l2_ioctl(this->fd, VIDIOC_QBUF, &buf);
-#else
- ioctl(this->fd, VIDIOC_QBUF, &buf);
-#endif
}
-void v4l2_input_dispose(input_plugin_t *this_gen) {
+static void v4l2_input_dispose(input_plugin_t *this_gen) {
lprintf("Disposing of myself.\n");
v4l2_input_plugin_t* this = (v4l2_input_plugin_t*)this_gen;
-
+
if (this->video != NULL) {
int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-#ifdef HAVE_LIBV4L2_H
if (-1 == v4l2_ioctl(this->fd, VIDIOC_STREAMOFF, &type)) {
-#else
- if (-1 == ioctl(this->fd, VIDIOC_STREAMOFF, &type)) {
-#endif
lprintf("Couldn't stop streaming. Uh oh.\n");
}
if (this->video->bufcount > 0) {
int i;
for(i = 0;i<this->video->bufcount;i++) {
-#ifdef HAVE_LIBV4L2_H
v4l2_munmap(this->video->buffers[i].start, this->video->buffers[i].length);
-#else
- munmap(this->video->buffers[i].start, this->video->buffers[i].length);
-#endif
}
free(this->video->buffers);
}
free(this->video);
}
-#ifdef HAVE_LIBV4L2_H
v4l2_close(this->fd);
-#else
- close(this->fd);
-#endif
free(this->mrl);
free(this);
}
-off_t v4l2_input_read(input_plugin_t *this_gen, char *buf, off_t nlen) {
+static off_t v4l2_input_read(input_plugin_t *this_gen, char *buf, off_t nlen) {
/* Only block reads are supported. */
return 0;
}
-uint32_t v4l2_input_get_capabilities(input_plugin_t* this_gen) {
+static uint32_t v4l2_input_get_capabilities(input_plugin_t* this_gen) {
return INPUT_CAP_BLOCK;
}
-const char* v4l2_input_get_mrl(input_plugin_t* this_gen) {
+static const char* v4l2_input_get_mrl(input_plugin_t* this_gen) {
v4l2_input_plugin_t* this = (v4l2_input_plugin_t*)this_gen;
/* HACK HACK HACK HACK */
/* So far, the only way to get the yuv_frames demuxer to work with this */
@@ -348,30 +300,30 @@ const char* v4l2_input_get_mrl(input_plugin_t* this_gen) {
//return this->mrl;
}
-int v4l2_input_get_optional_data(input_plugin_t *this_gen, void *data, int data_type) {
+static int v4l2_input_get_optional_data(input_plugin_t *this_gen, void *data, int data_type) {
return INPUT_OPTIONAL_UNSUPPORTED;
}
/* Seeking not supported. */
-off_t v4l2_input_seek(input_plugin_t *this_gen, off_t offset, int origin) {
+static off_t v4l2_input_seek(input_plugin_t *this_gen, off_t offset, int origin) {
return -1;
}
-off_t v4l2_input_seek_time(input_plugin_t *this_gen, int time_offset, int origin) {
+static off_t v4l2_input_seek_time(input_plugin_t *this_gen, int time_offset, int origin) {
return -1;
}
-off_t v4l2_input_pos(input_plugin_t *this_gen) {
+static off_t v4l2_input_pos(input_plugin_t *this_gen) {
/* TODO */
return 0;
}
-int v4l2_input_time(input_plugin_t *this_gen) {
+static int v4l2_input_time(input_plugin_t *this_gen) {
/* TODO */
return 0;
}
-off_t v4l2_input_length(input_plugin_t *this_gen) {
+static off_t v4l2_input_length(input_plugin_t *this_gen) {
return -1;
}
@@ -443,8 +395,8 @@ const input_info_t input_info_v4l2 = {
4000
};
-const plugin_info_t xine_plugin_info[] = {
- /* type, API, "name", version, special_info, init_function */
+const plugin_info_t xine_plugin_info[] EXPORTED = {
+ /* type, API, "name", version, special_info, init_function */
{ PLUGIN_INPUT, 17, "v4l2", XINE_VERSION_CODE, &input_info_v4l2, v4l2_init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};