[svn-commits] rizzo: branch rizzo/video_v2 r84144 - /team/rizzo/video_v2/channels/
SVN commits to the Digium repositories
svn-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 svn-commits
mailing list