コード例 #1
0
 public int Encode(YuvFrameBuffer inFrameBuffer, YuvFrameBuffer outFrameBuffer)
 {
     inputFrameBuffer = inFrameBuffer;
     outputFrameBuffer = outFrameBuffer;
     FillResidualMatrix();
     return ForwardTransform(mResd, mDc, mResd);
 }
コード例 #2
0
 public VideoSequence(YuvFormatType yuvFormatType, Size frameSize )
 {
     this.frameSize = frameSize;
     currentInputFrame = new YuvFrameBuffer(yuvFormatType, frameSize);
     currentOutputFrame = new YuvFrameBuffer(yuvFormatType, frameSize);
     picWidthInMbs = frameSize.Width / MbBlockSize;
     frameHeightInMbs = frameSize.Height / MbBlockSize;
     frameSizeInMbs = picWidthInMbs*frameHeightInMbs;
     lastIdr = 0;
     pictureIndex = 0;
 }
コード例 #3
0
        protected override bool DoIntraPrediction(YuvFrameBuffer codedFrameBuffer, int[][] mp)
        {
            var maxW = Macroblock.MbWidth;
            var maxH = Macroblock.MbHeight;
            var upAvail = access.IsUpAvailable(maxW);
            var leftAvail = access.IsLeftAvailable(maxH);
            var leftUpAvail = access.IsLeftUpAvailable();
            if (!upAvail || !leftAvail || !leftUpAvail) // edge
                return false;

            var h = 0;
            var v = 0;
            var pUp = new Point();
            var pLeft = new Point();
            var pLeftUp = new Point();

            access.GetNeighbour(0, -1, maxW, maxH, pUp);
            access.GetNeighbour(-1, 0, maxW, maxH, pLeft);
            access.GetNeighbour(-1, -1, maxW, maxH, pLeftUp);

            // H = sum(x' = 0 to 7){ (x'+1) * (p[8+x', -1] - p[6-x', -1]) }
            // V = sum(y' = 0 to 7){ (y'+1) * (p[-1, 8+y'] - p[-1, 6-y']) }
            for (var i = 1; i < 9; i++)
            {
                if (i < 8)
                {
                    h += i*(codedFrameBuffer.GetY8Bit(pUp.X + 7 + i, pUp.Y)- codedFrameBuffer.GetY8Bit(pUp.X + 7 - i, pUp.Y));
                    v += i*(codedFrameBuffer.GetY8Bit(pLeft.X, pLeft.Y + 7 + i)- codedFrameBuffer.GetY8Bit(pLeft.X, pLeft.Y + 8 - i));
                }
                else
                {
                    h += i*(codedFrameBuffer.GetY8Bit(pUp.X + 7 + i, pUp.Y)- codedFrameBuffer.GetY8Bit(pLeftUp.X, pLeftUp.Y));
                    v += i*(codedFrameBuffer.GetY8Bit(pLeft.X, pLeft.Y + 7 + i)- codedFrameBuffer.GetY8Bit(pLeftUp.X, pLeftUp.Y));
                }
            }

            var a = 16*(codedFrameBuffer.GetY8Bit(pLeft.X, pLeft.Y + 15) + codedFrameBuffer.GetY8Bit(pUp.X + 15, pUp.Y));
            var b = (5*h + 32) >> 6;
            var c = (5*v + 32) >> 6;

            // predL[x, y] = Clip1Y((a + b*(x - 7) + c*(y - 7) + 16) >> 5),
            // with x, y = 0..15
            for (var j = 0; j < Macroblock.MbHeight; j++)
            {
                for (var i = 0; i < Macroblock.MbWidth; i++)
                {
                    var value = MathHelper.RshiftRound((a + (i - 7)*b + (j - 7)*c), 5);
                    mp[j][i] = MathHelper.Clip(maxImagePelValue, value);
                }
            }

            return true;
        }
コード例 #4
0
        protected override bool DoIntraPrediction(YuvFrameBuffer codedFrameBuffer, int[][] mp)
        {
            var p = new Point();
            var sumUp = 0;
            var sumLeft = 0;
            var maxW = Macroblock.MbWidth;
            var maxH = Macroblock.MbHeight;
            var upAvail = access.IsUpAvailable(maxW);
            var leftAvail = access.IsLeftAvailable(maxH);

            // sum(x' = 0 to 15) { p[x', -1] }
            if (upAvail)
            {
                for (var i = 0; i < Macroblock.MbWidth; i++)
                {
                    access.GetNeighbour(i, -1, maxW, maxH, p);
                    sumUp += codedFrameBuffer.GetY8Bit(p.X, p.Y);
                }
            }
            // sum(y' = 0 to 15) { p[-1, y'] }
            if (leftAvail)
            {
                for (var i = 0; i < Macroblock.MbHeight; i++)
                {
                    access.GetNeighbour(-1, i, maxW, maxH, p);
                    sumLeft += codedFrameBuffer.GetY8Bit(p.X, p.Y);
                }
            }

            // no edge
            // predL[x, y] = (sumUp + sumLeft + 16) >> 5 , with x, y = 0..15
            // upper edge
            // predL[x, y] = (sumLeft + 8) >> 4, with x, y = 0..15
            // left edge
            // predL[x, y] = (sumUp + 8) >> 4, with x, y = 0..15
            // top left corner
            // predL[x, y] = (1 << (BitDepthY – 1)), with x, y = 0..15

            var predL = upAvail && leftAvail
                            ? MathHelper.RshiftRound((sumUp + sumLeft), 5)
                            : (!upAvail && leftAvail
                                   ? MathHelper.RshiftRound(sumLeft, 4)
                                   : (upAvail ? MathHelper.RshiftRound(sumUp, 4) : 1 << (bitDepthY - 1)));

            // store DC prediction
            for (var j = 0; j < Macroblock.MbHeight; j++)
                for (var i = 0; i < Macroblock.MbWidth; i++)
                    mp[j][i] = predL;

            return true;
        }
コード例 #5
0
ファイル: Slice.cs プロジェクト: pingmeaschandru/LiveMeeting
        public int Encode(YuvFrameBuffer inFrameBuffer, YuvFrameBuffer outFrameBuffer)
        {
            const int numberOfCodedMBs = 99;
            InitSlice();
            SetLagrangianMultipliers();
            for (var i = 0; i < numberOfCodedMBs; i++)
            {
                var mb = new Macroblock(this, i);
                mb.Encode(inFrameBuffer, outFrameBuffer);
                macroblocks.Add(mb);
            }

            return numberOfCodedMBs;
        }
コード例 #6
0
        protected override bool DoIntraPrediction(YuvFrameBuffer codedFrameBuffer, int[][] mp)
        {
            var maxW = Macroblock.MbWidth;
            var maxH = Macroblock.MbHeight;

            if (!access.IsUpAvailable(maxW)) return false;
            var p = new Point();

            // predL[ x, y ] = p[ x, -1 ], with x, y = 0..15
            for (var index0 = 0; index0 < maxW; index0++)
            {
                access.GetNeighbour(index0, -1, maxW, maxH, p);
                for (var index01 = 0; index01 < maxH; index01++)
                    mp[index01][index0] = codedFrameBuffer.GetY8Bit(p.X, p.Y);
            }

            return true;
        }
コード例 #7
0
        public override void Reconstruct(YuvFrameBuffer outFrameBuffer)
        {
            var x = macroblock.PixelX;
            var y = macroblock.PixelY;
            var cx = macroblock.PixelChromaX;
            var cy = macroblock.PixelChromaY;

            for (var j = 0; j < Macroblock.MbHeight; j++)
                for (var i = 0; i < Macroblock.MbWidth; i++)
                    outFrameBuffer.SetY8Bit(i + x, j + y, bufferY[i][j]);

            for (var j = 0; j < Macroblock.MbChromaHeight; j++)
                for (var i = 0; i < Macroblock.MbChromaWidth; i++)
                    outFrameBuffer.SetCb8Bit(i + cx, j + cy, bufferU[i][j]);

            for (var j = 0; j < Macroblock.MbChromaHeight; j++)
                for (var i = 0; i < Macroblock.MbChromaWidth; i++)
                    outFrameBuffer.SetCr8Bit(i + cx, j + cy, bufferV[i][j]);
        }
コード例 #8
0
        protected override bool DoIntraPrediction(YuvFrameBuffer codedFrameBuffer, int[][] mp)
        {
            var maxW = Macroblock.MbWidth;
            var maxH = Macroblock.MbHeight;

            if (!access.IsLeftAvailable(maxH)) return false;

            var p = new Point();

            // predL[ x, y ] = p[ -1, y ], with x, y = 0..15
            for (var i = 0; i < maxH; i++)
            {
                access.GetNeighbour(-1, i, maxW, maxH, p);
                for (var j = 0; j < maxW; j++)
                    mp[i][j] = codedFrameBuffer.GetY8Bit(p.X, p.Y);
            }

            return true;
        }
コード例 #9
0
        protected override void DoEncode(YuvFrameBuffer inFrameBuffer, YuvFrameBuffer codedFrameBuffer)
        {
            var x = macroblock.PixelX;
            var y = macroblock.PixelY;
            var cx = macroblock.PixelChromaX;
            var cy = macroblock.PixelChromaY;

            // LUMA
            for (var j = 0; j < Macroblock.MbHeight; j++)
                for (var i = 0; i < Macroblock.MbWidth; i++)
                    bufferY[i][j] = inputFrameBuffer.GetY8Bit(i + x, j + y);

            // CHROMA
            for (var j = 0; j < Macroblock.MbChromaHeight; j++)
                for (var i = 0; i < Macroblock.MbChromaWidth; i++)
                {
                    bufferU[i][j] = inputFrameBuffer.GetCb8Bit(i + cx, j + cy);
                    bufferV[i][j] = inputFrameBuffer.GetCr8Bit(i + cx, j + cy);
                }
        }
コード例 #10
0
        protected override bool DoIntraPrediction(YuvFrameBuffer codedFrameBuffer, int[][] mpCb, int[][] mpCr)
        {
            var maxW = Macroblock.MbChromaWidth;
            var maxH = Macroblock.MbChromaHeight;

            if (!access.IsLeftAvailable(maxH)) return false;
            var p = new Point();

            // predC[ x, y ] = p[ -1, y ],
            // with x = 0..MbWidthC - 1 and y = 0..MbHeightC - 1
            for (var i = 0; i < maxH; i++)
            {
                access.GetNeighbour(-1, i, maxW, maxH, p);
                for (var j = 0; j < maxW; j++)
                {
                    mpCb[i][j] = codedFrameBuffer.GetCb8Bit(p.X, p.Y);
                    mpCr[i][j] = codedFrameBuffer.GetCr8Bit(p.X, p.Y);
                }
            }

            return true;
        }
コード例 #11
0
 protected abstract bool DoIntraPrediction(YuvFrameBuffer codedFrameBuffer, int[][] mp);
コード例 #12
0
 private void FillOriginalMatrix(YuvFrameBuffer origiFrameBuffer)
 {
     for (var j = 0; j < mbHeight; j++)
     {
         var jj = y + j;
         for (var i = 0; i < mbWidth; i++)
         {
             var ii = x + i;
             mOrig[j][i] = origiFrameBuffer.GetY8Bit(ii, jj);
         }
     }
 }
コード例 #13
0
        protected override bool DoIntraPrediction(YuvFrameBuffer codedFrameBuffer, int[][] mpCb, int[][] mpCr)
        {
            var p = new Point();
            var maxW = Macroblock.MbChromaWidth;
            var maxH = Macroblock.MbChromaHeight;
            var upAvail = access.IsUpAvailable(maxW);
            var leftAvail = access.IsLeftAvailable(maxH);

            // For each chroma block of 4x4 samples indexed by
            // chroma4x4BlkIdx = 0..( 1 << ( ChromaArrayType + 1 ) ) – 1
            for (var chroma4X4BlkIdx = 0; chroma4X4BlkIdx < 4; chroma4X4BlkIdx++)
            {
                var predCb = 0;
                var predCr = 0;
                var sumUpCb = 0;
                var sumUpCr = 0;
                var sumLeftCb = 0;
                var sumLeftCr = 0;

                var xO = PosX(chroma4X4BlkIdx);
                var yO = PosY(chroma4X4BlkIdx);

                // sum(x' = 0 to 3) { p[x' + xO, -1] }
                if (upAvail)
                {
                    for (var i = 0; i < ChromaBlkWidth; i++)
                    {
                        access.GetNeighbour(i, -1, maxW, maxH, p);
                        sumUpCb += codedFrameBuffer.GetCb8Bit(p.X + xO, p.Y);
                        sumUpCr += codedFrameBuffer.GetCr8Bit(p.X + xO, p.Y);
                    }
                }
                // sum(y' = 0 to 3) { p[-1, y' + yO] }
                if (leftAvail)
                {
                    for (var i = 0; i < ChromaBlkHeight; i++)
                    {
                        access.GetNeighbour(-1, i, maxW, maxH, p);
                        sumLeftCb += codedFrameBuffer.GetCb8Bit(p.X, p.Y + yO);
                        sumLeftCr += codedFrameBuffer.GetCr8Bit(p.X, p.Y + yO);
                    }
                }

                // TOP-LEFT and BOTTOM-RIGHT
                if (((xO == 0) && (yO == 0)) || ((xO > 0) && (yO > 0)))
                {
                    if (upAvail && leftAvail)
                    {
                        // predC[x+xO, y+yO] = (sumUp + sumLeft + 4) >> 3
                        predCb = (sumUpCb + sumLeftCb + 4) >> 3;
                        predCr = (sumUpCr + sumLeftCr + 4) >> 3;
                    }
                    else if (leftAvail)
                    {
                        // predC[x+xO, y+yO] = (sumLeft + 2) >> 2
                        predCb = (sumLeftCb + 2) >> 2;
                        predCr = (sumLeftCr + 2) >> 2;
                    }
                    else if (upAvail)
                    {
                        // predC[x+xO, y+yO] = (sumUp + 2) >> 2
                        predCb = (sumUpCb + 2) >> 2;
                        predCr = (sumUpCr + 2) >> 2;
                    }
                    else
                    {
                        // predC[x+xO, y+yO] = (1 << ( BitDepthC – 1 ))
                        predCb = 1 << (bitDepthC - 1);
                        predCr = 1 << (bitDepthC - 1);
                    }
                } // TOP-RIGHT
                else if ((xO > 0) && (yO == 0))
                {
                    if (upAvail)
                    {
                        // predC[x+xO, y+yO] = (sumUp + 2) >> 2
                        predCb = (sumUpCb + 2) >> 2;
                        predCr = (sumUpCr + 2) >> 2;
                    }
                    else if (leftAvail)
                    {
                        // predC[x+xO, y+yO] = (sumLeft + 2) >> 2
                        predCb = (sumLeftCb + 2) >> 2;
                        predCr = (sumLeftCr + 2) >> 2;
                    }
                    else
                    {
                        // predC[x+xO, y+yO] = (1 << ( BitDepthC – 1 ))
                        predCb = 1 << (bitDepthC - 1);
                        predCr = 1 << (bitDepthC - 1);
                    }
                } // BOTTOM-LEFT
                else if ((xO == 0) && (yO > 0))
                {
                    if (leftAvail)
                    {
                        // predC[x+xO, y+yO] = (sumLeft + 2) >> 2
                        predCb = (sumLeftCb + 2) >> 2;
                        predCr = (sumLeftCr + 2) >> 2;
                    }
                    else if (upAvail)
                    {
                        // predC[x+xO, y+yO] = (sumUp + 2) >> 2
                        predCb = (sumUpCb + 2) >> 2;
                        predCr = (sumUpCr + 2) >> 2;
                    }
                    else
                    {
                        // predC[x+xO, y+yO] = (1 << ( BitDepthC – 1 ))
                        predCb = 1 << (bitDepthC - 1);
                        predCr = 1 << (bitDepthC - 1);
                    }
                }

                // store DC prediction
                for (var j = yO; j < ChromaBlkHeight + yO; j++)
                {
                    for (var i = xO; i < ChromaBlkWidth + xO; i++)
                    {
                        mpCb[j][i] = predCb;
                        mpCr[j][i] = predCr;
                    }
                }
            }

            return true;
        }
コード例 #14
0
        public void Reconstruct(YuvFrameBuffer outFrameBuffer)
        {
            const int dqBits = 6;
            var mrInv = new int[mbHeight][];
            for (var i = 0; i < mrInv.Length; i++)
                mrInv[i] = new int[mbWidth];

            InverseTransform(mDc, mResd, mrInv);

            for (var j = 0; j < mbHeight; j++)
            {
                var jj = y + j;

                for (var i = 0; i < mbWidth; i++)
                {
                    var ii = x + i;

                    var predicted = mPred[j][i]; // Predicted sample
                    var residualRecons = MathHelper.RshiftRound(mrInv[j][i], dqBits); // Reconstructed residual sample
                    var originalRecons = residualRecons + predicted; // Reconstructed original sample
                    originalRecons = MathHelper.Clip(maxImagePelValue, originalRecons);
                    outFrameBuffer.SetY8Bit(ii, jj, originalRecons);
                }
            }
        }
コード例 #15
0
 public bool Predict(YuvFrameBuffer origiFrameBuffer, YuvFrameBuffer codedFrameBuffer)
 {
     FillOriginalMatrix(origiFrameBuffer);
     return DoIntraPrediction(codedFrameBuffer, mPred);
 }
コード例 #16
0
 public abstract void Reconstruct(YuvFrameBuffer outFrameBuffer);
コード例 #17
0
 protected abstract void DoEncode(YuvFrameBuffer inFrameBuffer, YuvFrameBuffer codedFrameBuffer);
コード例 #18
0
 public void Encode(YuvFrameBuffer inFrameBuffer, YuvFrameBuffer outFrameBuffer)
 {
     inputFrameBuffer = inFrameBuffer;
     outputFrameBuffer = outFrameBuffer;
     DoEncode(inFrameBuffer, outFrameBuffer);
 }
コード例 #19
0
 public void Encode(YuvFrameBuffer inFrameBuffer, YuvFrameBuffer outFrameBuffer)
 {
     CodePicture(inFrameBuffer, outFrameBuffer);
 }
コード例 #20
0
 public void Encode(YuvFrameBuffer inFrameBuffer, YuvFrameBuffer outFrameBuffer)
 {
     const int bestDistortion = int.MaxValue;
     foreach (var mode in encodingModes)
     {
         mode.Encode(inFrameBuffer, outFrameBuffer);
         if (mode.GetDistortion() < bestDistortion)
             bestMode = mode;
     }
     bestMode.Reconstruct(outFrameBuffer);
 }
コード例 #21
0
        protected void CodePicture(YuvFrameBuffer inFrameBuffer, YuvFrameBuffer outFrameBuffer)
        {
            var numberOfCodedMBs = 0;

            // TODO FmoInit()
            // TODO FmoStartPicture() -> picture level initialization of FMO

            CalculateQuantParam();

            // loop over slices
            while (numberOfCodedMBs < picSizeInMbs)
            {
                slice = new Slice(this, type);
                numberOfCodedMBs += slice.Encode(inFrameBuffer, outFrameBuffer);
            }
        }
コード例 #22
0
        protected override bool DoIntraPrediction(YuvFrameBuffer codedFrameBuffer, int[][] mpCb, int[][] mpCr)
        {
            var maxW = Macroblock.MbChromaWidth;
            var maxH = Macroblock.MbChromaHeight;
            var upAvail = access.IsUpAvailable(maxW);
            var leftAvail = access.IsLeftAvailable(maxH);
            var leftUpAvail = access.IsLeftUpAvailable();
            if (!upAvail || !leftAvail || !leftUpAvail)
                return false;

            // Note: used (chroma_block_width >> 1) instead of (xCF + 4)
            // Note: used (chroma_block_height >> 1) instead of (yCF + 4)

            var hCb = 0;
            var vCb = 0;
            var hCr = 0;
            var vCr = 0;
            var pUp = new Point();
            var pLeft = new Point();
            var pLeftUp = new Point();

            access.GetNeighbour(0, -1, maxW, maxH, pUp);
            access.GetNeighbour(-1, 0, maxW, maxH, pLeft);
            access.GetNeighbour(-1, -1, maxW, maxH, pLeftUp);

            // H = sum(x' = 0 to (3 + xCF)){ (x'+1) * (p[4 + xCF + x', -1] - p[2 + xCF -x', -1]) }
            for (var i = 1; i <= (maxW >> 1); i++)
            {
                var x = i - 1; // x'
                hCb += i*(codedFrameBuffer.GetCb8Bit(pUp.X + (maxW >> 1) + x, pUp.Y) - codedFrameBuffer.GetCb8Bit(pUp.X + (maxW >> 1) - 2 - x, pUp.Y));
                hCr += i*(codedFrameBuffer.GetCr8Bit(pUp.X + (maxW >> 1) + x, pUp.Y) - codedFrameBuffer.GetCr8Bit(pUp.X + (maxW >> 1) - 2 - x, pUp.Y));
            }
            // V = sum(y' = 0 to (3 + yCF)){ (y'+1) * (p[-1, 4 + yCF + y'] - p[-1, 2 + yCF - y']) }
            for (var i = 1; i <= (maxH >> 1); i++)
            {
                var y = i - 1; // y'
                vCb += i*(codedFrameBuffer.GetCb8Bit(pLeft.X, pLeft.Y + (maxH >> 1) + y) - codedFrameBuffer.GetCb8Bit(pLeft.X, pLeft.Y + (maxH >> 1) - 2 - y));
                vCr += i*(codedFrameBuffer.GetCr8Bit(pLeft.X, pLeft.Y + (maxH >> 1) + y) - codedFrameBuffer.GetCr8Bit(pLeft.X, pLeft.Y + (maxH >> 1) - 2 - y));
            }
            // a = 16 * ( p[ -1, MbHeightC - 1 ] + p[ MbWidthC - 1, -1 ] )
            var aCb = 16*(codedFrameBuffer.GetCb8Bit(pLeft.X, pLeft.Y + maxH - 1) + codedFrameBuffer.GetCb8Bit(pUp.X + maxH - 1, pUp.Y));
            var aCr = 16*(codedFrameBuffer.GetCr8Bit(pLeft.X, pLeft.Y + maxH - 1) + codedFrameBuffer.GetCr8Bit(pUp.X + maxH - 1, pUp.Y));

            // b = ( ( 34 – 29 * ( ChromaArrayType == 3 ) ) * H + 32 ) >> 6
            var bCb = ((maxW == 8 ? 17 : 5)*hCb + 2*maxW) >> (maxW == 8 ? 5 : 6);
            var bCr = ((maxW == 8 ? 17 : 5)*hCr + 2*maxW) >> (maxW == 8 ? 5 : 6);

            // c = ( ( 34 – 29 * ( ChromaArrayType != 1 ) ) * V + 32 ) >> 6
            var cCb = ((maxH == 8 ? 17 : 5)*vCb + 2*maxH) >> (maxH == 8 ? 5 : 6);
            var cCr = ((maxH == 8 ? 17 : 5)*vCr + 2*maxH) >> (maxH == 8 ? 5 : 6);

            // predC[ x, y ] = Clip1C( ( a + b * ( x – 3 – xCF ) + c * ( y – 3 – yCF ) + 16 ) >> 5 ),
            // with x = 0..MbWidthC - 1 and y = 0..MbHeightC - 1
            for (var j = 0; j < maxH; j++)
            {
                for (var i = 0; i < maxW; i++)
                {
                    var predCb = (aCb + (i - (maxW >> 1) + 1)*bCb + (j - (maxH >> 1) + 1)*cCb + 16) >> 5;
                    var predCr = (aCr + (i - (maxW >> 1) + 1)*bCr + (j - (maxH >> 1) + 1)*cCr + 16) >> 5;
                    mpCb[j][i] = MathHelper.Clip(maxImagePelValue, predCb);
                    mpCr[j][i] = MathHelper.Clip(maxImagePelValue, predCr);
                }
            }
            return true;
        }