?? decoder.java
字號(hào):
mPastIntraAddress = -2; // See ISO-11172-2 page 36
// Reset at start of each slice
mForward.resetPrevious();
mBackward.resetPrevious();
/*
* Macroblocks have an address which is the number of the macroblock
* in raster scan order. The top left macroblock in a picture has
* address 0, the next one to the right has address 1 and so on.
* If there are M macroblocks in a picture, then the bottom right
* macroblock has an address M-1.
*/
mMacroblockAddress = (sliceVerticalPosition - 1) * mMacroblockWidth - 1;
mQuantizerScale = mInput.getBits(5);
int extraBitSlice = 0;
while (mInput.nextBits(1) == 0x1) {
extraBitSlice = mInput.getBits(1);
int extraInformationSlice = mInput.getBits(8);
}
extraBitSlice = mInput.getBits(1);
do {
parseMacroblock();
} while (mInput.nextBits(23) != 0x0);
nextStartCode();
}
// Used for decoding motion vectors
private int mMotionHorizontalForwardR;
private int mMotionVerticalForwardR;
private int mMotionHorizontalBackwardR;
private int mMotionVerticalBackwardR;
private Vlc.MacroblockType mMacroblockType = mVlc.new MacroblockType();
/*
* A macroblock has 4 luminance blocks and 2 chrominance blocks.
* The order of blocks in a macroblock is top-left, top-right,
* bottom-left, bottom-right block for Y, followed by Cb and Cr.
* A macroblock is the basic unit for motion compensation and
* quantizer scale changes.
*/
private void parseMacroblock() throws IOException {
// Discarded by decoder
while (mInput.nextBits(11) == 0xf) {
int macroblockStuffing = mInput.getBits(11);
}
int macroblockAddressIncrement = 0;
while (mInput.nextBits(11) == 0x8) {
int macroblockEscape = mInput.getBits(11);
macroblockAddressIncrement += 33;
}
macroblockAddressIncrement += mVlc.getMacroblockAddressIncrement(mInput);
// Process skipped macroblocks
if (macroblockAddressIncrement > 1) {
mDctDcYPast = mDctDcCrPast = mDctDcCbPast = 1024;
/*
* In P-pictures, the skipped macroblock is defined to be
* a macroblock with a reconstructed motion vector equal
* to zero and no DCT coefficients.
*/
if (mPictureCodingType == Picture.P_TYPE) {
mForward.resetPrevious();
for (int i = 0; i < macroblockAddressIncrement; ++i) {
int mbRow = (mMacroblockAddress + 1 + i) / mMacroblockWidth;
int mbCol = (mMacroblockAddress + 1 + i) % mMacroblockWidth;
mPictureStore[mCurrent].copy(mPictureStore[mPrevious], mbRow, mbCol);
}
}
/*
* In B-pictures, the skipped macroblock is defined to have
* the same macroblock_type (forward, backward, or both motion
* vectors) as the prior macroblock, differential motion
* vectors equal to zero, and no DCT coefficients.
*/
else if (mPictureCodingType == Picture.B_TYPE) {
for (int i = 0; i < macroblockAddressIncrement; ++i) {
int mbRow = (mMacroblockAddress + 1 + i) / mMacroblockWidth;
int mbCol = (mMacroblockAddress + 1 + i) % mMacroblockWidth;
if (!mMacroblockType.mMacroblockMotionForward && mMacroblockType.mMacroblockMotionBackward)
mPictureStore[mCurrent].compensate(mPictureStore[mFuture], mbRow, mbCol, mBackward);
else if (mMacroblockType.mMacroblockMotionForward && !mMacroblockType.mMacroblockMotionBackward)
mPictureStore[mCurrent].compensate(mPictureStore[mPrevious], mbRow, mbCol, mForward);
else if (mMacroblockType.mMacroblockMotionForward && mMacroblockType.mMacroblockMotionBackward) {
mPictureStore[mCurrent].interpolate(mPictureStore[mPrevious], mPictureStore[mFuture], mbRow, mbCol, mForward, mBackward);
}
}
}
}
mMacroblockAddress += macroblockAddressIncrement;
mMacroblockRow = mMacroblockAddress / mMacroblockWidth;
mMacroblockCol = mMacroblockAddress % mMacroblockWidth;
/*
* For macroblocks in I pictures, and for intra coded macroblocks in
* P and B pictures, the coded block pattern is not transmitted, but
* is assumed to have a value of 63, i.e. all the blocks in the
* macroblock are coded.
*/
int codedBlockPattern = 0x3f;
mVlc.getMacroblockType(mPictureCodingType, mInput, mMacroblockType);
if (!mMacroblockType.mMacroblockIntra) {
mDctDcYPast = mDctDcCrPast = mDctDcCbPast = 1024;
codedBlockPattern = 0;
}
if (mMacroblockType.mMacroblockQuant)
mQuantizerScale = mInput.getBits(5);
if (mMacroblockType.mMacroblockMotionForward) {
int motionHorizontalForwardCode = mVlc.getMotionVector(mInput);
if (mForwardF != 1 && motionHorizontalForwardCode != 0) {
mMotionHorizontalForwardR = mInput.getBits(mForwardRSize);
}
int motionVerticalForwardCode = mVlc.getMotionVector(mInput);
if (mForwardF != 1 && motionVerticalForwardCode != 0) {
mMotionVerticalForwardR = mInput.getBits(mForwardRSize);
}
mForward.calculate(motionHorizontalForwardCode, mMotionHorizontalForwardR, motionVerticalForwardCode, mMotionVerticalForwardR);
}
if (mMacroblockType.mMacroblockMotionBackward) {
int motionHorizontalBackwardCode = mVlc.getMotionVector(mInput);
if (mBackwardF != 1 && motionHorizontalBackwardCode != 0) {
mMotionHorizontalBackwardR = mInput.getBits(mBackwardRSize);
}
int motionVerticalBackwardCode = mVlc.getMotionVector(mInput);
if (mBackwardF != 1 && motionVerticalBackwardCode != 0) {
mMotionVerticalBackwardR = mInput.getBits(mBackwardRSize);
}
mBackward.calculate(motionHorizontalBackwardCode, mMotionHorizontalBackwardR, motionVerticalBackwardCode, mMotionVerticalBackwardR);
}
if (mPictureCodingType == Picture.P_TYPE) { // See 2.4.4.2
if (mMacroblockType.mMacroblockMotionForward) {
mPictureStore[mCurrent].compensate(mPictureStore[mPrevious], mMacroblockRow, mMacroblockCol, mForward);
}
else {
mPictureStore[mCurrent].copy(mPictureStore[mPrevious], mMacroblockRow, mMacroblockCol);
}
}
else if (mPictureCodingType == Picture.B_TYPE) { // See 2.4.4.3
if (mMacroblockType.mMacroblockMotionForward && !mMacroblockType.mMacroblockMotionBackward) {
mPictureStore[mCurrent].compensate(mPictureStore[mPrevious], mMacroblockRow, mMacroblockCol, mForward);
}
else if(!mMacroblockType.mMacroblockMotionForward && mMacroblockType.mMacroblockMotionBackward) {
mPictureStore[mCurrent].compensate(mPictureStore[mFuture], mMacroblockRow, mMacroblockCol, mBackward);
}
else if (mMacroblockType.mMacroblockMotionForward && mMacroblockType.mMacroblockMotionBackward) {
mPictureStore[mCurrent].interpolate(mPictureStore[mPrevious], mPictureStore[mFuture], mMacroblockRow, mMacroblockCol, mForward, mBackward);
}
}
if (mPictureCodingType == Picture.P_TYPE && !mMacroblockType.mMacroblockMotionForward)
mForward.resetPrevious();
if (mPictureCodingType == Picture.B_TYPE && mMacroblockType.mMacroblockIntra) {
mForward.resetPrevious();
mBackward.resetPrevious();
}
if (mMacroblockType.mMacroblockPattern)
codedBlockPattern = mVlc.getCodedBlockPattern(mInput);
/*
* The Coded Block Pattern informs the decoder which of the six blocks
* in the macroblock are coded, i.e. have transmitted DCT quantized
* coefficients, and which are not coded, i.e. have no additional
* correction after motion compensation
*/
for (int i = 0; i < 6; i++) {
if ((codedBlockPattern & (1 << (5 - i))) != 0) {
parseBlock(i);
if (mMacroblockType.mMacroblockIntra) {
if (i < 4) mPictureStore[mCurrent].setLumBlock(mDctRecon, mMacroblockRow, mMacroblockCol, i);
else mPictureStore[mCurrent].setColBlock(mDctRecon, mMacroblockRow, mMacroblockCol, i);
}
else {
if (i < 4) mPictureStore[mCurrent].correctLumBlock(mDctRecon, mMacroblockRow, mMacroblockCol, i);
else mPictureStore[mCurrent].correctColBlock(mDctRecon, mMacroblockRow, mMacroblockCol, i);
}
}
}
if (mPictureCodingType == Picture.D_TYPE)
mInput.getBits(1);
}
private int[] mNullMatrix = new int[64];
private int[] mDctRecon = new int[64];
private int[] mDctZigzag = new int[64];
/*
* A block is an orthogonal 8-pel by 8-line section of a
* luminance or chrominance component.
*/
private void parseBlock(int index) throws IOException {
Vlc.RunLevel runLevel = mVlc.new RunLevel();
System.arraycopy(mNullMatrix, 0, mDctRecon, 0, 64);
System.arraycopy(mNullMatrix, 0, mDctZigzag, 0, 64);
int run = 0;
if (mMacroblockType.mMacroblockIntra) {
if (index < 4) {
int dctDCSizeLuminance = mVlc.decodeDCTDCSizeLuminance(mInput);
int dctDCDifferential = 0;
if (dctDCSizeLuminance != 0) {
dctDCDifferential = mInput.getBits(dctDCSizeLuminance);
if ((dctDCDifferential & (1 << (dctDCSizeLuminance - 1))) != 0)
mDctZigzag[0] = dctDCDifferential;
else
mDctZigzag[0] = ((-1 << dctDCSizeLuminance) | (dctDCDifferential + 1));
}
}
else {
int dctDCSizeChrominance = mVlc.decodeDCTDCSizeChrominance(mInput);
int dctDCDifferential = 0;
if (dctDCSizeChrominance != 0) {
dctDCDifferential = mInput.getBits(dctDCSizeChrominance);
if ((dctDCDifferential & (1 << (dctDCSizeChrominance - 1))) != 0)
mDctZigzag[0] = dctDCDifferential;
else
mDctZigzag[0] = ((-1 << dctDCSizeChrominance) | (dctDCDifferential + 1));
}
}
}
else {
// dctCoeffFirst
mVlc.decodeDCTCoeff(mInput, true, runLevel);
run = runLevel.run;
mDctZigzag[run] = runLevel.level;
}
if (mPictureCodingType != Picture.D_TYPE) {
while (mInput.nextBits(2) != 0x2) {
// dctCoeffNext
mVlc.decodeDCTCoeff(mInput, false, runLevel);
run += runLevel.run + 1;
mDctZigzag[run] = runLevel.level;
}
int endOfBlock = mInput.getBits(2); // Should be == 0x2 (EOB)
if (mMacroblockType.mMacroblockIntra) {
if (index == 0)
firstLuminanceBlock(mDctRecon);
else if (index >= 1 && index <= 3)
nextLuminanceBlock(mDctRecon);
else if (index == 4)
cbBlock(mDctRecon);
else if (index == 5)
crBlock(mDctRecon);
mPastIntraAddress = mMacroblockAddress;
}
else {
// See ISO/IEC 11172 2.4.4.2 / 2.4.4.3
for (int i = 0; i < 64; ++i) {
int idx = ScanMatrix[i];
mDctRecon[i] = ((2 * mDctZigzag[idx] + sign(mDctZigzag[idx])) * mQuantizerScale * NonIntraQuantizerMatrix[i]) >> 4;
if ((mDctRecon[i] & 1) == 0) {
mDctRecon[i] -= sign(mDctRecon[i]);
if (mDctRecon[i] > 2047) mDctRecon[i] = 2047;
if (mDctRecon[i] < -2048) mDctRecon[i] = -2048;
if (mDctZigzag[idx] == 0)
mDctRecon[i] = 0;
}
}
}
mIdct.calculate(mDctRecon);
}
}
/*
* Helper function
*/
private int sign(int n) {
return n > 0? 1 : (n < 0? -1 : 0);
}
/*
* Reconstruct DCT coefficients, as defined in ISO/IEC 11172 2.4.4.1
*/
private void firstLuminanceBlock(int[] dct_recon) throws IOException {
for (int i = 0; i < 64; ++i) {
int index = ScanMatrix[i];
dct_recon[i] = (mDctZigzag[index] * mQuantizerScale * IntraQuantizerMatrix[i]) >> 3;
if ((dct_recon[i] & 1) == 0) {
dct_recon[i] -= sign(dct_recon[i]);
if (dct_recon[i] > 2047) dct_recon[i] = 2047;
if (dct_recon[i] < -2048) dct_recon[i] = -2048;
}
}
dct_recon[0] = mDctZigzag[0] << 3;
if (mMacroblockAddress - mPastIntraAddress > 1)
dct_recon[0] += 1024;
else
dct_recon[0] += mDctDcYPast;
mDctDcYPast = dct_recon[0];
}
private void nextLuminanceBlock(int[] dct_recon) throws IOException {
for (int i = 0; i < 64; ++i) {
int index = ScanMatrix[i];
dct_recon[i] = (mDctZigzag[index] * mQuantizerScale * IntraQuantizerMatrix[i]) >> 3;
if ((dct_recon[i] & 1) == 0) {
dct_recon[i] -= sign(dct_recon[i]);
if (dct_recon[i] > 2047) dct_recon[i] = 2047;
if (dct_recon[i] < -2048) dct_recon[i] = -2048;
}
}
dct_recon[0] = mDctDcYPast + (mDctZigzag[0] << 3);
mDctDcYPast = dct_recon[0];
}
private void cbBlock(int[] dct_recon) throws IOException {
for (int i = 0; i < 64; ++i) {
int index = ScanMatrix[i];
dct_recon[i] = (mDctZigzag[index] * mQuantizerScale * IntraQuantizerMatrix[i]) >> 3;
if ((dct_recon[i] & 1) == 0) {
dct_recon[i] -= sign(dct_recon[i]);
if (dct_recon[i] > 2047) dct_recon[i] = 2047;
if (dct_recon[i] < -2048) dct_recon[i] = -2048;
}
}
dct_recon[0] = mDctZigzag[0] << 3;
if (mMacroblockAddress - mPastIntraAddress > 1)
dct_recon[0] += 1024;
else
dct_recon[0] += mDctDcCbPast;
mDctDcCbPast = dct_recon[0];
}
private void crBlock(int[] dct_recon) throws IOException {
for (int i = 0; i < 64; ++i) {
int index = ScanMatrix[i];
dct_recon[i] = (mDctZigzag[index] * mQuantizerScale * IntraQuantizerMatrix[i]) >> 3;
if ((dct_recon[i] & 1) == 0) {
dct_recon[i] -= sign(dct_recon[i]);
if (dct_recon[i] > 2047) dct_recon[i] = 2047;
if (dct_recon[i] < -2048) dct_recon[i] = -2048;
}
}
dct_recon[0] = mDctZigzag[0] << 3;
if (mMacroblockAddress - mPastIntraAddress > 1)
dct_recon[0] += 1024;
else
dct_recon[0] += mDctDcCrPast;
mDctDcCrPast = dct_recon[0];
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -