public CabacSliceData(INalUnitReader reader, IState readerState) { _reader = reader; _readerState = readerState; _sliceState = reader.State.SliceState; _pictureState = _sliceState.PictureState; _sequenceState = _pictureState.SequenceState; _unavailableMacroblockState = _sliceState.IntraCoded ? MacroblockState.UnavailableIntraCoded : MacroblockState.UnavailableInterCoded; _macroblockStates = new MacroblockState[PicSizeInMbs]; _motionFieldL0 = IsList0Predicted ? new MotionField(_sliceState) : null; _motionFieldL1 = IsList1Predicted ? new MotionField(_sliceState) : null; _subMbTypes = new ISubMacroblockType[4]; _arithmeticDecoder = new ArithmeticDecoder(reader); for (int i = 0; i < _macroblockStates.Length; i++) { _macroblockStates[i] = _unavailableMacroblockState; } MbToSliceGroupMap = _mbToSliceGroup.CreateMacroBlockToSliceGroupMap(_sliceState); }
private void MacroBlockLayer() { IMacroblockType macroBlockType = GetMacroblockType(); #if DEBUG H264Debug.WriteLine("{0}: mb_type={1}", CurrentMbIndex, macroBlockType); #endif if (macroBlockType.IsIPcm) { _reader.GetPcmSamples(); InitializeCabac(); _currMbState = MacroblockState.Pcm; } else { bool transform8X8ModeFlagSet = false; if (macroBlockType.NumMbPart == 4) { // Note: Only inter-coded blocks can have mb parts, in particular, // we are not currently decoding an intra-coded block! SubMacroBlockPrediction(); if (HasSubMbPartSizeLessThan8X8()) { transform8X8ModeFlagSet = true; // Transform 8x8 mode is not possible! } } else { if (_pictureState.Transform8X8ModeFlag && macroBlockType.IsI_NxN) { GetTransformSize8X8Flag(); transform8X8ModeFlagSet = true; } MacroBlockPrediction(macroBlockType); } if (macroBlockType.IsIntra16X16) { _codedBlockPattern = new CodedBlockPattern(macroBlockType.CodedBlockPattern); } else { GetCodedBlockPattern(); if (_pictureState.Transform8X8ModeFlag && !transform8X8ModeFlagSet && _codedBlockPattern.IsLumaResidualPresent && (!macroBlockType.IsDirect || _sequenceState.Direct8X8InferenceFlag)) { GetTransformSize8X8Flag(); } } _currMbState.CodedBlockPattern = _codedBlockPattern.Bits; if (_codedBlockPattern.IsResidualPresent || macroBlockType.IsIntra16X16) { GetMbQpDelta(); // mb_qp_delta Residual(macroBlockType, 0, 15); } } }
public void Parse() { InitializeCabac(); _currMbAddr = _sliceState.FirstMacroBlockInSlice * (MbAffFrameFlag ? 2U : 1U); MbFieldDecodingFlag = _sliceState.FieldPicFlag; // The default for non-MBAFF frames bool moreDataFlag = true; bool prevMbSkipped = false; while (_readerState.Valid && moreDataFlag) { _currMbState = new MacroblockState(); _mbQpDeltaNotZero = 0; // Load macroblock states for block A (left) and B (top) _mbStateA = GetMacroblockState(_sliceState.GetMbAddrA(_currMbAddr)); _mbStateB = GetMacroblockState(_sliceState.GetMbAddrB(_currMbAddr)); _mbFlags = new MacroblockFlags(_mbStateA.Flags, _mbStateB.Flags); bool mbSkipFlag = false; if (!_sliceState.IntraCoded) { mbSkipFlag = GetMbSkipFlag(); // mb_skip_flag } if (!mbSkipFlag) { _mbFlags.SetCodedBlockFlag(); if (MbAffFrameFlag && (IsFirstMacroblockInPair() || prevMbSkipped)) { MbFieldDecodingFlag = GetMbFieldDecodingFlag(); // is field macro block } MacroBlockLayer(); } if (MbFieldDecodingFlag && (!MbAffFrameFlag || IsLastMacroblockInPair())) { _mbFlags.SetFieldDecodingMode(); } _currMbState.Flags = _mbFlags.Bits; _macroblockStates[_currMbAddr] = _currMbState; _prevMbQpDeltaNotZero = _mbQpDeltaNotZero; if (!_sliceState.IntraCoded) { prevMbSkipped = mbSkipFlag; } if (!MbAffFrameFlag || IsLastMacroblockInPair()) { moreDataFlag = !GetEndOfSliceFlag(); } if (moreDataFlag) { NextMbAddress(); } } #if DEBUG H264Debug.WriteLine(" - Terminated ({4}) at {0} of {1} ({2}), nextBits(16)={3}", _reader.Position, _reader.Length, _currMbAddr, ToBitString(_reader.ShowBits(16), 16), _sliceState.SliceType.ToString()); #endif }