?? encoder-h261.cxx
字號:
/*encoder-h261.cc (c) 1999-2000 Derek J Smithies (dereks@ibm.net) * Indranet Technologies ltd (lara@indranet.co.nz) * * This file is derived from vic, http://www-nrg.ee.lbl.gov/vic/ * Their copyright notice is below. *//* * 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: /home/cvsroot/openh323/src/vic/encoder-h261.cxx,v 1.2 2000/02/04 05:16:23 craigs Exp $ (LBL)";#include "encoder-h261.h"H261Encoder::H261Encoder(Transmitter *T) : Encoder(T), bs_(0), bc_(0), ngob_(12){ for (int q = 0; q < 32; ++q) { llm_[q] = 0; clm_[q] = 0; }}H261PixelEncoder:: H261PixelEncoder(Transmitter *T): H261Encoder(T){ quant_required_ = 0; setq(10);}H261DCTEncoder::H261DCTEncoder(Transmitter *T) : H261Encoder(T) { quant_required_ = 1; setq(10);}/* * Set up the forward DCT quantization table for * INTRA mode operation. */voidH261Encoder::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_); }}voidH261Encoder::setq(int q){ setquantizers(q, q / 2, 1);}voidH261PixelEncoder::SetSize(int w, int h){ if(width!=w){ Encoder::SetSize(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*/ PTRACE(0,"BAD GEOMETRY "<<w<<" x "<<h); printf("H261PixelEncoder: H.261 bad geometry: %d x %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_; } }//if(width!=w)}voidH261DCTEncoder::SetSize(int w, int h){ Encoder::SetSize(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*/ printf("H261DCTEncoder: H.261 bad geometry: %d x %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; }}/* * 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*H261Encoder::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) { u_int l = i; if (q) l /= q; lm[i] = l; lm[-i & 0xfff] = -l; if (l <= fthresh) l = 0; flm[i] = l; flm[-i & 0xfff] = -l; } return (lm);}/* * encode_blk: * encode a block of DCT coef's */voidH261Encoder::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;}/* * H261PixelEncoder::encode_mb * encode a macroblock given a set of input YUV pixels */voidH261PixelEncoder::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
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -