예제 #1
0
파일: CABAC.cs 프로젝트: billliwawa/net7mma
        public void writeMBQpDelta(MEncoder encoder, MBType prevMbType, int mbQpDelta)
        {
            int ctx = 60;

            ctx += prevMbType == null || prevMbType == MBType.I_PCM || (prevMbType != MBType.I_16x16 && prevCBP == 0) ||
                   prevMbQpDelta == 0 ? 0 : 1;

            prevMbQpDelta = mbQpDelta;
            if (mbQpDelta-- == 0)
            {
                encoder.encodeBin(ctx, 0);
            }
            else
            {
                encoder.encodeBin(ctx, 1);
                if (mbQpDelta-- == 0)
                {
                    encoder.encodeBin(62, 0);
                }
                else
                {
                    while (mbQpDelta-- > 0)
                    {
                        encoder.encodeBin(63, 1);
                    }
                    encoder.encodeBin(63, 0);
                }
            }
        }
예제 #2
0
파일: CABAC.cs 프로젝트: billliwawa/net7mma
        public void writeMBTypeI(MEncoder encoder, MBType left, MBType top, bool leftAvailable, bool topAvailable,
                                 int mbType)
        {
            int ctx = 3;

            ctx += !leftAvailable || left == MBType.I_NxN ? 0 : 1;
            ctx += !topAvailable || top == MBType.I_NxN ? 0 : 1;

            if (mbType == 0)
            {
                encoder.encodeBin(ctx, 0);
            }
            else
            {
                encoder.encodeBin(ctx, 1);
                if (mbType == 25)
                {
                    encoder.encodeBinFinal(1);
                }
                else
                {
                    encoder.encodeBinFinal(0);
                    writeMBType16x16(encoder, mbType - 1);
                }
            }
        }
예제 #3
0
파일: CABAC.cs 프로젝트: billliwawa/net7mma
 private void writeMBType16x16(MEncoder encoder, int mbType)
 {
     if (mbType < 12)
     {
         encoder.encodeBin(6, 0);
     }
     else
     {
         encoder.encodeBin(6, 1);
         mbType -= 12;
     }
     if (mbType < 4)
     {
         encoder.encodeBin(7, 0);
         encoder.encodeBin(9, mbType >> 1);
         encoder.encodeBin(10, mbType & 1);
     }
     else
     {
         mbType -= 4;
         encoder.encodeBin(7, 1);
         encoder.encodeBin(8, mbType >> 2);
         encoder.encodeBin(9, (mbType >> 1) & 1);
         encoder.encodeBin(10, mbType & 1);
     }
 }
예제 #4
0
파일: CABAC.cs 프로젝트: billliwawa/net7mma
        public void writeIntraChromaPredMode(MEncoder encoder, int mbX, MBType left, MBType top, bool leftAvailable,
                                             bool topAvailable, int mode)
        {
            int ctx = 64;

            ctx += !leftAvailable || !left.isIntra() || chromaPredModeLeft == 0 ? 0 : 1;
            ctx += !topAvailable || !top.isIntra() || chromaPredModeTop[mbX] == 0 ? 0 : 1;
            encoder.encodeBin(ctx, mode-- == 0 ? 0 : 1);
            for (int i = 0; mode >= 0 && i < 2; i++)
            {
                encoder.encodeBin(67, mode-- == 0 ? 0 : 1);
            }
            chromaPredModeLeft = chromaPredModeTop[mbX] = mode;
        }
예제 #5
0
파일: CABAC.cs 프로젝트: billliwawa/net7mma
        public void writeCoeffs(MEncoder encoder, BlockType blockType, int[] _out, int first, int num, int[] reorder)
        {
            for (int i = 0; i < num; i++)
            {
                tmp[i] = _out[reorder[first + i]];
            }

            int numCoeff = 0;

            for (int i = 0; i < num; i++)
            {
                if (tmp[i] != 0)
                {
                    numCoeff = i + 1;
                }
            }
            for (int i = 0; i < Math.Min(numCoeff, num - 1); i++)
            {
                if (tmp[i] != 0)
                {
                    encoder.encodeBin(blockType.sigCoeffFlagCtxOff + i, 1);
                    encoder.encodeBin(blockType.lastSigCoeffCtxOff + i, i == numCoeff - 1 ? 1 : 0);
                }
                else
                {
                    encoder.encodeBin(blockType.sigCoeffFlagCtxOff + i, 0);
                }
            }

            int numGt1 = 0, numEq1 = 0;

            for (int j = numCoeff - 1; j >= 0; j--)
            {
                if (tmp[j] == 0)
                {
                    continue;
                }
                int absLev = Math.Abs(tmp[j]) - 1;
                writeCoeffAbsLevel(encoder, blockType, numGt1, numEq1, absLev);
                if (absLev == 0)
                {
                    ++numEq1;
                }
                else
                {
                    ++numGt1;
                }
                encoder.encodeBinBypass(sign(tmp[j]));
            }
        }
예제 #6
0
파일: CABAC.cs 프로젝트: billliwawa/net7mma
        private void writeCoeffAbsLevel(MEncoder encoder, BlockType blockType, int numDecodAbsLevelGt1,
                                        int numDecodAbsLevelEq1, int absLev)
        {
            int incB0 = ((numDecodAbsLevelGt1 != 0) ? 0 : Math.Min(4, 1 + numDecodAbsLevelEq1));
            int incBN = 5 + Math.Min(4 - blockType.coeffAbsLevelAdjust, numDecodAbsLevelGt1);

            if (absLev == 0)
            {
                encoder.encodeBin(blockType.coeffAbsLevelCtxOff + incB0, 0);
            }
            else
            {
                encoder.encodeBin(blockType.coeffAbsLevelCtxOff + incB0, 1);
                if (absLev < 14)
                {
                    for (int i = 1; i < absLev; i++)
                    {
                        encoder.encodeBin(blockType.coeffAbsLevelCtxOff + incBN, 1);
                    }
                    encoder.encodeBin(blockType.coeffAbsLevelCtxOff + incBN, 0);
                }
                else
                {
                    for (int i = 1; i < 14; i++)
                    {
                        encoder.encodeBin(blockType.coeffAbsLevelCtxOff + incBN, 1);
                    }
                    absLev -= 14;
                    int sufLen, pow;
                    for (sufLen = 0, pow = 1; absLev >= pow; sufLen++, pow = (1 << sufLen))
                    {
                        encoder.encodeBinBypass(1);
                        absLev -= pow;
                    }
                    encoder.encodeBinBypass(0);
                    for (sufLen--; sufLen >= 0; sufLen--)
                    {
                        encoder.encodeBinBypass((absLev >> sufLen) & 1);
                    }
                }
            }
        }