diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/input/input_v4l2.c | 132 |
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 } }; |