⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p64.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 3 页
字号:
/*
 * Copyright (c) 1993-1995 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 Network Research
 *	Group at Lawrence Berkeley National 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.
 */
/*
 * This code is derived from the P64 software implementation by the
 * Stanford PVRG group:
 * 
 * Copyright (C) 1990, 1991, 1993 Andy C. Hung, all rights reserved.
 * PUBLIC DOMAIN LICENSE: Stanford University Portable Video Research
 * Group. If you use this software, you agree to the following: This
 * program package is purely experimental, and is licensed "as is".
 * Permission is granted to use, modify, and distribute this program
 * without charge for any purpose, provided this license/ disclaimer
 * notice appears in the copies.  No warranty or maintenance is given,
 * either expressed or implied.  In no event shall the author(s) be
 * liable to you or a third party for any special, incidental,
 * consequential, or other damages, arising out of the use or inability
 * to use the program for any purpose (or the loss of data), even if we
 * have been advised of such possibilities.  Any public reference or
 * advertisement of this source code should refer to it as the Portable
 * Video Research Group (PVRG) code, and not by any author(s) (or
 * Stanford University) name.
 */

/************ Change log
 *
 * $Log: p64.cxx,v $
 * Revision 1.1  2006/06/26 03:03:19  joegenbaclor
 * I have decided to include the latest development realease  of OPAL tagged Deimos Devel 1 (June 8 2006) as inegrated classes to opensipstack to avoid future version conflicts due to the fast pace in OPAL development.   This move is also aimed to reduce the size of projects using OPAL componets such as the soon to be relased OpenSIPPhone.
 *
 * Revision 2.7  2006/01/12 17:56:37  dsandras
 * Added initialization as in Mimas branch of openh323.
 *
 * Revision 2.6  2005/11/25 00:14:29  csoutheren
 * Applied patch #1303543 from Hannes Friederich
 * Added guard to weird conditions in H261 codec
 *
 * Revision 2.5  2005/10/12 21:20:25  dsandras
 * Added check for buffLen to prevent potential crash thanks to Hannes Friederich.
 *
 * Revision 2.4  2005/09/15 18:00:38  dsandras
 * Make sure qv_ is initialized when being used.
 *
 * Revision 2.3  2005/08/31 13:16:02  rjongbloed
 * Ported video fast update from OpenH323
 *
 * Revision 2.2  2005/08/15 01:47:27  csoutheren
 * Fixed compile problem on 64 bit
 *
 * Revision 2.1  2003/03/15 23:43:00  robertj
 * Update to OpenH323 v1.11.7
 *
 * Revision 1.13  2005/02/25 01:21:12  dominance
 * fixed building on amd64 with gcc-4.0 according to
 * http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=287864
 *
 * Thanks fly to Andreas Jochens <aj@andaco.de>.
 *
 * Revision 1.12  2003/03/14 07:25:55  robertj
 * Removed $header keyword so is not different on alternate repositories
 *
 * Revision 1.11  2002/10/10 05:40:29  robertj
 * VxWorks port, thanks Martijn Roest
 *
 * Revision 1.10  2002/04/26 04:57:41  dereks
 * Add Walter Whitlocks fixes, based on Victor Ivashim's suggestions to
 * improve the quality with Netmeeting. Thanks guys!!!!
 *
 * Revision 1.9  2001/05/10 05:25:44  robertj
 * Removed need for VIC code to use ptlib.
 *
 * Revision 1.8  2001/05/08 14:53:29  yurik
 * Fixed misshap with removing non Wince def!
 *
 * Revision 1.7  2001/05/08 05:26:24  yurik
 * No ifdef _WIN32_WCE anymore - 3+ version of  SDK allows it
 *
 * Revision 1.6  2001/01/30 06:39:44  yurik
 * Modification submitted by Dave Cassel, dcassel@cyberfone.com.
 *
 * Revision 1.5  2000/12/19 22:22:34  dereks
 * Remove connection to grabber-OS.cxx files. grabber-OS.cxx files no longer used.
 * Video data is now read from a video channel, using the pwlib classes.
 *
 * Revision 1.4  2000/08/25 03:18:50  dereks
 * Add change log facility (Thanks Robert for the info on implementation)
 *
 *
 *
 ********/


#include <stdarg.h>
#include <stdio.h>
#include <string.h>

#include "config.h"

#if defined(WIN32) || defined(_WIN32_WCE)
#include <winsock.h>
#else
#include <sys/file.h>
#endif
#include <sys/stat.h>

#include "p64.h"
#include "p64-huff.h"
#include "dct.h"
#include "bsd-endian.h"

#define SPLICE(v, p, n) (v) |= (p) << SHIFT(n)

void P64Decoder::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]);
#endif
}

P64Decoder::P64Decoder()
	: fs_(0), front_(0), back_(0), qt_(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) 
{
	fmt_ = IT_CIF;/*XXX*/
	inithuff();
	initquant();
}

P64Decoder::~P64Decoder()
{
	delete fs_;
}

void P64Decoder::init()
{
	if (fmt_ == IT_CIF) {
		ngob_ = 12;
		width_ = 352;
		height_ = 288;
	} else {
		ngob_ = 3;
		width_ = 176;
		height_ = 144;
	}
	size_ = width_ * height_;
	memset(mb_state_, MBST_OLD, sizeof(mb_state_));

	for (u_int gob = 0; gob < 12; ++gob) {
		u_short* p = &base_[gob << 6];
		for (int mba = 0; mba < MBPERGOB; ++mba) {
			u_int x = 2 * (mba % 11);
			u_int y;
			if (fmt_ == IT_CIF) {
				y = 2 * (3 * (gob >> 1) + mba / 11);
				if (gob & 1)
					x += 22;
			} else
				y = 2 * (3 * gob + mba / 11);
			
			p[mba] = (x << 8) | y;
		}
	}
	minx_ = width_;
	miny_ = height_;
	maxx_ = 0;
	maxy_ = 0;

	allocate();
}

#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 P64Decoder::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 P64Decoder::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 P64Decoder::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 P64Decoder::parse_block(short* blk, INT_64* mask)
#else
int P64Decoder::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_;

	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++];
		blk[r] = (qt?qt[v & 0xff]:0);
		++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);
}

/*
 * Mix in a motion-compensated, filtered block.  Note that
 * the input block may be misaligned so we cannot try fancy,
 * word-at-a-time accesses without being careful.  The output
 * block is, of course, aligned.
 * 
 * The 2-D loop filter is separable into 1-D FIR (0.25 0.5 0.25)
 * horizontal and vertical passes.  At the block edge, the filter
 * taps are (0 1 0).  Full arithmetic precision must be maintained,
 * until the output stage, where values are rounded (up).
 *
 * The code below tries to be efficient by caching the input
 * rows in registers, and running the filter on 3x3 chunks.
 * Multiple columns can be computed in parallel by using 
 * two 16-bit adds in a 32-bit register, or four 16-bit adds
 * in a 64-bit register.
 */
void P64Decoder::filter(u_char* in, u_char* out, u_int stride)
{
	/* Corner pixel has filter coef 1 */
	u_int s = in[0];
	u_int o = 0;
	SPLICE(o, s, 24);

	u_int r00 = s << 24 | in[1] << 16 | in[2] << 8 | in[3];
	u_int r01 = in[4] << 24 | in[5] << 16 | in[6] << 8 | in[7];
	in += stride;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -