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

📄 p64.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: p64.cpp,v 1.1.8.1 2004/07/09 01:50:08 hubbe Exp $ *  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved. *  * The contents of this file, and the files included with this file, * are subject to the current version of the RealNetworks Public * Source License (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (the "RCSL") available at * http://www.helixcommunity.org/content/rcsl, in which case the RCSL * will apply. You may also obtain the license terms directly from * RealNetworks.  You may not use this file except in compliance with * the RPSL or, if you have a valid RCSL with RealNetworks applicable * to this file, the RCSL.  Please see the applicable RPSL or RCSL for * the rights, obligations and limitations governing use of the * contents of the file. *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. *  * This file is part of the Helix DNA Technology. RealNetworks is the * developer of the Original Code and owns the copyrights in the * portions it created. *  * This file, and the files included with this file, is distributed * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET * ENJOYMENT OR NON-INFRINGEMENT. *  * Technology Compatibility Kit Test Suite(s) Location: *    http://www.helixcommunity.org/content/tck *  * Contributor(s): *  * ***** END LICENSE BLOCK ***** *//* * 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. */#ifndef lintstatic char rcsid[] =    "@(#) $Header: /cvsroot/datatype/h261/renderer/p64.cpp,v 1.1.8.1 2004/07/09 01:50:08 hubbe Exp $ (LBL)";#endif#include <stdarg.h>#include <stdio.h>#include <string.h>#include "hxtypes.h"#include "hxmarsh.h"#ifndef _MACINTOSH #ifdef WIN32 #  include <winsock.h> #else #  include <sys/param.h> #  include <sys/file.h> #endif // WIN32#   include <sys/stat.h>#else#   include "config.h"#endif // _MACINTOSH#include "p64.h"#include "p64-huff.h"#include "dct.h"#include "bsd-endian.h"#include "hxheap.h"#ifdef _DEBUG    #undef HX_THIS_FILE		    static char HX_THIS_FILE[] = __FILE__;#endifvoid 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#ifdef WIN32#ifdef _DEBUG	char sz[ 512 ]; /* Flawfinder: ignore */	va_list ap;	va_start(ap, msg);	vsprintf( sz, msg, ap); /* Flawfinder: ignore */	OutputDebugString(sz);	sprintf(sz, " @g%d m%d %d/%d of %d/%d: %04x %04x %04x %04x|%04x\n", /* Flawfinder: ignore */		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]);	OutputDebugString(sz);#endif#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 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_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;				// this is a hack to prevent player crash.		if (nbb < 16 && bs_ > es_)		{				    register int s__, v__;		    bb <<= 16;		    nbb += 16;	    	    s__ = ht_tcoeff_.maxlen;	    	    v__ = (bb >> (nbb - s__)) & MASK(s__);	    	    s__ = (ht_tcoeff_.prefix)[v__];	    	    nbb -= (s__ & 0x1f);	    	    r = s__ >> 5;	    	    		} else {				    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;

⌨️ 快捷键说明

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