📄 h261decoder.cpp
字号:
{20,11}, {11,11}, {21,11}, {10,10}, {10,10}, {22,10}, {22,10}, {9,10}, {9,10}, {23,10}, {23,10}, {8,10}, {8,10}, {24,10}, {24,10}, {7,8}, {7,8}, {7,8}, {7,8}, {7,8}, {7,8}, {7,8}, {7,8}, {25,8}, {25,8}, {25,8}, {25,8}, {25,8}, {25,8}, {25,8}, {25,8}, {6,8}, {6,8}, {6,8}, {6,8}, {6,8}, {6,8}, {6,8}, {6,8}, {26,8}, {26,8}, {26,8}, {26,8}, {26,8}, {26,8}, {26,8}, {26,8}, {5,8}, {5,8}, {5,8}, {5,8}, {5,8}, {5,8}, {5,8}, {5,8}, {27,8}, {27,8}, {27,8}, {27,8}, {27,8}, {27,8}, {27,8}, {27,8}, {4,7}, {4,7}, {4,7}, {4,7}, {4,7}, {4,7}, {4,7}, {4,7}, {4,7}, {4,7}, {4,7}, {4,7}, {4,7}, {4,7}, {4,7}, {4,7}, {28,7}, {28,7}, {28,7}, {28,7}, {28,7}, {28,7}, {28,7}, {28,7}, {28,7}, {28,7}, {28,7}, {28,7}, {28,7}, {28,7}, {28,7}, {28,7}};static int dec_MVD(H261DEC_STATE* dec_state){ unsigned int code; int mvd, len; H261_vlc vlc; code = _ShowBits(dec_state, 11); if (code & 1024) { mvd = 0; len = 1; } else if ((code >> 6) >= 2) { vlc = mvd_tab1[(code >> 6) - 2]; mvd = vlc.val; len = vlc.len; } else if (code >= 25) { vlc = mvd_tab2[code - 25]; mvd = vlc.val; len = vlc.len; } else return VLC_ERR; _FlushBits(dec_state, len); return mvd;}/*-------------------------------------------------------------*/static const Ipp8u cbp_tab1[64] ={ 34, 18, 10, 6, 33, 17, 9, 5, 63, 63, 3, 3, 36, 36, 24, 24, 62, 62, 62, 62, 2, 2, 2, 2, 61, 61, 61, 61, 1, 1, 1, 1, 56, 56, 56, 56, 52, 52, 52, 52, 44, 44, 44, 44, 28, 28, 28, 28, 40, 40, 40, 40, 20, 20, 20, 20, 48, 48, 48, 48, 12, 12, 12, 12};static const Ipp8s cbp_tab2[64] ={ VLC_ERR, VLC_ERR, 39, 27, 59, 55, 47, 31, 58, 58, 54, 54, 46, 46, 30, 30, 57, 57, 53, 53, 45, 45, 29, 29, 38, 38, 26, 26, 37, 37, 25, 25, 43, 43, 23, 23, 51, 51, 15, 15, 42, 42, 22, 22, 50, 50, 14, 14, 41, 41, 21, 21, 49, 49, 13, 13, 35, 35, 19, 19, 11, 11, 7, 7};static int dec_CBP(H261DEC_STATE* dec_state){ unsigned int code; int val, len, c4; code = _ShowBits(dec_state, 9); c4 = code >> 5; if (c4 >= 10) { if (c4 >= 14) { val = 60; len = 3; } else { val = 1 << (15 - c4); len = 4; } } else if (c4 > 1) { val = cbp_tab1[(code >> 2) - 16]; len = (c4 > 3) ? 5 : (9 - c4); } else { val = cbp_tab2[code]; len = (code > 7) ? 8 : 9; } _FlushBits(dec_state, len); return val;}/*-------------------------------------------------------------*/// decoded picture will be in dec_state->refPicint getPicture(H261DEC_STATE* dec_state){ int i, numgob, picType = 0, err = 0; int xpos; int ypos; int mbxpos, mbypos; int gob = 0; int mba = 0, mba_dif; int mtype; int cbp; int mquant; int r; int mvx, mvy, mvxd, mvyd; int bx, by; Ipp32u code; IppiSize roiY, roiC; int offY, offC; for (numgob = 0; numgob < dec_state->numgob; numgob ++) { if (dec_state->bufptr - dec_state->buffer >= (dec_state->buflen - 1)) { err = 0; break; } // GPSC code = _GetBits(dec_state, 20); if (code < 16) { err = -1; break; } gob = code & 15; if ((gob <= 0) || (gob > 12) || ((dec_state->picture_format == 0) && ((gob > 5) || ((gob & 1) == 0)))) { ErrMsg("Invalid GOB number"); // gob numbers 13-15 are reserved for future use err = -1; break; } mquant = _GetBits(dec_state, 5); // To be used until overriden by any subsequent MQUANT if (!mquant) { ErrMsg("Invalid GQUANT"); err = -1; break; } while (_GetBits(dec_state, 1)) { // extra insertion information (GEI) _FlushBits(dec_state, 8); // GSPARE } xpos = (gob & 1) ? 0 : 11; ypos = ((gob - 1) >> 1) * 3; mba = 0; mvx = mvy = 0; for (;;) { code = _ShowBits(dec_state, 11); while (code == 15) { /* MBA stuffing */ _FlushBits(dec_state, 11); code = _ShowBits(dec_state, 11); } if (code == 0) { /* start code */ if (mba < 33) { /* need to copy the gob's skipped tail */ mbxpos = mba % 11; mbypos = mba / 11; bx = 16 * (mbxpos + xpos); by = 16 * (mbypos + ypos); offY = by * dec_state->picture_width + bx; offC = (by * dec_state->picture_width >> 2) + (bx >> 1); roiY.width = (11 - mbxpos) * 16; roiY.height = 16; roiC.width = roiY.width >> 1; roiC.height = 8; ippiCopy_8u_C1R(dec_state->refPic[0] + offY, dec_state->picture_width, dec_state->curPic[0] + offY, dec_state->picture_width, roiY); ippiCopy_8u_C1R(dec_state->refPic[1] + offC, dec_state->picture_width >> 1, dec_state->curPic[1] + offC, dec_state->picture_width >> 1, roiC); ippiCopy_8u_C1R(dec_state->refPic[2] + offC, dec_state->picture_width >> 1, dec_state->curPic[2] + offC, dec_state->picture_width >> 1, roiC); if (mbypos < 2) { offY = (by + 16) * dec_state->picture_width + xpos * 16; offC = ((by + 16) * dec_state->picture_width >> 2) + xpos * 8; roiY.width = 16*11; roiC.width = 8*11; roiY.height = (2 - mbypos) * 16; roiC.height = roiY.height >> 1; ippiCopy_8u_C1R(dec_state->refPic[0] + offY, dec_state->picture_width, dec_state->curPic[0] + offY, dec_state->picture_width, roiY); ippiCopy_8u_C1R(dec_state->refPic[1] + offC, dec_state->picture_width >> 1, dec_state->curPic[1] + offC, dec_state->picture_width >> 1, roiC); ippiCopy_8u_C1R(dec_state->refPic[2] + offC, dec_state->picture_width >> 1, dec_state->curPic[2] + offC, dec_state->picture_width >> 1, roiC); } } break; } mba_dif = dec_MBA(dec_state); if (mba_dif < 0) { ErrMsg("Invalid MBA"); err = -1; break; } if (mba_dif > 1) { /* need to copy the skipped mbs */ int nmbs = mba_dif - 1; int w; mbxpos = mba % 11; mbypos = mba / 11; roiY.height = 16; roiC.height = 8; while (nmbs > 0) { bx = 16 * (mbxpos + xpos); by = 16 * (mbypos + ypos); offY = by * dec_state->picture_width + bx; offC = (by * dec_state->picture_width >> 2) + (bx >> 1); w = nmbs > (11 - mbxpos) ? (11 - mbxpos) : nmbs; nmbs -= w; roiY.width = w*16; roiC.width = roiY.width >> 1; ippiCopy_8u_C1R(dec_state->refPic[0] + offY, dec_state->picture_width, dec_state->curPic[0] + offY, dec_state->picture_width, roiY); ippiCopy_8u_C1R(dec_state->refPic[1] + offC, dec_state->picture_width >> 1, dec_state->curPic[1] + offC, dec_state->picture_width >> 1, roiC); ippiCopy_8u_C1R(dec_state->refPic[2] + offC, dec_state->picture_width >> 1, dec_state->curPic[2] + offC, dec_state->picture_width >> 1, roiC); mbxpos = 0; mbypos++; } } mba += mba_dif; mbxpos = xpos + ((mba - 1) % 11); mbypos = ypos + (mba - 1) / 11; if ((mba == 12) || (mba == 23) || (mba_dif > 1)) { mvx = mvy = 0; } mtype = dec_MTYPE(dec_state); if (mtype < 0) { ErrMsg("Invalid MTYPE"); err = -1; break; } if (mtype & MTYPE_MQUANT) { mquant = _GetBits(dec_state, 5); // To be used until overriden by any subsequent MQUANT if (!mquant) { ErrMsg("Invalid MQUANT"); err = -1; break; } } if (mtype & MTYPE_MVD) { mvxd = dec_MVD(dec_state); if (mvxd < 0) { ErrMsg("Invalid horizontal MV"); err = -1; break; } mvyd = dec_MVD(dec_state); if (mvyd < 0) { ErrMsg("Invalid vertical MV"); err = -1; break; } mvx += mvxd; if (mvx > 16) // MV range is [-15,15], (mv==16) implies an error in the stream mvx -= 32; mvy += mvyd; if (mvy > 16) mvy -= 32; } else { mvx = mvy = 0; } if (mtype & MTYPE_INTRA) cbp = 63; else if (mtype & MTYPE_TCOEFF) { cbp = dec_CBP(dec_state); if (cbp < 0) { ErrMsg("Invalid CBP"); err = -1; break; } } else cbp = 0; bx = 16 * mbxpos; by = 16 * mbypos; if (!(mtype & MTYPE_INTRA)) { picType = 1; reconstruct(bx, by, mvx, mvy, mtype & MTYPE_FIL, dec_state); for (i = 0; i < 6; i++) { if (cbp & (32 >> i)) { r = reconBlock(bx, by, i, mquant, dec_state); if (r < 0) { ErrMsg("reconBlock failed"); err = -1; break; } } } } else { // intra for (i = 0; i < 6; i++) { r = fillBlock(bx, by, i, mquant, dec_state); if (r < 0) { ErrMsg("fillBlock failed"); err = -1; break; } } } } if (err) { break; } } _SWAP(dec_state->curPic[0], dec_state->refPic[0]); _SWAP(dec_state->curPic[1], dec_state->refPic[1]); _SWAP(dec_state->curPic[2], dec_state->refPic[2]); dec_state->picType = picType; return err;} // getPicture()bool initDecoder(H261DEC_STATE *dec_state){ int picture_width, picture_height; dec_state->bufptr = dec_state->buffer; dec_state->bitoff = 0; if (getPictureHeader(dec_state) != 0) return false; dec_state->bufptr = dec_state->buffer; dec_state->bitoff = 0; picture_width = dec_state->picture_width; picture_height = dec_state->picture_height; dec_state->curPic[0] = dec_state->curPic[1] = dec_state->curPic[2] = dec_state->refPic[0] = dec_state->refPic[1] = dec_state->refPic[2] = 0; dec_state->curPic[0] = ippsMalloc_8u(picture_width * picture_height); dec_state->curPic[1] = ippsMalloc_8u(picture_width * picture_height / 4); dec_state->curPic[2] = ippsMalloc_8u(picture_width * picture_height / 4); dec_state->refPic[0] = ippsMalloc_8u(picture_width * picture_height); dec_state->refPic[1] = ippsMalloc_8u(picture_width * picture_height / 4); dec_state->refPic[2] = ippsMalloc_8u(picture_width * picture_height / 4); if (!dec_state->curPic[0] || !dec_state->curPic[1] || !dec_state->curPic[2] || !dec_state->refPic[0] || !dec_state->refPic[1] || !dec_state->refPic[2]) { freeDecoder(dec_state); return false; } return true;} // initDecoder()void freeDecoder(H261DEC_STATE* dec_state){ ippsFree(dec_state->curPic[0]); ippsFree(dec_state->curPic[1]); ippsFree(dec_state->curPic[2]); ippsFree(dec_state->refPic[0]); ippsFree(dec_state->refPic[1]); ippsFree(dec_state->refPic[2]);} // freeDecoder()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -