?? encoder-h261.cxx
字號:
* coef (so we can pick a new quantizer if gquant doesn't have * enough range). */ /*XXX this can be u_char instead of short but need smarts in fdct */ short blk[64 * 6]; register int stride = width; /* luminance */ const u_char* p = &frm[loff]; fdct(p, stride, blk + 0, qt); fdct(p + 8, stride, blk + 64, qt); fdct(p + 8 * stride, stride, blk + 128, qt); fdct(p + (8 * stride + 8), stride, blk + 192, qt); /* chominance */ int fs = framesize; p = &frm[fs + coff]; stride >>= 1; fdct(p, stride, blk + 256, qt); fdct(p + (fs >> 2), stride, blk + 320, qt); /* * if the default quantizer is too small to handle the coef. * dynamic range, spin through the blocks and see if any * coef. would significantly overflow. */ if (q < 8) { register int cmin = 0, cmax = 0; register short* bp = blk; for (register int i = 6; --i >= 0; ) { ++bp; // ignore dc coef for (register int j = 63; --j >= 0; ) { register int v = *bp++; if (v < cmin) cmin = v; else if (v > cmax) cmax = v; } } if (cmax < -cmin) cmax = -cmin; if (cmax >= 128) { /* need to re-quantize */ register int s; for (s = 1; cmax >= (128 << s); ++s) { } q <<= s; register short* bp = blk; for (register int i = 6; --i >= 0; ) { ++bp; // ignore dc coef for (register int j = 63; --j >= 0; ) { register int v = *bp; *bp++ = v >> s; } } } } u_int m = mba - mba_; mba_ = mba; huffent* he = &hte_mba[m - 1]; /* MBA */ PUT_BITS(he->val, he->nb, nbb_, bb_, bc_); if (q != mquant_) { /* MTYPE = INTRA + TC + MQUANT */ PUT_BITS(1, 7, nbb_, bb_, bc_); PUT_BITS(q, 5, nbb_, bb_, bc_); mquant_ = q; } else { /* MTYPE = INTRA + TC (no quantizer) */ PUT_BITS(1, 4, nbb_, bb_, bc_); } /* luminance */ const char* lm = llm_[q]; if (lm == 0) { lm = make_level_map(q, 1); llm_[q] = lm; clm_[q] = make_level_map(q, 2); } encode_blk(blk + 0, lm); encode_blk(blk + 64, lm); encode_blk(blk + 128, lm); encode_blk(blk + 192, lm); /* chominance */ lm = clm_[q]; encode_blk(blk + 256, lm); encode_blk(blk + 320, lm);}/* * H261DCTEncoder::encode_mb * encode a macroblock given a set of input DCT coefs * each coef is stored as a short */voidH261DCTEncoder::encode_mb(u_int mba, const u_char* frm, u_int loff, u_int coff, int how){ short *lblk = (short *)frm + loff; short *ublk = (short *)frm + coff; short *vblk = (short *)frm + coff + 64; register u_int q; if (how == CR_MOTION) q = lq_; else if (how == CR_BG) q = hq_; else /* must be at age threshold */ q = mq_; /* * if the default quantizer is too small to handle the coef. * dynamic range, spin through the blocks and see if any * coef. would significantly overflow. */ if (q < 8) { register int cmin = 0, cmax = 0; register short* bp = lblk; register int i, j; // Y U and V blocks for (i = 6; --i >= 0; ) { ++bp; // ignore dc coef for (j = 63; --j >= 0; ) { register int v = *bp++; if (v < cmin) cmin = v; else if (v > cmax) cmax = v; } } if (cmax < -cmin) cmax = -cmin; cmax /= (q << 1); if (cmax >= 128) { /* need to re-quantize */ register int s; for (s = 1; cmax >= (128 << s); ++s) { } q <<= s; } } u_int m = mba - mba_; mba_ = mba; huffent* he = &hte_mba[m - 1]; /* MBA */ PUT_BITS(he->val, he->nb, nbb_, bb_, bc_); if (q != mquant_) { /* MTYPE = INTRA + TC + MQUANT */ PUT_BITS(1, 7, nbb_, bb_, bc_); PUT_BITS(q, 5, nbb_, bb_, bc_); mquant_ = q; } else { /* MTYPE = INTRA + TC (no quantizer) */ PUT_BITS(1, 4, nbb_, bb_, bc_); } /* luminance */ const char* lm = llm_[q]; if (lm == 0) { /* * the filter thresh is 0 since we assume the jpeg percept. * quantizer already did the filtering. */ lm = make_level_map(q, 0); llm_[q] = lm; clm_[q] = make_level_map(q, 0); } encode_blk(lblk + 0, lm); encode_blk(lblk + 64, lm); encode_blk(lblk + 128, lm); encode_blk(lblk + 192, lm); /* chominance */ lm = clm_[q]; encode_blk(ublk, lm); encode_blk(vblk, lm);}intH261Encoder::flush(Transmitter::pktbuf* pb, int nbit, Transmitter::pktbuf* npb){ /* flush bit buffer */ STORE_BITS(bb_, bc_); int cc = (nbit + 7) >> 3; int ebit = (cc << 3) - nbit; /*XXX*/ if (cc == 0 && npb != 0) abort(); pb->lenHdr = HDRSIZE; pb->lenBuf = cc; u_int* rh = (u_int*)pb->hdr; *rh = (*rh) | ebit << 26 | sbit_ << 29; if (npb != 0) { u_char* nbs = (u_char*)npb->buf->data; u_int bc = (bc_ - bs_) << 3; int tbit = bc + nbb_; int extra = ((tbit + 7) >> 3) - (nbit >> 3); if (extra > 0) memcpy(nbs, bs_ + (nbit >> 3), extra); bs_ = nbs; sbit_ = nbit & 7; tbit -= nbit &~ 7; bc = tbit &~ (NBIT - 1); nbb_ = tbit - bc; bc_ = bs_ + (bc >> 3); /* * Prime the bit buffer. Be careful to set bits that * are not yet in use to 0, since output bits are later * or'd into the buffer. */ if (nbb_ > 0) { u_int n = NBIT - nbb_; bb_ = (LOAD_BITS(bc_) >> n) << n; } else bb_ = 0; } tx_->StoreOnePacket(pb); return (cc + HDRSIZE);}int H261DCTEncoder::consume(const VideoFrame *vf){ if (!SameSize(vf)) SetSize(vf->width, vf->height); DCTFrame* df = (DCTFrame *)vf; return(encode(df, df->crvec));}int H261PixelEncoder::consume(const VideoFrame *vf){ if (!SameSize(vf)) SetSize(vf->width, vf->height); return(encode(vf, vf->crvec));} //////NOTE: HDRSIZE is the size of the H261 hdr in the rtp packet.==4intH261Encoder::encode(const VideoFrame* vf, const BYTE *crvec){ Transmitter::pktbuf* pb = tx_->alloc(); bs_ = (u_char*)pb->buf->data; bc_ = bs_; u_int ec = (tx_->mtu() - HDRSIZE) << 3; bb_ = 0; nbb_ = 0; sbit_ = 0; /* RTP/H.261 header */ u_int* rh = (u_int*)pb->hdr; *rh = 1 << 25 | lq_ << 10; /* PSC */ PUT_BITS(0x0001, 16, nbb_, bb_, bc_); /* GOB 0 -> picture header */ PUT_BITS(0, 4, nbb_, bb_, bc_); /* TR (XXX should do this right) */ PUT_BITS(0, 5, nbb_, bb_, bc_); /* PTYPE = CIF */ int pt = cif_ ? 4 : 0; PUT_BITS(pt, 6, nbb_, bb_, bc_); /* PEI */ PUT_BITS(0, 1, nbb_, bb_, bc_); int step = cif_ ? 1 : 2; int cc = 0; BYTE* frm = vf->frameptr; for (u_int gob = 0; gob < ngob_; gob += step) { u_int loff = loff_[gob]; u_int coff = coff_[gob]; u_int blkno = blkno_[gob]; u_int nbit = ((bc_ - bs_) << 3) + nbb_; /* GSC/GN */ PUT_BITS(0x10 | (gob + 1), 20, nbb_, bb_, bc_); /* GQUANT/GEI */ mquant_ = lq_; PUT_BITS(mquant_ << 1, 6, nbb_, bb_, bc_); mba_ = 0; int line = 11; for (u_int mba = 1; mba <= 33; ++mba) { /* * If the conditional replenishment algorithm * has decided to send any of the blocks of * this macroblock, code it. */ u_int s = crvec[blkno]; if ((s & CR_SEND) != 0) { u_int mbpred = mba_; encode_mb(mba, frm, loff, coff, CR_STATE(s)); u_int cbits = ((bc_ - bs_) << 3) + nbb_; if (cbits > ec) { Transmitter::pktbuf* npb; npb = tx_->alloc(); cc += flush(pb, nbit, npb); cbits -= nbit; pb = npb; /* RTP/H.261 header */ u_int m = mbpred; u_int g; if (m != 0) { g = gob + 1; m -= 1; } else g = 0; rh = (u_int*)pb->hdr; *rh = 1 << 25 | //set motion vector flag. m << 15 | //macroblock address predictor. g << 20 | //Group of blocks number. mquant_ << 10;//quantizer value. } nbit = cbits; } loff += loffsize_; coff += coffsize_; blkno += bloffsize_; if (--line <= 0) { line = 11; blkno += bstride_; loff += lstride_; coff += cstride_; } } } cc += flush(pb, ((bc_ - bs_) << 3) + nbb_, 0); return (cc);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -