📄 p64.cxx
字号:
/*
* 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 = 0, r21 = 0;
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;
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);
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.
*/
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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -