[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