private SubMacroblockType(byte mbType, string name, byte numSubMbPart, SubMbPredMode direct, byte subMbPartPredWidth, byte subMbPartPredHeight) { _mbType = mbType; _name = name; _numSubMbPart = numSubMbPart; _subMbPredMode = direct; _macroblockPartitioning = MacroblockPartitioning.GetMacroblockPartitioning(subMbPartPredWidth, subMbPartPredHeight); }
private void SubMacroBlockPrediction() { if (_sliceState.SliceType == SliceType.B) { for (uint mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++) { uint subMbType = GetSubMbTypeB(); _subMbTypes[mbPartIdx] = SubMacroblockType.GetSubMbTypeB(subMbType); } } else // P or Sp { for (uint mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++) { uint subMbType = GetSubMbTypeP(); _subMbTypes[mbPartIdx] = SubMacroblockType.GetSubMbTypeP(subMbType); } } uint referencePictureCount0 = _sliceState.ActiveReferencePictureCount0; //defaults to _pictureState.DefaultReferencePictureCount0; if (HasReferencePictureIndex(referencePictureCount0)) { var referencePictureIndex = new ReferencePictureIndex(_mbStateA.RefIdxL0, _mbStateB.RefIdxL0); for (uint mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++) { if (_subMbTypes[mbPartIdx].List0Predicted) { uint idx = MacroblockPartitioning.M8X8[mbPartIdx].Idx; if (GetReferencePicture(referencePictureCount0, referencePictureIndex.GetCtxIdxInc(idx))) // ref_idx_l0[ mbPartIdx ] { referencePictureIndex.SetNonZeroRefIdx(idx); } } } _currMbState.RefIdxL0 = referencePictureIndex.Bits; } uint referencePictureCount1 = _sliceState.ActiveReferencePictureCount1; //defaults to _pictureState.DefaultReferencePictureCount1; if (HasReferencePictureIndex(referencePictureCount1)) { var referencePictureIndex = new ReferencePictureIndex(_mbStateA.RefIdxL1, _mbStateB.RefIdxL1); for (uint mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++) { if (_subMbTypes[mbPartIdx].List1Predicted) { uint idx = MacroblockPartitioning.M8X8[mbPartIdx].Idx; if (GetReferencePicture(referencePictureCount1, referencePictureIndex.GetCtxIdxInc(idx))) // ref_idx_l0[ mbPartIdx ] { referencePictureIndex.SetNonZeroRefIdx(idx); } } } _currMbState.RefIdxL1 = referencePictureIndex.Bits; } for (uint mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++) { ISubMacroblockType subMbType = _subMbTypes[mbPartIdx]; if (subMbType.List0Predicted) { MacroblockPartitioning macroblockPartitioning = subMbType.MacroblockPartitioning; uint subMbPartOffset = (mbPartIdx * subMbType.NumSubMbPart); for (uint subMbPartIdx = 0; subMbPartIdx < subMbType.NumSubMbPart; subMbPartIdx++) { GetMotionVector(_motionFieldL0, macroblockPartitioning[subMbPartOffset + subMbPartIdx]); // mvd_l0[ i ][ j ][ compIdx ] } } } for (uint mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++) { ISubMacroblockType subMbType = _subMbTypes[mbPartIdx]; if (subMbType.List1Predicted) { MacroblockPartitioning macroblockPartitioning = subMbType.MacroblockPartitioning; uint subMbPartOffset = (mbPartIdx * subMbType.NumSubMbPart); for (uint subMbPartIdx = 0; subMbPartIdx < subMbType.NumSubMbPart; subMbPartIdx++) { GetMotionVector(_motionFieldL1, macroblockPartitioning[subMbPartOffset + subMbPartIdx]); // mvd_l1[ i ][ j ][ compIdx ] } } } }
// 7.3.5.1 Macroblock prediction syntax private void MacroBlockPrediction(IMacroblockType macroBlockType) { if (macroBlockType.IsIntra4X4 || macroBlockType.IsIntra16X16) { if (macroBlockType.IsIntra4X4) { int lumaSubBlocks = _mbFlags.TransformSize8X8Flag ? 4 : 16; for (int i = 0; i < lumaSubBlocks; i++) { if (GetPrevIntra4X4PredModeFlag() == 0) // prev_intra4x4_pred_mode_flag[luma4x4BlkIdx]) { GetRemIntra4X4PredMode(); // rem_intra4x4_pred_mode[luma4x4BlkIdx] } } } if (_sequenceState.IsChromaSubsampling) { GetIntraChromaPredMode(); // intra_chroma_pred_mode } } else if (!macroBlockType.IsDirect) { uint numMbPart = macroBlockType.NumMbPart; // either 1 or 2 MacroblockPartitioning macroblockPartitioning = macroBlockType.MacroblockPartitioning; uint referencePictureCount0 = _sliceState.ActiveReferencePictureCount0; //defaults to _pictureState.DefaultReferencePictureCount0; if (HasReferencePictureIndex(referencePictureCount0)) { var referencePictureIndex = new ReferencePictureIndex(_mbStateA.RefIdxL0, _mbStateB.RefIdxL0); for (uint i = 0; i < numMbPart; i++) { if (macroBlockType.IsList0Predicted(i)) { uint idx = macroblockPartitioning[i].Idx; if (GetReferencePicture(referencePictureCount0, referencePictureIndex.GetCtxIdxInc(idx))) // ref_idx_l0[ mbPartIdx ] { referencePictureIndex.SetNonZeroRefIdx(idx); } } } _currMbState.RefIdxL0 = referencePictureIndex.Bits; } uint referencePictureCount1 = _sliceState.ActiveReferencePictureCount1; //defaults to _pictureState.DefaultReferencePictureCount1; if (HasReferencePictureIndex(referencePictureCount1)) { var referencePictureIndex = new ReferencePictureIndex(_mbStateA.RefIdxL1, _mbStateB.RefIdxL1); for (uint i = 0; i < numMbPart; i++) { if (macroBlockType.IsList1Predicted(i)) { uint idx = macroblockPartitioning[i].Idx; if (GetReferencePicture(referencePictureCount1, referencePictureIndex.GetCtxIdxInc(idx))) // ref_idx_l1[ mbPartIdx ] { referencePictureIndex.SetNonZeroRefIdx(idx); } } } _currMbState.RefIdxL1 = referencePictureIndex.Bits; } for (uint i = 0; i < numMbPart; i++) { if (macroBlockType.IsList0Predicted(i)) { GetMotionVector(_motionFieldL0, macroblockPartitioning[i]); // mvd_l0[ i ][ 0 ][ compIdx ] } } for (uint i = 0; i < numMbPart; i++) { if (macroBlockType.IsList1Predicted(i)) { GetMotionVector(_motionFieldL1, macroblockPartitioning[i]); // mvd_l1[ i ][ 0 ][ compIdx ] } } } }
private Rgb GetMaskedPixel(Rgb pixel, int x, int y, MacroblockPartitioning? decision) { switch (decision) { case MacroblockPartitioning.InterSkip: if ((x % 16 == 0) || (y % 16 == 0)) return new Rgb(0, 0, 0); else return new Rgb(pixel.R, (byte)Math.Min(255, pixel.G + 100), pixel.B); case MacroblockPartitioning.Inter16x16: if ((x % 16 == 0) || (y % 16 == 0)) return new Rgb(0, 0, 0); else return new Rgb(pixel.R, (byte)Math.Min(255, pixel.G + 100), pixel.B); case MacroblockPartitioning.Inter16x8: if ((x % 16 == 0) || (y % 8 == 0)) return new Rgb(0, 0, 0); else return new Rgb(pixel.R, (byte)Math.Min(255, pixel.G + 100), pixel.B); case MacroblockPartitioning.Inter4x4: if ((x % 4 == 0) || (y % 4 == 0)) return new Rgb(0, 0, 0); else return new Rgb(pixel.R, (byte)Math.Min(255, pixel.G + 100), pixel.B); case MacroblockPartitioning.Inter4x8: if ((x % 4 == 0) || (y % 8 == 0)) return new Rgb(0, 0, 0); else return new Rgb(pixel.R, (byte)Math.Min(255, pixel.G + 100), pixel.B); case MacroblockPartitioning.Inter8x16: if ((x % 8 == 0) || (y % 16 == 0)) return new Rgb(0, 0, 0); else return new Rgb(pixel.R, (byte)Math.Min(255, pixel.G + 100), pixel.B); case MacroblockPartitioning.Inter8x4: if ((x % 8 == 0) || (y % 4 == 0)) return new Rgb(0, 0, 0); else return new Rgb(pixel.R, (byte)Math.Min(255, pixel.G + 100), pixel.B); case MacroblockPartitioning.Inter8x8: if ((x % 8 == 0) || (y % 8 == 0)) return new Rgb(0, 0, 0); else return new Rgb(pixel.R, (byte)Math.Min(255, pixel.G + 100), pixel.B); case MacroblockPartitioning.Inter8x8OrBelow: if ((x % 8 == 0) || (y % 8 == 0)) return new Rgb(0, 0, 0); else return new Rgb(pixel.R, (byte)Math.Min(255, pixel.G + 100), pixel.B); case MacroblockPartitioning.Intra16x16: if ((x % 16 == 0) || (y % 16 == 0)) return new Rgb(0, 0, 0); else return new Rgb((byte)Math.Min(255, pixel.R + 80), pixel.G, (byte)Math.Min(255, pixel.B + 80)); case MacroblockPartitioning.Intra4x4: if ((x % 4 == 0) || (y % 4 == 0)) return new Rgb(0, 0, 0); else return new Rgb((byte)Math.Min(255, pixel.R + 80), pixel.G, (byte)Math.Min(255, pixel.B + 80)); case MacroblockPartitioning.Intra8x8: if ((x % 8 == 0) || (y % 8 == 0)) return new Rgb(0, 0, 0); else return new Rgb((byte)Math.Min(255, pixel.R + 80), pixel.G, (byte)Math.Min(255, pixel.B + 80)); case MacroblockPartitioning.IntraPCM: if ((x % 16 == 0) || (y % 16 == 0)) return new Rgb(0, 0, 0); else return new Rgb((byte)Math.Min(255, pixel.R + 80), pixel.G, (byte)Math.Min(255, pixel.B + 80)); case MacroblockPartitioning.Unknown: if ((x % 16 == 0) || (y % 16 == 0)) return new Rgb(0, 0, 0); else return new Rgb((byte)Math.Min(255, pixel.R + 100), pixel.G, pixel.B); default: if ((x % 16 == 0) || (y % 16 == 0)) return new Rgb(0, 0, 0); else return new Rgb(pixel.R, pixel.G, (byte)Math.Max(255, pixel.B + 40)); } }