📄 p64dump.cpp
字号:
* start code. */ 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_; DUMPBITS('\n'); 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; int mq; GET_BITS(bs_, 5, nbb_, bb_, mq); qt_ = &quant_[mq << 8]; int v; GET_BITS(bs_, 1, nbb_, bb_, v); printf("gob %d q %d x%d ", gob_, mq, v); while (v != 0) { GET_BITS(bs_, 9, nbb_, bb_, v); v &= 1; } DUMPBITS('\n'); gob_ = 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 P64Dumper::parse_mb_hdr(u_int& cbp){ /* * Read the macroblock address (MBA), throwing * away any prefixed stuff bits. */ int v; HUFF_DECODE(bs_, ht_mba_, nbb_, bb_, v); if (v <= 0) { if (v == SYM_STUFFBITS) { printf("pad "); DUMPBITS('\n'); } /* * (probably) hit a start code; either the * next GOB or the next picture header. */ return (v); } /* * MBA is differentially encoded. */ mba_ += v; if (mba_ >= MBPERGOB) { printf("mba? %d ", mba_); DUMPBITS('\n'); err("mba too big %d", mba_); return (SYM_ILLEGAL); } u_int omt = mt_; HUFF_DECODE(bs_, ht_mtype_, nbb_, bb_, mt_); printf("mba %d ", mba_); if (mt_ & MT_INTRA) printf("intra "); if (mt_ & MT_FILTER) printf("filter "); if (mt_ & MT_MQUANT) { int mq; GET_BITS(bs_, 5, nbb_, bb_, mq); qt_ = &quant_[mq << 8]; printf("q %d ", mq); } 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); printf("mv(%d,%d) ", dh, 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. XXX this code is broken */ 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); printf("cbp %02x ", cbp); if (cbp > 63) { DUMPBITS('\n'); err("cbp invalid %x", cbp); return (SYM_ILLEGAL); } } else cbp = 0x3f; DUMPBITS('\n'); return (1);}/* * Handle the next block in the current macroblock. * If tc is non-zero, then coeffcients 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 P64Dumper::decode_block(u_int tc, u_int x, u_int y, u_int stride, u_char* front, u_char* back, int sf, int n){ if (tc != 0) printf("blk %d ", n); 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 if (tc != 0) parse_block(blk, MASK_REF); int off = y * stride + x; u_char* out = front + off; if (mt_ & MT_INTRA) { if (tc != 0) 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) 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) rdct(blk, MASK_VAL, out, stride, out); } else { if (tc != 0) 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 P64Dumper::decode_mb(){ u_int cbp; //register int mba = mba_ + 1; 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, 1); decode_block(tc & (cbp >> 4), x + 8, y, s, front_, back_, 1, 2); decode_block(tc & (cbp >> 3), x, y + 8, s, front_, back_, 1, 3); decode_block(tc & (cbp >> 2), x + 8, y + 8, s, front_, back_, 1, 4); s >>= 1; int off = size_; decode_block(tc & (cbp >> 1), x >> 1, y >> 1, s, front_ + off, back_ + off, 2, 5); off += size_ >> 2; decode_block(tc & (cbp >> 0), x >> 1, y >> 1, s, front_ + off, back_ + off, 2, 6); 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 P64Dumper::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 even, ignore 8 extra bits in last short. */ int odd = cc & 1; ebit += (odd ^ 1) << 3; pebit_ = ebit; cc -= odd; es_ = (u_short*)(bp + cc); /* * 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; } dbs_ = bs_; dnbb_ = nbb_; dbb_ = bb_; 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]; int v = decode_mb(); if (v == 0) continue; if (v != SYM_STARTCODE) { ++bad_bits_; return (0); } gob = parse_gob_hdr(ebit); if (gob < 0) { /*XXX*/ ++bad_bits_; return (0); } } fflush(stdout); return (1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -