[asterisk-commits] rizzo: branch rizzo/video_v2 r84122 - /team/rizzo/video_v2/channels/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat Sep 29 03:06:19 CDT 2007


Author: rizzo
Date: Sat Sep 29 03:06:18 2007
New Revision: 84122

URL: http://svn.digium.com/view/asterisk?view=rev&rev=84122
Log:
let ffmpeg do the format conversion for the X11 grabber.


Modified:
    team/rizzo/video_v2/channels/console_video.c

Modified: team/rizzo/video_v2/channels/console_video.c
URL: http://svn.digium.com/view/asterisk/team/rizzo/video_v2/channels/console_video.c?view=diff&rev=84122&r1=84121&r2=84122
==============================================================================
--- team/rizzo/video_v2/channels/console_video.c (original)
+++ team/rizzo/video_v2/channels/console_video.c Sat Sep 29 03:06:18 2007
@@ -150,7 +150,8 @@
  * structure is not initialized, so the other fields are invalid.
  */
 struct fbuf_t {		/* frame buffers, dynamically allocated */
-	uint8_t	*data;	/* malloc-ed memory */
+	uint8_t	*data;	/* memory, malloced if size > 0, just reference
+			 * otherwise */
 	int	size;	/* total size in bytes */
 	int	used;	/* space used so far */
 	int	w;
@@ -275,9 +276,11 @@
 #include <linux/videodev.h>
 #endif
 
+static AVPicture *fill_pict(struct fbuf_t *b, AVPicture *p);
+
 static void free_fbuf(struct fbuf_t *b)
 {
-	if (b->data)
+	if (b->data && b->size)
 		ast_free(b->data);
 	bzero(b, sizeof(*b));
 }
@@ -288,7 +291,8 @@
  */
 static int video_open(struct video_out_desc *v)
 {
-	if (v->loc_src.data)	/* buffer allocated means device already open */
+	struct fbuf_t *b = &v->loc_src;
+	if (b->data)	/* buffer allocated means device already open */
 		return v->fd;
 	v->fd = -1;
 	/*
@@ -306,7 +310,7 @@
 	}
 	v->image = im = XGetImage(v->dpy,
 		RootWindow(v->dpy, DefaultScreen(v->dpy)),
-		x_ofs, y_ofs, v->loc_src.w, v->loc_src.h, AllPlanes, ZPixmap);
+		x_ofs, y_ofs, b->w, b->h, AllPlanes, ZPixmap);
 	if (v->image == NULL) {
 		ast_log(LOG_WARNING, "error creating Ximage\n");
 		goto error;
@@ -315,7 +319,16 @@
 		im->data,
 		im->bits_per_pixel,
 		im->red_mask, im->green_mask, im->blue_mask);
-	v->loc_src.pix_fmt = PIX_FMT_RGB565;
+	switch (im->bits_per_pixel) {
+	case 32:
+		b->pix_fmt = PIX_FMT_RGBA32;
+		break;
+	case 16:
+		b->pix_fmt = PIX_FMT_RGB565;
+		break;
+	}
+	/* set the pointer but not the size as this is not malloc'ed */
+	b->data = im->data;
 	v->fd = -2;
     }
 #if HAVE_V4L > 0
@@ -356,23 +369,23 @@
 		ast_log(LOG_WARNING, "error setting picture info\n");
 		goto error;
 	}
-	v->loc_src.pix_fmt = PIX_FMT_YUV420P;
+	b->pix_fmt = PIX_FMT_YUV420P;
+	/* allocate the source buffer */
+	b->size = (b->w * b->h * 3)/2;	/* yuv411 */
+	ast_log(LOG_WARNING, "videodev %s opened, size %dx%d %d\n",
+		v->device, b->w, b->h, b->size);
+	v->loc_src.data = ast_calloc(1, b->size);
+	if (!b->data) {
+		ast_log(LOG_WARNING, "error allocating buffer %d bytes\n",
+			b->size);
+		goto error;
+	}
     }
 #endif /* HAVE_V4L */
+
 	if (v->image == NULL && v->fd < 0)
 		goto error;
-	/* allocate the source buffer */
-	v->loc_src.size = (v->w * v->h * 3)/2;	/* yuv411 */
-	ast_log(LOG_WARNING, "videodev %s opened, size %dx%d %d\n",
-		v->device, v->loc_src.w, v->loc_src.h, v->loc_src.size);
-	v->loc_src.data = ast_calloc(1, v->loc_src.size);
-	if (!v->loc_src.data) {
-		ast_log(LOG_WARNING, "error allocating buffer %d bytes\n",
-			v->loc_src.size);
-		goto error;
-	}
-
-	v->loc_src.used = 0;
+	b->used = 0;
 	return 0;
 
 error:
@@ -395,7 +408,9 @@
 static int video_read(struct video_out_desc *v)
 {
 	struct timeval now = ast_tvnow();
-	if (v->loc_src.data == NULL)	/* not initialized */
+	struct fbuf_t *b = &v->loc_src;
+
+	if (b->data == NULL)	/* not initialized */
 		return 0;
 
 	/* check if it is time to read */
@@ -407,30 +422,14 @@
 
 	if (v->image) {
 		/* read frame from X11 */
+		AVPicture p;
 		XGetSubImage(v->dpy,
 		    RootWindow(v->dpy, DefaultScreen(v->dpy)),
-		    0, 0, v->w, v->h, AllPlanes, ZPixmap, v->image, 0, 0);
-
-		/* convert to yuv - surely ffmpeg could do ? */
-		/* this works for rgb565 */
-		{
-			int x, y;
-			int ulen = (v->h * v->w) / 4;
-			uint16_t *src = (uint16_t *)v->image->data;
-			uint8_t *dst = v->loc_src.data;
-			uint8_t *up = dst + ulen*4;
-			uint8_t *vp = up + ulen;
-
-			for (y = 0; y < v->h; y++) {
-			    for (x = 0; x < v->w; x++) {
-				*dst++ = (*src++ & 0x7e0) >> 3;
-			    }
-			}				
-			memset(up, 0x80, ulen);
-			memset(vp, 0x80, ulen);
-		}
-
-		return v->loc_src.size;	/* return the actual size */
+		    0, 0, b->w, b->h, AllPlanes, ZPixmap, v->image, 0, 0);
+
+		b->data = v->image->data;
+		fill_pict(b, &p);
+		return p.linesize[0] * b->h;
 	}
 	if (v->fd < 0)			/* no other source */
 		return 0;
@@ -801,13 +800,25 @@
 static AVPicture *fill_pict(struct fbuf_t *b, AVPicture *p)
 {
 	int l4 = b->w * b->h/4; /* size of U or V frame */
+	int len = b->w;		/* default */
+	int ly = b->w/2;	/* default */
 	bzero(p, sizeof(*p));
+	switch (b->pix_fmt) {
+	case PIX_FMT_RGB555:
+	case PIX_FMT_RGB565:
+		len *= 2;
+		break;
+	case PIX_FMT_RGBA32:
+		len *= 4;
+		break;
+	}
 	p->data[0] = b->data;
 	p->data[1] = b->data + 4*l4;
 	p->data[2] = b->data + 4*l4;
-	p->linesize[0] = b->w;
-	p->linesize[1] = b->w/2;
-	p->linesize[2] = b->w/2;
+	p->linesize[0] = len;
+	/* these are only valid for component images */
+	p->linesize[1] = ly;
+	p->linesize[2] = ly;
 	return p;
 }
 
@@ -866,10 +877,8 @@
 		return;
 
 	if (out) {	/* webcam/x11 to sdl */
-		int l4;
 		b_in = &env->out.loc_src;
 		b_out = &env->out.loc_dpy;
-		l4 = b_in->w * b_in->h/4; /* size of U or V frame */
 		p_in = NULL;
 	} else {
 		/* copy input format from the decoding context */




More information about the asterisk-commits mailing list