📄 h261decoder.cpp
字号:
/* ////////////////////////////////////////////////////////////////////////////// INTEL CORPORATION PROPRIETARY INFORMATION// This software is supplied under the terms of a license agreement or// nondisclosure agreement with Intel Corporation and may not be copied// or disclosed except in accordance with the terms of that agreement.// Copyright (c) 2005 Intel Corporation. All Rights Reserved.//*/#include "h261decoder.h"static Ipp32u _ShowBits(H261DEC_STATE* dec_state, int n){ Ipp8u* ptr = dec_state->bufptr; Ipp32u tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]); tmp <<= dec_state->bitoff; tmp >>= 32 - n; return tmp;}static void _FlushBits(H261DEC_STATE* dec_state, int n){ n = n + dec_state->bitoff; dec_state->bufptr += n >> 3; dec_state->bitoff = n & 7;}static Ipp32u _GetBits(H261DEC_STATE* dec_state, int n){ Ipp8u* ptr = dec_state->bufptr; Ipp32u tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]); tmp <<= dec_state->bitoff; tmp >>= 32 - n; n = n + dec_state->bitoff; dec_state->bufptr += n >> 3; dec_state->bitoff = n & 7; return tmp;}int getPictureHeader(H261DEC_STATE* dec_state){ Ipp32u code; // PSC code = _GetBits(dec_state, 20); if (code != 16) return 1; // decode TR code = _GetBits(dec_state, 5); // set picture time if (code < dec_state->tr) code += 32; dec_state->time += code - dec_state->tr; dec_state->tr = (Ipp8u)(code & 0x1F); // decode PTYPE code = _GetBits(dec_state, 6); // Split screen indicator is ignored// if (code & 0x20) {// ErrMsg("Split Screen Indicator not supported");// return -1;// } // Document camera indicator is ignored// if (code & 0x10) {// ErrMsg("Document Camera Indicator not supported");// return -1;// } // Freeze Picture Release bit is ignored// if (code & 0x8) {// ErrMsg("Freeze Picture Release not supported");// return -1;// } // Source format if (code & 0x4) { dec_state->picture_format = 1; // CIF dec_state->picture_width = 352; dec_state->picture_height = 288; dec_state->numgob = 12; } else { dec_state->picture_format = 0; // QCIF dec_state->picture_width = 352/2; dec_state->picture_height = 288/2; dec_state->numgob = 3; }// Still image bit is ignored - Annex D not supported// if ((code & 0x2) == 0) {// ErrMsg("Still Image Mode not supported");// return -1;// } // bit 6 of PTYPE is spare while (_GetBits(dec_state, 1)) { // extra insertion information (PEI) _FlushBits(dec_state, 8); // PSPARE } return 0;} // getPictureHeader()static void reconstruct(int bx, int by, int mvx, int mvy, int filter, H261DEC_STATE* dec_state){ Ipp8u* src; Ipp8u* dst; int i; int lx = dec_state->picture_width; /* Y */ src = dec_state->refPic[0] + lx * (by + mvy) + bx + mvx; dst = dec_state->curPic[0] + lx * by + bx; if (filter) { Ipp8u *dblock, *sblock; for (i = 0; i < 4; i++) { dblock = dst + (i & 2)*4*lx + (i & 1)*8; sblock = src + (i & 2)*4*lx + (i & 1)*8; ippiFilter8x8_H261_8u_C1R(sblock, lx, dblock, lx); } } else { ippiCopy16x16_8u_C1R(src, lx, dst, lx); } /* Chroma */ lx >>= 1; bx >>= 1; by >>= 1; mvx /= 2; // truncate towards zero, can be negative mvy /= 2; src = dec_state->refPic[1] + lx * (by + mvy) + bx + mvx; dst = dec_state->curPic[1] + lx * by + bx; if (filter) ippiFilter8x8_H261_8u_C1R(src, lx, dst, lx); else ippiCopy8x8_8u_C1R(src, lx, dst, lx); src = dec_state->refPic[2] + lx * (by + mvy) + bx + mvx; dst = dec_state->curPic[2] + lx * by + bx; if (filter) ippiFilter8x8_H261_8u_C1R(src, lx, dst, lx); else ippiCopy8x8_8u_C1R(src, lx, dst, lx);} // reconstruct()static int fillBlock(int bx, int by, int i, int quant, H261DEC_STATE* dec_state){ __ALIGN16(Ipp16s, coeffs, 64); int step; Ipp8u* pDst; IppStatus status; int iLNZ; int picture_width = dec_state->picture_width;#if 0 { __ALIGN16(Ipp16s, coeffsZ, 64); status = ippiDecodeCoeffsIntra_H261_1u16s(&dec_state->bufptr, &dec_state->bitoff, coeffsZ, &iLNZ, -1); if (status != ippStsNoErr) return -1; status = ippiQuantInvIntra_H263_16s_C1I(coeffsZ, iLNZ, quant, 0, 0); if (status != ippStsNoErr) return -1; status = ippiScanInv_16s_C1(coeffsZ, coeffs, iLNZ, IPPVC_SCAN_ZIGZAG); }#else status = ippiReconstructCoeffsIntra_H261_1u16s(&dec_state->bufptr, &dec_state->bitoff, coeffs, &iLNZ, quant);#endif if (status != ippStsNoErr) return -1; if (i > 3) { step = picture_width >> 1; bx >>= 1; by >>= 1; pDst = dec_state->curPic[i-3] + step*by + bx; } else { step = picture_width; pDst = dec_state->curPic[0] + picture_width*(by + (i & 2)*4) + bx + (i & 1)*8; } ippiDCT8x8Inv_16s8u_C1R(coeffs, pDst, step); return 0;} // fillBlock()static int reconBlock(int bx, int by, int i, int quant, H261DEC_STATE* dec_state){ __ALIGN16(Ipp16s, coeffs, 64); int step; Ipp8u* pSrcDst; IppStatus status = ippStsErr; int iLNZ; int picture_width = dec_state->picture_width;#if 0 { __ALIGN16(Ipp16s, coeffsZ, 64); status = ippiDecodeCoeffsInter_H261_1u16s(&dec_state->bufptr, &dec_state->bitoff, coeffsZ, &iLNZ, -1); if (status != ippStsNoErr) return -1; status = ippiQuantInvInter_H263_16s_C1I(coeffsZ, iLNZ, quant, 0); if (status != ippStsNoErr) return -1; status = ippiScanInv_16s_C1(coeffsZ, coeffs, iLNZ, IPPVC_SCAN_ZIGZAG); }#else status = ippiReconstructCoeffsInter_H261_1u16s(&dec_state->bufptr, &dec_state->bitoff, coeffs, &iLNZ, quant);#endif if (status != ippStsNoErr) return -1; if ((iLNZ < 5) && (!coeffs[16])) ippiDCT8x8Inv_2x2_16s_C1I(coeffs); else if ((iLNZ < 10) || ((iLNZ < 14) && (!coeffs[10])) || ((iLNZ < 19) && (!(coeffs[10] | coeffs[14] | coeffs[15] | coeffs[16])))) ippiDCT8x8Inv_4x4_16s_C1I(coeffs); else ippiDCT8x8Inv_16s_C1I(coeffs); if (i > 3) { step = picture_width >> 1; bx >>= 1; by >>= 1; pSrcDst = dec_state->curPic[i-3] + step*by + bx; } else { step = picture_width; pSrcDst = dec_state->curPic[0] + picture_width*(by + (i & 2)*4) + bx + (i & 1)*8; } ippiAdd8x8_16s8u_C1IRS(coeffs, 16, pSrcDst, step); return 0;} // reconBlock()/*-------------------------------------------------------------*/typedef struct { unsigned short val; unsigned short len;} H261_vlc;#define VLC_ERR -1static const H261_vlc mba_tab1[15] ={ {7,5}, {6,5}, {5,4}, {5,4}, {4,4}, {4,4}, {3,3}, {3,3}, {3,3}, {3,3}, {2,3}, {2,3}, {2,3}, {2,3}, {1,1}};static const H261_vlc mba_tab2[46] ={ {21,6}, {20,6}, {19,6}, {18,6}, {17,6}, {16,6}, {15,4}, {15,4}, {15,4}, {15,4}, {14,4}, {14,4}, {14,4}, {14,4}, {13,4}, {13,4}, {13,4}, {13,4}, {12,4}, {12,4}, {12,4}, {12,4}, {11,4}, {11,4}, {11,4}, {11,4}, {10,4}, {10,4}, {10,4}, {10,4}, {9, 3}, {9, 3}, {9, 3}, {9, 3}, {9, 3}, {9, 3}, {9, 3}, {9, 3}, {8, 3}, {8, 3}, {8, 3}, {8, 3}, {8, 3}, {8, 3}, {8, 3}, {8, 3},};static int dec_MBA(H261DEC_STATE* dec_state){ unsigned int code; int mba, len; H261_vlc vlc; code = _ShowBits(dec_state, 5); if (code >= 16) { _FlushBits(dec_state, 1); mba = 1; } else if (code > 1) { vlc = mba_tab1[code - 2]; mba = vlc.val; len = vlc.len; _FlushBits(dec_state, len); } else { _FlushBits(dec_state, 4); code = _ShowBits(dec_state, 7); if ((code >> 1) >= 18) { vlc = mba_tab2[(code >> 1) - 18]; mba = vlc.val; len = vlc.len; } else { len = 7; if (code >= 16) { mba = 57 - code; } else// mba = (code == 15) ? IPPVC_MB_STUFFING : VLC_ERR; mba = -1; } _FlushBits(dec_state, len); } return mba;}/*-------------------------------------------------------------*/#define MTYPE_INTRA 1#define MTYPE_MQUANT 2#define MTYPE_MVD 4#define MTYPE_TCOEFF 8#define MTYPE_FIL 16static const Ipp8u mtype_tab[10] ={ MTYPE_TCOEFF, MTYPE_TCOEFF | MTYPE_MVD | MTYPE_FIL, MTYPE_MVD | MTYPE_FIL, MTYPE_INTRA, // | MTYPE_TCOEFF, MTYPE_TCOEFF | MTYPE_MQUANT, MTYPE_TCOEFF | MTYPE_MQUANT | MTYPE_MVD | MTYPE_FIL, MTYPE_INTRA | MTYPE_MQUANT, // | MTYPE_TCOEFF, MTYPE_TCOEFF | MTYPE_MVD, MTYPE_MVD, MTYPE_TCOEFF | MTYPE_MQUANT | MTYPE_MVD};static int dec_MTYPE(H261DEC_STATE* dec_state){ unsigned int code; int mtype; int i; code = _ShowBits(dec_state, 10); for (i = 0; i < 10; i++) { if (code & (512 >> i)) break; } if (i > 9) return VLC_ERR; mtype = mtype_tab[i]; _FlushBits(dec_state, i+1); return mtype;}/*-------------------------------------------------------------*/static const H261_vlc mvd_tab1[14] ={ {3,5}, {29,5}, {2,4}, {2,4}, {30,4}, {30,4}, {1,3}, {1,3}, {1,3}, {1,3}, {31,3}, {31,3}, {31,3}, {31,3}};static const H261_vlc mvd_tab2[103] ={ {16,11}, {15,11}, {17,11}, {14,11}, {18,11}, {13,11}, {19,11}, {12,11},
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -