 4d02a2d2c0
			
		
	
	
		4d02a2d2c0
		
			
		
	
	
	
	
		
			
			* Initial NVDEC and VIC implementation * Update FFmpeg.AutoGen to 4.3.0 * Add nvdec dependencies for Windows * Unify some VP9 structures * Rename VP9 structure fields * Improvements to Video API * XML docs for Common.Memory * Remove now unused or redundant overloads from MemoryAccessor * NVDEC UV surface read/write scalar paths * Add FIXME comments about hacky things/stuff that will need to be fixed in the future * Cleaned up VP9 memory allocation * Remove some debug logs * Rename some VP9 structs * Remove unused struct * No need to compile Ryujinx.Graphics.Host1x with unsafe anymore * Name AsyncWorkQueue threads to make debugging easier * Make Vp9PictureInfo a ref struct * LayoutConverter no longer needs the depth argument (broken by rebase) * Pooling of VP9 buffers, plus fix a memory leak on VP9 * Really wish VS could rename projects properly... * Address feedback * Remove using * Catch OperationCanceledException * Add licensing informations * Add THIRDPARTY.md to release too Co-authored-by: Thog <me@thog.eu>
		
			
				
	
	
		
			761 lines
		
	
	
	
		
			26 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			761 lines
		
	
	
	
		
			26 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using Ryujinx.Graphics.Nvdec.Vp9.Common;
 | |
| using Ryujinx.Graphics.Nvdec.Vp9.Types;
 | |
| using static Ryujinx.Graphics.Nvdec.Vp9.Dsp.IntraPred;
 | |
| 
 | |
| namespace Ryujinx.Graphics.Nvdec.Vp9
 | |
| {
 | |
|     internal static class ReconIntra
 | |
|     {
 | |
|         public static readonly TxType[] IntraModeToTxTypeLookup = new TxType[]
 | |
|         {
 | |
|             TxType.DctDct,    // DC
 | |
|             TxType.AdstDct,   // V
 | |
|             TxType.DctAdst,   // H
 | |
|             TxType.DctDct,    // D45
 | |
|             TxType.AdstAdst,  // D135
 | |
|             TxType.AdstDct,   // D117
 | |
|             TxType.DctAdst,   // D153
 | |
|             TxType.DctAdst,   // D207
 | |
|             TxType.AdstDct,   // D63
 | |
|             TxType.AdstAdst   // TM
 | |
|         };
 | |
| 
 | |
|         private const int NeedLeft = 1 << 1;
 | |
|         private const int NeedAbove = 1 << 2;
 | |
|         private const int NeedAboveRight = 1 << 3;
 | |
| 
 | |
|         private static readonly byte[] ExtendModes = new byte[]
 | |
|         {
 | |
|             NeedAbove | NeedLeft,  // DC
 | |
|             NeedAbove,             // V
 | |
|             NeedLeft,              // H
 | |
|             NeedAboveRight,        // D45
 | |
|             NeedLeft | NeedAbove,  // D135
 | |
|             NeedLeft | NeedAbove,  // D117
 | |
|             NeedLeft | NeedAbove,  // D153
 | |
|             NeedLeft,              // D207
 | |
|             NeedAboveRight,        // D63
 | |
|             NeedLeft | NeedAbove,  // TM
 | |
|         };
 | |
| 
 | |
|         private unsafe delegate void IntraPredFn(byte* dst, int stride, byte* above, byte* left);
 | |
| 
 | |
|         private static unsafe IntraPredFn[][] _pred = new IntraPredFn[][]
 | |
|         {
 | |
|             new IntraPredFn[]
 | |
|             {
 | |
|                 null,
 | |
|                 null,
 | |
|                 null,
 | |
|                 null
 | |
|             },
 | |
|             new IntraPredFn[]
 | |
|             {
 | |
|                 VPredictor4x4,
 | |
|                 VPredictor8x8,
 | |
|                 VPredictor16x16,
 | |
|                 VPredictor32x32
 | |
|             },
 | |
|             new IntraPredFn[]
 | |
|             {
 | |
|                 HPredictor4x4,
 | |
|                 HPredictor8x8,
 | |
|                 HPredictor16x16,
 | |
|                 HPredictor32x32
 | |
|             },
 | |
|             new IntraPredFn[]
 | |
|             {
 | |
|                 D45Predictor4x4,
 | |
|                 D45Predictor8x8,
 | |
|                 D45Predictor16x16,
 | |
|                 D45Predictor32x32
 | |
|             },
 | |
|             new IntraPredFn[]
 | |
|             {
 | |
|                 D135Predictor4x4,
 | |
|                 D135Predictor8x8,
 | |
|                 D135Predictor16x16,
 | |
|                 D135Predictor32x32
 | |
|             },
 | |
|             new IntraPredFn[]
 | |
|             {
 | |
|                 D117Predictor4x4,
 | |
|                 D117Predictor8x8,
 | |
|                 D117Predictor16x16,
 | |
|                 D117Predictor32x32
 | |
|             },
 | |
|             new IntraPredFn[]
 | |
|             {
 | |
|                 D153Predictor4x4,
 | |
|                 D153Predictor8x8,
 | |
|                 D153Predictor16x16,
 | |
|                 D153Predictor32x32
 | |
|             },
 | |
|             new IntraPredFn[]
 | |
|             {
 | |
|                 D207Predictor4x4,
 | |
|                 D207Predictor8x8,
 | |
|                 D207Predictor16x16,
 | |
|                 D207Predictor32x32
 | |
|             },
 | |
|             new IntraPredFn[]
 | |
|             {
 | |
|                 D63Predictor4x4,
 | |
|                 D63Predictor8x8,
 | |
|                 D63Predictor16x16,
 | |
|                 D63Predictor32x32
 | |
|             },
 | |
|             new IntraPredFn[]
 | |
|             {
 | |
|                 TMPredictor4x4,
 | |
|                 TMPredictor8x8,
 | |
|                 TMPredictor16x16,
 | |
|                 TMPredictor32x32
 | |
|             }
 | |
|         };
 | |
| 
 | |
|         private static unsafe IntraPredFn[][][] _dcPred = new IntraPredFn[][][]
 | |
|         {
 | |
|             new IntraPredFn[][]
 | |
|             {
 | |
|                 new IntraPredFn[]
 | |
|                 {
 | |
|                     Dc128Predictor4x4,
 | |
|                     Dc128Predictor8x8,
 | |
|                     Dc128Predictor16x16,
 | |
|                     Dc128Predictor32x32
 | |
|                 },
 | |
|                 new IntraPredFn[]
 | |
|                 {
 | |
|                     DcTopPredictor4x4,
 | |
|                     DcTopPredictor8x8,
 | |
|                     DcTopPredictor16x16,
 | |
|                     DcTopPredictor32x32
 | |
|                 }
 | |
|             },
 | |
|             new IntraPredFn[][]
 | |
|             {
 | |
|                 new IntraPredFn[]
 | |
|                 {
 | |
|                     DcLeftPredictor4x4,
 | |
|                     DcLeftPredictor8x8,
 | |
|                     DcLeftPredictor16x16,
 | |
|                     DcLeftPredictor32x32
 | |
|                 },
 | |
|                 new IntraPredFn[]
 | |
|                 {
 | |
|                     DcPredictor4x4,
 | |
|                     DcPredictor8x8,
 | |
|                     DcPredictor16x16,
 | |
|                     DcPredictor32x32
 | |
|                 }
 | |
|             }
 | |
|         };
 | |
| 
 | |
|         private unsafe delegate void IntraHighPredFn(ushort* dst, int stride, ushort* above, ushort* left, int bd);
 | |
| 
 | |
|         private static unsafe IntraHighPredFn[][] _predHigh = new IntraHighPredFn[][]
 | |
|         {
 | |
|             new IntraHighPredFn[]
 | |
|             {
 | |
|                 null,
 | |
|                 null,
 | |
|                 null,
 | |
|                 null
 | |
|             },
 | |
|             new IntraHighPredFn[]
 | |
|             {
 | |
|                 HighbdVPredictor4x4,
 | |
|                 HighbdVPredictor8x8,
 | |
|                 HighbdVPredictor16x16,
 | |
|                 HighbdVPredictor32x32
 | |
|             },
 | |
|             new IntraHighPredFn[]
 | |
|             {
 | |
|                 HighbdHPredictor4x4,
 | |
|                 HighbdHPredictor8x8,
 | |
|                 HighbdHPredictor16x16,
 | |
|                 HighbdHPredictor32x32
 | |
|             },
 | |
|             new IntraHighPredFn[]
 | |
|             {
 | |
|                 HighbdD45Predictor4x4,
 | |
|                 HighbdD45Predictor8x8,
 | |
|                 HighbdD45Predictor16x16,
 | |
|                 HighbdD45Predictor32x32
 | |
|             },
 | |
|             new IntraHighPredFn[]
 | |
|             {
 | |
|                 HighbdD135Predictor4x4,
 | |
|                 HighbdD135Predictor8x8,
 | |
|                 HighbdD135Predictor16x16,
 | |
|                 HighbdD135Predictor32x32
 | |
|             },
 | |
|             new IntraHighPredFn[]
 | |
|             {
 | |
|                 HighbdD117Predictor4x4,
 | |
|                 HighbdD117Predictor8x8,
 | |
|                 HighbdD117Predictor16x16,
 | |
|                 HighbdD117Predictor32x32
 | |
|             },
 | |
|             new IntraHighPredFn[]
 | |
|             {
 | |
|                 HighbdD153Predictor4x4,
 | |
|                 HighbdD153Predictor8x8,
 | |
|                 HighbdD153Predictor16x16,
 | |
|                 HighbdD153Predictor32x32
 | |
|             },
 | |
|             new IntraHighPredFn[]
 | |
|             {
 | |
|                 HighbdD207Predictor4x4,
 | |
|                 HighbdD207Predictor8x8,
 | |
|                 HighbdD207Predictor16x16,
 | |
|                 HighbdD207Predictor32x32
 | |
|             },
 | |
|             new IntraHighPredFn[]
 | |
|             {
 | |
|                 HighbdD63Predictor4x4,
 | |
|                 HighbdD63Predictor8x8,
 | |
|                 HighbdD63Predictor16x16,
 | |
|                 HighbdD63Predictor32x32
 | |
|             },
 | |
|             new IntraHighPredFn[]
 | |
|             {
 | |
|                 HighbdTMPredictor4x4,
 | |
|                 HighbdTMPredictor8x8,
 | |
|                 HighbdTMPredictor16x16,
 | |
|                 HighbdTMPredictor32x32
 | |
|             }
 | |
|         };
 | |
| 
 | |
|         private static unsafe IntraHighPredFn[][][] _dcPredHigh = new IntraHighPredFn[][][]
 | |
|         {
 | |
|             new IntraHighPredFn[][]
 | |
|             {
 | |
|                 new IntraHighPredFn[]
 | |
|                 {
 | |
|                     HighbdDc128Predictor4x4,
 | |
|                     HighbdDc128Predictor8x8,
 | |
|                     HighbdDc128Predictor16x16,
 | |
|                     HighbdDc128Predictor32x32
 | |
|                 },
 | |
|                 new IntraHighPredFn[]
 | |
|                 {
 | |
|                     HighbdDcTopPredictor4x4,
 | |
|                     HighbdDcTopPredictor8x8,
 | |
|                     HighbdDcTopPredictor16x16,
 | |
|                     HighbdDcTopPredictor32x32
 | |
|                 }
 | |
|             },
 | |
|             new IntraHighPredFn[][]
 | |
|             {
 | |
|                 new IntraHighPredFn[]
 | |
|                 {
 | |
|                     HighbdDcLeftPredictor4x4,
 | |
|                     HighbdDcLeftPredictor8x8,
 | |
|                     HighbdDcLeftPredictor16x16,
 | |
|                     HighbdDcLeftPredictor32x32
 | |
|                 },
 | |
|                 new IntraHighPredFn[]
 | |
|                 {
 | |
|                     HighbdDcPredictor4x4,
 | |
|                     HighbdDcPredictor8x8,
 | |
|                     HighbdDcPredictor16x16,
 | |
|                     HighbdDcPredictor32x32
 | |
|                 }
 | |
|             }
 | |
|         };
 | |
| 
 | |
|         private static unsafe void BuildIntraPredictorsHigh(
 | |
|             ref MacroBlockD xd,
 | |
|             byte* ref8,
 | |
|             int refStride,
 | |
|             byte* dst8,
 | |
|             int dstStride,
 | |
|             PredictionMode mode,
 | |
|             TxSize txSize,
 | |
|             int upAvailable,
 | |
|             int leftAvailable,
 | |
|             int rightAvailable,
 | |
|             int x,
 | |
|             int y,
 | |
|             int plane)
 | |
|         {
 | |
|             int i;
 | |
|             ushort* dst = (ushort*)dst8;
 | |
|             ushort* refr = (ushort*)ref8;
 | |
|             ushort* leftCol = stackalloc ushort[32];
 | |
|             ushort* aboveData = stackalloc ushort[64 + 16];
 | |
|             ushort* aboveRow = aboveData + 16;
 | |
|             ushort* constAboveRow = aboveRow;
 | |
|             int bs = 4 << (int)txSize;
 | |
|             int frameWidth, frameHeight;
 | |
|             int x0, y0;
 | |
|             ref MacroBlockDPlane pd = ref xd.Plane[plane];
 | |
|             int needLeft = ExtendModes[(int)mode] & NeedLeft;
 | |
|             int needAbove = ExtendModes[(int)mode] & NeedAbove;
 | |
|             int needAboveRight = ExtendModes[(int)mode] & NeedAboveRight;
 | |
|             int baseVal = 128 << (xd.Bd - 8);
 | |
|             // 127 127 127 .. 127 127 127 127 127 127
 | |
|             // 129  A   B  ..  Y   Z
 | |
|             // 129  C   D  ..  W   X
 | |
|             // 129  E   F  ..  U   V
 | |
|             // 129  G   H  ..  S   T   T   T   T   T
 | |
|             // For 10 bit and 12 bit, 127 and 129 are replaced by base -1 and base + 1.
 | |
| 
 | |
|             // Get current frame pointer, width and height.
 | |
|             if (plane == 0)
 | |
|             {
 | |
|                 frameWidth = xd.CurBuf.Width;
 | |
|                 frameHeight = xd.CurBuf.Height;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 frameWidth = xd.CurBuf.UvWidth;
 | |
|                 frameHeight = xd.CurBuf.UvHeight;
 | |
|             }
 | |
| 
 | |
|             // Get block position in current frame.
 | |
|             x0 = (-xd.MbToLeftEdge >> (3 + pd.SubsamplingX)) + x;
 | |
|             y0 = (-xd.MbToTopEdge >> (3 + pd.SubsamplingY)) + y;
 | |
| 
 | |
|             // NEED_LEFT
 | |
|             if (needLeft != 0)
 | |
|             {
 | |
|                 if (leftAvailable != 0)
 | |
|                 {
 | |
|                     if (xd.MbToBottomEdge < 0)
 | |
|                     {
 | |
|                         /* slower path if the block needs border extension */
 | |
|                         if (y0 + bs <= frameHeight)
 | |
|                         {
 | |
|                             for (i = 0; i < bs; ++i)
 | |
|                             {
 | |
|                                 leftCol[i] = refr[i * refStride - 1];
 | |
|                             }
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             int extendBottom = frameHeight - y0;
 | |
|                             for (i = 0; i < extendBottom; ++i)
 | |
|                             {
 | |
|                                 leftCol[i] = refr[i * refStride - 1];
 | |
|                             }
 | |
| 
 | |
|                             for (; i < bs; ++i)
 | |
|                             {
 | |
|                                 leftCol[i] = refr[(extendBottom - 1) * refStride - 1];
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         /* faster path if the block does not need extension */
 | |
|                         for (i = 0; i < bs; ++i)
 | |
|                         {
 | |
|                             leftCol[i] = refr[i * refStride - 1];
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     MemoryUtil.Fill(leftCol, (ushort)(baseVal + 1), bs);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             // NEED_ABOVE
 | |
|             if (needAbove != 0)
 | |
|             {
 | |
|                 if (upAvailable != 0)
 | |
|                 {
 | |
|                     ushort* aboveRef = refr - refStride;
 | |
|                     if (xd.MbToRightEdge < 0)
 | |
|                     {
 | |
|                         /* slower path if the block needs border extension */
 | |
|                         if (x0 + bs <= frameWidth)
 | |
|                         {
 | |
|                             MemoryUtil.Copy(aboveRow, aboveRef, bs);
 | |
|                         }
 | |
|                         else if (x0 <= frameWidth)
 | |
|                         {
 | |
|                             int r = frameWidth - x0;
 | |
|                             MemoryUtil.Copy(aboveRow, aboveRef, r);
 | |
|                             MemoryUtil.Fill(aboveRow + r, aboveRow[r - 1], x0 + bs - frameWidth);
 | |
|                         }
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         /* faster path if the block does not need extension */
 | |
|                         if (bs == 4 && rightAvailable != 0 && leftAvailable != 0)
 | |
|                         {
 | |
|                             constAboveRow = aboveRef;
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             MemoryUtil.Copy(aboveRow, aboveRef, bs);
 | |
|                         }
 | |
|                     }
 | |
|                     aboveRow[-1] = leftAvailable != 0 ? aboveRef[-1] : (ushort)(baseVal + 1);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     MemoryUtil.Fill(aboveRow, (ushort)(baseVal - 1), bs);
 | |
|                     aboveRow[-1] = (ushort)(baseVal - 1);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             // NEED_ABOVERIGHT
 | |
|             if (needAboveRight != 0)
 | |
|             {
 | |
|                 if (upAvailable != 0)
 | |
|                 {
 | |
|                     ushort* aboveRef = refr - refStride;
 | |
|                     if (xd.MbToRightEdge < 0)
 | |
|                     {
 | |
|                         /* slower path if the block needs border extension */
 | |
|                         if (x0 + 2 * bs <= frameWidth)
 | |
|                         {
 | |
|                             if (rightAvailable != 0 && bs == 4)
 | |
|                             {
 | |
|                                 MemoryUtil.Copy(aboveRow, aboveRef, 2 * bs);
 | |
|                             }
 | |
|                             else
 | |
|                             {
 | |
|                                 MemoryUtil.Copy(aboveRow, aboveRef, bs);
 | |
|                                 MemoryUtil.Fill(aboveRow + bs, aboveRow[bs - 1], bs);
 | |
|                             }
 | |
|                         }
 | |
|                         else if (x0 + bs <= frameWidth)
 | |
|                         {
 | |
|                             int r = frameWidth - x0;
 | |
|                             if (rightAvailable != 0 && bs == 4)
 | |
|                             {
 | |
|                                 MemoryUtil.Copy(aboveRow, aboveRef, r);
 | |
|                                 MemoryUtil.Fill(aboveRow + r, aboveRow[r - 1], x0 + 2 * bs - frameWidth);
 | |
|                             }
 | |
|                             else
 | |
|                             {
 | |
|                                 MemoryUtil.Copy(aboveRow, aboveRef, bs);
 | |
|                                 MemoryUtil.Fill(aboveRow + bs, aboveRow[bs - 1], bs);
 | |
|                             }
 | |
|                         }
 | |
|                         else if (x0 <= frameWidth)
 | |
|                         {
 | |
|                             int r = frameWidth - x0;
 | |
|                             MemoryUtil.Copy(aboveRow, aboveRef, r);
 | |
|                             MemoryUtil.Fill(aboveRow + r, aboveRow[r - 1], x0 + 2 * bs - frameWidth);
 | |
|                         }
 | |
|                         aboveRow[-1] = leftAvailable != 0 ? aboveRef[-1] : (ushort)(baseVal + 1);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         /* faster path if the block does not need extension */
 | |
|                         if (bs == 4 && rightAvailable != 0 && leftAvailable != 0)
 | |
|                         {
 | |
|                             constAboveRow = aboveRef;
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             MemoryUtil.Copy(aboveRow, aboveRef, bs);
 | |
|                             if (bs == 4 && rightAvailable != 0)
 | |
|                             {
 | |
|                                 MemoryUtil.Copy(aboveRow + bs, aboveRef + bs, bs);
 | |
|                             }
 | |
|                             else
 | |
|                             {
 | |
|                                 MemoryUtil.Fill(aboveRow + bs, aboveRow[bs - 1], bs);
 | |
|                             }
 | |
| 
 | |
|                             aboveRow[-1] = leftAvailable != 0 ? aboveRef[-1] : (ushort)(baseVal + 1);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     MemoryUtil.Fill(aboveRow, (ushort)(baseVal - 1), bs * 2);
 | |
|                     aboveRow[-1] = (ushort)(baseVal - 1);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             // Predict
 | |
|             if (mode == PredictionMode.DcPred)
 | |
|             {
 | |
|                 _dcPredHigh[leftAvailable][upAvailable][(int)txSize](dst, dstStride, constAboveRow, leftCol, xd.Bd);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 _predHigh[(int)mode][(int)txSize](dst, dstStride, constAboveRow, leftCol, xd.Bd);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static unsafe void BuildIntraPredictors(
 | |
|             ref MacroBlockD xd,
 | |
|             byte* refr,
 | |
|             int refStride,
 | |
|             byte* dst,
 | |
|             int dstStride,
 | |
|             PredictionMode mode,
 | |
|             TxSize txSize,
 | |
|             int upAvailable,
 | |
|             int leftAvailable,
 | |
|             int rightAvailable,
 | |
|             int x,
 | |
|             int y,
 | |
|             int plane)
 | |
|         {
 | |
|             int i;
 | |
|             byte* leftCol = stackalloc byte[32];
 | |
|             byte* aboveData = stackalloc byte[64 + 16];
 | |
|             byte* aboveRow = aboveData + 16;
 | |
|             byte* constAboveRow = aboveRow;
 | |
|             int bs = 4 << (int)txSize;
 | |
|             int frameWidth, frameHeight;
 | |
|             int x0, y0;
 | |
|             ref MacroBlockDPlane pd = ref xd.Plane[plane];
 | |
| 
 | |
|             // 127 127 127 .. 127 127 127 127 127 127
 | |
|             // 129  A   B  ..  Y   Z
 | |
|             // 129  C   D  ..  W   X
 | |
|             // 129  E   F  ..  U   V
 | |
|             // 129  G   H  ..  S   T   T   T   T   T
 | |
|             // ..
 | |
| 
 | |
|             // Get current frame pointer, width and height.
 | |
|             if (plane == 0)
 | |
|             {
 | |
|                 frameWidth = xd.CurBuf.Width;
 | |
|                 frameHeight = xd.CurBuf.Height;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 frameWidth = xd.CurBuf.UvWidth;
 | |
|                 frameHeight = xd.CurBuf.UvHeight;
 | |
|             }
 | |
| 
 | |
|             // Get block position in current frame.
 | |
|             x0 = (-xd.MbToLeftEdge >> (3 + pd.SubsamplingX)) + x;
 | |
|             y0 = (-xd.MbToTopEdge >> (3 + pd.SubsamplingY)) + y;
 | |
| 
 | |
|             // NEED_LEFT
 | |
|             if ((ExtendModes[(int)mode] & NeedLeft) != 0)
 | |
|             {
 | |
|                 if (leftAvailable != 0)
 | |
|                 {
 | |
|                     if (xd.MbToBottomEdge < 0)
 | |
|                     {
 | |
|                         /* Slower path if the block needs border extension */
 | |
|                         if (y0 + bs <= frameHeight)
 | |
|                         {
 | |
|                             for (i = 0; i < bs; ++i)
 | |
|                             {
 | |
|                                 leftCol[i] = refr[i * refStride - 1];
 | |
|                             }
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             int extendBottom = frameHeight - y0;
 | |
|                             for (i = 0; i < extendBottom; ++i)
 | |
|                             {
 | |
|                                 leftCol[i] = refr[i * refStride - 1];
 | |
|                             }
 | |
| 
 | |
|                             for (; i < bs; ++i)
 | |
|                             {
 | |
|                                 leftCol[i] = refr[(extendBottom - 1) * refStride - 1];
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         /* Faster path if the block does not need extension */
 | |
|                         for (i = 0; i < bs; ++i)
 | |
|                         {
 | |
|                             leftCol[i] = refr[i * refStride - 1];
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     MemoryUtil.Fill(leftCol, (byte)129, bs);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             // NEED_ABOVE
 | |
|             if ((ExtendModes[(int)mode] & NeedAbove) != 0)
 | |
|             {
 | |
|                 if (upAvailable != 0)
 | |
|                 {
 | |
|                     byte* aboveRef = refr - refStride;
 | |
|                     if (xd.MbToRightEdge < 0)
 | |
|                     {
 | |
|                         /* Slower path if the block needs border extension */
 | |
|                         if (x0 + bs <= frameWidth)
 | |
|                         {
 | |
|                             MemoryUtil.Copy(aboveRow, aboveRef, bs);
 | |
|                         }
 | |
|                         else if (x0 <= frameWidth)
 | |
|                         {
 | |
|                             int r = frameWidth - x0;
 | |
|                             MemoryUtil.Copy(aboveRow, aboveRef, r);
 | |
|                             MemoryUtil.Fill(aboveRow + r, aboveRow[r - 1], x0 + bs - frameWidth);
 | |
|                         }
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         /* Faster path if the block does not need extension */
 | |
|                         if (bs == 4 && rightAvailable != 0 && leftAvailable != 0)
 | |
|                         {
 | |
|                             constAboveRow = aboveRef;
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             MemoryUtil.Copy(aboveRow, aboveRef, bs);
 | |
|                         }
 | |
|                     }
 | |
|                     aboveRow[-1] = leftAvailable != 0 ? aboveRef[-1] : (byte)129;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     MemoryUtil.Fill(aboveRow, (byte)127, bs);
 | |
|                     aboveRow[-1] = 127;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             // NEED_ABOVERIGHT
 | |
|             if ((ExtendModes[(int)mode] & NeedAboveRight) != 0)
 | |
|             {
 | |
|                 if (upAvailable != 0)
 | |
|                 {
 | |
|                     byte* aboveRef = refr - refStride;
 | |
|                     if (xd.MbToRightEdge < 0)
 | |
|                     {
 | |
|                         /* Slower path if the block needs border extension */
 | |
|                         if (x0 + 2 * bs <= frameWidth)
 | |
|                         {
 | |
|                             if (rightAvailable != 0 && bs == 4)
 | |
|                             {
 | |
|                                 MemoryUtil.Copy(aboveRow, aboveRef, 2 * bs);
 | |
|                             }
 | |
|                             else
 | |
|                             {
 | |
|                                 MemoryUtil.Copy(aboveRow, aboveRef, bs);
 | |
|                                 MemoryUtil.Fill(aboveRow + bs, aboveRow[bs - 1], bs);
 | |
|                             }
 | |
|                         }
 | |
|                         else if (x0 + bs <= frameWidth)
 | |
|                         {
 | |
|                             int r = frameWidth - x0;
 | |
|                             if (rightAvailable != 0 && bs == 4)
 | |
|                             {
 | |
|                                 MemoryUtil.Copy(aboveRow, aboveRef, r);
 | |
|                                 MemoryUtil.Fill(aboveRow + r, aboveRow[r - 1], x0 + 2 * bs - frameWidth);
 | |
|                             }
 | |
|                             else
 | |
|                             {
 | |
|                                 MemoryUtil.Copy(aboveRow, aboveRef, bs);
 | |
|                                 MemoryUtil.Fill(aboveRow + bs, aboveRow[bs - 1], bs);
 | |
|                             }
 | |
|                         }
 | |
|                         else if (x0 <= frameWidth)
 | |
|                         {
 | |
|                             int r = frameWidth - x0;
 | |
|                             MemoryUtil.Copy(aboveRow, aboveRef, r);
 | |
|                             MemoryUtil.Fill(aboveRow + r, aboveRow[r - 1], x0 + 2 * bs - frameWidth);
 | |
|                         }
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         /* Faster path if the block does not need extension */
 | |
|                         if (bs == 4 && rightAvailable != 0 && leftAvailable != 0)
 | |
|                         {
 | |
|                             constAboveRow = aboveRef;
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             MemoryUtil.Copy(aboveRow, aboveRef, bs);
 | |
|                             if (bs == 4 && rightAvailable != 0)
 | |
|                             {
 | |
|                                 MemoryUtil.Copy(aboveRow + bs, aboveRef + bs, bs);
 | |
|                             }
 | |
|                             else
 | |
|                             {
 | |
|                                 MemoryUtil.Fill(aboveRow + bs, aboveRow[bs - 1], bs);
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                     aboveRow[-1] = leftAvailable != 0 ? aboveRef[-1] : (byte)129;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     MemoryUtil.Fill(aboveRow, (byte)127, bs * 2);
 | |
|                     aboveRow[-1] = 127;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             // Predict
 | |
|             if (mode == PredictionMode.DcPred)
 | |
|             {
 | |
|                 _dcPred[leftAvailable][upAvailable][(int)txSize](dst, dstStride, constAboveRow, leftCol);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 _pred[(int)mode][(int)txSize](dst, dstStride, constAboveRow, leftCol);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static unsafe void PredictIntraBlock(
 | |
|             ref MacroBlockD xd,
 | |
|             int bwlIn,
 | |
|             TxSize txSize,
 | |
|             PredictionMode mode,
 | |
|             byte* refr,
 | |
|             int refStride,
 | |
|             byte* dst,
 | |
|             int dstStride,
 | |
|             int aoff,
 | |
|             int loff,
 | |
|             int plane)
 | |
|         {
 | |
|             int bw = 1 << bwlIn;
 | |
|             int txw = 1 << (int)txSize;
 | |
|             int haveTop = loff != 0 || !xd.AboveMi.IsNull ? 1 : 0;
 | |
|             int haveLeft = aoff != 0 || !xd.LeftMi.IsNull ? 1 : 0;
 | |
|             int haveRight = (aoff + txw) < bw ? 1 : 0;
 | |
|             int x = aoff * 4;
 | |
|             int y = loff * 4;
 | |
| 
 | |
|             if (xd.CurBuf.HighBd)
 | |
|             {
 | |
|                 BuildIntraPredictorsHigh(
 | |
|                     ref xd,
 | |
|                     refr,
 | |
|                     refStride,
 | |
|                     dst,
 | |
|                     dstStride,
 | |
|                     mode,
 | |
|                     txSize,
 | |
|                     haveTop,
 | |
|                     haveLeft,
 | |
|                     haveRight,
 | |
|                     x,
 | |
|                     y,
 | |
|                     plane);
 | |
|                 return;
 | |
|             }
 | |
|             BuildIntraPredictors(
 | |
|                 ref xd,
 | |
|                 refr,
 | |
|                 refStride,
 | |
|                 dst,
 | |
|                 dstStride,
 | |
|                 mode,
 | |
|                 txSize,
 | |
|                 haveTop,
 | |
|                 haveLeft,
 | |
|                 haveRight,
 | |
|                 x,
 | |
|                 y,
 | |
|                 plane);
 | |
|         }
 | |
|     }
 | |
| }
 |