diff options
-rw-r--r-- | src/input/input_v4l2.c | 95 |
1 files changed, 92 insertions, 3 deletions
diff --git a/src/input/input_v4l2.c b/src/input/input_v4l2.c index aea947478..20cf4f8b6 100644 --- a/src/input/input_v4l2.c +++ b/src/input/input_v4l2.c @@ -1,4 +1,32 @@ +/* +* Copyright (C) 2010 the xine project +* Copyright (C) 2010 Trever Fischer <tdfischer@fedoraproject.org> +* +* This file is part of xine, a free video player. +* +* xine is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* xine is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +* +* v4l2 input plugin +*/ + #define LOG_MODULE "v4l2" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #define LOG #include <xine/input_plugin.h> @@ -12,9 +40,13 @@ #include <linux/videodev2.h> #include <sys/mman.h> #include <stdio.h> -#include <libv4l2.h> #include <errno.h> +#ifdef HAVE_LIBV4L2_H +#include <libv4l2.h> +#else +#include <sys/ioctl.h> +#endif typedef struct { void *start; size_t length; @@ -58,10 +90,19 @@ int v4l2_input_setup_video_streaming(v4l2_input_plugin_t *this); 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); - if ((this->fd = v4l2_open(this->mrl, O_RDWR))) { +#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; @@ -101,7 +142,11 @@ 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; } @@ -118,21 +163,36 @@ int v4l2_input_setup_video_streaming(v4l2_input_plugin_t *this) { 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; @@ -146,10 +206,18 @@ int v4l2_input_setup_video_streaming(v4l2_input_plugin_t *this) { 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; } @@ -167,6 +235,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? */ 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); @@ -203,7 +272,11 @@ void v4l2_input_dequeue_video_buffer(v4l2_input_plugin_t *this, buf_element_t *o 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; @@ -216,7 +289,11 @@ void v4l2_input_enqueue_video_buffer(v4l2_input_plugin_t *this, int idx) { 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) { @@ -225,19 +302,31 @@ void v4l2_input_dispose(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); } @@ -358,4 +447,4 @@ const plugin_info_t xine_plugin_info[] = { /* 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 } -};
\ No newline at end of file +}; |