private void BufferingPeriod() { SeqParameterSetID = _bitReader.DecodeUnsignedExpGolomb(); if (SeqParameterSetID != _sps.gSPSID) { throw new Exception("wrong sps ID in SEI"); } if (_sps.vuiParams.NALHRDParametersPresent) { ushort icpbBitLen = _sps.vuiParams.NalHRDParams.InitialCpbRemovalDelayLength; uint cpbCount = _sps.vuiParams.NalHRDParams.CpbCount; InitialCPBRemovalDelay = new uint[cpbCount]; InitialCPBRemovalDelayOffset = new uint[cpbCount]; for (int i = 0; i < cpbCount; i++) { InitialCPBRemovalDelay[i] = _bitReader.GetUIntFromNBits(icpbBitLen); InitialCPBRemovalDelayOffset[i] = _bitReader.GetUIntFromNBits(icpbBitLen); } } // FIXME: The following if statement should probably be "else if". // ITU-T Rec. H.264(05/2003) p. 259 // FIXME: set to true for now bool needForPresenceOfBufferingPeriods = true; if (_sps.vuiParams.VclHRDParametersPresent || needForPresenceOfBufferingPeriods) { ushort icpbBitLen = _sps.vuiParams.VclHRDParams.InitialCpbRemovalDelayLength; uint cpbCount = _sps.vuiParams.VclHRDParams.CpbCount; InitialCPBRemovalDelay = new uint[cpbCount]; InitialCPBRemovalDelayOffset = new uint[cpbCount]; for (int i = 0; i < cpbCount; i++) { InitialCPBRemovalDelay[i] = _bitReader.GetUIntFromNBits(icpbBitLen); InitialCPBRemovalDelayOffset[i] = _bitReader.GetUIntFromNBits(icpbBitLen); } } }
public void Read(BitReader bitReader) { FirstMBInSlice = bitReader.DecodeUnsignedExpGolomb(); SliceType = ReadSliceType(bitReader); PICParameterSetID = bitReader.DecodeUnsignedExpGolomb(); FrameNum = bitReader.GetUIntFromNBits(_frameNumBits); if (!_sps.FrameMBSOnly) { FieldPicFlag = bitReader.GetNextBit(); if (FieldPicFlag) { BottomFieldFlag = bitReader.GetNextBit(); } } if (_nalu.NALUType == NALUnitType.IDRSlice) { IDRPictureID = bitReader.DecodeUnsignedExpGolomb(); PrevRefFrameNum = 0; } if (_sps.gPicOrderCntType == 0) { PictureOrderCountLSB = bitReader.GetUIntFromNBits((ushort)(_sps.gMaxPicOrderCntLsbMinus4 + 4u)); if (_pps.PICOrderPresentFlag && !FieldPicFlag) { DeltaPictureOrderCountBottom = bitReader.DecodeSignedExpGolomb(); } } if ((_sps.gPicOrderCntType == 1) && !_sps.DeltaPicOrderAlwaysZero) { DeltaPictureOrderCount = new int[2]; DeltaPictureOrderCount[0] = bitReader.DecodeSignedExpGolomb(); if (_pps.PICOrderPresentFlag && !FieldPicFlag) { DeltaPictureOrderCount[1] = bitReader.DecodeSignedExpGolomb(); } } if (_pps.RedundantPICCountPresentFlag) { RedundantPictureCount = bitReader.DecodeUnsignedExpGolomb(); } if (SliceType == SliceTypes.B) { DirectSpatialMVPredFlag = bitReader.GetNextBit(); } if ((SliceType == SliceTypes.P) || (SliceType == SliceTypes.SP) || (SliceType == SliceTypes.B)) { NumRefIdxActiveOverrideFlag = bitReader.GetNextBit(); if (NumRefIdxActiveOverrideFlag) { NumRefIdx10ActiveMinus1 = bitReader.DecodeUnsignedExpGolomb(); if (SliceType == SliceTypes.B) { NumRefIdx11ActiveMinus1 = bitReader.DecodeUnsignedExpGolomb(); } } } ReferencePictureListReordering(bitReader); if ((_pps.WeightedPredFlag && ((SliceType == SliceTypes.P) || (SliceType == SliceTypes.SP))) || ((_pps.WeightedBiPredIDC == 1) && (SliceType == SliceTypes.B))) { PredictionWeightTable(bitReader); } if (_nalu.NALRefIDC != 0) { DecodedReferencePictureMarking(bitReader); } if (_pps.EntropyCodingModeFlag && (SliceType != SliceTypes.I) && (SliceType != SliceTypes.SI)) { uint initIdc = bitReader.DecodeUnsignedExpGolomb(); if (initIdc < 4) { CABACInitIDC = (byte)initIdc; } else { throw new Exception("SliceHeader: bad CABACInitIDC"); } } SliceQPDelta = bitReader.DecodeSignedExpGolomb(); SliceQPy = 26 + _pps.PICInitQPMinus26 + SliceQPDelta; if ((SliceType == SliceTypes.SP) || (SliceType == SliceTypes.SI)) { if (SliceType == SliceTypes.SP) { SP4SwitchFlag = bitReader.GetNextBit(); } SliceQSDelta = bitReader.DecodeSignedExpGolomb(); SliceQSy = 26 + _pps.PICInitQSMinus26 + SliceQSDelta; } if (_pps.DeblockingFilterControlPresentFlag) { DisableDeblockingFilterIDC = bitReader.DecodeUnsignedExpGolomb(); if (DisableDeblockingFilterIDC != 1) { SliceAlphaC0OffsetDiv2 = bitReader.DecodeSignedExpGolomb(); SliceBetaOffsetDiv2 = bitReader.DecodeSignedExpGolomb(); } } if ((_pps.NumSliceGroupsMinus1 > 0) && (_pps.SliceGroupMapType >= 3) && (_pps.SliceGroupMapType <= 5)) { SliceGroupChangeCycle = bitReader.GetUIntFromNBits(BitReader.CalcBitsNeededToRepresent(_pps.NumSliceGroupsMinus1 + 1)); } // once the header is read, we can derive the MacroBlock to SliceGroup mapping (Section 8.2.2 of H264 Spec) if (_pps.NumSliceGroupsMinus1 > 0) { MbToSliceGroupMap = DeriveMB2SliceGroupMap(); } }
public void Read(BitReader bitReader) { AspectRatioInfoPresent = bitReader.GetNextBit(); if (AspectRatioInfoPresent) { AspectRatio = bitReader.GetByteFromNBits(8); if (AspectRatio == Extended_SAR) { SARWidth = (ushort)bitReader.GetUIntFromNBits(16); SARHeight = (ushort)bitReader.GetUIntFromNBits(16); } } OverscanInfoPresent = bitReader.GetNextBit(); if (OverscanInfoPresent) { OverscanAppropriate = bitReader.GetNextBit(); } VideoSignalTypePresent = bitReader.GetNextBit(); if (VideoSignalTypePresent) { VideoFormat = bitReader.GetByteFromNBits(3); VideoFullRange = bitReader.GetNextBit(); ColourDescriptionPresent = bitReader.GetNextBit(); if (ColourDescriptionPresent) { ColourPrimaries = bitReader.GetByteFromNBits(8); TransferCharacteristics = bitReader.GetByteFromNBits(8); MatrixCoefficients = bitReader.GetByteFromNBits(8); } } ChromaLocInfoPresent = bitReader.GetNextBit(); if (ChromaLocInfoPresent) { ChromaSampleLocTypeTopField = bitReader.DecodeUnsignedExpGolomb(); ChromaSampleLocTypeBottomField = bitReader.DecodeUnsignedExpGolomb(); } TimingInfoPresent = bitReader.GetNextBit(); if (TimingInfoPresent) { NumUnitsInTick = bitReader.GetUIntFromNBits(32); TimeScale = bitReader.GetUIntFromNBits(32); FixedFrameRate = bitReader.GetNextBit(); } NALHRDParametersPresent = bitReader.GetNextBit(); if (NALHRDParametersPresent) { NalHRDParams = new HRDParams(); NalHRDParams.Read(bitReader); } VclHRDParametersPresent = bitReader.GetNextBit(); if (VclHRDParametersPresent) { VclHRDParams = new HRDParams(); VclHRDParams.Read(bitReader); } if (NALHRDParametersPresent || VclHRDParametersPresent) { LowDelayHRDFlag = bitReader.GetNextBit(); } PicStructPresent = bitReader.GetNextBit(); BitstreamRestriction = bitReader.GetNextBit(); if (BitstreamRestriction) { MotionVectorsOverPicBoundaries = bitReader.GetNextBit(); MaxBytesPerPicDenom = bitReader.DecodeUnsignedExpGolomb(); MaxBitsPerMBDenom = bitReader.DecodeUnsignedExpGolomb(); Log2MaxMVLengthHorizontal = bitReader.DecodeUnsignedExpGolomb(); Log2MaxMVLengthVertical = bitReader.DecodeUnsignedExpGolomb(); NumReorderFrames = bitReader.DecodeUnsignedExpGolomb(); MaxDecFrameBuffering = bitReader.DecodeUnsignedExpGolomb(); } if ((AspectRatio > 0) && (AspectRatio < 17)) { AspectRatioX = vui_aspect_x[AspectRatio]; AspectRatioY = vui_aspect_y[AspectRatio]; } // gWidth = (uint)(gWidth * ((double)vui_aspect_x[vuiParams.AspectRatio]) / ((double)vui_aspect_y[vuiParams.AspectRatio])); }
public void Read(BitReader bitReader) { AspectRatioInfoPresent = bitReader.GetNextBit(); if (AspectRatioInfoPresent) { AspectRatio = bitReader.GetByteFromNBits(8); if (AspectRatio == Extended_SAR) { SARWidth = (ushort)bitReader.GetUIntFromNBits(16); SARHeight = (ushort)bitReader.GetUIntFromNBits(16); } } OverscanInfoPresent = bitReader.GetNextBit(); if (OverscanInfoPresent) OverscanAppropriate = bitReader.GetNextBit(); VideoSignalTypePresent = bitReader.GetNextBit(); if (VideoSignalTypePresent) { VideoFormat = bitReader.GetByteFromNBits(3); VideoFullRange = bitReader.GetNextBit(); ColourDescriptionPresent = bitReader.GetNextBit(); if (ColourDescriptionPresent) { ColourPrimaries = bitReader.GetByteFromNBits(8); TransferCharacteristics = bitReader.GetByteFromNBits(8); MatrixCoefficients = bitReader.GetByteFromNBits(8); } } ChromaLocInfoPresent = bitReader.GetNextBit(); if (ChromaLocInfoPresent) { ChromaSampleLocTypeTopField = bitReader.DecodeUnsignedExpGolomb(); ChromaSampleLocTypeBottomField = bitReader.DecodeUnsignedExpGolomb(); } TimingInfoPresent = bitReader.GetNextBit(); if (TimingInfoPresent) { NumUnitsInTick = bitReader.GetUIntFromNBits(32); TimeScale = bitReader.GetUIntFromNBits(32); FixedFrameRate = bitReader.GetNextBit(); } NALHRDParametersPresent = bitReader.GetNextBit(); if (NALHRDParametersPresent) { NalHRDParams = new HRDParams(); NalHRDParams.Read(bitReader); } VclHRDParametersPresent = bitReader.GetNextBit(); if (VclHRDParametersPresent) { VclHRDParams = new HRDParams(); VclHRDParams.Read(bitReader); } if (NALHRDParametersPresent || VclHRDParametersPresent) LowDelayHRDFlag = bitReader.GetNextBit(); PicStructPresent = bitReader.GetNextBit(); BitstreamRestriction = bitReader.GetNextBit(); if (BitstreamRestriction) { MotionVectorsOverPicBoundaries = bitReader.GetNextBit(); MaxBytesPerPicDenom = bitReader.DecodeUnsignedExpGolomb(); MaxBitsPerMBDenom = bitReader.DecodeUnsignedExpGolomb(); Log2MaxMVLengthHorizontal = bitReader.DecodeUnsignedExpGolomb(); Log2MaxMVLengthVertical = bitReader.DecodeUnsignedExpGolomb(); NumReorderFrames = bitReader.DecodeUnsignedExpGolomb(); MaxDecFrameBuffering = bitReader.DecodeUnsignedExpGolomb(); } if ((AspectRatio > 0) && (AspectRatio < 17)) { AspectRatioX = vui_aspect_x[AspectRatio]; AspectRatioY = vui_aspect_y[AspectRatio]; } // gWidth = (uint)(gWidth * ((double)vui_aspect_x[vuiParams.AspectRatio]) / ((double)vui_aspect_y[vuiParams.AspectRatio])); }
public void Read(BitReader bitReader) { FirstMBInSlice = bitReader.DecodeUnsignedExpGolomb(); SliceType = ReadSliceType(bitReader); PICParameterSetID = bitReader.DecodeUnsignedExpGolomb(); FrameNum = bitReader.GetUIntFromNBits(_frameNumBits); if (!_sps.FrameMBSOnly) { FieldPicFlag = bitReader.GetNextBit(); if (FieldPicFlag) BottomFieldFlag = bitReader.GetNextBit(); } if (_nalu.NALUType == NALUnitType.IDRSlice) { IDRPictureID = bitReader.DecodeUnsignedExpGolomb(); PrevRefFrameNum = 0; } if (_sps.gPicOrderCntType == 0) { PictureOrderCountLSB = bitReader.GetUIntFromNBits((ushort)(_sps.gMaxPicOrderCntLsbMinus4 + 4u)); if (_pps.PICOrderPresentFlag && !FieldPicFlag) DeltaPictureOrderCountBottom = bitReader.DecodeSignedExpGolomb(); } if ((_sps.gPicOrderCntType == 1) && !_sps.DeltaPicOrderAlwaysZero) { DeltaPictureOrderCount = new int[2]; DeltaPictureOrderCount[0] = bitReader.DecodeSignedExpGolomb(); if (_pps.PICOrderPresentFlag && !FieldPicFlag) DeltaPictureOrderCount[1] = bitReader.DecodeSignedExpGolomb(); } if (_pps.RedundantPICCountPresentFlag) RedundantPictureCount = bitReader.DecodeUnsignedExpGolomb(); if (SliceType == SliceTypes.B) DirectSpatialMVPredFlag = bitReader.GetNextBit(); if ((SliceType == SliceTypes.P) || (SliceType == SliceTypes.SP) || (SliceType == SliceTypes.B)) { NumRefIdxActiveOverrideFlag = bitReader.GetNextBit(); if (NumRefIdxActiveOverrideFlag) { NumRefIdx10ActiveMinus1 = bitReader.DecodeUnsignedExpGolomb(); if (SliceType == SliceTypes.B) NumRefIdx11ActiveMinus1 = bitReader.DecodeUnsignedExpGolomb(); } } ReferencePictureListReordering(bitReader); if ((_pps.WeightedPredFlag && ((SliceType == SliceTypes.P) || (SliceType == SliceTypes.SP))) || ((_pps.WeightedBiPredIDC == 1) && (SliceType == SliceTypes.B))) { PredictionWeightTable(bitReader); } if (_nalu.NALRefIDC != 0) DecodedReferencePictureMarking(bitReader); if (_pps.EntropyCodingModeFlag && (SliceType != SliceTypes.I) && (SliceType != SliceTypes.SI)) { uint initIdc = bitReader.DecodeUnsignedExpGolomb(); if (initIdc < 4) CABACInitIDC = (byte)initIdc; else throw new Exception("SliceHeader: bad CABACInitIDC"); } SliceQPDelta = bitReader.DecodeSignedExpGolomb(); SliceQPy = 26 + _pps.PICInitQPMinus26 + SliceQPDelta; if ((SliceType == SliceTypes.SP) || (SliceType == SliceTypes.SI)) { if (SliceType == SliceTypes.SP) SP4SwitchFlag = bitReader.GetNextBit(); SliceQSDelta = bitReader.DecodeSignedExpGolomb(); SliceQSy = 26 + _pps.PICInitQSMinus26 + SliceQSDelta; } if (_pps.DeblockingFilterControlPresentFlag) { DisableDeblockingFilterIDC = bitReader.DecodeUnsignedExpGolomb(); if (DisableDeblockingFilterIDC != 1) { SliceAlphaC0OffsetDiv2 = bitReader.DecodeSignedExpGolomb(); SliceBetaOffsetDiv2 = bitReader.DecodeSignedExpGolomb(); } } if ((_pps.NumSliceGroupsMinus1 > 0) && (_pps.SliceGroupMapType >= 3) && (_pps.SliceGroupMapType <= 5)) SliceGroupChangeCycle = bitReader.GetUIntFromNBits(BitReader.CalcBitsNeededToRepresent(_pps.NumSliceGroupsMinus1 + 1)); // once the header is read, we can derive the MacroBlock to SliceGroup mapping (Section 8.2.2 of H264 Spec) if (_pps.NumSliceGroupsMinus1 > 0) MbToSliceGroupMap = DeriveMB2SliceGroupMap(); }
public override void Read(BitReader bitReader) { base.Read(bitReader); PICParamSetID = bitReader.DecodeUnsignedExpGolomb(); SEQParamSetID = bitReader.DecodeUnsignedExpGolomb(); EntropyCodingModeFlag = bitReader.GetNextBit(); PICOrderPresentFlag = bitReader.GetNextBit(); NumSliceGroupsMinus1 = bitReader.DecodeUnsignedExpGolomb(); if (NumSliceGroupsMinus1 > 0) { SliceGroupMapType = bitReader.DecodeUnsignedExpGolomb(); switch (SliceGroupMapType) { case 0: RunLengthMinus1 = new uint[NumSliceGroupsMinus1 + 1]; for (int grp = 0; grp <= NumSliceGroupsMinus1; grp++) { RunLengthMinus1[grp] = bitReader.DecodeUnsignedExpGolomb(); } break; case 1: break; case 2: TopLeft = new uint[NumSliceGroupsMinus1 + 1]; BottomRight = new uint[NumSliceGroupsMinus1 + 1]; for (int grp = 0; grp <= NumSliceGroupsMinus1; grp++) // standards doc, this reads grp < NumSliceGroupsMinus1 { TopLeft[grp] = bitReader.DecodeUnsignedExpGolomb(); BottomRight[grp] = bitReader.DecodeUnsignedExpGolomb(); } break; case 3: case 4: case 5: SliceGroupChangeDirectionFlag = bitReader.GetNextBit(); SliceGroupChangeRateMinus1 = bitReader.DecodeUnsignedExpGolomb(); break; case 6: PICSizeInMapUnitsMinus1 = bitReader.DecodeUnsignedExpGolomb(); SliceGroupID = new uint[PICSizeInMapUnitsMinus1 + 1]; ushort bitCount = BitReader.CalcBitsNeededToRepresent(NumSliceGroupsMinus1 + 1); for (int grp = 0; grp <= PICSizeInMapUnitsMinus1; grp++) { SliceGroupID[grp] = bitReader.GetUIntFromNBits(bitCount); } break; default: throw new Exception("BitReader: bad slice group map type"); } } NumRefIDx10ActiveMinus1 = bitReader.DecodeUnsignedExpGolomb(); NumRefIDx11ActiveMinus1 = bitReader.DecodeUnsignedExpGolomb(); WeightedPredFlag = bitReader.GetNextBit(); WeightedBiPredIDC = (ushort)bitReader.GetUIntFromNBits(2); PICInitQPMinus26 = bitReader.DecodeSignedExpGolomb(); PICInitQSMinus26 = bitReader.DecodeSignedExpGolomb(); ChromaQPIndexOffset = bitReader.DecodeSignedExpGolomb(); DeblockingFilterControlPresentFlag = bitReader.GetNextBit(); ConstrainedIntraPredFlag = bitReader.GetNextBit(); RedundantPICCountPresentFlag = bitReader.GetNextBit(); bitReader.DiscardTrailingBits(); }
void ParseThreadProc(object buffer) { byte[] sliceBytes = buffer as byte[]; BitReader br = new BitReader(new MemoryStream(sliceBytes)); int totalSize = _totalSize; int offset = 0; int state = 0; while (totalSize > 4) { int naluLen = (int)br.GetUIntFromNBits(32); if (naluLen > totalSize) { throw new Exception("H264 parsing: wrong byte count encountered"); } if (naluLen > 0) { byte b = br.PeekByte(); byte refIDC = (byte)(b >> 5); NALUnitType naluType = (NALUnitType)(b & 0x1F); switch (state) { case 0: AccessUnitDelimiter aud = new AccessUnitDelimiter((uint)naluLen); aud.Read(br); state = 1; break; case 1: // either SEI or SPS (if it's an SEI, don't change state) if (naluType == NALUnitType.SupplementalEnhancementInfo) { SupplementatlEnhancementMessage sei = new SupplementatlEnhancementMessage(_sps, (uint)naluLen); sei.Read(br); } else if (naluType == NALUnitType.SequenceParamSet) { // replace _sps _sps = new SequenceParameterSet((uint)naluLen); _sps.Read(br); } else if (naluType == NALUnitType.PictureParamSet) { // replace _pps _pps = new PictureParameterSet((uint)naluLen); _pps.Read(br); } else if (naluType == NALUnitType.IDRSlice) { CodedSliceIDR idr = new CodedSliceIDR(_sps, _pps, (uint)naluLen); idr.Read(br); SliceType = idr.Header.SliceType; FrameNum = idr.Header.FrameNum; state = 2; // next should be zero or more redundant coded pictures } else if (naluType == NALUnitType.NonIDRSlice) { CodedSliceNonIDR nonIdr = new CodedSliceNonIDR(_sps, _pps, GetIDC(refIDC), (uint)naluLen); nonIdr.Read(br); SliceType = nonIdr.Header.SliceType; FrameNum = nonIdr.Header.FrameNum; state = 2; // next should be zero or more redundant coded pictures } else if (naluType == NALUnitType.SlicePartitionA) { CodedSlicePartitionA partA = new CodedSlicePartitionA(_sps, _pps, GetIDC(refIDC), (uint)naluLen); partA.Read(br); SliceType = partA.Header.SliceType; FrameNum = partA.Header.FrameNum; state = 2; // next should be zero or more redundant coded pictures } else if ((naluType == NALUnitType.SlicePartitionB) || (naluType == NALUnitType.SlicePartitionC)) { CodedSlicePartitionBorC partBC = new CodedSlicePartitionBorC(_sps, _pps, GetIDC(refIDC), naluType, (uint)naluLen); partBC.Read(br); // FIXME: check that SliceType and FrameNum are set at this point state = 2; // next should be zero or more redundant coded pictures } break; case 2: // either coded picture or end of sequence break; default: break; } offset += naluLen; totalSize -= (naluLen + 4); } else { naluLen = 0; // debugging break point } } if (SampleDoneEvent != null) { SampleDoneEvent(this); } }