[asterisk-commits] rizzo: branch rizzo/video_v2 r82365 - in /team/rizzo/video_v2: ./ channels/ i...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Sep 13 19:16:34 CDT 2007


Author: rizzo
Date: Thu Sep 13 19:16:33 2007
New Revision: 82365

URL: http://svn.digium.com/view/asterisk?view=rev&rev=82365
Log:
compilable version of chan_oss with video support.
Functionality still not tested, nor autoconf issues to detect
the correct version of ffmpeg and the presence of the various
libs involved.


Added:
    team/rizzo/video_v2/channels/console_video.c   (with props)
Modified:
    team/rizzo/video_v2/Makefile
    team/rizzo/video_v2/channels/Makefile
    team/rizzo/video_v2/channels/chan_oss.c
    team/rizzo/video_v2/configure
    team/rizzo/video_v2/configure.ac
    team/rizzo/video_v2/include/asterisk/autoconfig.h.in
    team/rizzo/video_v2/utils/Makefile

Modified: team/rizzo/video_v2/Makefile
URL: http://svn.digium.com/view/asterisk/team/rizzo/video_v2/Makefile?view=diff&rev=82365&r1=82364&r2=82365
==============================================================================
--- team/rizzo/video_v2/Makefile (original)
+++ team/rizzo/video_v2/Makefile Thu Sep 13 19:16:33 2007
@@ -283,6 +283,10 @@
   HAVEDOT=no
 endif
 
+# Add library for ffmpeg and SDL lib.
+ASTCFLAGS+=`sdl-config --cflags`
+SOLINK+=-lavcodec -lz -lm -g `sdl-config --libs`
+
 all: _all
 	@echo " +--------- Asterisk Build Complete ---------+"  
 	@echo " + Asterisk has successfully been built, and +"  

Modified: team/rizzo/video_v2/channels/Makefile
URL: http://svn.digium.com/view/asterisk/team/rizzo/video_v2/channels/Makefile?view=diff&rev=82365&r1=82364&r2=82365
==============================================================================
--- team/rizzo/video_v2/channels/Makefile (original)
+++ team/rizzo/video_v2/channels/Makefile Thu Sep 13 19:16:33 2007
@@ -103,6 +103,8 @@
 	$(CMD_PREFIX) $(CXX) $(PTHREAD_CFLAGS) $(ASTLDFLAGS) $(SOLINK) -o $@ $< h323/libchanh323.a $(CHANH323LIB) -L$(PWLIBDIR)/lib $(PTLIB) -L$(OPENH323DIR)/lib $(H323LIB) -L/usr/lib -lcrypto -lssl -lexpat
 endif
 
+chan_oss.o: console_video.c
+
 chan_misdn.o: ASTCFLAGS+=-Imisdn
 
 misdn_config.o: ASTCFLAGS+=-Imisdn

Modified: team/rizzo/video_v2/channels/chan_oss.c
URL: http://svn.digium.com/view/asterisk/team/rizzo/video_v2/channels/chan_oss.c?view=diff&rev=82365&r1=82364&r2=82365
==============================================================================
--- team/rizzo/video_v2/channels/chan_oss.c (original)
+++ team/rizzo/video_v2/channels/chan_oss.c Thu Sep 13 19:16:33 2007
@@ -286,6 +286,8 @@
 
 static int oss_debug;
 
+#include "console_video.c"
+
 /*!
  * Each sound is made of 'datalen' samples of sound, repeated as needed to
  * generate 'samplen' samples of data, then followed by 'silencelen' samples
@@ -382,7 +384,15 @@
 	char oss_read_buf[FRAME_SIZE * 2 + AST_FRIENDLY_OFFSET];
 	int readpos;				/*!< read position above */
 	struct ast_frame read_f;	/*!< returned by oss_read */
+
+	struct video_desc env;		/* video support stuff */
 };
+
+static struct video_desc *get_video_desc(struct ast_channel *c)
+{
+	struct chan_oss_pvt *o = c->tech_pvt;
+	return o ? &(o->env) : NULL;
+}
 
 static struct chan_oss_pvt oss_default = {
 	.cursound = -1,
@@ -420,7 +430,7 @@
 static const struct ast_channel_tech oss_tech = {
 	.type = "Console",
 	.description = tdesc,
-	.capabilities = AST_FORMAT_SLINEAR,
+	.capabilities = AST_FORMAT_SLINEAR | CONSOLE_FORMAT_VIDEO,
 	.requester = oss_request,
 	.send_digit_begin = oss_digit_begin,
 	.send_digit_end = oss_digit_end,
@@ -430,6 +440,7 @@
 	.read = oss_read,
 	.call = oss_call,
 	.write = oss_write,
+	.write_video = console_write_video,
 	.indicate = oss_indicate,
 	.fixup = oss_fixup,
 };
@@ -864,6 +875,7 @@
 	c->tech_pvt = NULL;
 	o->owner = NULL;
 	ast_verbose(" << Hangup on console >> \n");
+	console_video_uninit(&o->env);
 	ast_module_unref(ast_module_info->self);
 	if (o->hookstate) {
 		if (o->autoanswer || o->autohangup) {
@@ -920,10 +932,12 @@
 	int res;
 	struct chan_oss_pvt *o = c->tech_pvt;
 	struct ast_frame *f = &o->read_f;
+	struct ast_frame *fv = get_video_frames(get_video_desc(c));
 
 	/* XXX can be simplified returning &ast_null_frame */
 	/* prepare a NULL frame in case we don't have enough data to return */
 	bzero(f, sizeof(struct ast_frame));
+	AST_LIST_NEXT(f, frame_list) = fv;	/* append video frames */
 	f->frametype = AST_FRAME_NULL;
 	f->src = oss_tech.type;
 
@@ -1028,6 +1042,10 @@
 		setformat(o, O_RDWR);
 	ast_channel_set_fd(c, 0, o->sounddev); /* -1 if device closed, override later */
 	c->nativeformats = AST_FORMAT_SLINEAR;
+	/* if the console makes the call, add video */
+	if (state == 5)
+		c->nativeformats |= CONSOLE_FORMAT_VIDEO;
+
 	c->readformat = AST_FORMAT_SLINEAR;
 	c->writeformat = AST_FORMAT_SLINEAR;
 	c->tech_pvt = o;
@@ -1051,6 +1069,7 @@
 			/* XXX what about the channel itself ? */
 		}
 	}
+	console_video_start(get_video_desc(c), o->owner); /* XXX cleanup */
 
 	return c;
 }
@@ -1529,6 +1548,10 @@
 		M_F("mixer", store_mixer(o, v->value))
 		M_F("callerid", store_callerid(o, v->value))
 		M_F("boost", store_boost(o, v->value))
+		M_STR("videodevice", o->env.videodevice)
+		M_UINT("videowidth", o->env.w)
+		M_UINT("videoheight", o->env.h)
+		M_UINT("fps", o->env.fps)
 
 		M_END(/* */);
 	}

Added: team/rizzo/video_v2/channels/console_video.c
URL: http://svn.digium.com/view/asterisk/team/rizzo/video_v2/channels/console_video.c?view=auto&rev=82365
==============================================================================
--- team/rizzo/video_v2/channels/console_video.c (added)
+++ team/rizzo/video_v2/channels/console_video.c Thu Sep 13 19:16:33 2007
@@ -1,0 +1,959 @@
+/* header for console video */
+/*
+ * experimental support for video sessions. We use:
+ * - SDL for rendering both incoming and outgoing data,
+ * - ffmpeg for encoding and decoding;
+ * - video4linux for accessing the source.
+ */
+//#define DROP_PACKETS 5       // if set, simulate this percentage of lost video packets
+#define HAVE_V4L	1
+#define HAVE_SDL	1
+#define HAVE_FFMPEG	1
+
+#if !defined(HAVE_FFMPEG) || HAVE_FFMPEG == 0 || !defined(HAVE_SDL) || HAVE_SDL == 0
+/* stubs for everything */
+struct video_desc {	/* empty */
+	int 	w;
+	int 	h;
+	int 	fps;
+	char videodevice[64];
+};
+#define CONSOLE_FORMAT_VIDEO	0
+#define	console_write_video	NULL
+static void console_video_start(struct video_desc *env,
+	struct ast_channel *owner)
+{
+}
+
+static void console_video_uninit(struct video_desc *env)
+{
+}
+
+static struct ast_frame *get_video_frames(struct video_desc *env)
+{
+	return NULL;
+}
+
+#else	/* the body of the file */
+/*
+ * In order to decode video you need the following patch to the
+ * main Makefile:
+
+@@ -269,6 +273,11 @@
+   SOLINK=-shared -fpic -L/usr/local/ssl/lib
+ endif
+ 
++# GCC configuration flags for SDL library
++ASTCFLAGS+=`sdl-config --cflags`
++# Add library for ffmpeg and SDL lib.
++SOLINK+=-lavcodec -lz -lm -g `sdl-config --libs`
++
+ # This is used when generating the doxygen documentation
+ ifneq ($(DOT),:)
+   HAVEDOT=yes
+
+Then you need to add to sip.conf:
+	[general](+)
+		allow=h263p
+		videosupport=yes
+
+ */
+/*
+ * Examples for video encoding are at http://www.irisa.fr/texmex/people/dufouil/ffmpegdoxy/apiexample_8c-source.html
+ */
+
+#include <ffmpeg/avcodec.h>
+// #include <ffmpeg/swscale.h>	/* requires a recent ffmpeg */
+#include <SDL/SDL.h>
+
+/* Structures for ffmpeg processing */
+/*
+ * Information for decoding incoming video stream.
+ * We need:
+ * - one descriptor per output stream (camera or file, plus encoding context)
+ * - one descriptor per incoming stream (network data, plus decoding context)
+ * - one descriptor per window (SDL).
+ */
+
+struct dbuf_t {		/* buffers, dynamically allocated */
+	uint8_t	*data;
+	int	size;
+	int	used;
+};
+
+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.
+	 */
+	int 		w;		/* geometry */
+	int 		h;
+	int 		fd;		/* file descriptor */
+	struct dbuf_t	buf;
+	AVCodecContext	*context;
+	AVCodec		*codec;
+	AVFrame		*frame;
+	int		lasttxframe;
+	int		fps;
+	struct dbuf_t	decbuf;
+	struct timeval	ts;
+	struct timeval	msts;
+	int		mtu;
+};
+
+struct video_in_desc {
+	AVCodecContext          *context;	/* information about the codec in the stream */
+	AVCodec                 *codec;		/* reference to the codec */
+	AVFrame                 *frame;		/* place to store the frame */
+	AVCodecParserContext    *parser;
+	int                     completed;	/* probably unnecessary */
+	struct dbuf_t buf;
+	int                     lastrxframe;
+	int                     discard;
+	struct timeval	ts;
+	int received;
+};
+
+struct video_desc {
+	int 	w;
+	int 	h;
+	int 	fps;
+	char videodevice[64];
+
+	struct video_in_desc in;
+	struct video_out_desc out;
+
+	SDL_Surface             *screen;
+	int                     initialized;
+	SDL_Overlay             *bmp[2];
+
+	struct ast_frame *echo;
+
+};
+
+struct _cm {	/* map ffmpeg codec types to asterisk formats */
+	uint32_t	ast_format;	/* 0 is a terminator */
+	enum CodecID	codec;
+};
+
+/*! the list of video formats we support */
+#define CONSOLE_FORMAT_VIDEO	AST_FORMAT_H263_PLUS
+
+static struct _cm video_formats[] = {
+	{ AST_FORMAT_H263_PLUS,	CODEC_ID_H263 },
+	{ 0,			0 },
+};
+
+/*! \brief support to open a webcam using video4linux1 and read()
+ *
+ */
+#if !defined(HAVE_V4L) || HAVE_V4L != 1
+/* stubs */
+static int webcam_open(struct video_desc *env)
+{
+	return -1;
+}
+static int webcam_read(struct video_out_desc *v)
+{
+	return 0;
+}
+
+#else
+
+/* the real thing */
+#include <linux/videodev.h>
+
+static int webcam_open(struct video_desc *env)
+{
+	int i;
+	const char *device = env->videodevice;
+	struct video_window vw = { 0 };	/* camera attributes */
+	struct video_picture vp;
+	struct video_out_desc *v = &env->out;
+
+	/* copy config from parent */
+	v->w = env->w;
+	v->h = env->h;
+	v->fps = env->fps;
+
+	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 v->fd;
+	}
+
+	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", device, strerror(errno));
+	}
+	/* set format */
+	vw.width = v->w;
+	vw.height = v->h;
+	vw.flags = v->fps << 16;
+	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 [%s]\n", 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",
+		vp.contrast, vp.brightness,
+		vp.colour, vp.hue,
+		vp.whiteness, 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;
+	}
+	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;
+	}
+
+	v->buf.used = 0;
+	return v->fd;
+
+error:
+	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_out_desc *v)
+{
+	if (v->buf.data == NULL)	/* not initialized */
+		return 0;
+
+	for (;;) {
+		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;
+		v->buf.used += r;
+		if (r == l) {
+			v->buf.used = 0; /* prepare for next frame */
+			return v->buf.size;
+		}
+	}
+}
+#endif /* HAVE_V4L */
+
+static void show_frame(struct video_desc *env, int out);
+
+static int webcam_encode(struct video_desc *env)
+{
+	int n_enc;
+
+	// 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, 1);
+	// XXX Codichiamo il frame
+	// XXX Vedi la alsa_read per il continuo
+	n_enc = avcodec_encode_video(env->out.context, env->out.decbuf.data, env->out.decbuf.size, env->out.frame);
+
+	return n_enc;
+}
+
+/* Helper function to process incoming video.
+ * For each incoming video call invoke ffmpeg_init() to intialize
+ * the decoding structure then incoming video frames are processed
+ * by write_video() which in turn calls pre_process_data(), to extract
+ * the bitstream; accumulates data into a buffer within video_desc. When
+ * a frame is complete (determined by the marker bit in the RTP header)
+ * call decode_video() to decoding and if it successful call show_frame()
+ * to display the frame.
+ */
+
+static struct video_desc *get_video_desc(struct ast_channel *c);
+
+/*! \brief map an asterisk format into an ffmpeg one */
+static enum CodecID map_video_format(uint32_t ast_format)
+{
+	struct _cm *i;
+
+	for (i = video_formats; i->ast_format != 0; i++)
+		if (ast_format & i->ast_format)
+			return i->codec;
+	return CODEC_ID_NONE;
+}
+
+static int video_in_uninit(struct video_in_desc *v)
+{
+	if (v->context) {
+		avcodec_close(v->context);
+		av_free(v->context);
+	}
+	if (v->frame)
+		av_free(v->frame);
+	if (v->buf.data)
+		free(v->buf.data);
+	bzero(v, sizeof(*v));
+	return -1;	/* error, in case someone cares */
+}
+
+static int video_in_init(struct video_in_desc *v, uint32_t format)
+{
+	enum CodecID codec;
+
+	v->codec = NULL;
+	v->context = NULL;
+	v->frame = NULL;
+	v->parser = NULL;
+	v->buf.data = NULL;
+	v->completed = 0;
+	v->lastrxframe        = -1;
+
+	v->ts = ast_tvnow();
+	codec = map_video_format(format);
+	ast_log(LOG_WARNING, "init for format 0x%x gives %d\n", format, codec);
+
+	v->codec = avcodec_find_decoder(codec);
+	if (!v->codec) {
+		ast_log(LOG_WARNING, "Unable to find the decoder for format %d\n", codec);
+		return video_in_uninit(v);
+	}
+	/*
+	* Initialize the codec context.
+	*/
+	v->context = avcodec_alloc_context();
+	if (avcodec_open(v->context, v->codec) < 0) {
+		ast_log(LOG_WARNING, "Unable to open the codec context\n");
+		return video_in_uninit(v);
+	}
+
+	v->parser = av_parser_init(codec);
+	if (!v->parser) {
+		ast_log(LOG_WARNING, "Unable to 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");
+		return video_in_uninit(v);
+	}
+	return 0;	/* ok */
+}
+
+static int video_out_uninit(struct video_out_desc *v)
+{
+	if (v->context) {
+		avcodec_close(v->context);
+		av_free(v->context);
+	}
+
+	if (v->frame) 
+		av_free(v->frame);
+
+	if (v->buf.data) 
+		free(v->buf.data);
+
+	if(v->fd >= 0) 
+		close(v->fd);
+
+	if(v->decbuf.data)
+		free(v->decbuf.data);
+
+	v->fd = -1;
+
+	return -1;
+}
+
+static int video_out_init(struct video_out_desc *v, uint32_t format)
+{
+	int codec;
+	int size;
+
+	v->context		= NULL;
+	v->codec		= NULL;
+	v->frame		= NULL;
+	v->lasttxframe		= -1;
+	v->decbuf.data		= NULL;
+
+	ast_log(LOG_WARNING, "video_out_init start 0x%x", format);
+	codec = map_video_format(format);
+	v->codec = avcodec_find_encoder(codec);
+	if (!v->codec) {
+		ast_log(LOG_WARNING, "Unable to find the encoder for format %d\n", codec);
+		return video_out_uninit(v);
+	}
+
+	v->context = avcodec_alloc_context();
+	v->context->pix_fmt = PIX_FMT_YUV420P;
+	v->context->width = v->w;
+	v->context->height = v->h;
+	v->context->rtp_mode = 1;
+	v->context->rtp_payload_size = v->mtu / 2; // mtu/2
+	v->context->flags|=CODEC_FLAG_H263P_UMV;
+	v->context->flags|=CODEC_FLAG_AC_PRED;
+	v->context->flags|=CODEC_FLAG_H263P_SLICE_STRUCT;
+	//v->context->bit_rate = 20000;
+	//v->context->gop_size = (int) v->fps*5; // emit I frame every 5 seconds
+ 
+	fprintf(stderr, "w: %d...h: %d...fps: %d...", v->w, v->h, v->fps);
+	v->context->time_base = (AVRational){1, v->fps};
+	if (avcodec_open(v->context, v->codec) < 0) {
+		ast_log(LOG_WARNING, "Unable to initialize the encoder parser\n");
+		av_free(v->context);
+		v->context = NULL;
+		return video_out_uninit(v);
+	}
+	fprintf(stderr, "2...");
+
+	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);
+	}
+	fprintf(stderr, "3...\n");
+
+	if(!v->buf.data) {
+		ast_log(LOG_WARNING, "Unable to set frame buffer\n");
+		return video_out_uninit(v);
+	}
+	
+	size = v->w*v->h;
+	v->frame->data[0] = v->buf.data;
+	v->frame->data[1] = v->frame->data[0] + size;
+	v->frame->data[2] = v->frame->data[1] + size/4;
+	v->frame->linesize[0] = v->context->width;
+	v->frame->linesize[1] = v->context->width/2;
+	v->frame->linesize[2] = v->context->width/2;
+
+	v->decbuf.data = ast_calloc(1, v->buf.size);
+	v->decbuf.size = v->buf.size;
+	v->decbuf.used = 0;
+
+	v->msts = ast_tvnow();
+
+	v->mtu = 1400;
+	ast_log(LOG_VERBOSE, "video_out_init done");
+
+	return 0;
+}
+
+/*
+ * It initializes the video_desc struct which contains all the structures
+ * needed by ffmpeg and SDL libraries.
+ * - Registering of all codecs supported by the ffmpeg.
+ * - Searching for H.263+ decoder (H.263 decoder can decode H.263+ stream).
+ * - Allocation and initialization of codec context.
+ * - Initialization of codec parser (it should be used
+ *     to reconstruct the entire bitstream from a fragmented stream)
+ * - Allocation of a new frame
+ * - Initializzation of the SDL environment to support the video
+ */
+static void ffmpeg_init(struct video_desc *env, uint32_t format)
+{
+	env->screen = NULL;
+	env->initialized = 0;
+	env->bmp[0] = env->bmp[1] = NULL;
+
+	// SDL specific
+	if(SDL_Init(SDL_INIT_VIDEO)) {
+		fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
+		return;
+	}
+
+	if (video_in_init(&env->in, format))
+		return;
+
+	env->initialized = 1;
+}
+
+/*
+ * Freeing all memory used and uninitialize
+ * the ffmpeg and SDL environments.
+ */
+static void console_video_uninit(struct video_desc *env)
+{
+	struct ast_frame *f;
+	int i = 0;
+
+	while ( (f = env->echo) != NULL) {
+		env->echo = AST_LIST_NEXT(f, frame_list);
+		ast_frfree(f);
+		i++;
+	}
+	ast_log(LOG_WARNING, "ffmpeg_uninit drop %d frames\n", i);
+	video_in_uninit(&env->in);
+	video_out_uninit(&env->out);
+	if (env->bmp[0])
+		SDL_FreeYUVOverlay(env->bmp[0]);
+	if (env->bmp[1])
+		SDL_FreeYUVOverlay(env->bmp[1]);
+	SDL_Quit();
+
+	/*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 */
+		struct video_desc x = *env; /* make a copy */
+		fprintf(stderr, "vd: %s\n", x.videodevice);
+		bzero(env, sizeof(struct video_desc));
+		/* restore fields... */
+		bcopy(x.videodevice, env->videodevice, sizeof(env->videodevice));
+		env->w = x.w;
+		env->h = x.h;
+		env->fps = x.fps;
+	}
+}
+
+#define MAKE_MASK(bits)                ( (1<<(bits)) -1 )
+
+/*
+ * Get the P flag from the H.263+ header from the RTP payload (see RFC 2429).
+ */
+static inline unsigned int rfc2429_get_P(const uint8_t *header){
+	return (header[0]>>2) & 0x1;
+}
+
+/*
+ * Get the PLEN variable from the H.263+ header from the RTP payload (see RFC 2429).
+ */
+static inline unsigned int rfc2429_get_PLEN(const uint8_t *header){
+	unsigned short *p=(unsigned short*)header;
+	return (ntohs(p[0])>>3) & MAKE_MASK(6);
+}
+
+/*! \brief extract the bitstreem from the RTP payload.
+ * This is format dependent.
+ * For h261, the format is defined in RFC 4587
+ * and basically has a fixed 4-byte header as follows:
+ * 3 bits	SBIT	start bit, how many msbits to ignore in first byte
+ * 3 bits	EBIT	end bit, how many lsbits to ignore in last byte
+ * 1 bit	I	1 if frame only contain INTRA blocks
+ * 1 bit	V	0 if motion vector not used, 1 if may be used
+ * 4 bits	GOBN	gob number at start of packet (0 for gob header)
+ * 5 bits	MBAP	macroblock address predictor
+ * 5 bits	QUANT	quantizer value
+ * 5 bits	HMVD	horiz motion vector
+ * 5 bits	VMVD	vert. motion vector
+ *
+ * For h263, the format is defined in RFC 2429
+ * and basically has a fixed 2-byte header as follows:
+ * 5 bits	RR	reserved, shall be 0
+ * 1 bit	P	indicate a start/end condition,
+ *			in which case the payload should be prepended
+ *			by two zero-valued bytes.
+ * 1 bit	V	there is an additional VRC header after this header
+ * 6 bits	PLEN	length in bytes of extra picture header
+ * 3 bits	PEBIT	how many bits to be ignored in the last byte
+ *
+ * XXX the code below is not complete.
+ */
+static uint8_t *pre_process_data(uint8_t *data, int *len)
+{
+	int PLEN;
+	int P;
+
+	if(data == NULL)
+		return NULL;
+	if(*len < 2)
+		return NULL;
+
+	PLEN = rfc2429_get_PLEN(data);
+	P = rfc2429_get_P(data);
+
+	if(PLEN > 0) {
+		data += PLEN;
+		(*len) -= PLEN;
+	}
+	if(P)
+		data[0] = data[1] = 0;
+	else {
+		data += 2;
+		(*len) -= 2;
+	}
+
+	return data;
+}
+
+/*
+ * It decodes a valid H.263 frame.
+ * The av_parser_parse should merge a randomly choped up stream into proper frames.
+ * After that, if we have a valid frame, we decode it until the entire frame is processed.
+ */
+static int decode_video(struct video_in_desc *v)
+{
+	uint8_t *src = v->buf.data;
+	int srclen = v->buf.used;
+
+	if (!srclen)
+		return 0;
+	while (srclen) {
+		uint8_t *data;
+		int datalen;
+		int ret = av_parser_parse(v->parser, v->context, &data, &datalen, src, srclen, 0, 0);
+		if (datalen) {
+			ret = avcodec_decode_video(v->context, v->frame, &(v->completed), data, datalen);
+			if(ret < 0) {
+				ast_log(LOG_NOTICE, "Errore nella decodifica\n");
+				return 0;
+			}
+			src += ret;
+			srclen -= ret;
+		}
+		// ast_log(LOG_WARNING, "in %d ret %d/%d outlen %d complete %d\n", v->buf.used, srclen, ret, datalen, v->completed);
+	}
+	return 1;
+}
+
+/*
+ * It displays the decoded video frame using the SDL library.
+ * - Set the video mode to use the resolution specified by the codec context
+ * - Create a YUV Overlay to copy into it the decoded frame
+ * - After the decoded frame is copied into the overlay, we display it
+ * TODO: change the call img_convert(): it is deprecated.
+ * 'out' is set to display the outgoing stream
+ */
+static void show_frame(struct video_desc *env, int out)
+{
+	AVPicture pict;
+	SDL_Rect rect;
+	AVCodecContext *c = env->in.context;	/* shorthand */
+	int w = env->out.w ? env->out.w : c->width;	/* pick geometry between webcam and default */
+	int h = env->out.h ? env->out.h : c->height; /* pick geometry between webcam and default */
+	SDL_Overlay *bmp;
+
+	if (!env->initialized)
+		return;
+	if(env->screen == NULL) {
+		env->screen = SDL_SetVideoMode(2*w, h, 0, 0);
+		if(!env->screen) {
+			ast_log(LOG_ERROR, "SDL: could not set video mode - exiting\n");
+			return;
+		}
+		SDL_WM_SetCaption("Asterisk console Video Output", NULL);
+	}
+
+	if(!env->bmp[0])
+		env->bmp[0] = SDL_CreateYUVOverlay(w, h, SDL_YV12_OVERLAY, env->screen);
+	if(!env->bmp[1])
+		env->bmp[1] = SDL_CreateYUVOverlay(w, h, SDL_YV12_OVERLAY, env->screen);
+
+	bmp = env->bmp[out];
+	SDL_LockYUVOverlay(bmp);
+	pict.data[0] = bmp->pixels[0];
+	pict.data[1] = bmp->pixels[2];
+	pict.data[2] = bmp->pixels[1];
+	pict.linesize[0] = bmp->pitches[0];
+	pict.linesize[1] = bmp->pitches[2];
+	pict.linesize[2] = bmp->pitches[1];
+
+	if (out) {	/* raw stream from camera */
+		int l4 = w*h/4;	/* U or v frame */
+		bcopy(env->out.buf.data, bmp->pixels[0], 4*l4);
+		bcopy(env->out.buf.data + 4*l4, bmp->pixels[2], l4);
+		bcopy(env->out.buf.data + 5*l4, bmp->pixels[1], l4);
+	} else {	/* decode */
+#if 1 /* XXX img_convert is deprecated */
+		img_convert(&pict, PIX_FMT_YUV420P, (AVPicture *)env->in.frame, c->pix_fmt, c->width, c->height);
+#else /* XXX replacement */
+		struct SwsContext *convert_ctx;
+		AVPicture *pict_in = (AVPicture *)env->in.frame;
+
+		convert_ctx = sws_getContext(c->width, c->height, c->pix_fmt /* input format */,
+			w, h, PIX_FMT_YUV420P /* output format ? */,
+			SWS_BICUBIC, NULL, NULL, NULL);
+		if (convert_ctx == NULL) {
+			ast_log(LOG_ERROR, "FFMPEG::convert_cmodel : swscale context initialization failed");
+			return;
+		}
+
+		sws_scale(convert_ctx,
+			pict_in->data, pict_in->linesize,
+			w, h, /* src slice */
+			pict.data, pict.linesize);
+
+		sws_freeContext(convert_ctx);
+
+#endif /* XXX replacement */
+	}
+	SDL_UnlockYUVOverlay(bmp);
+	rect.x = w*out;
+	rect.y = 0;
+	rect.w = w;
+	rect.h = h;
+	SDL_DisplayYUVOverlay(bmp, &rect);
+}
+
+/*
+ * This function is called (by asterisk) for each video packet that needs to be processed.
+ * We need to reconstruct the entire video frame before we can decode it.
+ * After a video packet is received we have to:
+ * - extract the bitstream with pre_process_data()
+ * - append the bitstream to a buffer
+ * - if the fragment is the last (RTP Marker) we decode it with decode_video()
+ * - after the decoding is completed we display the decoded frame with show_frame()
+ */
+static int console_write_video(struct ast_channel *chan, struct ast_frame *f)
+{
+	uint8_t *data;
+	int len;
+	struct video_desc *env = get_video_desc(chan);
+	struct timeval now = ast_tvnow();
+	int i;
+
+	if(!env->initialized)
+		ffmpeg_init(env, f->subclass);
+	if(!env->initialized)
+		return -1;	/* error */
+
+	if (0) {	/* echo frames back to the sender */
+		struct ast_frame *f1, **fp;
+		f1 = ast_frdup(f);
+		for (fp = &env->echo; (*fp) != NULL ; fp = &AST_LIST_NEXT((*fp), frame_list) )
+			;
+		*fp = f1;
+	}
+
+	i = ast_tvdiff_ms(now, env->in.ts);
+	if (i > 1000) {
+		//ast_log(LOG_WARNING, "received %d video frames in %d ms\n", env->in.received, i);
+		env->in.received = 0;
+		env->in.ts = now;
+	}
+	env->in.received++;
+#if defined(DROP_PACKETS) && DROP_PACKETS > 0
+	/*
+	* Fragment of code to simulate lost/delayed packets
+	*/
+	if((random() % 10000) <= 100*DROP_PACKETS) {
+		ast_log(LOG_NOTICE, "Packet lost [%d]\n", f->seqno);
+		return 0;
+	}
+#endif
+	/*
+	 * If there is the discard flag, every packet must be discarded.
+	 * When a marked packet arrive we can restart the decoding.
+	 * XXX note that the RTP marker flag is sent as the LSB of the
+	 * subclass. This is slightly annoying as it goes to overwrite
+	 * the payload type entry.
+	 */
+	if(env->in.discard) {
+		if(f->subclass & 0x01) {
+			free(env->in.buf.data);
+			env->in.buf.data = NULL;
+			env->in.buf.used = 0;
+			env->in.lastrxframe = f->seqno;
+			env->in.discard = 0;
+		}
+		return 0;
+	}
+
+	/*
+	* Only ordered fragment will be accepted.
+	* We can handle the circular seqno with the following operation
+	* (seqno is a 16 bits number)
+	*/
+	if((env->in.lastrxframe+1)%0x10000 != f->seqno && env->in.lastrxframe != -1) {
+		env->in.discard = 1;
+		return 0;
+	}
+
+	len = f->datalen;
+	data = pre_process_data(f->data, &len);
+
+	/* allocate buffer as we see fit. ffmpeg wants an extra FF_INPUT_BUFFER_PADDING_SIZE
+	 * and a 0 as a buffer terminator to prevent trouble.
+	 */
+	if(env->in.buf.data == NULL) {
+		env->in.buf.size = len + FF_INPUT_BUFFER_PADDING_SIZE;
+		env->in.buf.used = 0;
+		env->in.buf.data = malloc(len);
+	} else if (env->in.buf.used + len + FF_INPUT_BUFFER_PADDING_SIZE> env->in.buf.size) {
+		env->in.buf.size = env->in.buf.used + len + FF_INPUT_BUFFER_PADDING_SIZE;
+		env->in.buf.data = realloc(env->in.buf.data, env->in.buf.size);
+	}
+	memcpy(env->in.buf.data+env->in.buf.used, data, len);
+	env->in.buf.used += len;
+	env->in.buf.data[env->in.buf.used] = '\0';
+	if(f->subclass & 0x01) // RTP Marker
+		if(decode_video(&env->in)) {
+			show_frame(env, 0);
+			env->in.completed = 0;
+			env->in.buf.used = 0;
+		}
+	env->in.lastrxframe = f->seqno;
+
+	return 0;
+}
+
+ 
+/*
+ * Find the next PSC (Picture Start Code) of the frame
+ */
+static uint8_t *get_psc(uint8_t *begin, uint8_t *end, int packet_size)
+{
+	int i;
+	uint8_t *ret=NULL;
+	uint8_t *p;
+	if (begin==end) return NULL;
+	for(i=1,p=begin+1;p<end && i<packet_size;++i,++p){
+		if (p[-1]==0 && p[0]==0){
+			ret=p-1;
+		}
+		p++;/* to skip possible 0 after the PSC that would make a double detection */
+	}
+	return ret;
+}
+ 
+#ifndef MIN
+#define MIN(a, b) (a) < (b) ? (a) : (b)
+#endif
+
+/*
+ * Create RTP/H.263 fragmets to avoid IP fragmentation
+ */
+static struct ast_frame *create_video_segment(struct video_out_desc *out, uint8_t *start, uint8_t *end, int last_packet)
+{
+	int len = end-start;
+	int size = MIN(len, out->mtu);
+	uint8_t *data;
+	struct ast_frame *f, *fp = NULL, *ftop = NULL;
+	int header = 0; // the first frag contains the PSC
+
+	do {
+		f = ast_malloc(sizeof(*f));
+		if(fp)
+			fp->frame_list.next = f;
+		else
+			ftop = f;
+		fp = f;
+
+		data = ast_malloc(size+header);
+		memcpy(data+header, start, size);
+
+		if(header == 2)
+			data[0] = data[1] = 0; // P == 0
+		else {
+			data[0] |= 0x04; // P == 1
+			header = 2;
+		}
+
+		f->has_timing_info = 1;
+		f->ts = ast_tvdiff_ms(ast_tvnow(), out->ts);
+		f->frametype = AST_FRAME_VIDEO;
+		f->subclass = CONSOLE_FORMAT_VIDEO;
+		f->samples = 0;
+		f->offset = 0;
+		f->src = "Console";
+		// This flags teels asterisk that the data and
+		// the header are dinamically allocated
+		f->mallocd = AST_MALLOCD_DATA | AST_MALLOCD_HDR;
+		f->delivery.tv_sec = 0;
+		f->delivery.tv_usec = 0;
+		f->seqno = ++(out->lasttxframe);
+		f->datalen = size+header;
+		f->data = data;
+		f->frame_list.next = NULL;
+
+		start += size;
+		len = end-start;
+		size = MIN(len, out->mtu);
+	} while(len > 0);
+
+	f->subclass |= last_packet; // RTP Marker
+
+	return ftop;
+}
+
+/*
+ * Search for PSCs and create ast_frame list of RTP packets
+ */
+static struct ast_frame *split_frame(struct video_out_desc *out, int len)
+{
+	uint8_t *lastpsc = out->decbuf.data;
+	uint8_t *end = out->decbuf.data+len;
+	uint8_t *psc, *pos;
+	struct ast_frame *f, *fp = NULL, *ftop = NULL;
+
+	while(1) {
+		psc = get_psc(lastpsc+2, end, out->mtu);
+
+		pos = (psc == NULL) ? end : psc;
+
+		f = create_video_segment(out, lastpsc, pos, 0);
+		lastpsc = psc;
+
+		if(fp)
+			fp->frame_list.next = f;
+		else
+			ftop = f;
+
+		if(psc == NULL)
+			break;
+
+		fp = f;
+	}
+
+	return ftop;
+}
+
+static struct ast_frame *get_video_frames(struct video_desc *env)
+{
+	int webcam_buflen;
+	struct timeval tvnow;
+	int period, fdiff;
+
+	if (!webcam_read(&env->out))
+		return NULL;
+
+	// XXX - questa porzione di codice limita la generazione dei
+	// frame al framerate specificato nel file di configurazione
+	// I frame della webcam che non rientrano nel framerate
+	// vengono scartati.
+	tvnow = ast_tvnow();
+	period = 1000/env->out.fps;
+	fdiff = ast_tvdiff_ms(tvnow, env->out.msts);
+	if (fdiff < period)
+		return NULL;
+
+	env->out.msts.tv_sec = tvnow.tv_sec;
+	env->out.msts.tv_usec = tvnow.tv_usec;
+	/* get frame and put them in the queue */
+	webcam_buflen = webcam_encode(env);
+	return split_frame(&(env->out), webcam_buflen);
+}
+
+static void console_video_start(struct video_desc *env,
+	struct ast_channel *owner)
+{
+	avcodec_init();
+	/*
+	 * Register all codecs supported by the ffmpeg library.
+	 * Doing it once is enough.
+	 */
+	avcodec_register_all();
+
+	webcam_open(env);
+	if (env->out.buf.data && owner) {  /* drive webcam */
+		owner->fds[1] = env->out.fd;
+		video_out_init(&env->out, CONSOLE_FORMAT_VIDEO);
+	}
+	ast_log(LOG_VERBOSE, "console_video_start owner %p", owner);
+	env->out.ts = ast_tvnow(); 
+}
+#endif	/* video support */

Propchange: team/rizzo/video_v2/channels/console_video.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/rizzo/video_v2/channels/console_video.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/rizzo/video_v2/channels/console_video.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/rizzo/video_v2/configure
URL: http://svn.digium.com/view/asterisk/team/rizzo/video_v2/configure?view=diff&rev=82365&r1=82364&r2=82365
==============================================================================
--- team/rizzo/video_v2/configure (original)
+++ team/rizzo/video_v2/configure Thu Sep 13 19:16:33 2007
@@ -1,10 +1,9 @@
 #! /bin/sh
-# From configure.ac Revision: 79972 .
+# From configure.ac Revision: 81873 .
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61.
+# Generated by GNU Autoconf 2.59.
 #
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# Copyright (C) 2003 Free Software Foundation, Inc.
 # This configure script is free software; the Free Software Foundation
 # gives unlimited permission to copy, distribute and modify it.
 #
@@ -13,26 +12,73 @@
 ## M4sh Initialization.  ##
 ## --------------------- ##
 
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
+# Be Bourne compatible
 if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
   emulate sh
   NULLCMD=:
   # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in
-  *posix*) set -o posix ;;
-esac
-
-fi
-
-
-
-
-# PATH needs CR
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
 # Avoid depending upon Character Ranges.
 as_cr_letters='abcdefghijklmnopqrstuvwxyz'
 as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
@@ -53,466 +99,124 @@
   rm -f conf$$.sh
 fi
 
-# Support unset when possible.
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
-  as_unset=unset
-else
-  as_unset=false
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-as_nl='
-'
-IFS=" ""	$as_nl"
-
-# Find who we are.  Look in the path if we contain no directory separator.
-case $0 in
-  *[\\/]* ) as_myself=$0 ;;
-  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
   test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
 done
-IFS=$as_save_IFS
-
-     ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
-  as_myself=$0
-fi
-if test ! -f "$as_myself"; then
-  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
-  { (exit 1); exit 1; }
-fi
-
-# Work around bugs in pre-3.0 UWIN ksh.
-for as_var in ENV MAIL MAILPATH
-do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-for as_var in \
-  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
-  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
-  LC_TELEPHONE LC_TIME
-do
-  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
-    eval $as_var=C; export $as_var
-  else
-    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
   fi
-done
-
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
-  as_expr=expr
-else
-  as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
-  as_basename=basename
-else
-  as_basename=false
-fi
-
-
-# Name of the executable.
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
-	 X"$0" : 'X\(//\)$' \| \
-	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\/\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\/\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-
-# CDPATH.
-$as_unset CDPATH
-
-
-if test "x$CONFIG_SHELL" = x; then
-  if (eval ":") 2>/dev/null; then
-  as_have_required=yes
-else
-  as_have_required=no
-fi
-
-  if test $as_have_required = yes && 	 (eval ":
-(as_func_return () {
-  (exit \$1)
-}
-as_func_success () {
-  as_func_return 0
-}
-as_func_failure () {
-  as_func_return 1
-}
-as_func_ret_success () {
-  return 0
-}
-as_func_ret_failure () {
-  return 1
-}
-
-exitcode=0
-if as_func_success; then
-  :
-else
-  exitcode=1
-  echo as_func_success failed.
-fi
-
-if as_func_failure; then
-  exitcode=1
-  echo as_func_failure succeeded.
-fi
-
-if as_func_ret_success; then
-  :
-else
-  exitcode=1
-  echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
-  exitcode=1
-  echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
-  :
-else
-  exitcode=1
-  echo positional parameters were not saved.
-fi
-
-test \$exitcode = 0) || { (exit 1); exit 1; }
-
-(
-  as_lineno_1=\$LINENO
-  as_lineno_2=\$LINENO
-  test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
-  test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
-") 2> /dev/null; then
-  :
-else
-  as_candidate_shells=
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
     as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  case $as_dir in
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
 	 /*)
-	   for as_base in sh bash ksh sh5; do
-	     as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
-	   done;;

[... 47155 lines stripped ...]



More information about the asterisk-commits mailing list