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

📄 p64.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 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;	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 P64Decoder::mvblk(u_char* in, u_char* out, u_int stride){#ifdef INT_64	if (((u_long)in & 7) == 0) {		mvblka(in, out, stride);		return;	}#else	if (((u_long)in & 3) == 0) {		mvblka(in, out, stride);		return;	}#endif	for (int k = 8; --k >= 0;) {		u_int* o = (u_int*)out;#if BYTE_ORDER == LITTLE_ENDIAN		o[0] = in[3] << 24 | in[2] << 16 | in[1] << 8 | in[0];		o[1] = in[7] << 24 | in[6] << 16 | in[5] << 8 | in[4];#else		o[0] = in[0] << 24 | in[1] << 16 | in[2] << 8 | in[3];		o[1] = in[4] << 24 | in[5] << 16 | in[6] << 8 | in[7];#endif		in += stride;		out += stride;	}}/* * Parse a picture header.  We assume that the * start code has already been snarfed. */int P64Decoder::parse_picture_hdr(){	/* throw away the temporal reference */	SKIP_BITS(bs_, 5, nbb_, bb_);	int pt;	GET_BITS(bs_, 6, nbb_, bb_, pt);	u_int fmt = (pt >> 2) & 1;	if (fmt_ != fmt) {		/* change formats */		fmt_ = fmt;		init();	}	int v;	GET_BITS(bs_, 1, nbb_, bb_, v);	while (v != 0) {		GET_BITS(bs_, 9, nbb_, bb_, v);		/*		 * XXX from pvrg code: 0x8c in PSPARE means ntsc.		 * this is a hack.  we don't support it.		 */		int pspare = v >> 1;		if (pspare == 0x8c && (pt & 0x04) != 0) {			static int first = 1;			if (first) {				err("pvrg ntsc not supported");				first = 0;			}		}		v &= 1;	}	return (0);}inline int P64Decoder::parse_sc(){	int v;	GET_BITS(bs_, 16, nbb_, bb_, v);	if (v != 0x0001) {		err("bad start code %04x", v);		++bad_psc_;		return (-1);	}	return (0);}/* * Parse a GOB header, which consists of the GOB quantiation * factor (GQUANT) and spare bytes that we ignore. */int P64Decoder::parse_gob_hdr(int ebit){	mba_ = -1;	mvdh_ = 0;	mvdv_ = 0;	/*	 * Get the next GOB number (or 0 for a picture header).	 * The invariant at the top of this loop is that the	 * bit stream is positioned immediately past the last	 * start code.	 */	u_int gob;	for (;;) {		GET_BITS(bs_, 4, nbb_, bb_, gob);		if (gob != 0)			break;		/*		 * should happen only on first iteration		 * (if at all).  pictures always start on		 * packet boundaries per section 5 of the		 * Internet Draft.		 */		if (parse_picture_hdr() < 0) {			++bad_fmt_;			return (-1);		}		/*		 * Check to see that the next 16 bits		 * are a start code and throw them away.		 * But first check that we have the bits.		 */		int nbit = ((es_ - bs_) << 4) + nbb_ - ebit;		if (nbit < 20)			return (0);		if (parse_sc() < 0)			return (-1);	}	gob -= 1;	if (fmt_ == IT_QCIF)		/*		 * Number QCIF GOBs 0,1,2 instead of 0,2,4.		 */		gob >>= 1;	if (gob >= ngob_) {		err("gob number too big (%d>%d)", gob, ngob_);		return (-1);	}	int mq;	GET_BITS(bs_, 5, nbb_, bb_, mq);	gobquant_ = mq;	qt_ = &quant_[mq << 8];	int v;	GET_BITS(bs_, 1, nbb_, bb_, v);	while (v != 0) {		GET_BITS(bs_, 9, nbb_, bb_, v);		v &= 1;	}	gob_ = gob;	if (gob > maxgob_)		maxgob_ = gob;	return (gob);}/* * Parse a macroblock header.  If there is no mb header because * we hit the next start code, return -1, otherwise 0. */int P64Decoder::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) {		err("mba too big %d", mba_);		return (SYM_ILLEGAL);	}	u_int omt = mt_;	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];	}	if (mt_ & MT_MVD) {		/*		 * Read motion vector.		 */		int dh;		int dv;		HUFF_DECODE(bs_, ht_mvd_, nbb_, bb_, dh);		HUFF_DECODE(bs_, ht_mvd_, nbb_, bb_, dv);		/*		 * Section 4.2.3.4		 * The vector is differentially coded unless any of:		 *   - the current mba delta isn't 1		 *   - the current mba is 1, 12, or 23 (mba mod 11 = 1)		 *   - the last block didn't have motion vectors.		 *		 * This arithmetic is twos-complement restricted		 * to 5 bits.		 */		if ((omt & MT_MVD) != 0 && v == 1 &&		    mba_ != 0 && mba_ != 11 && mba_ != 22) {			dh += mvdh_;			dv += mvdv_;		}		mvdh_ = (dh << 27) >> 27;		mvdv_ = (dv << 27) >> 27;	}	/*	 * 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 P64Decoder::decode_block(u_int tc, u_int x, u_int y, u_int stride,			      u_char* front, u_char* back, int 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;	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);#ifdef notdef			else if (nc == 1) {#ifdef INT_64				u_int dc = (mask & 1) ? (blk[0] + 4) >> 3 : 0;				for (int k = 1; k < 64; ++k) {					if (mask & ((INT_64)1 << k)) {						bv_rdct1(dc, blk, k,							 out, stride);						return;					}				}#else				u_int m0 = mask[0];				u_int m1 = mask[1];				u_int dc = (m0 & 1) ? (blk[0] + 4) >> 3 : 0;				for (int k = 1; k < 64; ++k) {					m0 >>= 1;					m0 |= m1 << 31;					m1 >>= 1;					if (m0 & 1) {						bv_rdct1(dc, blk, k,							 out, stride);						return;					}				}#endif#endif			 else				rdct(blk, MASK_VAL, out, stride, (u_char*)0);		} else {			u_char* in = back + off;			mvblka(in, out, stride);		}		return;	}	if ((mt_ & MT_MVD) == 0) {		u_char* in = back + off;		if (tc != 0) {				if (nc == 0) {				dcsum((blk[0] + 4) >> 3, in, out, stride);			} else				rdct(blk, MASK_VAL, out, stride, in);		} else			mvblka(in, out, stride);		return;	}	u_int sx = x + (mvdh_ / sf);	u_int sy = y + (mvdv_ / sf);	u_char* in = back + sy * stride + sx;	if (mt_ & MT_FILTER) {		filter(in, out, stride);		if (tc != 0) {			if (nc == 0)				dcsum2((blk[0] + 4) >> 3, out, out, stride);			else				rdct(blk, MASK_VAL, out, stride, out);		}	} else {		if (tc != 0) {			if (nc == 0)				dcsum2((blk[0] + 4) >> 3, in, out, stride);			else				rdct(blk, MASK_VAL, out, stride, in);		} else			mvblk(in, out, stride);	}}/* * 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 P64Decoder::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_[mba_];	y = (x & 0xff) << 3;	x >>= 8;	x <<= 3;	/* 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 P64Decoder::decode(const u_char* bp, int cc, int sbit, int ebit,		       int mba, int gob, int mq, int mvdh, int mvdv){	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 ((int)bp & 1) {		bs_ = (u_short*)(bp + 1);		bb_ = *bp;		nbb_ = 8 - sbit;	} else {		bs_ = (u_short*)bp;		HUFFRQ(bs_, bb_);		nbb_ = 16 - sbit;	}	mba_ = mba;	qt_ = &quant_[mq << 8];	mvdh_ = mvdh;	mvdv_ = mvdv;	/*XXX don't rely on this*/	if (gob != 0) {		gob -= 1;		if (fmt_ == IT_QCIF)			gob >>= 1;	}	while (bs_ < es_ || (bs_ == es_ && nbb_ > ebit)) {		mbst_ = &mb_state_[gob << 6];		coord_ = &base_[gob << 6];		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);}FullP64Decoder::FullP64Decoder(){	init();}void FullP64Decoder::allocate(){	delete fs_;	int n = size_ + (size_ >> 1);	fs_ = new u_char[2 * n];	/* initialize to gray */	memset(fs_, 0x80, 2 * n);	front_ = fs_;	back_ = front_ + n;}/* * Swap the `front' and `back' frame buffers.  While decoding a * frame, the front buffer is the image being constructed while * the back buffer is the reference image.  Rather than copy * the whole image each time, we just swap pointers here. * We defer this copying until we find out that we're skipping * over a macroblock, or even a whole gob.  In this case, we * go ahead and copy it, but take note in the mb_skip_ array. * Next time we need to copy it, we skip it if the skip array * says it's okay (e.g., there is no reason to copy a given block * back and forth between buffers if it never changes).  When we * modify a macroblock, we clear out it's entry in mb_skip_. */void FullP64Decoder::swap(){	u_char* p = front_;	front_ = back_;	back_ = p;}/* * Copy a macroblock from the saved frame (back buffer) * to the current frame (front buffer). coord_ determines * which GOB we're in. */void FullP64Decoder::mbcopy(u_int mba){	u_int x, y;	x = coord_[mba];	y = (x & 0xff) << 3;	x >>= 8;	x <<= 3;	u_int stride = width_;	u_int off = y * stride + x;	u_char* in = back_ + off;	u_char* out = front_ + off;	mvblka(in, out, stride);	mvblka(in + 8, out + 8, stride);	in += stride << 3;	out += stride << 3;	mvblka(in, out, stride);	mvblka(in + 8, out + 8, stride);	x >>= 1;	y >>= 1;	stride >>= 1;	off = y * stride + x;	off += size_;	in = back_ + off;	out = front_ + off;	mvblka(in, out, stride);	off += size_ >> 2;	in = back_ + off;	out = front_ + off;	mvblka(in, out, stride);}void P64Decoder::sync(){	bbx_ = minx_;	bby_ = miny_;	bbw_ = maxx_ - minx_ + 16;	bbh_ = maxy_ - miny_ + 16;	minx_ = width_;	miny_ = height_;	maxx_ = 0;	maxy_ = 0;	maxgob_ = 0;}void FullP64Decoder::sync(){	for (u_int k = 0; k < ngob_; ++k) {		coord_ = &base_[k << 6];		u_char* mbst = &mb_state_[k << 6];		for (int mba = 0; mba < MBPERGOB; ++mba) {			int s = mbst[mba];			if (s == MBST_FRESH) {				mbcopy(mba);				mbst[mba] = MBST_OLD;			} else if (s == MBST_NEW)				mbst[mba] = MBST_FRESH;		}	}	swap();	P64Decoder::sync();}IntraP64Decoder::IntraP64Decoder(){	init();}void IntraP64Decoder::allocate(){	delete fs_;	int n = size_ + (size_ >> 1);	fs_ = new u_char[n];	/* initialize to gray */	memset(fs_, 0x80, n);	front_ = back_ = fs_;}

⌨️ 快捷键说明

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