[Sumover-dev] [svn commit] r3795 - in vic/trunk: . codec codec/p64 tcl

sumover-dev at cs.ucl.ac.uk sumover-dev at cs.ucl.ac.uk
Tue Aug 22 02:06:08 BST 2006


Author: rhys
Date: Tue Aug 22 02:04:58 2006
New Revision: 3795

Added:
   vic/trunk/codec/decoder-h261as.cpp
   vic/trunk/codec/encoder-h261as.cpp
   vic/trunk/codec/p64/p64as.cpp
   vic/trunk/codec/p64/p64as.h
Modified:
   vic/trunk/configure
   vic/trunk/configure.in
   vic/trunk/rtp/rtp.h
   vic/trunk/rtp/session.cpp
   vic/trunk/tcl/cf-main.tcl

Log:
Added support for h261as decoding. Enable using ./configure 
--enable-h261as



Added: vic/trunk/codec/decoder-h261as.cpp
==============================================================================
--- (empty file)
+++ vic/trunk/codec/decoder-h261as.cpp	Tue Aug 22 02:04:58 2006
@@ -0,0 +1,223 @@
+/*-
+ * Copyright (c) 1993-1994 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the University of
+ *      California, Berkeley and the Network Research Group at
+ *      Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+static const char rcsid[] =
+    "@(#) $Header$ (LBL)";
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "inet.h"
+#include "rtp.h"
+#include "decoder.h"
+#include "renderer.h"
+#include "p64/p64as.h"
+
+class H261ASDecoder : public Decoder {
+    public:
+	H261ASDecoder();
+	virtual ~H261ASDecoder();
+	virtual void info(char* wrk) const;
+	virtual void recv(pktbuf*);
+	int colorhist(u_int* hist) const;
+	virtual void stats(char* wrk);
+    protected:
+	void decode(const u_char* vh, const u_char* bp, int cc);
+	virtual void redraw();
+	P64ASDecoder* codec_;
+};
+
+static class H261ASDecoderMatcher : public Matcher {
+    public:
+	H261ASDecoderMatcher() : Matcher("decoder") {}
+	TclObject* match(const char* id) {
+		if (strcasecmp(id, "h.261as") == 0 ||
+		    strcasecmp(id, "h261as") == 0)
+			return (new H261ASDecoder());
+		return (0);
+	}
+} dm_h261as;
+
+#define STAT_BAD_PSC	0
+#define STAT_BAD_GOB	1
+#define STAT_BAD_SYNTAX	2
+#define STAT_BAD_FMT	3
+#define STAT_FMT_CHANGE 4	/* # times fmt changed */
+#define STAT_BAD_HEADER 5
+
+
+H261ASDecoder::H261ASDecoder() : Decoder(4), codec_(0)
+{
+	stat_[STAT_BAD_PSC].name = "H261AS-Bad-PSC";
+	stat_[STAT_BAD_GOB].name = "H261AS-Bad-GOB";
+	stat_[STAT_BAD_SYNTAX].name = "H261AS-Bad-Syntax";
+	stat_[STAT_BAD_FMT].name = "H261AS-Bad-fmt";
+	stat_[STAT_FMT_CHANGE].name = "H261AS-Fmt-change";
+	stat_[STAT_BAD_HEADER].name = "H261AS-Bad-Header";
+	nstat_ = 6;
+
+	decimation_ = 411;
+	/*
+	 * Assume CIF.  Picture header will trigger a resize if
+	 * we encounter QCIF instead.
+	 */
+	inw_ = 352;
+	inh_ = 288;
+
+	/*XXX*/
+	resize(inw_, inh_);
+}
+
+H261ASDecoder::~H261ASDecoder()
+{
+	delete codec_;
+}
+
+void H261ASDecoder::info(char* wrk) const
+{
+	if (codec_ == 0)
+		*wrk = 0;
+	else
+		sprintf(wrk, "[q=%d]", codec_->gobquant());
+}
+
+void H261ASDecoder::stats(char* wrk)
+{
+	/* pull stats out of vic indepdendent P64Decoder */
+	setstat(STAT_BAD_PSC, codec_->bad_psc());
+	setstat(STAT_BAD_GOB, codec_->bad_GOBno());
+	setstat(STAT_BAD_SYNTAX, codec_->bad_bits());
+	setstat(STAT_BAD_FMT, codec_->bad_fmt());
+	Decoder::stats(wrk);
+}
+
+int H261ASDecoder::colorhist(u_int* hist) const
+{
+	const u_char* frm = codec_->frame();
+	int w = inw_;
+	int h = inh_;
+	int s = w * h;
+	colorhist_411_556(hist, frm, frm + s, frm + s + (s >> 2), w, h);
+	return (1);
+}
+
+
+#ifdef CR_STATS
+u_char shadow[640*480/64];
+
+void dumpShadow(u_int32_t ts, u_char* p, int nblk)
+{
+	ts &= 0x7fffffff;
+	static u_int32_t lastTS = 0;
+	if (ts != lastTS) {
+		printf("ts %u\n", ts);
+		lastTS = ts;
+	}
+	int left = -1;
+	for (int i = 0; i < nblk; ++i) {
+		if (shadow[i] != p[i]) {
+			if (left < 0) {
+				left = i;
+			}
+		} else {
+			if (left > 0)
+				printf("b %d %d\n", left, i - 1);
+			left = -1;
+		}
+	}
+	if (left > 0)
+		printf("b %d %d\n", left, i - 1);
+}
+#endif
+
+void H261ASDecoder::recv(pktbuf* pb)
+{	
+	rtphdr* rh = (rtphdr*)pb->dp;
+	u_int8_t* vh = (u_int8_t*)(rh + 1);
+	if (codec_ == 0) {
+		codec_ = new P64ASDecoder();
+		codec_->marks(rvts_);
+	}
+#ifdef CR_STATS
+	memcpy(shadow, rvts_, nblk_);
+#endif
+	/*
+	 * h261as header is as follows:
+         * ebit    3
+         * quant   5
+         * width  12
+         * height 12 
+         */
+	u_int v = ntohl(*(u_int32_t*)vh);
+	int ebit = v >> 29;
+	int quant = (v >> 24) & 0x1f;
+	int pwidth = (v >> 12) & 0x7ff;
+	int pheight = v & 0x7ff;
+
+	int cc = pb->len - (sizeof(*rh) + 4);
+
+	pwidth = (pwidth + 1) * 16;
+	pheight = (pheight + 1) * 16;
+
+	/*
+	 * If the stream changes format, issue a resize.
+	 */
+	if (pwidth != codec_->width() ||
+	    pheight != codec_->height()) {
+	        codec_->set_size(pwidth, pheight);
+		resize(codec_->width(), codec_->height());
+		codec_->marks(rvts_);
+		count(STAT_FMT_CHANGE);
+	}
+
+	codec_->mark(now_);
+	(void)codec_->decode(vh + 4, cc, ebit, quant);
+
+#ifdef CR_STATS
+	dumpShadow(ntohl(rh->rh_ts), rvts_, nblk_);
+#endif
+	/*XXX*/
+	if (ntohs(rh->rh_flags) & RTP_M) {
+		codec_->sync();
+		ndblk_ = codec_->ndblk();
+		render_frame(codec_->frame());
+		codec_->resetndblk();
+	}
+	pb->release();
+}
+
+void H261ASDecoder::redraw()
+{
+	if (codec_ != 0)
+		Decoder::redraw(codec_->frame());
+}

Added: vic/trunk/codec/encoder-h261as.cpp
==============================================================================
--- (empty file)
+++ vic/trunk/codec/encoder-h261as.cpp	Tue Aug 22 02:04:58 2006
@@ -0,0 +1,877 @@
+/*
+ * Copyright (c) 1994-1995 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the University of
+ *      California, Berkeley and the Network Research Group at
+ *      Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+static const char rcsid[] =
+    "@(#) $Header$ (LBL)";
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "inet.h"
+#include "net.h"
+#include "rtp.h"
+#include "dct.h"
+#include "p64/p64-huff.h"
+#include "bsd-endian.h"
+#include "vic_tcl.h"
+#include "crdef.h"
+#include "transmitter.h"
+#include "pktbuf-rtp.h"
+#include "module.h"
+
+#define HDRSIZE (sizeof(rtphdr) + 4)
+#define	CIF_WIDTH	352
+#define	CIF_HEIGHT	288
+#define	QCIF_WIDTH	176
+#define	QCIF_HEIGHT	144
+#define	BMB		6	/* # blocks in a MB */
+#define MBPERGOB	33	/* # of Macroblocks per GOB */
+
+#ifdef INT_64
+#define NBIT 64
+#define BB_INT INT_64
+#else
+#define NBIT 32
+#define BB_INT u_int
+#endif
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+#if NBIT == 64
+#define STORE_BITS(bb, bc) \
+	bc[0] = bb >> 56; \
+	bc[1] = bb >> 48; \
+	bc[2] = bb >> 40; \
+	bc[3] = bb >> 32; \
+	bc[4] = bb >> 24; \
+	bc[5] = bb >> 16; \
+	bc[6] = bb >> 8; \
+	bc[7] = bb;
+#define LOAD_BITS(bc) \
+	((BB_INT)bc[0] << 56 | \
+	 (BB_INT)bc[1] << 48 | \
+	 (BB_INT)bc[2] << 40 | \
+	 (BB_INT)bc[3] << 32 | \
+	 (BB_INT)bc[4] << 24 | \
+	 (BB_INT)bc[5] << 16 | \
+	 (BB_INT)bc[6] << 8 | \
+	 (BB_INT)bc[7])
+#else
+#define STORE_BITS(bb, bc) \
+	bc[0] = bb >> 24; \
+	bc[1] = bb >> 16; \
+	bc[2] = bb >> 8; \
+	bc[3] = bb;
+#define LOAD_BITS(bc) (ntohl(*(BB_INT*)(bc)))
+#endif
+#else
+#define STORE_BITS(bb, bc) *(BB_INT*)bc = (bb);
+#define LOAD_BITS(bc) (*(BB_INT*)(bc))
+#endif
+
+#define PUT_BITS(bits, n, nbb, bb, bc) \
+{ \
+	nbb += (n); \
+	if (nbb > NBIT)  { \
+		u_int extra = (nbb) - NBIT; \
+		bb |= (BB_INT)(bits) >> extra; \
+		STORE_BITS(bb, bc) \
+		bc += sizeof(BB_INT); \
+		bb = (BB_INT)(bits) << (NBIT - extra); \
+		nbb = extra; \
+	} else \
+		bb |= (BB_INT)(bits) << (NBIT - (nbb)); \
+}
+
+
+class H261ASEncoder : public TransmitterModule {
+    public:
+	void setq(int q);
+    protected:
+	H261ASEncoder(int ft);
+	~H261ASEncoder();
+	int encode(const VideoFrame*, const u_int8_t *crvec);
+	int command(int argc, const char*const* argv);
+	void encode_blk(const short* blk, const char* lm);
+	int flush(pktbuf* pb, int nbit, pktbuf* npb);
+	char* make_level_map(int q, u_int fthresh);
+	void setquantizers(int lq, int mq, int hq);
+
+	virtual void size(int w, int h) = 0;
+	virtual void encode_mb(u_int mba, const u_char* frm,
+		       u_int loff, u_int coff, int how) = 0;
+
+	/* bit buffer */
+	BB_INT bb_;
+	u_int nbb_;
+
+	u_char* bs_;
+	u_char* bc_;
+	int sbit_;
+
+	u_char lq_;		/* low quality quantizer */
+	u_char mq_;		/* medium quality quantizer */
+	u_char hq_;		/* high quality quantizer */
+	u_char mquant_;		/* the last quantizer we sent to other side */
+	int quant_required_;	/* 1 if not quant'd in dct */
+	u_int ngob_;
+	u_int mba_;
+
+	u_int cif_;		/* 1 for CIF, 0 for QCIF */
+	u_int bstride_;
+	u_int lstride_;
+	u_int cstride_;
+
+	u_int loffsize_;	/* amount of 1 luma block */
+	u_int coffsize_;	/* amount of 1 chroma block */
+	u_int bloffsize_;	/* amount of 1 block advance */
+
+	const char* llm_[32];	/* luma dct val -> level maps */
+	const char* clm_[32];	/* chroma dct val -> level maps */
+
+	float lqt_[64];		/* low quality quantizer */
+	float mqt_[64];		/* medium quality quantizer */
+	float hqt_[64];		/* high quality quantizer */
+
+	u_int coff_[12];	/* where to find U given gob# */
+	u_int loff_[12];	/* where to find Y given gob# */
+	u_int blkno_[12];	/* for CR */
+};
+
+class H261ASDCTEncoder : public H261ASEncoder {
+    public:
+	H261ASDCTEncoder();
+	int consume(const VideoFrame*);
+	void size(int w, int h);
+    protected:
+	void encode_mb(u_int mba, const u_char* frm,
+		       u_int loff, u_int coff, int how);
+};
+
+class H261ASPixelEncoder : public H261ASEncoder {
+    public:
+	H261ASPixelEncoder();
+	int consume(const VideoFrame*);
+	void size(int w, int h);
+    protected:
+	void encode_mb(u_int mba, const u_char* frm,
+		       u_int loff, u_int coff, int how);
+};
+
+static class H261ASEncoderMatcher : public Matcher {
+    public:
+	H261ASEncoderMatcher() : Matcher("module") {}
+	TclObject* match(const char* fmt) {
+		if (strcasecmp(fmt, "h261as/pixel") == 0)
+			return (new H261ASPixelEncoder);
+		if (strcasecmp(fmt, "h261as/dct") == 0)
+			return (new H261ASDCTEncoder);
+		/* XXX for now, this is compatible with ui-ctrlmenu.tcl */
+		if (strcasecmp(fmt, "h261as") == 0)
+			return (new H261ASPixelEncoder);
+		return (0);
+	}
+} encoder_matcher_h261as;
+
+
+H261ASEncoder::H261ASEncoder(int ft) : TransmitterModule(ft),
+	bs_(0), bc_(0), ngob_(12)
+{
+	for (int q = 0; q < 32; ++q) {
+		llm_[q] = 0;
+		clm_[q] = 0;
+	}
+}
+
+H261ASEncoder::~H261ASEncoder()
+{
+	for (int q = 0; q < 32; ++q) {
+		if (llm_[q] != 0)
+			delete llm_[q]; //SV-XXX: Debian
+		if (clm_[q] != 0)
+			delete clm_[q]; //SV-XXX: Debian
+	}
+}
+
+H261ASPixelEncoder::H261ASPixelEncoder() : H261ASEncoder(FT_YUV_CIF)
+{
+	quant_required_ = 0;
+	setq(10);
+}
+
+H261ASDCTEncoder::H261ASDCTEncoder() : H261ASEncoder(FT_DCT)
+{
+	quant_required_ = 1;
+	setq(10);
+}
+
+/*
+ * Set up the forward DCT quantization table for
+ * INTRA mode operation.
+ */
+void
+H261ASEncoder::setquantizers(int lq, int mq, int hq)
+{
+	int qt[64];
+	if (lq > 31)
+		lq = 31;
+	if (lq <= 0)
+		lq = 1;
+	lq_ = lq;
+
+	if (mq > 31)
+		mq = 31;
+	if (mq <= 0)
+		mq = 1;
+	mq_ = mq;
+
+	if (hq > 31)
+		hq = 31;
+	if (hq <= 0)
+		hq = 1;
+	hq_ = hq;
+
+	/*
+	 * quant_required_ indicates quantization is not folded
+	 * into fdct [because fdct is not performed]
+	 */
+	if (quant_required_ == 0) {
+		/*
+		 * Set the DC quantizer to 1, since we want to do this
+		 * coefficient differently (i.e., the DC is rounded while
+		 * the AC terms are truncated).
+		 */
+		qt[0] = 1;
+		int i;
+		for (i = 1; i < 64; ++i)
+			qt[i] = lq_ << 1;
+		fdct_fold_q(qt, lqt_);
+
+		qt[0] = 1;
+		for (i = 1; i < 64; ++i)
+			qt[i] = mq_ << 1;
+		fdct_fold_q(qt, mqt_);
+
+		qt[0] = 1;
+		for (i = 1; i < 64; ++i)
+			qt[i] = hq_ << 1;
+		fdct_fold_q(qt, hqt_);
+	}
+}
+
+void
+H261ASEncoder::setq(int q)
+{
+	setquantizers(q, q / 2, 1);
+}
+
+void
+H261ASPixelEncoder::size(int w, int h)
+{
+	Module::size(w, h);
+	if (w == CIF_WIDTH && h == CIF_HEIGHT) {
+		/* CIF */
+		cif_ = 1;
+		ngob_ = 12;
+		bstride_ = 11;
+		lstride_ = 16 * CIF_WIDTH - CIF_WIDTH / 2;
+		cstride_ = 8 * 176 - 176 / 2;
+		loffsize_ = 16;
+		coffsize_ = 8;
+		bloffsize_ = 1;
+	} else if (w == QCIF_WIDTH && h == QCIF_HEIGHT) {
+		/* QCIF */
+		cif_ = 0;
+		ngob_ = 6; /* not really number of GOBs, just loop limit */
+		bstride_ = 0;
+		lstride_ = 16 * QCIF_WIDTH - QCIF_WIDTH;
+		cstride_ = 8 * 88 - 88;
+		loffsize_ = 16;
+		coffsize_ = 8;
+		bloffsize_ = 1;
+	} else {
+		/*XXX*/
+		fprintf(stderr, "H261ASPixelEncoder: H.261 bad geometry: %dx%d\n",
+			w, h);
+		exit(1);
+	}
+	u_int loff = 0;
+	u_int coff = 0;
+	u_int blkno = 0;
+	for (u_int gob = 0; gob < ngob_; gob += 2) {
+		loff_[gob] = loff;
+		coff_[gob] = coff;
+		blkno_[gob] = blkno;
+		/* width of a GOB (these aren't ref'd in QCIF case) */
+		loff_[gob + 1] = loff + 11 * 16;
+		coff_[gob + 1] = coff + 11 * 8;
+		blkno_[gob + 1] = blkno + 11;
+
+		/* advance to next GOB row */
+		loff += (16 * 16 * MBPERGOB) << cif_;
+		coff += (8 * 8 * MBPERGOB) << cif_;
+		blkno += MBPERGOB << cif_;
+	}
+}
+
+void
+H261ASDCTEncoder::size(int w, int h)
+{
+
+	Module::size(w, h);
+	if (w == CIF_WIDTH && h == CIF_HEIGHT) {
+		/* CIF */
+		cif_ = 1;
+		ngob_ = 12;
+		bstride_ = 11;
+		lstride_ = - (11 * (64*BMB)) + 2 * 11 * 64 * BMB;
+		cstride_ = - (11 * (64*BMB)) + 2 * 11 * 64 * BMB;
+		loffsize_ = 64 * BMB;
+		coffsize_ = 64 * BMB;
+		bloffsize_ = 1;
+	} else if (w == QCIF_WIDTH && h == QCIF_HEIGHT) {
+		/* QCIF */
+		cif_ = 0;
+		ngob_ = 6; /* not really number of GOBs, just loop limit */
+		bstride_ = 0;
+		lstride_ = 0;
+		cstride_ = 0;
+		loffsize_ = 64 * BMB;
+		coffsize_ = 64 * BMB;
+		bloffsize_ = 1;
+	} else {
+		/*XXX*/
+		fprintf(stderr, "H261ASDCTEncoder: H.261 bad geometry: %dx%d\n",
+			w, h);
+		exit(1);
+	}
+
+	u_int gob;
+	for (gob = 0; gob < ngob_; gob += 2) {
+
+		if (gob != 0) {
+			loff_[gob] = loff_[gob-2] +
+				(MBPERGOB << cif_) * BMB * 64;
+			coff_[gob] = coff_[gob-2] +
+				(MBPERGOB << cif_) * BMB * 64;
+			blkno_[gob] = blkno_[gob-2] +
+				(MBPERGOB << cif_);
+		} else {
+			loff_[0] = 0;
+			coff_[0] = loff_[0] + 4 * 64;	// 4 Y's
+			blkno_[0] = 0;
+		}
+
+		loff_[gob + 1] = loff_[gob] + 11 * BMB * 64;
+		coff_[gob + 1] = coff_[gob] + 11 * BMB * 64;
+		blkno_[gob + 1] = blkno_[gob] + 11;
+	}
+}
+
+
+int
+H261ASEncoder::command(int argc, const char*const* argv)
+{
+	if (argc == 3 && strcmp(argv[1], "q") == 0) {
+		setq(atoi(argv[2]));
+		return (TCL_OK);
+	}
+	return (TransmitterModule::command(argc, argv));
+}
+
+/*
+ * Make a map to go from a 12 bit dct value to an 8 bit quantized
+ * 'level' number.  The 'map' includes both the quantizer (for the
+ * dct encoder) and the perceptual filter 'threshhold' (for both
+ * the pixel & dct encoders).  The first 4k of the map is for the
+ * unfiltered coeff (the first 20 in zigzag order; roughly the
+ * upper left quadrant) and the next 4k of the map are for the
+ * filtered coef.
+ */
+char*
+H261ASEncoder::make_level_map(int q, u_int fthresh)
+{
+	/* make the luminance map */
+	char* lm = new char[0x2000];
+	char* flm = lm + 0x1000;
+	int i;
+	lm[0] = 0;
+	flm[0] = 0;
+	q = quant_required_? q << 1 : 0;
+	for (i = 1; i < 0x800; ++i) {
+		int l = i;
+		if (q)
+			l /= q;
+		lm[i] = l;
+		lm[-i & 0xfff] = -l;
+
+		if ((u_int)l <= fthresh)
+			l = 0;
+		flm[i] = l;
+		flm[-i & 0xfff] = -l;
+	}
+	return (lm);
+}
+
+/*
+ * encode_blk:
+ *	encode a block of DCT coef's
+ */
+void
+H261ASEncoder::encode_blk(const short* blk, const char* lm)
+{
+	BB_INT bb = bb_;
+	u_int nbb = nbb_;
+	u_char* bc = bc_;
+
+	/*
+	 * Quantize DC.  Round instead of truncate.
+	 */
+	int dc = (blk[0] + 4) >> 3;
+
+	if (dc <= 0)
+		/* shouldn't happen with CCIR 601 black (level 16) */
+		dc = 1;
+	else if (dc > 254)
+		dc = 254;
+	else if (dc == 128)
+		/* per Table 6/H.261 */
+		dc = 255;
+	/* Code DC */
+	PUT_BITS(dc, 8, nbb, bb, bc);
+	int run = 0;
+	const u_char* colzag = &COLZAG[0];
+	for (int zag; (zag = *++colzag) != 0; ) {
+		if (colzag == &COLZAG[20])
+			lm += 0x1000;
+		int level = lm[((const u_short*)blk)[zag] & 0xfff];
+		if (level != 0) {
+			int val, nb;
+			huffent* he;
+			if (u_int(level + 15) <= 30 &&
+			    (nb = (he = &hte_tc[((level&0x1f) << 6)|run])->nb))
+				/* we can use a VLC. */
+				val = he->val;
+			else {
+				 /* Can't use a VLC.  Escape it. */
+				val = (1 << 14) | (run << 8) | (level & 0xff);
+				nb = 20;
+			}
+			PUT_BITS(val, nb, nbb, bb, bc);
+			run = 0;
+		} else
+			++run;
+	}
+	/* EOB */
+	PUT_BITS(2, 2, nbb, bb, bc);
+
+	bb_ = bb;
+	nbb_ = nbb;
+	bc_ = bc;
+}
+
+/*
+ * H261ASPixelEncoder::encode_mb
+ *	encode a macroblock given a set of input YUV pixels
+ */
+void
+H261ASPixelEncoder::encode_mb(u_int mba, const u_char* frm,
+			    u_int loff, u_int coff, int how)
+{
+	register int q;
+	float* qt;
+	if (how == CR_MOTION) {
+		q = lq_;
+		qt = lqt_;
+	} else if (how == CR_BG) {
+		q = hq_;
+		qt = hqt_; 
+	} else {
+		/* must be at age threshold */
+		q = mq_;
+		qt = mqt_; 
+	}
+
+	/*
+	 * encode all 6 blocks of the macro block to find the largest
+	 * coef (so we can pick a new quantizer if gquant doesn't have
+	 * enough range).
+	 */
+	/*XXX this can be u_char instead of short but need smarts in fdct */
+	short blk[64 * 6];
+	register int stride = width_;
+	/* luminance */
+	const u_char* p = &frm[loff];
+	fdct(p, stride, blk + 0, qt);
+	fdct(p + 8, stride, blk + 64, qt);
+	fdct(p + 8 * stride, stride, blk + 128, qt);
+	fdct(p + (8 * stride + 8), stride, blk + 192, qt);
+	/* chominance */
+	int fs = framesize_;
+	p = &frm[fs + coff];
+	stride >>= 1;
+	fdct(p, stride, blk + 256, qt);
+	fdct(p + (fs >> 2), stride, blk + 320, qt);
+
+	/*
+	 * if the default quantizer is too small to handle the coef.
+	 * dynamic range, spin through the blocks and see if any
+	 * coef. would significantly overflow.
+	 */
+	if (q < 8) {
+		register int cmin = 0, cmax = 0;
+		register short* bp = blk;
+		for (register int i = 6; --i >= 0; ) {
+			++bp;	// ignore dc coef
+			for (register int j = 63; --j >= 0; ) {
+				register int v = *bp++;
+				if (v < cmin)
+					cmin = v;
+				else if (v > cmax)
+					cmax = v;
+			}
+		}
+		if (cmax < -cmin)
+			cmax = -cmin;
+		if (cmax >= 128) {
+			/* need to re-quantize */
+			register int s;
+			for (s = 1; cmax >= (128 << s); ++s) {
+			}
+			q <<= s;
+			register short* bp = blk;
+			for (register int i = 6; --i >= 0; ) {
+				++bp;	// ignore dc coef
+				for (register int j = 63; --j >= 0; ) {
+					register int v = *bp;
+					*bp++ = v >> s;
+				}
+			}
+		}
+	}
+
+	u_int m = mba - mba_;
+	mba_ = mba;
+	huffent* he = &hte_mba[m - 1];
+	/* MBA */
+	PUT_BITS(he->val, he->nb, nbb_, bb_, bc_);
+	if (q != mquant_) {
+		/* MTYPE = INTRA + TC + MQUANT */
+		PUT_BITS(1, 7, nbb_, bb_, bc_);
+		PUT_BITS(q, 5, nbb_, bb_, bc_);
+		mquant_ = q;
+	} else {
+		/* MTYPE = INTRA + TC (no quantizer) */
+		PUT_BITS(1, 4, nbb_, bb_, bc_);
+	}
+
+	/* luminance */
+	const char* lm = llm_[q];
+	if (lm == 0) {
+		lm = make_level_map(q, 1);
+		llm_[q] = lm;
+		clm_[q] = make_level_map(q, 2);
+	}
+	encode_blk(blk + 0, lm);
+	encode_blk(blk + 64, lm);
+	encode_blk(blk + 128, lm);
+	encode_blk(blk + 192, lm);
+	/* chominance */
+	lm = clm_[q];
+	encode_blk(blk + 256, lm);
+	encode_blk(blk + 320, lm);
+}
+
+
+/*
+ * H261ASDCTEncoder::encode_mb
+ *	encode a macroblock given a set of input DCT coefs
+ *	each coef is stored as a short
+ */
+void
+H261ASDCTEncoder::encode_mb(u_int mba, const u_char* frm,
+			  u_int loff, u_int coff, int how)
+{
+	short *lblk = (short *)frm + loff;
+	short *ublk = (short *)frm + coff;
+	short *vblk = (short *)frm + coff + 64;
+
+	register u_int q;
+	if (how == CR_MOTION)
+		q = lq_;
+	else if (how == CR_BG)
+		q = hq_;
+	else
+		/* must be at age threshold */
+		q = mq_;
+
+	/*
+	 * if the default quantizer is too small to handle the coef.
+	 * dynamic range, spin through the blocks and see if any
+	 * coef. would significantly overflow.
+	 */
+	if (q < 8) {
+		register int cmin = 0, cmax = 0;
+		register short* bp = lblk;
+		register int i, j;
+
+		// Y U and V blocks
+		for (i = 6; --i >= 0; ) {
+			++bp;	// ignore dc coef
+			for (j = 63; --j >= 0; ) {
+				register int v = *bp++;
+				if (v < cmin)
+					cmin = v;
+				else if (v > cmax)
+					cmax = v;
+			}
+		}
+
+		if (cmax < -cmin)
+			cmax = -cmin;
+		cmax /= (q << 1);
+		if (cmax >= 128) {
+			/* need to re-quantize */
+			register int s;
+
+			for (s = 1; cmax >= (128 << s); ++s) {
+			}
+			q <<= s;
+
+		}
+	}
+
+	u_int m = mba - mba_;
+	mba_ = mba;
+	huffent* he = &hte_mba[m - 1];
+	/* MBA */
+	PUT_BITS(he->val, he->nb, nbb_, bb_, bc_);
+	if (q != mquant_) {
+		/* MTYPE = INTRA + TC + MQUANT */
+		PUT_BITS(1, 7, nbb_, bb_, bc_);
+		PUT_BITS(q, 5, nbb_, bb_, bc_);
+		mquant_ = q;
+	} else {
+		/* MTYPE = INTRA + TC (no quantizer) */
+		PUT_BITS(1, 4, nbb_, bb_, bc_);
+	}
+
+	/* luminance */
+	const char* lm = llm_[q];
+	if (lm == 0) {
+		/*
+		 * the filter thresh is 0 since we assume the jpeg percept.
+		 * quantizer already did the filtering.
+		 */
+		lm = make_level_map(q, 0);
+		llm_[q] = lm;
+		clm_[q] = make_level_map(q, 0);
+	}
+	encode_blk(lblk + 0, lm);
+	encode_blk(lblk + 64, lm);
+	encode_blk(lblk + 128, lm);
+	encode_blk(lblk + 192, lm);
+	/* chominance */
+	lm = clm_[q];
+	encode_blk(ublk, lm);
+	encode_blk(vblk, lm);
+}
+
+int
+H261ASEncoder::flush(pktbuf* pb, int nbit, pktbuf* npb)
+{
+	/* flush bit buffer */
+	STORE_BITS(bb_, bc_);
+
+	int cc = (nbit + 7) >> 3;
+	int ebit = (cc << 3) - nbit;
+
+	/*XXX*/
+	if (cc == 0 && npb != 0)
+		abort();
+
+	pb->len = cc + HDRSIZE;
+	rtphdr* rh = (rtphdr*)pb->data;
+	if (npb == 0)
+		rh->rh_flags |= htons(RTP_M);
+
+	int h = *(u_int*)(rh + 1) | ebit << 26 | sbit_ << 29;
+	*(u_int*)(rh + 1) = htonl(h);
+
+	if (npb != 0) {
+		u_char* nbs = &npb->data[HDRSIZE];
+		u_int bc = (bc_ - bs_) << 3;
+		int tbit = bc + nbb_;
+		int extra = ((tbit + 7) >> 3) - (nbit >> 3);
+		if (extra > 0)
+			memcpy(nbs, bs_ + (nbit >> 3), extra);
+		bs_ = nbs;
+		sbit_ = nbit & 7;
+		tbit -= nbit &~ 7;
+		bc = tbit &~ (NBIT - 1);
+		nbb_ = tbit - bc;
+		bc_ = bs_ + (bc >> 3);
+		/*
+		 * Prime the bit buffer.  Be careful to set bits that
+		 * are not yet in use to 0, since output bits are later
+		 * or'd into the buffer.
+		 */
+		if (nbb_ > 0) {
+			u_int n = NBIT - nbb_;
+			bb_ = (LOAD_BITS(bc_) >> n) << n;
+		} else
+			bb_ = 0;
+	}
+	tx_->send(pb);
+
+	return (cc + HDRSIZE);
+}
+
+int H261ASDCTEncoder::consume(const VideoFrame *vf)
+{
+	if (!samesize(vf))
+		size(vf->width_, vf->height_);
+
+	DCTFrame* df = (DCTFrame *)vf;
+
+	return(encode(df, df->crvec_));
+}
+
+int H261ASPixelEncoder::consume(const VideoFrame *vf)
+{
+	if (!samesize(vf))
+		size(vf->width_, vf->height_);
+
+	YuvFrame* p = (YuvFrame*)vf;
+	return(encode(p, p->crvec_));
+}
+		
+
+int
+H261ASEncoder::encode(const VideoFrame* vf, const u_int8_t *crvec)
+{
+	tx_->flush();
+
+	pktbuf* pb = pool_->alloc(vf->ts_, RTP_PT_H261);
+	bs_ = &pb->data[HDRSIZE];
+	bc_ = bs_;
+	u_int ec = (tx_->mtu() - HDRSIZE) << 3;
+	bb_ = 0;
+	nbb_ = 0;
+	sbit_ = 0;
+	/* RTP/H.261 header */
+	rtphdr* rh = (rtphdr*)pb->data;
+	*(u_int*)(rh + 1) = 1 << 25 | lq_ << 10;
+
+	/* PSC */
+	PUT_BITS(0x0001, 16, nbb_, bb_, bc_);
+	/* GOB 0 -> picture header */
+	PUT_BITS(0, 4, nbb_, bb_, bc_);
+	/* TR (XXX should do this right) */
+	PUT_BITS(0, 5, nbb_, bb_, bc_);
+	/* PTYPE = CIF */
+	int pt = cif_ ? 4 : 0;
+	PUT_BITS(pt, 6, nbb_, bb_, bc_);
+	/* PEI */
+	PUT_BITS(0, 1, nbb_, bb_, bc_);
+
+	int step = cif_ ? 1 : 2;
+	int cc = 0;
+
+	u_int8_t* frm = vf->bp_;
+	for (u_int gob = 0; gob < ngob_; gob += step) {
+		u_int loff = loff_[gob];
+		u_int coff = coff_[gob];
+		u_int blkno = blkno_[gob];
+		u_int nbit = ((bc_ - bs_) << 3) + nbb_;
+
+		/* GSC/GN */
+		PUT_BITS(0x10 | (gob + 1), 20, nbb_, bb_, bc_);
+		/* GQUANT/GEI */
+		mquant_ = lq_;
+		PUT_BITS(mquant_ << 1, 6, nbb_, bb_, bc_);
+
+		mba_ = 0;
+		int line = 11;
+		for (u_int mba = 1; mba <= 33; ++mba) {
+			/*
+			 * If the conditional replenishment algorithm
+			 * has decided to send any of the blocks of
+			 * this macroblock, code it.
+			 */
+			u_int s = crvec[blkno];
+
+			if ((s & CR_SEND) != 0) {
+				u_int mbpred = mba_;
+				encode_mb(mba, frm, loff, coff, CR_STATE(s));
+				u_int cbits = ((bc_ - bs_) << 3) + nbb_;
+				if (cbits > ec) {
+					pktbuf* npb;
+					npb = pool_->alloc(vf->ts_, RTP_PT_H261);
+					cc += flush(pb, nbit, npb);
+					cbits -= nbit;
+					pb = npb;
+					/* RTP/H.261 header */
+					u_int m = mbpred;
+					u_int g;
+					if (m != 0) {
+						g = gob + 1;
+						m -= 1;
+					} else
+						g = 0;
+
+					rh = (rtphdr*)pb->data;
+					*(u_int*)(rh + 1) =
+						1 << 25 |
+						m << 15 |
+						g << 20 |
+						mquant_ << 10;
+				}
+				nbit = cbits;
+			}
+
+			loff += loffsize_;
+			coff += coffsize_;
+			blkno += bloffsize_;
+			if (--line <= 0) {
+				line = 11;
+				blkno += bstride_;
+				loff += lstride_;
+				coff += cstride_;
+			}
+
+		}
+	}
+	cc += flush(pb, ((bc_ - bs_) << 3) + nbb_, 0);
+	return (cc);
+}

Added: vic/trunk/codec/p64/p64as.cpp
==============================================================================
--- (empty file)
+++ vic/trunk/codec/p64/p64as.cpp	Tue Aug 22 02:04:58 2006
@@ -0,0 +1,663 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef WIN32
+//#include <winsock.h>
+#else
+#include <sys/param.h>
+#include <sys/file.h>
+#endif
+#include <sys/stat.h>
+
+#include "p64as.h"
+#include "p64-huff.h"
+#include "dct.h"
+#include "bsd-endian.h"
+
+#define inverseDCT( block, mask, image, rowstride, merge ) \
+  rdct( block, mask, image, rowstride, merge )
+
+void P64ASDecoder::err(const char* msg ...) const
+{
+#ifdef DEVELOPMENT_VERSION
+	va_list ap;
+	va_start(ap, msg);
+	vfprintf(stderr, msg, ap);
+	fprintf(stderr, " @g%d m%d %d/%d of %d/%d: %04x %04x %04x %04x|%04x\n",
+		gob_, mba_,
+		(int)((u_char*)bs_ - (u_char*)ps_), nbb_,
+		(int)((u_char*)es_ - (u_char*)ps_), pebit_,
+	       bs_[-4], bs_[-3], bs_[-2], bs_[-1], bs_[0]);
+#else
+	UNUSED(msg);
+#endif
+}
+
+P64ASDecoder::P64ASDecoder() : 
+  fs_(0), 
+  front_(0), 
+  back_(0),
+  width_(0),
+  height_(0),
+  ngob_(0), 
+  maxgob_(0),
+  ndblk_(0),
+  gobquant_(0), 
+  mt_(0), 
+  gob_(0), 
+  mba_(0), 
+  mvdh_(0), 
+  mvdv_(0), 
+  marks_(0), 
+  mark_(0),
+  bad_psc_(0), 
+  bad_bits_(0), 
+  bad_GOBno_(0), 
+  bad_fmt_(0),
+  coord_(0),
+  mb_state_(0)
+{
+  inithuff();
+  initquant();
+}
+
+P64ASDecoder::~P64ASDecoder()
+{
+  delete [] fs_;
+}
+
+void 
+P64ASDecoder::init()
+{
+  //memset(mb_state_, MBST_OLD, sizeof(mb_state_));
+
+  minx_ = width_;
+  miny_ = height_;
+  maxx_ = 0;
+  maxy_ = 0;
+  
+  front_ = 0;
+  back_ = 0;
+
+}
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define HUFFRQ(bs, bb) \
+ { \
+	register int t = *bs++; \
+	bb <<= 16; \
+	bb |= (t & 0xff) << 8; \
+	bb |= t >> 8; \
+}
+#else
+#define HUFFRQ(bs, bb) \
+ { \
+	bb <<= 16; \
+	bb |= *bs++; \
+}
+#endif
+
+#define MASK(s) ((1 << (s)) - 1)
+
+#define HUFF_DECODE(bs, ht, nbb, bb, result) { \
+	register int s__, v__; \
+ \
+	if (nbb < 16) { \
+		HUFFRQ(bs, bb); \
+		nbb += 16; \
+	} \
+	s__ = ht.maxlen; \
+	v__ = (bb >> (nbb - s__)) & MASK(s__); \
+	s__ = (ht.prefix)[v__]; \
+	nbb -= (s__ & 0x1f); \
+	result = s__ >> 5; \
+ }
+
+#define GET_BITS(bs, n, nbb, bb, result) \
+{ \
+	nbb -= n; \
+	if (nbb < 0)  { \
+		HUFFRQ(bs, bb); \
+		nbb += 16; \
+	} \
+	(result) = ((bb >> nbb) & MASK(n)); \
+}
+
+#define SKIP_BITS(bs, n, nbb, bb) \
+{ \
+	nbb -= n; \
+	if (nbb < 0)  { \
+		HUFFRQ(bs, bb); \
+		nbb += 16; \
+	} \
+}
+
+/*
+ * Set up the huffman tables.
+ */
+void 
+P64ASDecoder::inithuff()
+{
+  ht_mtype_.prefix = htd_mtype;
+  ht_mtype_.maxlen = htd_mtype_width;
+  ht_mba_.prefix = htd_mba;
+  ht_mba_.maxlen = htd_mba_width;
+  ht_mvd_.prefix = htd_dvm;
+  ht_mvd_.maxlen = htd_dvm_width;
+  ht_cbp_.prefix = htd_cbp;
+  ht_cbp_.maxlen = htd_cbp_width;
+  ht_tcoeff_.prefix = htd_tcoeff;
+  ht_tcoeff_.maxlen = htd_tcoeff_width;
+}
+
+int 
+P64ASDecoder::quantize(int v, int q)
+{
+  if (v > 0) 
+    return (((v << 1) + 1) * q) - (~q & 1);
+  else 
+    return (((v << 1) - 1) * q) + (~q & 1);
+}
+
+/*
+ * Build quantization lookup table.
+ * One for each possible MQUANT paramenter.
+ */
+void 
+P64ASDecoder::initquant()
+{
+  for (int mq = 0; mq < 32; ++mq) {
+    short* qt = &quant_[mq << 8];
+    for (int v = 0; v < 256; ++v) {
+      int s = (v << 24) >> 24;
+      qt[v] = quantize(s, mq);
+    }
+  }
+}
+
+/*
+ * Decode the next block of transform coefficients
+ * from the input stream.
+ * Return number of non-zero ac coefficients.
+ */
+#ifdef INT_64
+int P64ASDecoder::parse_block(short* blk, INT_64* mask)
+#else
+int P64ASDecoder::parse_block(short* blk, u_int* mask)
+#endif
+{
+#ifdef INT_64
+  INT_64 m0 = 0;
+#else
+  u_int m1 = 0, m0 = 0;
+#endif
+  /*
+   * Cache bit buffer in registers.
+   */
+  register int nbb = nbb_;
+  register int bb = bb_;
+  register short* qt = qt_;
+
+  for (int i = 0; i < 64; i ++ ) {
+    blk[i] = 0;
+  }
+  int k;
+  if ((mt_ & MT_CBP) == 0) {
+    int v;
+    GET_BITS(bs_, 8, nbb, bb, v);
+    if (v == 255)
+      v = 128;
+    if (mt_ & MT_INTRA)
+      v <<= 3;
+    else
+      v = qt[v];
+    blk[0] = v;
+    k = 1;
+    m0 |= 1;
+  } else if ((bb >> (nbb - 1)) & 1) {
+    /*
+     * In CBP blocks, the first block present must be
+     * non-empty (otherwise it's mask bit wouldn't
+     * be set), so the first code cannot be an EOB.
+     * CCITT optimizes this case by using a huffman
+     * table equivalent to ht_tcoeff_ but without EOB,
+     * in which 1 is coded as "1" instead of "11".
+     * We grab two bits, the first bit is the code
+     * and the second is the sign.
+     */
+    int v;
+    GET_BITS(bs_, 2, nbb, bb, v);
+    /*XXX quantize?*/
+    blk[0] = qt[(v & 1) ? 0xff : 1];
+    k = 1;
+    m0 |= 1;
+  } else {
+    k = 0;
+#ifndef INT_64
+    blk[0] = 0;/*XXX need this because the way we set bits below*/
+#endif
+  }
+  int nc = 0;
+  for (;;) {
+    int r, v;
+    HUFF_DECODE(bs_, ht_tcoeff_, nbb, bb, r);
+    if (r <= 0) {
+      /* SYM_EOB, SYM_ILLEGAL, or SYM_ESCAPE */
+      if (r == SYM_ESCAPE) {
+	GET_BITS(bs_, 14, nbb, bb, r);
+	v = r & 0xff;
+	r >>= 8;
+      } else {
+	if (r == SYM_ILLEGAL) {
+	  bb_ = bb;
+	  nbb_ = nbb;
+	  err("illegal symbol in block");
+	}
+	/* EOB */
+	break;
+      }
+    } else {
+      v = (r << 22) >> 27;
+      r = r & 0x1f;
+    }
+    k += r;
+    if (k >= 64) {
+      bb_ = bb;
+      nbb_ = nbb;
+      err("bad run length %d (r %d, v %d)", k, r, v);
+      break;
+    }
+    r = COLZAG[k++];
+    //r = ROWZAG[k++];
+    blk[r] = qt[v & 0xff];
+    ++nc;
+#ifdef INT_64
+    m0 |= (INT_64)1 << r;
+#else
+    if (r < 32)
+      m0 |= 1 << r;
+    else
+      m1 |= 1 << (r - 32);
+#endif
+  }
+  /*
+   * Done reading input.  Update bit buffer.
+   */
+  bb_ = bb;
+  nbb_ = nbb;
+
+  *mask = m0;
+#ifndef INT_64
+  mask[1] = m1;
+#endif
+  return (nc);
+}
+
+/*
+ * Parse a GOB header, which consists of the GOB quantiation
+ * factor (GQUANT) and spare bytes that we ignore.
+ */
+int P64ASDecoder::parse_gob_hdr(int ebit)
+{
+  UNUSED(ebit);
+  int gobu, gobm, gobl;
+
+  mba_ = -1;
+
+  GET_BITS(bs_, 7, nbb_, bb_, gobu);
+  GET_BITS(bs_, 6, nbb_, bb_, gobm);
+  GET_BITS(bs_, 7, nbb_, bb_, gobl);
+  gob_ = (gobu << 13) | (gobm << 7) | (gobl);
+
+  int mq;
+  GET_BITS(bs_, 5, nbb_, bb_, mq);
+  gobquant_ = mq;
+  qt_ = &quant_[mq << 8];  
+
+  return gob_;
+}
+
+/*
+ * Parse a macroblock header.  If there is no mb header because
+ * we hit the next start code, return -1, otherwise 0.
+ */
+int P64ASDecoder::parse_mb_hdr(u_int& cbp)
+{
+  /*
+   * Read the macroblock address (MBA)
+   */
+  int v;
+  HUFF_DECODE(bs_, ht_mba_, nbb_, bb_, v);
+  if (v <= 0) {
+    /*
+     * (probably) hit a start code; either the
+     * next GOB or the next picture header.
+     * If we got MBA stuffing (0) we need to return
+     * so the outer loop can check if we're at the
+     * end of the buffer (lots of codecs put stuffing
+     * at the end of a picture to byte align the psc).
+     */
+    return (v);
+  }
+
+  /*
+   * MBA is differentially encoded.
+   */
+  mba_ += v;
+  if (mba_ >= MBPERGOB) {
+    return (SYM_ILLEGAL);
+  }
+
+  HUFF_DECODE(bs_, ht_mtype_, nbb_, bb_, mt_);
+  if (mt_ & MT_MQUANT) {
+    int mq;
+    GET_BITS(bs_, 5, nbb_, bb_, mq);
+    qt_ = &quant_[mq << 8];
+  }
+
+  /*
+   * Coded block pattern.
+   */
+  if (mt_ & MT_CBP) {
+    HUFF_DECODE(bs_, ht_cbp_, nbb_, bb_, cbp);
+    if (cbp > 63) {
+      err("cbp invalid %x", cbp);
+      return (SYM_ILLEGAL);
+    }
+  } else
+    cbp = 0x3f;
+  
+  return (1);
+}
+
+/*
+ * Handle the next block in the current macroblock.
+ * If tc is non-zero, then coefficients are present
+ * in the input stream and they are parsed.  Otherwise,
+ * coefficients are not present, but we take action
+ * according to the type macroblock that we have.
+ */
+void P64ASDecoder::decode_block(u_int tc, 
+				u_int x, 
+				u_int y, 
+				u_int stride,
+				u_char* front, 
+				u_char* back, 
+				int sf)
+{
+  UNUSED(sf);
+  short blk[64];
+#ifdef INT_64
+  INT_64 mask;
+#define MASK_VAL	mask
+#define MASK_REF	&mask
+#else
+  u_int mask[2];
+#define MASK_VAL	mask[0], mask[1]
+#define MASK_REF	mask
+#endif
+  int nc = 0;
+  if (tc != 0)
+    nc = parse_block(blk, MASK_REF);
+  
+  int off = y * stride + x;
+  u_char* out = front + off;
+  
+  if (mt_ & MT_INTRA) {
+    if (tc != 0) {
+      if (nc == 0) {
+	dcfill((blk[0] + 4) >> 3, out, stride);
+      } else {
+	inverseDCT(blk, MASK_VAL, out, stride, (u_char*)0);
+      }
+    } else {
+      u_char* in = back + off;
+      mvblka(in, out, stride);
+    }
+    return;
+  }
+}
+
+/*
+ * Decompress the next macroblock.  Return 0 if the macroblock
+ * was present (with no errors).  Return SYM_STARTCODE (-1),
+ * if there was no macroblock but instead the start of the
+ * next GOB or picture (in which case the start code has
+ * been consumed).  Return SYM_ILLEGAL (-2) if there was an error.
+ */
+int P64ASDecoder::decode_mb()
+{
+  u_int cbp;
+  register int v;
+
+  if ((v = parse_mb_hdr(cbp)) <= 0)
+    return (v);
+  
+  /*
+   * Lookup the base coordinate for this MBA.
+   * Convert from a block to a pixel coord.
+   */
+  register u_int x, y;
+  x = coord_[33 * gob_ + mba_];
+  y = (x & 0xffff);
+  x >>= 16;
+  
+  /* Update bounding box */
+  if (x < minx_)
+    minx_ = x;
+  if (x > maxx_)
+    maxx_ = x;
+  if (y < miny_)
+    miny_ = y;
+  if (y > maxy_)
+    maxy_ = y;
+
+  /*
+   * Decode the six blocks in the MB (4Y:1U:1V).
+   * (This code assumes MT_TCOEFF is 1.)
+   */
+  register u_int tc = mt_ & MT_TCOEFF;
+  register u_int s = width_;
+  decode_block(tc & (cbp >> 5), x, y, s, front_, back_, 1);
+  decode_block(tc & (cbp >> 4), x + 8, y, s, front_, back_, 1);
+  decode_block(tc & (cbp >> 3), x, y + 8, s, front_, back_, 1);
+  decode_block(tc & (cbp >> 2), x + 8, y + 8, s, front_, back_, 1);
+  s >>= 1;
+  int off = size_;
+  decode_block(tc & (cbp >> 1), x >> 1, y >> 1, s,
+	       front_ + off, back_ + off, 2);
+  off += size_ >> 2;
+  decode_block(tc & (cbp >> 0), x >> 1, y >> 1, s,
+	       front_ + off, back_ + off, 2);
+  
+  mbst_[mba_] = MBST_NEW;
+	
+  /*
+   * If a marking table was attached, take note.
+   * This allows us to dither only the blocks that have changed,
+   * rather than the entire image on each frame.
+   */
+  if (marks_) {
+    /* convert to 8x8 block offset */
+    off = (x >> 3) + (y >> 3) * (width_ >> 3);
+    int m = mark_;
+    marks_[off] = m;
+    marks_[off + 1] = m;
+    off += width_ >> 3;
+    marks_[off] = m;
+    marks_[off + 1] = m;
+  }
+  return (0);
+}
+
+/*
+ * Decode H.261 stream.  Decoding can begin on either
+ * a GOB or macroblock header.  All the macroblocks of
+ * a given frame can be decoded in any order, but chunks
+ * cannot be reordered across frame boundaries.  Since data
+ * can be decoded in any order, this entry point can't tell
+ * when a frame is fully decoded (actually, we could count
+ * macroblocks but if there is loss, we would not know when
+ * to sync).  Instead, the callee should sync the decoder
+ * by calling the sync() method after the entire frame 
+ * has been decoded (modulo loss).
+ *
+ * This routine should not be called with more than
+ * one frame present since there is no callback mechanism
+ * for renderering frames (i.e., don't call this routine
+ * with a buffer that has a picture header that's not
+ * at the front).
+ */
+int P64ASDecoder::decode(const u_char* bp, 
+			 int cc,
+			 int ebit,
+			 int quant)
+{
+	ps_ = (u_short*)bp;
+	/*
+	 * If cc is odd, ignore 8 extra bits in last short.
+	 */
+	int odd = cc & 1;
+	ebit += odd << 3;
+	pebit_ = ebit;
+	es_ = (u_short*)(bp + ((cc - 1) &~ 1));
+
+	/*
+	 * If input buffer not aligned, prime bit-buffer
+	 * with 8 bits; otherwise, prime it with a 16.
+	 */
+	if ((long)bp & 1) {
+		bs_ = (u_short*)(bp + 1);
+		bb_ = *bp;
+		nbb_ = 8;
+	} else {
+		bs_ = (u_short*)bp;
+		HUFFRQ(bs_, bb_);
+		nbb_ = 16;
+	}
+
+	int gob = 0;
+	qt_ = &quant_[quant << 8];
+	
+	while (bs_ < es_ || (bs_ == es_ && nbb_ > ebit)) {
+		mbst_ = &mb_state_[gob * 33];
+
+		ndblk_++;
+		int v = decode_mb();
+		if (v == 0)
+			continue;
+
+		if (v != SYM_STARTCODE) {
+			err("expected GOB startcode");
+			++bad_bits_;
+			return (0);
+		}
+		gob = parse_gob_hdr(ebit);
+		if (gob < 0) {
+			/*XXX*/
+			++bad_bits_;
+			return (0);
+		}
+	}
+	return (1);
+}
+
+void P64ASDecoder::sync()
+{
+	bbx_ = minx_;
+	bby_ = miny_;
+	bbw_ = maxx_ - minx_ + 16;
+	bbh_ = maxy_ - miny_ + 16;
+
+	minx_ = width_;
+	miny_ = height_;
+	maxx_ = 0;
+	maxy_ = 0;
+
+	maxgob_ = 0;
+}
+
+void P64ASDecoder::getPreviewLevelSize( u_short level, u_int &width, u_int &height )
+{
+  width = width_ >> level;
+  height = height_ >> level;
+}
+
+void P64ASDecoder::mvblka(u_char* in, u_char* out, u_int stride)
+{
+#ifdef INT_64
+	*(INT_64*)out = *(INT_64*)in;
+	out += stride; in += stride;
+	*(INT_64*)out = *(INT_64*)in;
+	out += stride; in += stride;
+	*(INT_64*)out = *(INT_64*)in;
+	out += stride; in += stride;
+	*(INT_64*)out = *(INT_64*)in;
+	out += stride; in += stride;
+	*(INT_64*)out = *(INT_64*)in;
+	out += stride; in += stride;
+	*(INT_64*)out = *(INT_64*)in;
+	out += stride; in += stride;
+	*(INT_64*)out = *(INT_64*)in;
+	out += stride; in += stride;
+	*(INT_64*)out = *(INT_64*)in;
+#else
+	for (int k = 8; --k >= 0; ) {
+		*(u_int*)out = *(u_int*)in;
+		*(u_int*)(out + 4) = *(u_int*)(in + 4);
+		in += stride;
+		out += stride;
+	}
+#endif
+}
+
+void 
+P64ASDecoder::set_size(int w, int h)
+{
+  width_ = w;
+  height_ = h;
+  size_ = w * h;
+
+  int hblks = w/16;
+  int vblks = h/16;
+
+  int blks = hblks * vblks;
+
+  if (mb_state_) {
+    delete [] mb_state_;
+  }
+  mb_state_ = new u_char[blks];
+  memset(mb_state_, MBST_OLD, blks);
+
+  if (coord_) {
+    delete [] coord_;
+  }
+
+  coord_ = new u_int[blks];
+  
+  int i = 0;
+  for (int y = 0; y < vblks; y ++) {
+    for (int x = 0; x < hblks; x ++, i ++) {
+      coord_[i] = (0xffff & (x * 16)) << 16 | (0xffff & (y * 16));
+    }
+  }
+
+  if (front_) {
+    delete [] front_;
+  }
+  if (back_) {
+    delete [] back_;
+  }
+
+  int buffer_size = size_ + size_/2;
+
+  front_ = new u_char[buffer_size];
+  back_ = new u_char[buffer_size];
+
+  memset(front_, 127, buffer_size);
+  memset(back_, 127, buffer_size);
+
+  sync();
+}
+

Added: vic/trunk/codec/p64/p64as.h
==============================================================================
--- (empty file)
+++ vic/trunk/codec/p64/p64as.h	Tue Aug 22 02:04:58 2006
@@ -0,0 +1,149 @@
+
+#ifndef lib_p64as_h
+#define lib_p64as_h
+
+#include <sys/types.h>
+#include <stdio.h>
+
+struct huffcode;
+
+#define MBPERGOB 33
+
+class P64ASDecoder {
+public:
+  P64ASDecoder();
+  virtual ~P64ASDecoder();
+
+  virtual const u_char* frame() const { return (front_); }
+
+  inline int ndblk() const { return (ndblk_); }
+  inline void resetndblk() { ndblk_ = 0; }
+  inline int width() const { return (width_); }
+  inline int height() const { return (height_); }
+
+  virtual void set_size(int w, int h);
+   
+  virtual int decode(const u_char* bp, 
+		     int cc, 
+		     int ebit,
+		     int quant);
+
+  virtual void sync();
+  inline void bb(int& x, int& y, int& w, int& h) {
+    x = bbx_; y = bby_; w = bbw_; h = bbh_;
+  };
+  inline u_int bad_psc() const { return (bad_psc_); }
+  inline u_int bad_bits() const { return (bad_bits_); }
+  inline u_int bad_GOBno() const { return (bad_GOBno_); }
+  inline u_int bad_fmt() const { return (bad_fmt_); }
+  inline int seenMaxGob() const { return (maxgob_ >= ngob_ - 1); }
+  inline u_int gobquant() const { return (gobquant_); }
+  
+  inline void marks(u_char* p) { marks_ = p; }
+  inline void mark(int v) { mark_ = v; }
+  
+  inline void setPreviewLevel( u_short level ) { set_preview_level = level; }
+  inline u_short getPreviewLevel() const { return preview_level; }
+  
+  inline u_short getPreviewLevelMax() const { return 3; }
+  void getPreviewLevelSize( u_short level, u_int &width, u_int &height );
+  
+  void mvblk(u_char* in, u_char* out, u_int stride);
+  void mvblka(u_char*, u_char*, u_int stride);
+
+protected:
+  void init();
+  void inithuff();
+  void initquant();
+  virtual void err(const char* msg ...) const;
+  int quantize(int v, int q);
+#ifdef INT_64
+  int parse_block(short* blk, INT_64* mask);
+#else
+  int parse_block(short* blk, u_int* mask);
+#endif
+  void decode_block(u_int tc, u_int x, u_int y, u_int stride,
+		    u_char* front, u_char* back, int sf);
+  
+  int parse_gob_hdr(int);
+  int parse_mb_hdr(u_int& cbp);
+  int decode_gob(u_int gob);
+  int decode_mb();
+  
+  u_int size_;
+  u_char* fs_;
+  u_char* front_;
+  u_char* back_;
+
+  struct hufftab {
+    int maxlen;
+    const short* prefix;
+  };
+  hufftab ht_mba_;
+  hufftab ht_mvd_;
+  hufftab ht_cbp_;
+  hufftab ht_tcoeff_;
+  hufftab ht_mtype_;
+  
+  u_int bb_;		/* 32-bit bit buffer */
+  int nbb_;		/* number bits in bit buffer */
+  const u_short* bs_;	/* input bit stream (less bits in bb_) */
+  const u_short* es_;	/* pointer to end if input stream */
+  const u_short* ps_;	/* packet start (for error reporting) */
+  int pebit_;		/* packet end bit (for error reporting) */
+  
+#define MBST_FRESH	0
+#define MBST_OLD	1
+#define MBST_NEW	2
+  u_char* mbst_;
+  short* qt_;
+  
+  u_int width_;		/* width of Y component */
+  u_int height_;		/* height of Y component */
+  
+  u_int ngob_;		/* number of gobs (12 for CIF, 3 for QCIF) */
+  u_int maxgob_;		/* max gob seen this frame */
+  int ndblk_;		/* # of decoded macroblocks */
+  u_int gobquant_;	/* last gob quantizer (for info funtion) */
+  
+  u_int mt_;		/* macroblock type (flags in p64-huff.h) */
+  u_int gob_;		/* current gob index */
+  int mba_;		/* macroblock address (predictor) */
+  int mvdh_;		/* motion vector (predictor) */
+  int mvdv_;		/* motion vector (predictor) */
+  
+  /* bounding box */
+  u_int minx_;
+  u_int miny_;
+  u_int maxx_;
+  u_int maxy_;
+  u_int bbx_;
+  u_int bby_;
+  u_int bbw_;
+  u_int bbh_;
+  
+  /*
+   * Table to indicate which blocks have changed.
+   */
+  u_char* marks_;
+  int mark_;
+  
+  /* error counters */
+  int bad_psc_;
+  int bad_bits_;
+  int bad_GOBno_;
+  int bad_fmt_;		/* # times RTP fmt != H.261 fmt */
+  
+  /* inverse quantization via table lookup */
+  short quant_[32 * 256];
+  
+  /* gob/mba to coordinate mappings */
+  u_int* coord_;
+  u_char* mb_state_;
+  
+  
+  u_short preview_level;
+  u_short set_preview_level;
+};
+
+#endif

Modified: vic/trunk/configure
==============================================================================
--- vic/trunk/configure	(original)
+++ vic/trunk/configure	Tue Aug 22 02:04:58 2006
@@ -309,7 +309,7 @@
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX CPP EGREP V_INCLUDE_X11 V_LIB_X11 V_INCLUDE_TCL V_LIB_TCL V_LIBRARY_TCL V_TKDOSNAMES V_INCLUDE_TK V_LIB_TK V_LIBRARY_TK V_INCLUDE_GRABBER V_LIB_GRABBER V_OBJ_GRABBER V_LIB_XIL V_OBJ_XIL V_STATIC V_TAR_TARGET V_ALL V_CCOPT V_CCOPT_H261 V_TAR_EXTRA V_LIB V_DEFINE V_SIGRET V_SHELL V_TARCMD V_INCLUDE V_OBJ V_BROKEN_OBJ V_OBJ_CRYPT LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX CPP EGREP V_INCLUDE_X11 V_LIB_X11 V_INCLUDE_TCL V_LIB_TCL V_LIBRARY_TCL V_TKDOSNAMES V_INCLUDE_TK V_LIB_TK V_LIBRARY_TK V_INCLUDE_GRABBER V_LIB_GRABBER V_OBJ_GRABBER V_LIB_XIL V_OBJ_XIL V_OBJ V_STATIC V_TAR_TARGET V_ALL V_CCOPT V_CCOPT_H261 V_TAR_EXTRA V_LIB V_DEFINE V_SIGRET V_SHELL V_TARCMD V_INCLUDE V_BROKEN_OBJ V_OBJ_CRYPT LIBOBJS LTLIBOBJS'
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -719,13 +719,13 @@
   	  /^X\(\/\).*/{ s//\1/; q; }
   	  s/.*/./; q'`
   srcdir=$ac_confdir
-  if test ! -r $srcdir/$ac_unique_file; then
+  if test ! -r "$srcdir/$ac_unique_file"; then
     srcdir=..
   fi
 else
   ac_srcdir_defaulted=no
 fi
-if test ! -r $srcdir/$ac_unique_file; then
+if test ! -r "$srcdir/$ac_unique_file"; then
   if test "$ac_srcdir_defaulted" = yes; then
     { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
    { (exit 1); exit 1; }; }
@@ -734,7 +734,7 @@
    { (exit 1); exit 1; }; }
   fi
 fi
-(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+(cd $srcdir && test -r "./$ac_unique_file") 2>/dev/null ||
   { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
    { (exit 1); exit 1; }; }
 srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
@@ -855,6 +855,7 @@
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
 --enable-debug		build with debugging enabled
 --enable-ipv6		build with ipv6 enabled
+--enable-h261as    Enable or disable the h261as codec
 --enable-v4l2old    Enable or disable old Video4Linux2 grabber
 --enable-XvGrabber    Enable or disable old XvGrabber
 
@@ -4487,6 +4488,21 @@
 	exit 1
 fi
 
+V_OBJ=""
+V_H261AS=""
+
+# Check whether --enable-h261as or --disable-h261as was given.
+if test "${enable_h261as+set}" = set; then
+  enableval="$enable_h261as"
+  h261as=yes
+else
+  h261as=no
+fi;
+if test "$h261as" = "yes"; then
+   V_OBJ="$V_OBJ codec/p64/p64as.o codec/decoder-h261as.o codec/encoder-h261as.o"
+   V_H261AS="-DUSE_H261AS"
+fi
+
 # lots of hairy special cases for detecting which frame capture
 # support to compile in
 
@@ -4821,7 +4837,8 @@
 
 
 
-V_DEFINE="$V_DEFINE $V_SHM"
+
+V_DEFINE="$V_DEFINE $V_SHM $V_H261AS"
 
 
 # tcl7.5 needs a dynamic loading library (unless built with the
@@ -5708,6 +5725,7 @@
 s, at V_OBJ_GRABBER@,$V_OBJ_GRABBER,;t t
 s, at V_LIB_XIL@,$V_LIB_XIL,;t t
 s, at V_OBJ_XIL@,$V_OBJ_XIL,;t t
+s, at V_OBJ@,$V_OBJ,;t t
 s, at V_STATIC@,$V_STATIC,;t t
 s, at V_TAR_TARGET@,$V_TAR_TARGET,;t t
 s, at V_ALL@,$V_ALL,;t t
@@ -5720,7 +5738,6 @@
 s, at V_SHELL@,$V_SHELL,;t t
 s, at V_TARCMD@,$V_TARCMD,;t t
 s, at V_INCLUDE@,$V_INCLUDE,;t t
-s, at V_OBJ@,$V_OBJ,;t t
 s, at V_BROKEN_OBJ@,$V_BROKEN_OBJ,;t t
 s, at V_OBJ_CRYPT@,$V_OBJ_CRYPT,;t t
 s, at LIBOBJS@,$LIBOBJS,;t t

Modified: vic/trunk/configure.in
==============================================================================
--- vic/trunk/configure.in	(original)
+++ vic/trunk/configure.in	Tue Aug 22 02:04:58 2006
@@ -29,6 +29,16 @@
 	exit 1
 fi
 
+V_OBJ=""
+V_H261AS=""
+
+dnl h261 as (arbitrary size) 
+AC_ARG_ENABLE(h261as, --enable-h261as    Enable or disable the h261as codec, h261as=yes, h261as=no)
+if test "$h261as" = "yes"; then
+   V_OBJ="$V_OBJ codec/p64/p64as.o codec/decoder-h261as.o codec/encoder-h261as.o"
+   V_H261AS="-DUSE_H261AS"
+fi
+
 # lots of hairy special cases for detecting which frame capture
 # support to compile in
 
@@ -351,7 +361,8 @@
 AC_SUBST(V_OBJ_GRABBER)
 AC_SUBST(V_LIB_XIL)
 AC_SUBST(V_OBJ_XIL)
+AC_SUBST(V_OBJ)
 
-V_DEFINE="$V_DEFINE $V_SHM"
+V_DEFINE="$V_DEFINE $V_SHM $V_H261AS"
 
 builtin(include, configure.in.tail)

Modified: vic/trunk/rtp/rtp.h
==============================================================================
--- vic/trunk/rtp/rtp.h	(original)
+++ vic/trunk/rtp/rtp.h	Tue Aug 22 02:04:58 2006
@@ -63,6 +63,9 @@
 /* backward compat hack for decoding RTPv1 ivs streams */
 #define RTP_PT_H261_COMPAT 127
 
+/* non-standard arbitrary sized h261 */
+#define RTP_PT_H261AS           77
+
 /* RTP standard content encodings for audio */
 #define RTP_PT_PCMU		0
 #define RTP_PT_CELP		1

Modified: vic/trunk/rtp/session.cpp
==============================================================================
--- vic/trunk/rtp/session.cpp	(original)
+++ vic/trunk/rtp/session.cpp	Tue Aug 22 02:04:58 2006
@@ -81,6 +81,9 @@
 		case RTP_PT_H263P:
 		case RTP_PT_LDCT:
 		case RTP_PT_PVH:
+#ifdef USE_H261AS
+		case RTP_PT_H261AS:
+#endif 
 		return (1);
 	}
 	return (0);

Modified: vic/trunk/tcl/cf-main.tcl
==============================================================================
--- vic/trunk/tcl/cf-main.tcl	(original)
+++ vic/trunk/tcl/cf-main.tcl	Tue Aug 22 02:04:58 2006
@@ -46,6 +46,7 @@
 set rtp_type(42) h263+
 set rtp_type(34) h263
 set rtp_type(127) h261v1
+set rtp_type(77) h261as
 
 proc vic_main {} {
 	global V tcl_platform



More information about the Sumover-dev mailing list