[asterisk-commits] rizzo: branch rizzo/astobj2 r77807 - /team/rizzo/astobj2/channels/chan_oss.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Jul 30 18:51:21 CDT 2007
Author: rizzo
Date: Mon Jul 30 18:51:21 2007
New Revision: 77807
URL: http://svn.digium.com/view/asterisk?view=rev&rev=77807
Log:
hook the webcam descriptor onto the channel
Modified:
team/rizzo/astobj2/channels/chan_oss.c
Modified: team/rizzo/astobj2/channels/chan_oss.c
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/channels/chan_oss.c?view=diff&rev=77807&r1=77806&r2=77807
==============================================================================
--- team/rizzo/astobj2/channels/chan_oss.c (original)
+++ team/rizzo/astobj2/channels/chan_oss.c Mon Jul 30 18:51:21 2007
@@ -343,7 +343,18 @@
};
struct video_out_desc {
+ /* webcam support.
+ * videodevice and geometry are read from the config file.
+ * At the right time we try to open it and allocate a buffer.
+ * If we are successful, webcam_bufsize > 0 and we can read.
+ */
+ const char *videodevice; /* pointer in the parent struct */
+ int w; /* geometry */
+ int h;
+ int fd; /* file descriptor */
+ struct dbuf_t buf;
};
+
struct video_in_desc {
AVCodecContext *context; /* information about the codec in the stream */
AVCodec *codec; /* reference to the codec */
@@ -366,18 +377,6 @@
struct ast_frame *echo;
- /* webcam support.
- * videodevice and geometry are read from the config file.
- * At the right time we try to open it and allocate a buffer.
- * If we are successful, webcam_bufsize > 0 and we can read.
- */
- const char *videodevice; /* pointer in the parent struct */
- int w; /* geometry */
- int h;
- int webcam_fd; /* file descriptor */
- int webcam_bufsize; /* buffer size, also total bytes per frame */
- int webcam_ofs; /* offset for next read */
- char *webcam_imgbuf; /* malloced area of size webcam_bufsize */
};
struct _cm { /* map ffmpeg codec types to asterisk formats */
@@ -395,11 +394,11 @@
*/
#if !defined(HAVE_V4L) || HAVE_V4L != 1
/* stubs */
-static int webcam_open(struct video_desc *env)
+static int webcam_open(struct video_out_desc *v)
{
return -1;
}
-static int webcam_read(struct video_desc *env)
+static int webcam_read(struct video_out_desc *v)
{
return 0;
}
@@ -409,90 +408,87 @@
/* the real thing */
#include <linux/videodev.h>
-static int webcam_open(struct video_desc *env)
-{
- int fd, i;
- const char *device = env->videodevice;
+static int webcam_open(struct video_out_desc *v)
+{
+ int i;
+ const char *device = v->videodevice;
struct video_window vw = { 0 }; /* camera attributes */
struct video_picture vp;
- int bufsize;
- char *imgbuf = NULL;
-
- if (env->webcam_imgbuf)
- return env->webcam_fd;
-
- fd = open(device, O_RDONLY | O_NONBLOCK);
- if (fd < 0) {
+ if (v->buf.data) /* buffer allocated means device already open */
+ return v->fd;
+
+ v->fd = open(device, O_RDONLY | O_NONBLOCK);
+ if (v->fd < 0) {
ast_log(LOG_WARNING, "error opening camera %s\n", device);
- return fd;
- }
-
- i = fcntl(fd, F_GETFL);
- if (-1 == fcntl(fd, F_GETFL, i | O_NONBLOCK)) {
+ return v->fd;
+ }
+
+ i = fcntl(v->fd, F_GETFL);
+ if (-1 == fcntl(v->fd, F_GETFL, i | O_NONBLOCK)) {
ast_log(LOG_WARNING, "error F_SETFL for %s\n", device);
goto error;
}
/* set format */
- vw.width = env->w;
- vw.height = env->h;
- bufsize = (vw.width * vw.height * 3)/2; /* yuv411 */
- if (ioctl(fd, VIDIOCSWIN, &vw) == -1) {
+ vw.width = v->w;
+ vw.height = v->h;
+ v->buf.size = (vw.width * vw.height * 3)/2; /* yuv411 */
+ if (ioctl(v->fd, VIDIOCSWIN, &vw) == -1) {
ast_log(LOG_WARNING, "error setting format for %s\n", device);
goto error;
}
- if (ioctl(fd, VIDIOCGPICT, &vp) == -1) {
+ if (ioctl(v->fd, VIDIOCGPICT, &vp) == -1) {
ast_log(LOG_WARNING, "error reading picture info\n");
- return -1;
+ goto error;
}
ast_log(LOG_WARNING, "contrast %d bright %d colour %d hue %d whiteness %d palette %d\n",
vp.contrast, vp.brightness,
vp.colour, vp.hue,
vp.whiteness, vp.palette);
vp.palette = VIDEO_PALETTE_YUV420P;
- if(ioctl(fd,VIDIOCSPICT,&vp) == -1) {
+ if (ioctl(v->fd, VIDIOCSPICT, &vp) == -1) {
ast_log(LOG_WARNING, "error setting picture info\n");
goto error;
}
- imgbuf = malloc(bufsize);
- if (!imgbuf)
+ ast_log(LOG_WARNING, "videodev %s opened, size %dx%d %d\n", device, v->w, v->h, v->buf.size);
+ v->buf.data = ast_calloc(1, v->buf.size);
+ if (!v->buf.data) {
+ ast_log(LOG_WARNING, "error allocating buffer %d bytes\n", v->buf.size);
goto error;
-
- env->webcam_fd = fd;
- env->webcam_bufsize = bufsize;
- env->webcam_ofs = 0;
- env->webcam_imgbuf = imgbuf;
- ast_log(LOG_WARNING, "videodev %s opened, size %dx%d %d\n", device, env->w, env->h, bufsize);
- return fd;
+ }
+
+ v->buf.used = 0;
+ return v->fd;
error:
- if (fd >= 0)
- close(fd);
- if (imgbuf)
- free(imgbuf);
- env->webcam_fd = -1;
+ if (v->fd >= 0)
+ close(v->fd);
+ v->fd = -1;
+ if (v->buf.data)
+ ast_free(v->buf.data);
+ v->buf.data = NULL;
return -1;
}
/*! \brief complete a buffer from the webcam */
-static int webcam_read(struct video_desc *env)
-{
- if (env->webcam_bufsize == 0)
+static int webcam_read(struct video_out_desc *v)
+{
+ if (v->buf.data == NULL) /* not initialized */
return 0;
for (;;) {
- int r, l = env->webcam_bufsize - env->webcam_ofs;
- r = read(env->webcam_fd, env->webcam_imgbuf + env->webcam_ofs, l);
- // ast_log(LOG_WARNING, "read %d of %d bytes from webcam\n", r, l);
+ int r, l = v->buf.size - v->buf.used;
+ r = read(v->fd, v->buf.data + v->buf.used, l);
+ ast_log(LOG_WARNING, "read %d of %d bytes from webcam\n", r, l);
if (r < 0) { /* read error */
return 0;
}
if (r == 0) /* no data */
return 0;
- env->webcam_ofs += r;
+ v->buf.used += r;
if (r == l) {
- env->webcam_ofs = 0; /* prepare for next frame */
- return env->webcam_bufsize;
+ v->buf.used = 0; /* prepare for next frame */
+ return v->buf.size;
}
}
}
@@ -500,12 +496,11 @@
static void show_frame(struct video_desc *env);
-static void webcam_encode(struct video_desc *env)
+static void webcam_encode(struct video_out_desc *v)
{
struct timeval now = ast_tvnow();
ast_log(LOG_WARNING, "video frame ready at %d.%06d\n",
(int)now.tv_sec % 1000, (int)now.tv_usec);
- show_frame(env);
}
/* Helper function to process incoming video.
@@ -645,23 +640,24 @@
}
ast_log(LOG_WARNING, "ffmpeg_uninit drop %d frames\n", i);
video_in_uninit(&env->in);
- if(env->bmp)
+ if (env->bmp)
SDL_FreeYUVOverlay(env->bmp);
SDL_Quit();
- if (env->webcam_imgbuf) {
- free(env->webcam_imgbuf);
- if (env->webcam_fd >= 0)
- close(env->webcam_fd);
+ if (env->out.buf.data) {
+ free(env->out.buf.data);
+ env->out.buf.data = NULL;
+ if (env->out.fd >= 0)
+ close(env->out.fd);
}
{ /* clear the struct but restore some fields */
- const char *vd = env->videodevice;
- int w = env->w, h = env->h;
+ const char *vd = env->out.videodevice;
+ int w = env->out.w, h = env->out.h;
bzero(env, sizeof(struct video_desc));
/* restore fields... */
- env->videodevice = vd;
- env->w = w;
- env->h = h;
+ env->out.videodevice = vd;
+ env->out.w = w;
+ env->out.h = h;
}
}
@@ -1446,7 +1442,9 @@
res = ioctl(fd, SNDCTL_DSP_SETTRIGGER, &res);
/* it may fail if we are in half duplex, never mind */
- fd = webcam_open(&o->env);
+ webcam_open(&o->env.out);
+ if (o->env.out.buf.data && o->owner) /* drive webcam */
+ o->owner->fds[1] = o->env.out.fd;
return 0;
}
@@ -1613,8 +1611,8 @@
struct video_desc *env = get_video_desc(c);
- if (webcam_read(env) && 0)
- webcam_encode(env); /* get frames and put them in the queue */
+ if (webcam_read(&env->out))
+ webcam_encode(&env->out); /* get frames and put them in the queue */
if (env->echo) {
struct ast_frame *f1;
int i = 0;
@@ -2253,12 +2251,12 @@
M_F("callerid", store_callerid(o, v->value))
M_F("boost", store_boost(o, v->value))
M_STR("videodevice", o->videodevice)
- M_UINT("videowidth", o->env.w)
- M_UINT("videoheight", o->env.h)
+ M_UINT("videowidth", o->env.out.w)
+ M_UINT("videoheight", o->env.out.h)
M_END(/* */);
}
- o->env.videodevice = o->videodevice;
+ o->env.out.videodevice = o->videodevice;
if (ast_strlen_zero(o->device))
ast_copy_string(o->device, DEV_DSP, sizeof(o->device));
if (o->mixer_cmd) {
More information about the asterisk-commits
mailing list