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

📄 p64.cpp

📁 网络MPEG4IP流媒体开发源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * 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. */#include "systems.h"#include "p64.h"#include "p64-huff.h"#include "dct.h"#include "bsd-endian.h"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(){	mt_ = 0;	mvdh_ = 0;	mvdv_ = 0;	mba_ = 0;	ngob_ = 0;	ndblk_ = 0;	gobquant_ = 0;	gob_ = 0;	maxgob_ = 0;	bad_psc_ = 0;	bad_bits_ = 0;	bad_GOBno_ = 0;	bad_fmt_ = 0;	fs_ = 0;	front_ = 0;	back_ = 0;	marks_ = 0;	mark_ = 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 P64MASK(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__)) & P64MASK(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) & P64MASK(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_64int P64Decoder::parse_block(short* blk, INT_64* mask)#elseint 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[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);}/* * 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;	/*	 * First row.	 */	s += (r00 >> 15) & 0x1fe;	s += (r00 >> 8) & 0xff;	/* round */	s += 2;	s >>= 2;	SPLICE(o, s, 16);	s = (r00 >> 16) & 0xff;	s += (r00 >> 7) & 0x1fe;	s += r00 & 0xff;	/* round */	s += 2;	s >>= 2;	SPLICE(o, s, 8);		s = (r00 >> 8) & 0xff;	s += (r00 & 0xff) << 1;	s += r01 >> 24;	/* round */	s += 2;	s >>= 2;	SPLICE(o, s, 0);	*(u_int*)out = o;		s = r00 & 0xff;	s += (r01 >> 23) & 0x1fe;	s += (r01 >> 16) & 0xff;	/* round */	s += 2;	s >>= 2;	o = 0;	SPLICE(o, s, 24);		s = r01 >> 24;	s += (r01 >> 15) & 0x1fe;	s += (r01 >> 8) & 0xff;	/* round */	s += 2;	s >>= 2;	SPLICE(o, s, 16);		s = (r01 >> 16) & 0xff;	s += (r01 >> 7) & 0x1fe;	s += r01 & 0xff;	/* round */	s += 2;	s >>= 2;	SPLICE(o, s, 8);	/* corner has filter coef 1 */	s = r01 & 0xff;	SPLICE(o, s, 0);	*(u_int*)(out + 4) = o;	out += stride;	/* load next rows into cache */	u_int r10 = in[0] << 24 | in[1] << 16 | in[2] << 8 | in[3];	u_int r11 = in[4] << 24 | in[5] << 16 | in[6] << 8 | in[7];	in += stride;	u_int r20, r21;	u_int mask = 0xff00ff;	for (int k = 6; --k >= 0; ) {		/* load next row */		r20 = in[0] << 24 | in[1] << 16 | in[2] << 8 | in[3];		r21 = in[4] << 24 | in[5] << 16 | in[6] << 8 | in[7];		in += stride;		/* columns 0,2 */		u_int v = (r00 >> 8) & mask;		v += ((r10 >> 8) & mask) << 1;		v += (r20 >> 8) & mask;		/* first pixel */		s = v >> 16;		/* round */		s += 2;		s >>= 2;		o = 0;		SPLICE(o, s, 24);				/* columns 1,3 */		u_int w = r00 & mask;		w += (r10 & mask) << 1;		w += r20 & mask;		/* row */		s = v >> 16;		s += v & 0xffff;		s += w >> (16-1);		/* round */		s += 8;		s >>= 4;		SPLICE(o, s, 16);		s = w >> 16;		s += w & 0xffff;		s += (v & 0xffff) << 1;		/* round */		s += 8;		s >>= 4;		SPLICE(o, s, 8);		/* start next row */		s = v & 0xffff;		s += (w & 0xffff) << 1;		/* but first do columns 4,6 */		v = (r01 >> 8) & mask;		v += ((r11 >> 8) & mask) << 1;		v += (r21 >> 8) & mask;		/* finish row */		s += v >> 16;		/* round */		s += 8;		s >>= 4;		SPLICE(o, s, 0);		*(u_int*)out = o;		/* start next row */		s = w & 0xffff;		s += (v >> 16) << 1;		/* but first do columns 5,7 */		w = r01 & mask;		w += (r11 & mask) << 1;		w += r21 & mask;		/* finish row */		s += w >> 16;		/* round */		s += 8;		s >>= 4;		o = 0;		SPLICE(o, s, 24);		s = v >> 16;		s += v & 0xffff;		s += w >> (16-1);		/* round */		s += 8;		s >>= 4;		SPLICE(o, s, 16);		s = w >> 16;		s += w & 0xffff;		s += (v & 0xffff) << 1;		/* round */		s += 8;		s >>= 4;		SPLICE(o, s, 8);		s = w & 0xffff;		/* round */		s += 2;		s >>= 2;		SPLICE(o, s, 0);		*(u_int*)(out + 4) = o;		out += stride;		/* roll lines up cache */		r00 = r10;		r01 = r11;		r10 = r20;		r11 = r21;	}	/*	 * last row	 */	s = r20 >> 24;	o = 0;	SPLICE(o, s, 24);	s += (r20 >> 15) & 0x1fe;	s += (r20 >> 8) & 0xff;	/* round */	s += 2;	s >>= 2;	SPLICE(o, s, 16);	s = (r20 >> 16) & 0xff;	s += (r20 >> 7) & 0x1fe;	s += r20 & 0xff;	/* round */	s += 2;	s >>= 2;	SPLICE(o, s, 8);		s = (r20 >> 8) & 0xff;	s += (r20 & 0xff) << 1;	s += r21 >> 24;	/* round */	s += 2;	s >>= 2;	SPLICE(o, s, 0);	*(u_int*)out = o;		s = r20 & 0xff;	s += (r21 >> 23) & 0x1fe;	s += (r21 >> 16) & 0xff;	/* round */	s += 2;	s >>= 2;	o = 0;	SPLICE(o, s, 24);		s = r21 >> 24;	s += (r21 >> 15) & 0x1fe;	s += (r21 >> 8) & 0xff;	/* round */	s += 2;	s >>= 2;	SPLICE(o, s, 16);		s = (r21 >> 16) & 0xff;	s += (r21 >> 7) & 0x1fe;	s += r21 & 0xff;	/* round */	s += 2;	s >>= 2;	SPLICE(o, s, 8);	/* corner has filter coef 1 */	s = r21 & 0xff;	SPLICE(o, s, 0);	*(u_int*)(out + 4) = o;}void P64Decoder::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;

⌨️ 快捷键说明

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