public void Parse(INalUnitReader reader, IResultNodeState resultState) { reader.GetFixedBits(1, 0, Attribute.ForbiddenZeroBit); reader.State.NalRefIdc = reader.GetBits(2, Attribute.NalRefIdc); reader.State.NalUnitType = (NalUnitType)reader.GetBits(5, Attribute.NalUnitType); INalUnitPayloadParser nalUnitPayloadParser; if (!_nalUnitParsers.TryGetValue(reader.State.NalUnitType, out nalUnitPayloadParser)) { resultState.Invalidate(); return; } //Parse remainder with specific nalunitparser (NOTE: Is not a sub-object) nalUnitPayloadParser.Parse(reader, resultState); if (!resultState.Valid) { return; // Stop processing of invalid NAL unit. } if (!CanParseNalUnitType(reader.State.SliceState, reader.State.NalUnitType)) { // Forward to the estimated end of the NAL unit reader.Position = reader.Length; resultState.Invalidate(); // Invalidates the result resultState.Recover(); // Revalidates the reader state so parsing can continue! return; } if (reader.State.NalUnitType == NalUnitType.SequenceParameterSet) { return; // Note: SPS validate their own data! } if (reader.State.NalUnitType == NalUnitType.PictureParameterSet) { return; // Note: PPS validate their own data! } if (!IsSlice(reader.State.NalUnitType) || !reader.State.SliceState.PictureState.EntropyCodingMode) { if (reader.GetBits(1) != 1) // rbsp_stop_one_bit (equal to 1) { resultState.Invalidate(); return; } } if (IsSlice(reader.State.NalUnitType) && resultState.Valid) { return; // Random (e.g. audio) data is allowed after a valid slice } reader.ReadZeroAlignmentBits(); }