diff options
author | alex <alex@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2001-11-09 23:46:06 +0000 |
---|---|---|
committer | alex <alex@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2001-11-09 23:46:06 +0000 |
commit | aabf596111a5545a6d4217646f69b80b1aba3552 (patch) | |
tree | df60e7387884d47dc0fec52cb53eda097caf7ab2 /libmpdemux/tvi_v4l.c | |
parent | 74aea030e144420f1560d2a4621bf0edaf1b15cd (diff) | |
download | mpv-aabf596111a5545a6d4217646f69b80b1aba3552.tar.bz2 mpv-aabf596111a5545a6d4217646f69b80b1aba3552.tar.xz |
added tv subsystem
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@2791 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpdemux/tvi_v4l.c')
-rw-r--r-- | libmpdemux/tvi_v4l.c | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/libmpdemux/tvi_v4l.c b/libmpdemux/tvi_v4l.c new file mode 100644 index 0000000000..43fb8713f4 --- /dev/null +++ b/libmpdemux/tvi_v4l.c @@ -0,0 +1,267 @@ +#include "config.h" + +#ifdef USE_TV + +#include <stdio.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <linux/videodev.h> +#include <unistd.h> +#include <sys/mman.h> + +#include "tv.h" + +static tvi_info_t info = { + "Video for Linux TV Input", + "v4l", + "alex", + "non-completed" +}; + +typedef struct { + char *video_device; + int fd; + struct video_capability capability; + struct video_channel *channels; + struct video_tuner tuner; + struct video_audio audio; + struct video_picture picture; + + int buffered; + struct video_mbuf mbuf; + unsigned int *mmap; + struct video_mmap *buf; + + int width; + int height; +} priv_t; + +#include "tvi_def.h" + +static const char *device_cap[] = { + "capture", "tuner", "teletext", "overlay", "chromakey", "clipping", + "frameram", "scales", "monochrome", NULL +}; + +tvi_handle_t *tvi_init_v4l(char *device) +{ + tvi_handle_t *h; + priv_t *priv; + + h = new_handle(); + if (!h) + return(NULL); + + priv = h->priv; + + if (!device) + { + priv->video_device = malloc(strlen("/dev/video0")); + strcpy(priv->video_device, &"/dev/video0"); + } + else + { + priv->video_device = malloc(strlen(device)); + strcpy(priv->video_device, device); + } + + return(h); +} + +static int init(priv_t *priv) +{ + int i; + + priv->fd = open(priv->video_device, O_RDONLY); + if (priv->fd == -1) + { + printf("v4l: open %s: %s\n", priv->video_device, strerror(errno)); + goto err; + } + + printf("fd: %d\n", priv->fd); + + /* get capabilities */ + if (ioctl(priv->fd, VIDIOCGCAP, &priv->capability) == -1) + { + printf("v4l: ioctl error: %s\n", strerror(errno)); + goto err; + } + + fcntl(priv->fd, F_SETFD, FD_CLOEXEC); + + printf("capabilites: "); + for (i = 0; device_cap[i] != NULL; i++) + if (priv->capability.type & (1 << i)) + printf(" %s", device_cap[i]); + printf("\n"); + printf(" type: %d\n", priv->capability.type); + printf(" size: %dx%d => %dx%d\n", + priv->capability.minwidth, priv->capability.minheight, + priv->capability.maxwidth, priv->capability.maxheight); + priv->width = priv->capability.minwidth; + priv->height = priv->capability.minheight; + printf(" channels: %d\n", priv->capability.channels); + + priv->channels = malloc(sizeof(struct video_channel)*priv->capability.channels); + memset(priv->channels, 0, sizeof(struct video_channel)*priv->capability.channels); + for (i = 0; i < priv->capability.channels; i++) + { + priv->channels[i].channel = i; + ioctl(priv->fd, VIDIOCGCHAN, &priv->channels[i]); + printf(" %s: tuners:%d %s%s %s%s\n", + priv->channels[i].name, + priv->channels[i].tuners, + (priv->channels[i].flags & VIDEO_VC_TUNER) ? "tuner " : "", + (priv->channels[i].flags & VIDEO_VC_AUDIO) ? "audio " : "", + (priv->channels[i].flags & VIDEO_TYPE_TV) ? "tv " : "", + (priv->channels[i].flags & VIDEO_TYPE_CAMERA) ? "camera " : ""); + } + + if (priv->capability.type & VID_TYPE_CAPTURE) + { + if (ioctl(priv->fd, VIDIOCGMBUF, &priv->mbuf) == 0) + { + printf("mbuf: size=%d, frames=%d (first offset: %p)\n", + priv->mbuf.size, priv->mbuf.frames, priv->mbuf.offsets[0]); + priv->mmap = mmap(0, priv->mbuf.size, PROT_READ|PROT_WRITE, + MAP_SHARED, priv->fd, 0); + if (priv->mmap == -1) + perror("mmap"); + } + else + priv->mmap = -1; + + if (priv->mmap != -1) + { + priv->buf = malloc(priv->mbuf.frames * sizeof(struct video_mmap)); + memset(priv->buf, 0, priv->mbuf.frames * sizeof(struct video_mmap)); + priv->buffered = 1; + } + else + priv->buffered = 0; + } + + printf("buffered: %d\n", priv->buffered); + + return(1); + +err: + if (priv->fd != -1) + close(priv->fd); + return(0); +} + +static int exit(priv_t *priv) +{ +} + +static int tune(priv_t *priv, int freq, int chan, int norm) +{ + if (freq) + { + ioctl(priv->fd, VIDIOCSFREQ, &freq); + return(1); + } + + if (chan && norm) + { + /* set channel & norm ! */ + } + + return(0); +} + +static int control(priv_t *priv, int cmd, void *arg) +{ + switch(cmd) + { + case TVI_CONTROL_VID_GET_FORMAT: + (int)*(void **)arg = 0x0; + return(TVI_CONTROL_TRUE); + case TVI_CONTROL_VID_GET_PLANES: + (int)*(void **)arg = 1; + return(TVI_CONTROL_TRUE); + case TVI_CONTROL_VID_GET_BITS: + (int)*(void **)arg = 12; + return(TVI_CONTROL_TRUE); + case TVI_CONTROL_VID_GET_WIDTH: + (int)*(void **)arg = priv->width; + return(TVI_CONTROL_TRUE); + case TVI_CONTROL_VID_CHK_WIDTH: + { + int req_width = (int)*(void **)arg; + + printf("req_width: %d\n", req_width); + if ((req_width > priv->capability.minwidth) && + (req_width < priv->capability.maxwidth)) + return(TVI_CONTROL_TRUE); + return(TVI_CONTROL_FALSE); + } + case TVI_CONTROL_VID_SET_WIDTH: + priv->width = (int)*(void **)arg; + return(TVI_CONTROL_TRUE); + case TVI_CONTROL_VID_GET_HEIGHT: + (int)*(void **)arg = priv->height; + return(TVI_CONTROL_TRUE); + case TVI_CONTROL_VID_CHK_HEIGHT: + { + int req_height = (int)*(void **)arg; + + printf("req_height: %d\n", req_height); + if ((req_height > priv->capability.minheight) && + (req_height < priv->capability.maxheight)) + return(TVI_CONTROL_TRUE); + return(TVI_CONTROL_FALSE); + } + case TVI_CONTROL_VID_SET_HEIGHT: + priv->height = (int)*(void **)arg; + return(TVI_CONTROL_TRUE); + + case TVI_CONTROL_TUN_SET_FREQ: + { + long freq = (long)*(void **)arg; /* shit: long -> freq */ + + printf("requested frequency: %f\n", freq); + if (ioctl(priv->fd, VIDIOCSFREQ, &freq) != -1) + return(TVI_CONTROL_TRUE); + return(TVI_CONTROL_FALSE); + } + } + + return(TVI_CONTROL_UNKNOWN); +} + +static int grab_video_frame(priv_t *priv, char *buffer, int len) +{ + priv->buf[0].frame = 0; + priv->buf[0].width = 320; + priv->buf[0].height = 240; + priv->buf[0].format = VIDEO_PALETTE_YUV422; + + if (ioctl(priv->fd, VIDIOCMCAPTURE, priv->buf) == -1) + { + printf("grab_video_frame failed: %s\n", strerror(errno)); + return 0; + } + + return 1; +} + +static int get_video_framesize(priv_t *priv) +{ + return 65536; +} + +static int grab_audio_frame(priv_t *priv, char *buffer, int len) +{ +} + +static int get_audio_framesize(priv_t *priv) +{ + return 65536; +} + +#endif /* USE_TV */ |