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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sun Sep 30 04:55:39 CDT 2007


Author: rizzo
Date: Sun Sep 30 04:55:37 2007
New Revision: 84144

URL: http://svn.digium.com/view/asterisk?view=rev&rev=84144
Log:
cleanup some comments and rearrange code, no functional changes.


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=84144&r1=84143&r2=84144
==============================================================================
--- team/rizzo/video_v2/channels/console_video.c (original)
+++ team/rizzo/video_v2/channels/console_video.c Sun Sep 30 04:55:37 2007
@@ -7,8 +7,8 @@
  * If one of these pieces is not available, either at compile time or at
  * runtime, we do our best to run without it. Of course, no codec library
  * means we can only deal with raw data, no SDL means we cannot do rendering,
- * no V4L or X11 means we cannot generate data (but eventually we could
- * stream from a file!).
+ * no V4L or X11 means we cannot generate data (but in principle we could
+ * stream from or record to a file).
  *
  * We need a recent (2007.07.12 or newer) version of ffmpeg to avoid warnings.
  * Older versions might give 'deprecated' messages during compilation,
@@ -17,11 +17,11 @@
  */
 
 
-//#define DROP_PACKETS 5       // if set, simulate this percentage of lost video packets
+//#define DROP_PACKETS 5       /* if set, drop this % of video packets */
 #define HAVE_V4L	1
 #define HAVE_SDL	1
 #define HAVE_FFMPEG	1
-//#define OLD_FFMPEG	1	/* set for old ffmpeg with no swscale */
+#define OLD_FFMPEG	1	/* set for old ffmpeg with no swscale */
 
 
 #if !defined(HAVE_FFMPEG)
@@ -63,21 +63,20 @@
 
 #else
 /*
- * The real thing, with support for SDL and codecs, and possibly V4L/X11.
+ * The real code, with support for SDL and codecs, and possibly V4L/X11.
  *
 
 The code is structured as follows.
 
 When a new console channel is created, we call console_video_start()
-to initialize SDL, the source, and the encoder/ decoder for
-the formats in use
-(XXX the latter two should be done later, once the codec
-negotiation is complete).
-Also, a thread is created to handle the video source and generate frames.
+to initialize SDL, the source, and the encoder/ decoder for the
+formats in use (XXX the latter two should be done later, once the
+codec negotiation is complete).  Also, a thread is created to handle
+the video source and generate frames.
 
 While communication is on, the local source is generated by the
-video thread, which wakes up periodically, generates frames and enqueues
-them in chan->readq.  Incoming rtp frames are passed to
+video thread, which wakes up periodically, generates frames and
+enqueues them in chan->readq.  Incoming rtp frames are passed to
 console_write_video(), decoded and passed to SDL for display.
 
 For as unfortunate and confusing as it can be, we need to deal with a
@@ -109,13 +108,14 @@
  rem_dpy	the format used to display the remote stream
 
 We store the format info together with the buffer storing the data.
-As an optimization, a format/buffer may reference another one
-if the formats are equivalent.
-
- *
- * In order to decode video you need the following patch to the
- * main Makefile:
-
+As a future optimization, a format/buffer may reference another one
+if the formats are equivalent. This will save some unnecessary format
+conversion.
+
+
+In order to decode video you need the following patch to the
+main Makefile:
+------ begin patch -----------
 @@ -269,6 +273,11 @@
    SOLINK=-shared -fpic -L/usr/local/ssl/lib
  endif
@@ -128,12 +128,14 @@
  # This is used when generating the doxygen documentation
  ifneq ($(DOT),:)
    HAVEDOT=yes
+------------- end patch ----------------
 
 Then you need to add to sip.conf:
 	[general](+)
-		allow=h263p
+		allow=h263p	; this or other video formats
 		videosupport=yes
 
+This concludes the install instructions.
  */
 
 #include <X11/Xlib.h>		/* this should be conditional */
@@ -149,6 +151,7 @@
  * In many places we use buffers to store the raw frames (but not only),
  * so here is a structure to keep all the info. data = NULL means the
  * structure is not initialized, so the other fields are invalid.
+ * size = 0 means the buffer is not malloc'ed so we don't have to free it.
  */
 struct fbuf_t {		/* frame buffers, dynamically allocated */
 	uint8_t	*data;	/* memory, malloced if size > 0, just reference
@@ -169,7 +172,7 @@
  *    frames at the correct rate;
  *  + source-specific info, i.e. fd for /dev/video, dpy-image for x11, etc,
  *    filled in by video_open
- * NOTE: buf.data == NULL means the rest of the struct is invalid, and
+ * NOTE: loc_src.data == NULL means the rest of the struct is invalid, and
  *	the video source is not available.
  */
 struct video_out_desc {
@@ -232,14 +235,14 @@
  */
 struct video_desc {
 	int 			w;	/* geometry */
-	int 	h;
+	int 			h;
 	int 			fps;	/* framerate */
-	int 	bitrate;
-	char videodevice[64];
-
-	pthread_t vthread;	/* video thread */
-	int			shutdown;	/* set to ask the thread to shutdown */
-	struct ast_channel *owner;	/* owner channel */
+	int 			bitrate;
+	char			videodevice[64];
+
+	pthread_t		vthread;	/* video thread */
+	int			shutdown;	/* set to shutdown vthread */
+	struct ast_channel	*owner;		/* owner channel */
 
 	struct video_in_desc	in;		/* remote video descriptor */
 	struct video_out_desc	out;		/* local video descriptor */
@@ -273,11 +276,6 @@
 	{ AST_FORMAT_H263_PLUS,	CODEC_ID_H263P, CM_WR }, /* XXX H263P ? */
 	{ 0,			0, 0 },
 };
-
-/* Video4Linux stuff is only used in video_open() */
-#if HAVE_V4L > 0
-#include <linux/videodev.h>
-#endif
 
 static AVPicture *fill_pict(struct fbuf_t *b, AVPicture *p);
 
@@ -293,6 +291,11 @@
 	b->h = x.h;
 	b->pix_fmt = x.pix_fmt;
 }
+
+/* Video4Linux stuff is only used in video_open() */
+#if HAVE_V4L > 0
+#include <linux/videodev.h>
+#endif
 
 /*!
  * Open the local video source and allocate a buffer
@@ -355,31 +358,46 @@
 
 	i = fcntl(v->fd, F_GETFL);
 	if (-1 == fcntl(v->fd, F_SETFL, i | O_NONBLOCK)) {
-		ast_log(LOG_WARNING, "error F_SETFL for %s [%s]\n", v->device, strerror(errno));
-	}
-	/* set format */
+		/* non fatal, just emit a warning */
+		ast_log(LOG_WARNING, "error F_SETFL for %s [%s]\n",
+			v->device, strerror(errno));
+	}
+	/* set format for the camera.
+	 * In principle we could retry with a different format if the
+	 * one we are asking for is not supported.
+	 */
 	vw.width = v->loc_src.w;
 	vw.height = v->loc_src.h;
 	vw.flags = v->fps << 16;
 	if (ioctl(v->fd, VIDIOCSWIN, &vw) == -1) {
-		ast_log(LOG_WARNING, "error setting format for %s [%s]\n", v->device, strerror(errno));
+		ast_log(LOG_WARNING, "error setting format for %s [%s]\n",
+			v->device, strerror(errno));
 		goto error;
 	}
 	if (ioctl(v->fd, VIDIOCGPICT, &vp) == -1) {
 		ast_log(LOG_WARNING, "error reading picture info\n");
 		goto error;
 	}
-	ast_log(LOG_WARNING, "contrast %d bright %d colour %d hue %d whiteness %d palette %d\n",
+	ast_log(LOG_WARNING,
+		"contrast %d bright %d colour %d hue %d white %d palette %d\n",
 		vp.contrast, vp.brightness,
 		vp.colour, vp.hue,
 		vp.whiteness, vp.palette);
+	/* set the video format. Here again, we don't necessary have to
+	 * fail if the required format is not supported, but try to use
+	 * what the camera gives us.
+	 */
+	b->pix_fmt = vp.palette;
 	vp.palette = VIDEO_PALETTE_YUV420P;
 	if (ioctl(v->fd, VIDIOCSPICT, &vp) == -1) {
-		ast_log(LOG_WARNING, "error setting picture info\n");
-		goto error;
-	}
-	b->pix_fmt = PIX_FMT_YUV420P;
-	/* allocate the source buffer */
+		ast_log(LOG_WARNING, "error setting palette, using %d\n",
+			b->pix_fmt);
+	} else
+		b->pix_fmt = vp.palette;
+	/* allocate the source buffer.
+	 * XXX, the code here only handles yuv411, for other formats
+	 * we need to look at pix_fmt and set size accordingly
+	 */
 	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);
@@ -412,8 +430,7 @@
 }
 
 /*! \brief complete a buffer from the local video source.
- * called by get_video_frames(), in turn called by asterisk
- * as part of the read callback
+ * Called by get_video_frames(), in turn called by the video thread.
  */
 static int video_read(struct video_out_desc *v)
 {
@@ -493,7 +510,7 @@
 	free_fbuf(&v->dec_in);
 	free_fbuf(&v->dec_out);
 	free_fbuf(&v->rem_dpy);
-	bzero(v, sizeof(*v));
+	bzero(v, sizeof(*v));	/* XXX too much, we are losing config info */
 	return -1;	/* error, in case someone cares */
 }
 
@@ -522,9 +539,8 @@
 	* Initialize the codec context.
 	*/
 	v->dec_ctx = avcodec_alloc_context();
-	/* XXX not here! */
 	if (avcodec_open(v->dec_ctx, v->codec) < 0) {
-		ast_log(LOG_WARNING, "Unable to open the codec context\n");
+		ast_log(LOG_WARNING, "Cannot open the codec context\n");
 		av_free(v->dec_ctx);
 		v->dec_ctx = NULL;
 		return video_in_uninit(v);
@@ -532,13 +548,13 @@
 
 	v->parser = av_parser_init(codec);
 	if (!v->parser) {
-		ast_log(LOG_WARNING, "Unable to initialize the decoder parser\n");
+		ast_log(LOG_WARNING, "Cannot initialize the decoder parser\n");
 		return video_in_uninit(v);
 	}
 
 	v->frame = avcodec_alloc_frame();
 	if (!v->frame) {
-		ast_log(LOG_WARNING, "Unable to allocate the decoding video frame\n");
+		ast_log(LOG_WARNING, "Cannot allocate decoding video frame\n");
 		return video_in_uninit(v);
 	}
 	return 0;	/* ok */
@@ -595,20 +611,37 @@
 	codec = map_video_format(format, CM_WR);
 	v->codec = avcodec_find_encoder(codec);
 	if (!v->codec) {
-		ast_log(LOG_WARNING, "Unable to find the encoder for format %d\n", codec);
+		ast_log(LOG_WARNING, "Cannot find the encoder for format %d\n",
+			codec);
 		return video_out_uninit(v);
 	}
 
-	/* allocate the input buffer for encoding */
+	/* allocate the input buffer for encoding.
+	 * Once again we assume the encoder works on some 411 format.
+	 */
 	enc_in = &v->enc_in;
 	enc_in->size = (enc_in->w * enc_in->h * 3)/2;	/* yuv411 */
 	enc_in->data = ast_calloc(1, enc_in->size);
 	if (!enc_in->data) {
-		ast_log(LOG_WARNING, "Unable to allocate enc.in\n");
+		ast_log(LOG_WARNING, "Cannot allocate encoder input buffer\n");
 		return video_out_uninit(v);
 	}
-	ast_log(LOG_WARNING, "enc_in data at %p size %d\n",
-		enc_in->data, enc_in->size);
+	v->frame = avcodec_alloc_frame();
+	if (!v->frame) {
+		ast_log(LOG_WARNING, "Unable to allocate the encoding video frame\n");
+		return video_out_uninit(v);
+	}
+
+	/* Here we assume that the encoder has some 411 format */
+	size = enc_in->w * enc_in->h;
+	v->frame->data[0] = enc_in->data;
+	v->frame->data[1] = v->frame->data[0] + size;
+	v->frame->data[2] = v->frame->data[1] + size/4;
+	v->frame->linesize[0] = enc_in->w;
+	v->frame->linesize[1] = enc_in->w/2;
+	v->frame->linesize[2] = enc_in->w/2;
+
+	/* now setup the parameters for the encoder */
 	v->enc_ctx = avcodec_alloc_context();
 	v->enc_ctx->pix_fmt = enc_in->pix_fmt;
 	v->enc_ctx->width = enc_in->w;
@@ -619,8 +652,13 @@
 	v->enc_ctx->rtp_mode = 1;
 	v->enc_ctx->rtp_payload_size = v->mtu / 2; // mtu/2
 	v->enc_ctx->bit_rate_tolerance = v->enc_ctx->bit_rate/5;
+
+	/* now set codec-specific parameters, which differ for
+	 * the various video codecs in use.
+	 * At the moment we only support h263p, but presumably we
+	 * need to deal with this in some external function.
+	 */
 	if (0) {	/* normal h263 */
-		// v->enc_ctx->codec = CODEC_ID_H263;
 	} else {
 		v->enc_ctx->flags |=CODEC_FLAG_H263P_UMV;
 		v->enc_ctx->flags |=CODEC_FLAG_AC_PRED;
@@ -637,21 +675,6 @@
 		v->enc_ctx = NULL;
 		return video_out_uninit(v);
 	}
-
-	v->frame = avcodec_alloc_frame();
-	if (!v->frame) {
-		ast_log(LOG_WARNING, "Unable to allocate the encoding video frame\n");
-		return video_out_uninit(v);
-	}
-
-	/* Here we assume that the encoder has some 411 format */
-	size = enc_in->w * enc_in->h;
-	v->frame->data[0] = enc_in->data;
-	v->frame->data[1] = v->frame->data[0] + size;
-	v->frame->data[2] = v->frame->data[1] + size/4;
-	v->frame->linesize[0] = enc_in->w;
-	v->frame->linesize[1] = enc_in->w/2;
-	v->frame->linesize[2] = enc_in->w/2;
 
 	/*
 	 * Allocate enough for the encoded bitstream. As we are compressing,




More information about the asterisk-commits mailing list