summaryrefslogtreecommitdiffstats
path: root/libmpdemux/tvi_v4l.c
diff options
context:
space:
mode:
authoralex <alex@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-11-10 23:32:10 +0000
committeralex <alex@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-11-10 23:32:10 +0000
commitfc363d39bc8a1aecc72b62c1108d7cc3b0b40a64 (patch)
tree7af9a7653c089d0c57bda269d4ffc82a2a97b789 /libmpdemux/tvi_v4l.c
parent31dc28382695dd2fa4a86a9676113a4eb36010ec (diff)
downloadmpv-fc363d39bc8a1aecc72b62c1108d7cc3b0b40a64.tar.bz2
mpv-fc363d39bc8a1aecc72b62c1108d7cc3b0b40a64.tar.xz
tv update
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@2803 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpdemux/tvi_v4l.c')
-rw-r--r--libmpdemux/tvi_v4l.c555
1 files changed, 485 insertions, 70 deletions
diff --git a/libmpdemux/tvi_v4l.c b/libmpdemux/tvi_v4l.c
index 43fb8713f4..11b80fa587 100644
--- a/libmpdemux/tvi_v4l.c
+++ b/libmpdemux/tvi_v4l.c
@@ -1,3 +1,14 @@
+/*
+ v4l interface for libmpemux/tvi
+
+ (C) Alex Beregszaszi <alex@naxine.org>
+
+ Some ideas are based on xawtv/libng's grab-v4l.c written by
+ Gerd Knorr <kraxel@bytesex.org>
+
+ CODE IS UNDER DEVELOPMENT, NO FEATURE REQUESTS PLEASE!
+*/
+
#include "config.h"
#ifdef USE_TV
@@ -5,6 +16,7 @@
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
+#include <signal.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <linux/videodev.h>
@@ -16,35 +28,168 @@
static tvi_info_t info = {
"Video for Linux TV Input",
"v4l",
- "alex",
- "non-completed"
+ "Alex Beregszaszi <alex@naxine.org>",
+ "under development"
+};
+
+struct vid_fmt {
+ int fmtid;
+ int width;
+ int height;
+ int bytesperline;
};
typedef struct {
+ /* general */
char *video_device;
int fd;
struct video_capability capability;
struct video_channel *channels;
struct video_tuner tuner;
- struct video_audio audio;
+
+ /* video */
struct video_picture picture;
+ int format; /* output format */
+ int width;
+ int height;
+ int bytesperline;
- int buffered;
struct video_mbuf mbuf;
- unsigned int *mmap;
+ unsigned char *mmap;
struct video_mmap *buf;
-
- int width;
- int height;
+ int nbuf;
+ int queue;
+
+ /* audio */
+ struct video_audio audio;
} priv_t;
#include "tvi_def.h"
static const char *device_cap[] = {
"capture", "tuner", "teletext", "overlay", "chromakey", "clipping",
- "frameram", "scales", "monochrome", NULL
+ "frameram", "scales", "monochrome", "subcapture", "mpeg-decoder",
+ "mpeg-encoder", "mjpeg-decoder", "mjpeg-encoder", NULL
};
+static const char *device_pal[] = {
+ "-", "grey", "hi240", "rgb16", "rgb24", "rgb32", "rgb15", "yuv422",
+ "yuyv", "uyvy", "yuv420", "yuv411", "raw", "yuv422p", "yuv411p",
+ "yuv420p", "yuv410p", NULL
+};
+#define PALETTE(x) ((x < sizeof(device_pal)/sizeof(char*)) ? device_pal[x] : "UNKNOWN")
+
+static int palette2depth(int palette)
+{
+ if (palette == VIDEO_PALETTE_YUV420P)
+ return 12;
+ return 32;
+}
+
+static int format2palette(int format)
+{
+ if (format == IMGFMT_YV12)
+ return VIDEO_PALETTE_YUV420P;
+ return VIDEO_PALETTE_RGB24;
+}
+
+#if 0
+struct STRTAB {
+ long nr;
+ const char *str;
+};
+
+static struct STRTAB stereo[] = {
+ { 0, "auto" },
+ { VIDEO_SOUND_MONO, "mono" },
+ { VIDEO_SOUND_STEREO, "stereo" },
+ { VIDEO_SOUND_LANG1, "lang1" },
+ { VIDEO_SOUND_LANG2, "lang1" },
+ { -1, NULL }
+};
+
+static struct STRTAB norms_v4l[] = {
+ { VIDEO_MODE_PAL, "PAL" },
+ { VIDEO_MODE_NTSC, "NTSC" },
+ { VIDEO_MODE_SECAM, "SECAM" },
+ { VIDEO_MODE_AUTO, "AUTO" },
+ { -1, NULL }
+};
+
+static struct STRTAB norms_bttv[] = {
+ { VIDEO_MODE_PAL, "PAL" },
+ { VIDEO_MODE_NTSC, "NTSC" },
+ { VIDEO_MODE_SECAM, "SECAM" },
+ { 3, "PAL-NC" },
+ { 4, "PAL-M" },
+ { 5, "PAL-N" },
+ { 6, "NTSC-JP" },
+ { -1, NULL }
+};
+
+static unsigned short _format2palette[VIDEO_FMT_COUNT] = {
+ 0, /* unused */
+ VIDEO_PALETTE_HI240, /* RGB8 */
+ VIDEO_PALETTE_GREY,
+ VIDEO_PALETTE_RGB555,
+ VIDEO_PALETTE_RGB565,
+ 0,
+ 0,
+ VIDEO_PALETTE_RGB24,
+ VIDEO_PALETTE_RGB32,
+ 0,
+ 0,
+ 0,
+ 0,
+ VIDEO_PALETTE_YUV422,
+ VIDEO_PALETTE_YUV422P,
+ VIDEO_PALETTE_YUV420P,
+};
+#define FMT2PAL(fmt) ((fmt < sizeof(format2palette)/sizeof(unsigned short)) ? \
+ format2palette[fmt] : 0);
+
+const unsigned int vfmt_to_depth[] = {
+ 0,
+ 8,
+ 8,
+ 16,
+ 16,
+ 16,
+ 16,
+ 24,
+ 32,
+ 24,
+ 32,
+ 16,
+ 32,
+ 16,
+ 16,
+ 12,
+ 0,
+ 0,
+};
+#endif
+
+static int one = 1, zero = 0;
+
+static int alarms;
+
+static void sigalarm(int signal)
+{
+ alarms++;
+ printf("v4l: timeout (got SIGALRM), hardware/driver problems?\n");
+}
+
+static void siginit(void)
+{
+ struct sigaction act, old;
+
+ memset(&act, 0, sizeof(act));
+ act.sa_handler = sigalarm;
+ sigemptyset(&act.sa_mask);
+ sigaction(SIGALRM, &act, &old);
+}
+
tvi_handle_t *tvi_init_v4l(char *device)
{
tvi_handle_t *h;
@@ -56,10 +201,11 @@ tvi_handle_t *tvi_init_v4l(char *device)
priv = h->priv;
+ /* set video device name */
if (!device)
{
priv->video_device = malloc(strlen("/dev/video0"));
- strcpy(priv->video_device, &"/dev/video0");
+ sprintf(priv->video_device, "/dev/video0");
}
else
{
@@ -70,40 +216,52 @@ tvi_handle_t *tvi_init_v4l(char *device)
return(h);
}
-static int init(priv_t *priv)
+static int init(priv_t *priv, tvi_param_t *params)
{
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));
+ printf("v4l: unable to open '%s': %s\n",
+ priv->video_device, strerror(errno));
goto err;
}
printf("fd: %d\n", priv->fd);
- /* get capabilities */
+ /* get capabilities (priv->capability is needed!) */
if (ioctl(priv->fd, VIDIOCGCAP, &priv->capability) == -1)
{
- printf("v4l: ioctl error: %s\n", strerror(errno));
+ printf("ioctl get capabilites error: %s\n", strerror(errno));
goto err;
}
fcntl(priv->fd, F_SETFD, FD_CLOEXEC);
-
- printf("capabilites: ");
+ siginit();
+
+#if 0
+ for (i=0; params[i].opt; i++)
+ {
+ if (!strcmp(params[i].opt, "input"))
+ priv->input = (int)*(void **)params[i].value;
+ }
+ printf("priv->input: %d\n", priv->input);
+#endif
+
+ printf("Selected device: %s\n", priv->capability.name);
+ printf(" Capabilites: ");
for (i = 0; device_cap[i] != NULL; i++)
if (priv->capability.type & (1 << i))
- printf(" %s", device_cap[i]);
+ printf("%s ", device_cap[i]);
printf("\n");
- printf(" type: %d\n", priv->capability.type);
- printf(" size: %dx%d => %dx%d\n",
+ printf(" Device type: %d\n", priv->capability.type);
+ printf(" Supported sizes: %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);
+ printf(" Inputs: %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);
@@ -111,40 +269,51 @@ static int init(priv_t *priv)
{
priv->channels[i].channel = i;
ioctl(priv->fd, VIDIOCGCHAN, &priv->channels[i]);
- printf(" %s: tuners:%d %s%s %s%s\n",
+ printf(" %d: %s: %s%s%s%s (tuner:%d, norm:%d)\n", i,
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 " : "");
+ (priv->channels[i].flags & VIDEO_TYPE_CAMERA) ? "camera " : "",
+ priv->channels[i].tuners,
+ priv->channels[i].norm);
}
- if (priv->capability.type & VID_TYPE_CAPTURE)
+ 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;
+ printf("Only grabbing supported (for overlay use another program)\n");
+ goto err;
+ }
+
+ /* map grab buffer */
+ if (ioctl(priv->fd, VIDIOCGMBUF, &priv->mbuf) == -1)
+ {
+ printf("ioctl get mbuf failed: %s\n", strerror(errno));
+ goto err;
+ }
- 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("mbuf: size=%d, frames=%d\n",
+ priv->mbuf.size, priv->mbuf.frames);
+ priv->mmap = mmap(0, priv->mbuf.size, PROT_READ|PROT_WRITE,
+ MAP_SHARED, priv->fd, 0);
+ if (priv->mmap == -1)
+ {
+ printf("Unabel to map memory for buffers: %s\n", strerror(errno));
+ priv->mmap = malloc(priv->mbuf.size); /* our buffer */
}
+ if (!priv->mmap)
+ {
+ printf("Unable to allocate memory for buffers: %s\n", strerror(errno));
+ goto err;
+ }
+ printf("our buffer: %p\n", priv->mmap);
+
+ /* num of buffers */
+ priv->nbuf = priv->mbuf.frames;
- printf("buffered: %d\n", priv->buffered);
+ /* video buffers */
+ priv->buf = malloc(priv->nbuf * sizeof(struct video_mmap));
+ memset(priv->buf, 0, priv->nbuf * sizeof(struct video_mmap));
return(1);
@@ -154,32 +323,119 @@ err:
return(0);
}
-static int exit(priv_t *priv)
+static int uninit(priv_t *priv)
{
+#warning "Implement uninit!"
}
-static int tune(priv_t *priv, int freq, int chan, int norm)
+static int start(priv_t *priv)
{
- if (freq)
+ int i;
+
+
+ if (ioctl(priv->fd, VIDIOCGPICT, &priv->picture) == -1)
{
- ioctl(priv->fd, VIDIOCSFREQ, &freq);
- return(1);
+ printf("ioctl get picture failed: %s\n", strerror(errno));
+ return(0);
}
- if (chan && norm)
+ priv->picture.palette = format2palette(priv->format);
+ priv->picture.depth = palette2depth(priv->picture.palette);
+ priv->bytesperline = priv->width * priv->picture.depth / 8;
+
+ printf("Picture values:\n");
+ printf(" Depth: %d, Palette: %d (Format: %s)\n", priv->picture.depth,
+ priv->picture.palette, vo_format_name(priv->format));
+ printf(" Brightness: %d, Hue: %d, Colour: %d, Contrast: %d\n",
+ priv->picture.brightness, priv->picture.hue,
+ priv->picture.colour, priv->picture.contrast);
+
+
+ if (ioctl(priv->fd, VIDIOCSPICT, &priv->picture) == -1)
{
- /* set channel & norm ! */
+ printf("ioctl set picture failed: %s\n", strerror(errno));
+ return(0);
}
- return(0);
+ priv->nbuf = priv->mbuf.frames;
+ for (i=0; i < priv->nbuf; i++)
+ {
+ priv->buf[i].format = priv->picture.palette;
+ priv->buf[i].frame = i;
+ priv->buf[i].width = priv->width;
+ priv->buf[i].height = priv->height;
+ printf("buffer: %d => %p\n", i, &priv->buf[i]);
+ }
+
+ /* start capture */
+ if (ioctl(priv->fd, VIDIOCCAPTURE, &one) == -1)
+ {
+ printf("ioctl capture failed: %s\n", strerror(errno));
+ return(0);
+ }
}
static int control(priv_t *priv, int cmd, void *arg)
{
+ printf("debug: control(priv=%p, cmd=%d, arg=%p)\n",
+ priv, cmd, arg);
switch(cmd)
{
+ /* ========== GENERIC controls =========== */
+ case TVI_CONTROL_IS_VIDEO:
+ {
+ if (priv->capability.type & VID_TYPE_CAPTURE)
+ return(TVI_CONTROL_TRUE);
+ return(TVI_CONTROL_FALSE);
+ }
+ case TVI_CONTROL_IS_AUDIO:
+ return(TVI_CONTROL_FALSE); /* IMPLEMENT CHECK! */
+ case TVI_CONTROL_IS_TUNER:
+ {
+ if (priv->capability.type & VID_TYPE_TUNER)
+ return(TVI_CONTROL_TRUE);
+ return(TVI_CONTROL_FALSE);
+ }
+
+ /* ========== VIDEO controls =========== */
case TVI_CONTROL_VID_GET_FORMAT:
- (int)*(void **)arg = 0x0;
+ {
+ int output_fmt = -1;
+
+#if 0
+ switch(priv->palette)
+ {
+ case VIDEO_PALETTE_RGB555:
+ output_fmt = IMGFMT_RGB15;
+ break;
+ case VIDEO_PALETTE_RGB565:
+ output_fmt = IMGFMT_RGB16;
+ break;
+ case VIDEO_PALETTE_RGB24:
+ output_fmt = IMGFMT_RGB24;
+ break;
+ case VIDEO_PALETTE_RGB32:
+ output_fmt = IMGFMT_RGB32;
+ break;
+ case VIDEO_PALETTE_UYVY:
+ output_fmt = IMGFMT_UYVY;
+ break;
+ case VIDEO_PALETTE_YUV420P:
+ output_fmt = IMGFMT_YV12;
+ break;
+ default:
+ printf("no suitable output format found (%s)\n",
+ PALETTE(priv->palette));
+ return(TVI_CONTROL_FALSE);
+ }
+#endif
+ output_fmt = priv->format;
+ (int)*(void **)arg = output_fmt;
+ printf("Output format: %s\n", vo_format_name(output_fmt));
+ return(TVI_CONTROL_TRUE);
+ }
+ case TVI_CONTROL_VID_SET_FORMAT:
+ priv->format = (int)*(void **)arg;
return(TVI_CONTROL_TRUE);
case TVI_CONTROL_VID_GET_PLANES:
(int)*(void **)arg = 1;
@@ -194,7 +450,7 @@ static int control(priv_t *priv, int cmd, void *arg)
{
int req_width = (int)*(void **)arg;
- printf("req_width: %d\n", req_width);
+ printf("Requested width: %d\n", req_width);
if ((req_width > priv->capability.minwidth) &&
(req_width < priv->capability.maxwidth))
return(TVI_CONTROL_TRUE);
@@ -210,7 +466,7 @@ static int control(priv_t *priv, int cmd, void *arg)
{
int req_height = (int)*(void **)arg;
- printf("req_height: %d\n", req_height);
+ printf("Requested height: %d\n", req_height);
if ((req_height > priv->capability.minheight) &&
(req_height < priv->capability.maxheight))
return(TVI_CONTROL_TRUE);
@@ -220,14 +476,163 @@ static int control(priv_t *priv, int cmd, void *arg)
priv->height = (int)*(void **)arg;
return(TVI_CONTROL_TRUE);
+ /* ========== TUNER controls =========== */
+ case TVI_CONTROL_TUN_GET_FREQ:
+ {
+ unsigned long freq;
+
+ if (ioctl(priv->fd, VIDIOCGFREQ, &freq) == -1)
+ {
+ printf("ioctl get freq failed: %s\n", strerror(errno));
+ return(TVI_CONTROL_FALSE);
+ }
+
+ /* tuner uses khz not mhz ! */
+ if (priv->tuner.flags & VIDEO_TUNER_LOW)
+ freq /= 1000;
+ (unsigned long)*(void **)arg = freq;
+ return(TVI_CONTROL_TRUE);
+ }
case TVI_CONTROL_TUN_SET_FREQ:
{
- long freq = (long)*(void **)arg; /* shit: long -> freq */
+ /* argument is in MHz ! */
+ unsigned long freq = (unsigned long)*(void **)arg;
- printf("requested frequency: %f\n", freq);
- if (ioctl(priv->fd, VIDIOCSFREQ, &freq) != -1)
- return(TVI_CONTROL_TRUE);
- return(TVI_CONTROL_FALSE);
+ printf("requested frequency: %lu MHz\n", (float)freq/16);
+
+ /* tuner uses khz not mhz ! */
+ if (priv->tuner.flags & VIDEO_TUNER_LOW)
+ freq *= 1000;
+ printf(" requesting from driver: freq=%.3f\n", (float)freq/16);
+ if (ioctl(priv->fd, VIDIOCSFREQ, &freq) == -1)
+ {
+ printf("ioctl set freq failed: %s\n", strerror(errno));
+ return(TVI_CONTROL_FALSE);
+ }
+ return(TVI_CONTROL_TRUE);
+ }
+ case TVI_CONTROL_TUN_GET_TUNER:
+ {
+ if (ioctl(priv->fd, VIDIOCGTUNER, &priv->tuner) == -1)
+ {
+ printf("ioctl get tuner failed: %s\n", strerror(errno));
+ return(TVI_CONTROL_FALSE);
+ }
+
+ printf("Tuner (%s) range: %lu -> %lu\n", priv->tuner.name,
+ priv->tuner.rangelow, priv->tuner.rangehigh);
+ return(TVI_CONTROL_TRUE);
+ }
+ case TVI_CONTROL_TUN_SET_TUNER:
+ {
+ if (ioctl(priv->fd, VIDIOCSTUNER, &priv->tuner) == -1)
+ {
+ printf("ioctl get tuner failed: %s\n", strerror(errno));
+ return(TVI_CONTROL_FALSE);
+ }
+ return(TVI_CONTROL_TRUE);
+ }
+ case TVI_CONTROL_TUN_SET_NORM:
+ {
+ int req_mode = (int)*(void **)arg;
+
+ if ((!(priv->tuner.flags & VIDEO_TUNER_NORM)) ||
+ ((req_mode == VIDEO_MODE_PAL) && !(priv->tuner.flags & VIDEO_TUNER_PAL)) ||
+ ((req_mode == VIDEO_MODE_NTSC) && !(priv->tuner.flags & VIDEO_TUNER_NTSC)) ||
+ ((req_mode == VIDEO_MODE_SECAM) && !(priv->tuner.flags & VIDEO_TUNER_SECAM)))
+ {
+ printf("tuner isn't capable to set norm!\n");
+ return(TVI_CONTROL_FALSE);
+ }
+
+ priv->tuner.mode = req_mode;
+
+ if (control(priv->fd, TVI_CONTROL_TUN_SET_TUNER, &priv->tuner) != TVI_CONTROL_TRUE)
+ return(TVI_CONTROL_FALSE);
+ return(TVI_CONTROL_TRUE);
+ }
+ case TVI_CONTROL_TUN_GET_NORM:
+ {
+ (int)*(void **)arg = priv->tuner.mode;
+
+ return(TVI_CONTROL_TRUE);
+ }
+
+ /* ========== AUDIO controls =========== */
+ case TVI_CONTROL_AUD_GET_FORMAT:
+ {
+ (int)*(void **)arg = AFMT_S16_LE;
+ return(TVI_CONTROL_TRUE);
+ }
+ case TVI_CONTROL_AUD_GET_CHANNELS:
+ {
+ (int)*(void **)arg = 2;
+ return(TVI_CONTROL_TRUE);
+ }
+ case TVI_CONTROL_AUD_GET_SAMPLERATE:
+ {
+ (int)*(void **)arg = 44100;
+ return(TVI_CONTROL_TRUE);
+ }
+ case TVI_CONTROL_AUD_GET_SAMPLESIZE:
+ {
+ (int)*(void **)arg = 76000;
+ return(TVI_CONTROL_TRUE);
+ }
+
+ /* ========== SPECIFIC controls =========== */
+ case TVI_CONTROL_SPC_GET_INPUT:
+ {
+ int req_chan = (int)*(void **)arg;
+ int i;
+
+ for (i = 0; i < priv->capability.channels; i++)
+ {
+ if (priv->channels[i].channel == req_chan)
+ break;
+ }
+
+ if (ioctl(priv->fd, VIDIOCGCHAN, &priv->channels[i]) == -1)
+ {
+ printf("ioctl get channel failed: %s\n", strerror(errno));
+ return(TVI_CONTROL_FALSE);
+ }
+ return(TVI_CONTROL_TRUE);
+ }
+
+ case TVI_CONTROL_SPC_SET_INPUT:
+ {
+ struct video_channel chan;
+ int req_chan = (int)*(void **)arg;
+ int i;
+
+ if (req_chan >= priv->capability.channels)
+ {
+ printf("Invalid input requested: %d, valid: 0-%d\n",
+ req_chan, priv->capability.channels);
+ return(TVI_CONTROL_FALSE);
+ }
+
+ for (i = 0; i < priv->capability.channels; i++)
+ {
+ if (priv->channels[i].channel == req_chan)
+ chan = priv->channels[i];
+ }
+
+ if (ioctl(priv->fd, VIDIOCSCHAN, &chan) == -1)
+ {
+ printf("ioctl set chan failed: %s\n", strerror(errno));
+ return(TVI_CONTROL_FALSE);
+ }
+ printf("Using input '%s'\n", chan.name);
+
+ /* update tuner state */
+ if (priv->capability.type & VID_TYPE_TUNER)
+ control(priv, TVI_CONTROL_TUN_GET_TUNER, 0);
+
+ /* update local channel list */
+ control(priv, TVI_CONTROL_SPC_GET_INPUT, &req_chan);
+ return(TVI_CONTROL_TRUE);
}
}
@@ -236,23 +641,33 @@ static int control(priv_t *priv, int cmd, void *arg)
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)
+ int frame = priv->queue % priv->nbuf;
+
+ printf("grab_video_frame(priv=%p, buffer=%p, len=%d\n",
+ priv, buffer, len);
+
+ printf("buf: %p + frame: %d => %p\n",
+ priv->buf, frame, &priv->buf[frame]);
+ if (ioctl(priv->fd, VIDIOCMCAPTURE, &priv->buf[frame]) == -1)
{
- printf("grab_video_frame failed: %s\n", strerror(errno));
- return 0;
+ printf("ioctl mcapture failed: %s\n", strerror(errno));
+ return(0);
}
- return 1;
+ ioctl(priv->fd, VIDIOCSYNC, &priv->buf[frame]);
+ priv->queue++;
+
+ printf("mmap: %p + offset: %d => %p\n",
+ priv->mmap, priv->mbuf.offsets[frame],
+ priv->mmap+priv->mbuf.offsets[frame]);
+ memcpy(buffer, priv->mmap+priv->mbuf.offsets[frame], len);
+
+ return(len);
}
static int get_video_framesize(priv_t *priv)
{
- return 65536;
+ return priv->bytesperline * priv->height;
}
static int grab_audio_frame(priv_t *priv, char *buffer, int len)