public void Parse(IMpeg2VideoReader reader, IResultNodeState resultState)
        {
            if (reader.State.LastHeaderName == null)
            {
                // MPEG data cannot start with an extension!
                resultState.Invalidate();
                return;
            }

            var extensionId = (ExtensionId)reader.GetBits(4, Attribute.ExtensionStartCodeIdentifier, _extensionTypeResultFormatter);

            IExtensionParser extensionParser;

            if (!_extensionParsers.TryGetValue(extensionId, out extensionParser) || !CheckExtensionOccurance(reader.State, extensionId))
            {
                resultState.Invalidate();
                return;
            }

            // Note: Do not invoke the reader state here, it is *NOT* recursive!!
            extensionParser.Parse(reader, resultState);

            if (resultState.Valid)
            {
                if (reader.State.Picture.Initialized)
                {
                    reader.State.Picture.AddExtension(extensionId);
                }
                else
                {
                    reader.State.Sequence.AddExtension(extensionId);
                }
            }
        }
Exemple #2
0
        public void Parse(IMpeg2VideoReader reader, IResultNodeState resultState)
        {
            IPictureState pictureState = reader.State.Picture;

            resultState.Name = Name;

            // It can occur after the last slice of the previous picture or after a sequence header
            // or group of pictures header, possible followed by user data and/or extensions.
            if ((reader.State.LastHeaderName != Slice.Name) && pictureState.Initialized)
            {
                resultState.Invalidate();
                return;
            }
            if (!reader.State.Sequence.Initialized && !reader.State.SeenGop)
            {
                reader.InsertReferenceHeaderBeforeStartCode();
            }

            pictureState.Reset();
            reader.State.Slice.Reset();

            reader.GetBits(10, Attribute.TemporalReference);
            var pictureCodingType = (PictureCodingType)reader.GetBits(3, Attribute.PictureCodingType, _pictureCodingTypeResultFormatter);

            pictureState.CodingType = pictureCodingType;
            reader.GetBits(16, Attribute.VbvDelay);

            if ((pictureCodingType == PictureCodingType.PType) || (pictureCodingType == PictureCodingType.BType))
            {
                reader.GetFlag(Attribute.FullPelForwardVector);

                byte forwardFCode = (byte)reader.GetBits(3, Attribute.ForwardFCode);
                pictureState.ForwardHorizontalFCode = forwardFCode;
                pictureState.ForwardVerticalFCode   = forwardFCode;
            }
            if (pictureCodingType == PictureCodingType.BType)
            {
                reader.GetFlag(Attribute.FullPelBackwardVector);

                byte backwardFCode = (byte)reader.GetBits(3, Attribute.BackwardFCode);
                pictureState.BackwardHorizontalFCode = backwardFCode;
                pictureState.BackwardVerticalFCode   = backwardFCode;
            }

            int  count = 0;             // Sanity check
            uint maxExtraInformationLength = reader.State.Configuration.PictureHeaderMaxLengthOfExtraInformation;

            while (reader.ShowBits(1) == 1)
            {
                reader.GetBits(1);                              // ExtraBitPicture
                reader.GetBits(8);                              // ExtraInformationPicture

                if (count++ > maxExtraInformationLength)
                {
                    resultState.Invalidate();
                    return;
                }
            }
        }
Exemple #3
0
        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();
        }
Exemple #4
0
        public void Parse(IMpeg2VideoReader reader, IResultNodeState resultState)
        {
            resultState.Name = Name;
            reader.State.Picture.Reset();
            reader.State.SeenGop = false;

            if ((reader.State.LastHeaderName != null) && (reader.State.LastHeaderName != Slice.Name))
            {
                resultState.Invalidate();
                return;                 // Invalid header sequence
            }

            ISequenceState sequenceState = reader.State.Sequence;

            sequenceState.Reset();
            sequenceState.Initialized    = true;
            sequenceState.HorizontalSize = (ushort)reader.GetBits(12, Attribute.HorizontalSizeValue);
            sequenceState.VerticalSize   = (ushort)reader.GetBits(12, Attribute.VerticalSizeValue);
            reader.GetBits(4, Attribute.AspectRatioInformation, AspectRatioResultFormatter);
            reader.GetBits(4, Attribute.FrameRateCode, FrameRateResultFormatter);
            reader.GetBits(18, Attribute.BitRateValue);
            reader.GetMarker();
            reader.GetBits(10, Attribute.VbvBufferSizeValue);
            reader.GetFlag(Attribute.ConstrainedParametersFlag);

            if (reader.GetFlag(Attribute.LoadIntraQuantiserMatrix))
            {
                reader.GetData(Attribute.IntraQuantiserMatrix, 64);
            }
            if (reader.GetFlag(Attribute.LoadNonIntraQuantiserMatrix))
            {
                reader.GetData(Attribute.NonIntraQuantiserMatrix, 64);
            }
        }
Exemple #5
0
// ReSharper disable UnusedParameter.Local
        private static void RefPicListModification(INalUnitReader reader, IResultNodeState resultState)
// ReSharper restore UnusedParameter.Local
        {
            bool refPicListReorderingFlag = reader.GetBit();

            if (refPicListReorderingFlag)             // ref_pic_list_reordering_flag_lX
            {
                uint reorderingOfPicNumsIdc;          // reordering_of_pic_nums_idc
                do
                {
                    if (!reader.HasMoreRbspData())
                    {
                        resultState.Invalidate();
                        return;
                    }

                    reorderingOfPicNumsIdc = reader.GetExpGolombCoded();                     // reordering_of_pic_nums_idc

                    if ((reorderingOfPicNumsIdc == 0) || (reorderingOfPicNumsIdc == 1))
                    {
                        reader.GetExpGolombCoded();                         // abs_diff_pic_num_minus1
                    }
                    else if (reorderingOfPicNumsIdc == 2)
                    {
                        reader.GetExpGolombCoded();                         // long_term_pic_num
                    }
                } while (reorderingOfPicNumsIdc != 3);
            }
        }
        public void Parse(IMpeg2VideoReader reader, IResultNodeState resultState)
        {
            resultState.Name = Name;

            if ((reader.State.LastHeaderName != SequenceHeader.Name))
            {
                resultState.Invalidate();
                return;                 // Invalid header sequence
            }

            ISequenceState sequenceState = reader.State.Sequence;

            reader.GetBits(8, Attribute.ProfileAndLevelIndication);
            sequenceState.Progressive  = reader.GetFlag(Attribute.ProgressiveSequence);
            sequenceState.ChromaFormat = (ChromaFormat)reader.GetBits(2, Attribute.ChromaFormat);

            uint horizontalSizeExtension = reader.GetBits(2, Attribute.HorizontalSizeExtension);

            sequenceState.HorizontalSize = (ushort)((sequenceState.HorizontalSize & 0x0fff) | (horizontalSizeExtension << 12));
            uint verticalSizeExtension = reader.GetBits(2, Attribute.VerticalSizeExtension);

            sequenceState.VerticalSize = (ushort)((sequenceState.VerticalSize & 0x0fff) | (verticalSizeExtension << 12));

            reader.GetBits(12, Attribute.BitRateExtension);
            reader.GetMarker();
            reader.GetBits(8, Attribute.VbvBufferSizeExtension);
            reader.GetBits(1, Attribute.LowDelay);
            reader.GetBits(2, Attribute.FrameRateExtensionN);
            reader.GetBits(5, Attribute.FrameRateExtensionD);
        }
        public void Parse(IH264Reader reader, IResultNodeState resultState)
        {
            long bytesRemaining = (reader.Length - reader.Position);

            if (bytesRemaining < 4)
            {
                resultState.Invalidate();
                return;
            }

            long startPosition = reader.Position;

            // Check whether a sequence parameter set and a picture parameter set are
            // separated by exactly one byte in a NAL unit stream.
            // This is the case for H.264 streams embedded in 3GPP files.
            ulong nextFiveBytes = reader.PeekFiveBytes();

            if ((_state.NalUnitType == NalUnitType.SequenceParameterSet) &&
                !IsShortLengthPrefixedNalUnit((uint)(nextFiveBytes >> 16), bytesRemaining) &&
                IsShortLengthPrefixedNalUnit((uint)(nextFiveBytes >> 8) & 0xffffff, (bytesRemaining - 1)))
            {
                // Skip the byte that is part of the 3GPP container
                reader.Position++;
                bytesRemaining--;
                nextFiveBytes = reader.PeekFiveBytes();
            }
            if (IsShortLengthPrefixedNalUnit((uint)(nextFiveBytes >> 16), bytesRemaining))
            {
                if (ParseShortLengthPrefixedNalUnit(reader, resultState) && resultState.Valid)
                {
                    return;                     // Successfully parse SPS or PPS NAL unit
                }

                resultState.Reset();
                reader.Position = startPosition;
            }
            if (IsLongLengthPrefixedNalUnit(nextFiveBytes, bytesRemaining))
            {
                if (ParseLongLengthPrefixedNalUnit(reader, resultState))
                {
                    return;                     // Successfully parse slice NAL unit
                }
            }

            resultState.Invalidate();
        }
Exemple #8
0
        /// <summary>
        /// Parse the ExampleHeader.
        /// </summary>
        /// <param name="reader">The <see cref="IExampleReader"/> for parsing the data</param>
        public void Parse(IExampleReader reader, IResultNodeState resultState)
        {
            // Now parse the header. Implement your own parsing code below.
            reader.GetEqualByteSequence(Attribute.Count);

            if (!reader.GetFinalExampleHeaderByte(Attribute.ValueOfLastByte))
            {
                resultState.Invalidate();
            }
        }
Exemple #9
0
        public void Parse(IMpeg2SystemReader reader, IResultNodeState resultState)
        {
            resultState.Name = Name;

            // This header should not be the first header in a block or directly succeeding a program end code
            string lastHeaderName = reader.State.LastHeaderName;

            if ((lastHeaderName == null) || (lastHeaderName == Name))
            {
                resultState.Invalidate();
            }
        }
Exemple #10
0
        public void Parse(IMpeg2SystemReader reader, IResultNodeState resultState)
        {
            resultState.Name       = Name;
            resultState.ParentName = PackHeader.Name;

            // This header should be preceeded by a pack header, but which may have been overwritten
            if ((reader.State.LastHeaderName != PackHeader.Name) && reader.State.SeenPackHeader /*|| SeenPesPacket)*/)
            {
                resultState.Invalidate();
                return;
            }

            reader.GetBits(16, Attribute.HeaderLength);
            reader.GetMarker();

            uint rateBound = reader.GetBits(22, Attribute.RateBound);

            if (reader.State.SeenPackHeader && (rateBound < reader.State.ProgramMuxRate))
            {
                resultState.Invalidate();
                return;
            }

            reader.GetMarker();
            reader.GetBits(6, Attribute.AudioBound, ab => ab <= 32);
            reader.GetFlag(Attribute.FixedFlag);
            reader.GetFlag(Attribute.CspsFlag);
            reader.GetFlag(Attribute.SystemAudioLockFlag);
            reader.GetFlag(Attribute.SystemVideoLockFlag);
            reader.GetMarker();
            reader.GetBits(5, Attribute.VideoBound, vb => vb <= 16);
            reader.GetFlag(Attribute.PacketRateRestrictionFlag);
            reader.GetReservedBits(7);                  // 0x7F

            // Stream information (MPEG-2 only)
            while (resultState.Valid && (reader.ShowBits(1) == 1))
            {
                resultState.Parse(_streamInfoAttributeParser, reader);
            }
        }
        public void Parse(IMpeg2VideoReader reader, IResultNodeState resultState)
        {
            resultState.Name = Name;
            reader.State.Sequence.Reset();
            reader.State.Picture.Reset();
            reader.State.SeenGop = false;

            if (reader.State.LastHeaderName != Slice.Name)
            {
                resultState.Invalidate();
                return;                 // Invalid header sequence
            }
        }
        public void Parse(IMpeg2SystemReader reader, IResultNodeState resultState)
        {
            resultState.Name       = Name;
            resultState.ParentName = PackHeader.Name;             // if no pack headers have been encountered, it ends up in the root.

            int bytesRemaining = (int)reader.GetBits(16, Attribute.ProgramStreamMapLength, n => (n >= 10) && (n <= Math.Min(1018, reader.BytesRemaining)));

            if (!resultState.Valid)
            {
                return;
            }

            reader.GetBits(1, Attribute.CurrentNextIndicator);
            reader.GetReservedBits(2);
            reader.GetBits(5, Attribute.ProgramStreamMapVersion);
            reader.GetReservedBits(7);
            reader.GetMarker();

            bytesRemaining -= 2;

            // TODO: issue 2282: MPEG-2 system detector does not implement full specification

            int  maxProgramStreamInfoLength = (bytesRemaining - 2);
            uint programStreamInfoLength    = reader.GetBits(16, Attribute.ProgramStreamInfoLength, n => n <= maxProgramStreamInfoLength);

            if (!resultState.Valid)
            {
                return;
            }

            bytesRemaining -= 2 + reader.SkipBytes((int)programStreamInfoLength);

            int  maxElementaryStreamInfoLength = (bytesRemaining - 2);
            uint elementaryStreamInfoLength    = reader.GetBits(16, Attribute.ElementaryStreamMapLength, n => n <= maxElementaryStreamInfoLength);

            if (!resultState.Valid)
            {
                return;
            }

            bytesRemaining -= 2 + reader.SkipBytes((int)elementaryStreamInfoLength);

            if (bytesRemaining < 4)
            {
                resultState.Invalidate();
                return;
            }

            reader.GetBits(32, Attribute.Crc32);
            reader.SkipBytes(bytesRemaining - 4);
        }
        public void Parse(IMpeg2VideoReader reader, IResultNodeState resultState)
        {
            resultState.Name = Name;

            // Note: Last header must be a sequence, group of pictures or picture header, or an extension.
            // Note: Sequence end code always ends parsing of a block, so it cannot occur at this point!
            string lastHeader = reader.State.LastHeaderName;

            if ((lastHeader == Slice.Name) || (lastHeader == UserData.Name))
            {
                // User data cannot occur immediately after a slice or (another) user data
                resultState.Invalidate();
                return;
            }

            reader.GetAttribute(_userDataAttribute);
        }
Exemple #14
0
        public void Parse(IMpeg2SystemReader reader, IResultNodeState resultState)
        {
            IMpeg2SystemState state = reader.State;

            // Check start code and determine header-specific parsing strategy
            state.StartCode = reader.GetBits(32, Attribute.StartCode, "{0:X8}");

            ISystemHeaderParser headerParser;

            if (!resultState.Valid || !_headerParsers.TryGetValue(state.StartCode, out headerParser))
            {
                resultState.Invalidate();
                return;
            }

            // Invoke the header-specific parsing strategy
            headerParser.Parse(reader, resultState);

            if (!reader.Valid)
            {
                return;
            }

            // Handle stuffing (leading 00's before the next start code)
            uint zeroByteStuffing = reader.GetZeroByteStuffing(Attribute.ZeroByteStuffing);

            if (IsFragmentBreakPoint(state))
            {
                reader.BreakFragment();
                return;
            }

            string headerName = resultState.Name as string;

            // Record the header and (possible) the extension
            if (state.LastHeaderName == null)
            {
                state.FirstHeaderName = headerName;
            }
            state.LastHeaderName             = headerName;
            state.LastHeaderZeroByteStuffing = zeroByteStuffing;
            state.ParsedHeaderCount++;
        }
        public void AddNode(IResultNode rootNode, IResultNode newChildNode, IResultNodeState resultState)
        {
            if (IsSlice(newChildNode))
            {
                _state.SliceCount++;
            }

            // Check occurance of new child node (at this point)
            if (!IsSuitableSibling(_lastHeader, newChildNode))
            {
                resultState.Invalidate();
                return;
            }

            // Add new child node to the tree
            var parent = GetParentFor(rootNode, newChildNode);

            parent.AddChild(newChildNode);
            _lastHeader = newChildNode;
            _state.ParsedHeaderCount++;
        }
Exemple #16
0
        // 7.3.3.3 Decoded reference picture marking syntax
        private static void DecRefPicMarking(INalUnitReader reader, IResultNodeState resultState)
        {
            if (reader.State.NalUnitType == NalUnitType.CodedSliceOfAnIdrPicture)
            {
                reader.GetBit();                 // no_output_of_prior_pics_flag
                reader.GetBit();                 // long_term_reference_flag
            }
            else if (reader.GetBit())            // adaptive_ref_pic_marking_mode_flag
            {
                uint memoryManagementControlOperation;
                do
                {
                    if (!reader.HasMoreRbspData())
                    {
                        resultState.Invalidate();
                        return;
                    }

                    memoryManagementControlOperation = reader.GetExpGolombCoded();                     // memory_management_control_operation

                    if ((memoryManagementControlOperation == 1) || (memoryManagementControlOperation == 3))
                    {
                        reader.GetExpGolombCoded();                         // difference_of_pic_nums_minus1
                    }
                    if (memoryManagementControlOperation == 2)
                    {
                        reader.GetExpGolombCoded();                         // long_term_pic_num
                    }
                    if ((memoryManagementControlOperation == 3) || (memoryManagementControlOperation == 6))
                    {
                        reader.GetExpGolombCoded();                         // long_term_frame_idx
                    }
                    if (memoryManagementControlOperation == 4)
                    {
                        reader.GetExpGolombCoded();                         // max_long_term_frame_idx_plus1
                    }
                } while (memoryManagementControlOperation != 0);
            }
        }
Exemple #17
0
        public void Parse(IH264Reader reader, IResultNodeState resultState)
        {
            if (reader.Position == reader.Length)
            {
                resultState.Invalidate();
                return;
            }

            long nalUnitEndPosition;

            // Remove 'zero byte' and 'start code prefix' for the 'byte stream' format
            if (reader.PeekUInt() == 0x00000001)
            {
                // TODO: hoort eigenlijk bij de StartCodePrefix - zie pg. 305 van ITU-T H.264 (03/2010)
                reader.GetFixedByte(0x00, NalUnitParser.Attribute.ZeroByte);
            }

            reader.GetFixedThreeBytes(0x000001, NalUnitParser.Attribute.StartCodePrefix);
            var windowStart = reader.Position;

            if (reader.NextNalUnit())                 //Forward till after next nalunit startcode
            {
                nalUnitEndPosition = reader.Position; //Position of next nalunit start
            }
            else
            {
                nalUnitEndPosition = reader.Length;
            }

            reader.Position = windowStart;            //rewind

            if (!resultState.Valid)
            {
                return;
            }

            //Parse remainder with specific nalunitparser (NOTE: Is not a sub-object)
            reader.ParseOneNalUnit(_nalUnitParser, resultState, nalUnitEndPosition);
        }
        public void Parse(IMpeg2SystemReader reader, IResultNodeState resultState)
        {
            resultState.Name = Name;

            if (reader.ShowBits(2) == 1)
            {
                reader.GetBits(2, Attribute.Mpeg2Flag);
                reader.SetMpegFormat(CodecID.Mpeg2System);
            }
            else if (reader.ShowBits(4) == 2)
            {
                reader.GetBits(4, Attribute.Mpeg2Flag);
                reader.SetMpegFormat(CodecID.Mpeg1System);
            }
            else
            {
                // Unknown whether it is MPEG-1 or 2, cannot parse header!
                reader.GetBits(2, Attribute.Mpeg2Flag, mpeg2Flag => false);
                resultState.Invalidate();
                return;
            }

            reader.GetAttribute(_systemClockReferenceAttribute);
            reader.GetMarker();
            reader.State.ProgramMuxRate = reader.GetBits(22, Attribute.ProgramMuxRate, muxRate => muxRate != 0);
            reader.GetMarker();

            if (reader.State.IsMpeg2())
            {
                reader.GetMarker();
                reader.GetReservedBits(5);
                int packStuffingLength = (int)reader.GetBits(3, Attribute.PackStuffingLength);
                if (packStuffingLength > 0)
                {
                    reader.GetStuffingBytes(packStuffingLength);
                }
            }
        }
        public void Parse(IMpeg2VideoReader reader, IResultNodeState resultState)
        {
            resultState.Name = Name;

            if (reader.State.LastHeaderName != PictureHeader.Name)
            {
                resultState.Invalidate();
                return;                 // Invalid header sequence
            }

            IPictureState pictureState = reader.State.Picture;

            pictureState.ForwardHorizontalFCode  = (byte)reader.GetBits(4, Attribute.ForwardHorizontalFCode);
            pictureState.ForwardVerticalFCode    = (byte)reader.GetBits(4, Attribute.ForwardVerticalFCode);
            pictureState.BackwardHorizontalFCode = (byte)reader.GetBits(4, Attribute.BackwardHorizontalFCode);
            pictureState.BackwardVerticalFCode   = (byte)reader.GetBits(4, Attribute.BackwardVerticalFCode);
            reader.GetBits(2, Attribute.IntraDCPrecision);
            pictureState.Structure                = (PictureStructure)reader.GetBits(2, Attribute.PictureStructure, _pictureStructureResultFormatter);
            pictureState.TopFieldFirst            = reader.GetFlag(Attribute.TopFieldFirst);
            pictureState.FramePredFrameDct        = reader.GetFlag(Attribute.FramePredFrameDct);
            pictureState.ConcealmentMotionVectors = reader.GetFlag(Attribute.ConcealmentMotionVectors);
            reader.GetBits(1, Attribute.QuantiserScaleType);
            pictureState.IntraVlcFormat = (reader.GetBits(1, Attribute.IntraVlcFormat) == 0) ? false : true;
            reader.GetFlag(Attribute.AlternateScan);
            pictureState.RepeatFirstField = reader.GetFlag(Attribute.RepeatFirstField);
            reader.GetFlag(Attribute.Chroma420Type);
            reader.GetFlag(Attribute.ProgressiveFrame);

            if (reader.GetFlag(Attribute.CompositeDisplayFlag))
            {
                reader.GetBits(1, Attribute.VAxis);
                reader.GetBits(3, Attribute.FieldSequence);
                reader.GetBits(1, Attribute.SubCarrier);
                reader.GetBits(7, Attribute.BurstAmplitude);
                reader.GetBits(8, Attribute.SubCarrierPhase);
            }
        }
        public void Parse(IMpeg2VideoReader reader, IResultNodeState resultState)
        {
            resultState.Name = Name;

            IMpeg2VideoState state = reader.State;

            // It can occur after the last slice of a picture or after a sequence header, possible followed by user data and/or extensions
            if ((state.LastHeaderName != Slice.Name) && (state.LastHeaderName != null) && (!state.Sequence.Initialized || state.SeenGop || state.Picture.Initialized))
            {
                resultState.Invalidate();
                return;
            }
            if (!reader.State.Sequence.Initialized)
            {
                reader.InsertReferenceHeaderBeforeStartCode();
            }

            state.SeenGop = true;
            state.Picture.Reset();

            reader.GetAttribute(_timeCodeAttribute);
            reader.GetFlag(Attribute.ClosedGop);
            reader.GetFlag(Attribute.BrokenLink);
        }
Exemple #21
0
        // 7.3.3 Slice header syntax
        public void Parse(INalUnitReader reader, IResultNodeState resultState)
        {
            reader.State.SliceState = null;                                                                          // Invalid, unless the slice header is valid!

            uint firstMacroblockInSlice = reader.GetExpGolombCoded(Attribute.FirstMacroblockInSlice, uint.MaxValue); // first_mb_in_slice

#if DEBUG
            H264Debug.WriteLine("+ first_mb_in_slice={0}", firstMacroblockInSlice);
#endif
            SliceType pictureSliceType = (SliceType)reader.GetExpGolombCoded(Attribute.SliceType, _sliceTypeResultFormatter);
            SliceType sliceType        = (SliceType)((int)pictureSliceType % 5);
#if DEBUG
            H264Debug.WriteLine("+ slice_type={0}", (int)sliceType);
#endif
            byte pictureParamaterSetId = (byte)reader.GetExpGolombCoded(Attribute.PictureParameterSetId, 255);
#if DEBUG
            H264Debug.WriteLine("+ pic_parameter_set_id={0}", pictureParamaterSetId);
#endif
            var pictureState = reader.State.PictureStates[pictureParamaterSetId];
            if (pictureState == null)
            {
                if (resultState.Valid)
                {
                    if (IsFalseHit(firstMacroblockInSlice, sliceType, pictureParamaterSetId) || (pictureParamaterSetId > 10))
                    {
                        resultState.Invalidate();
                    }
                }
                return;                 // cannot validate slice header!!
            }

            ISliceStateBuilder builder = new SliceStateBuilder(pictureState);
            builder.FirstMacroBlockInSlice = firstMacroblockInSlice;
            builder.SliceType = sliceType;

            if (pictureState.PictureSliceType.HasValue && (sliceType != pictureState.PictureSliceType))
            {
                // FIXME: This rule only applies to slices within a single picture.
                //        Since we currently don't detect whether this slice starts a
                //        new picture, we have to disable this rule for now!
                //				oldIReaderState.Invalidate();
                //				return;
            }
            if (/*!pictureState.PictureSliceType.HasValue && */ sliceType != pictureSliceType)
            {
                pictureState.PictureSliceType = pictureSliceType;
            }
            if (IsNonIntraSliceInIntraCodedPicture(reader, sliceType, pictureState))
            {
                resultState.Invalidate();
                return;
            }

            var sequenceState = pictureState.SequenceState;
            if (sequenceState.ChromaFormat == ChromaFormat.SeparateColorPlane)
            {
                reader.GetBits(2, Attribute.ColorPlane, _colorPlaneResultFormatter);                 // colour_plane_id
            }

            ParseFrameNum(reader, sequenceState);

            bool fieldPicFlag = false;
            if (!sequenceState.FrameMbsOnlyFlag)
            {
                fieldPicFlag         = reader.GetBit();         // field_pic_flag
                builder.FieldPicFlag = fieldPicFlag;
                if (fieldPicFlag)
                {
                    reader.GetBit();                     // bottom_field_flag
                }
            }
            if (reader.State.IdrPicFlag)
            {
                reader.GetExpGolombCoded(Attribute.IdrPictureId, 65535);                 // idr_pic_id
            }
            if (sequenceState.PictureOrderCountType == 0)
            {
                reader.GetBits((int)sequenceState.Log2MaxPicOrderCntLsb);                  // pic_order_cnt_lsb

                if (pictureState.PictureOrderPresent && !fieldPicFlag)
                {
                    reader.GetSignedExpGolombCoded();                     // delta_pic_order_cnt_bottom
                }
            }
            else if ((sequenceState.PictureOrderCountType == 1) && !sequenceState.DeltaPicOrderAlwaysZeroFlag)
            {
                reader.GetSignedExpGolombCoded();                 // delta_pic_order_cnt_0

                if (pictureState.PictureOrderPresent && !fieldPicFlag)
                {
                    reader.GetSignedExpGolombCoded();                     // delta_pic_order_cnt_1
                }
            }
            if (pictureState.RedundantPictureControlPresent)
            {
                reader.GetExpGolombCoded(Attribute.RedundantPictureCounter, 127);                 // redundant_pic_cnt
            }
            if (sliceType == SliceType.B)
            {
                reader.GetBit();                 // direct_spatial_mv_pred_flag
            }

            uint activeReferencePictureCount0 = pictureState.DefaultReferencePictureCount0;
            uint activeReferencePictureCount1 = pictureState.DefaultReferencePictureCount1;
            if (!IsIntraCoded(sliceType) && reader.GetBit())             // num_ref_idx_active_override_flag
            {
                uint maxRefIdxActiveMinus1 = fieldPicFlag ? 31U : 15U;
                activeReferencePictureCount0 = reader.GetExpGolombCoded(maxRefIdxActiveMinus1) + 1;                 // num_ref_idx_l0_active_minus1

                if (sliceType == SliceType.B)
                {
                    activeReferencePictureCount1 = reader.GetExpGolombCoded(maxRefIdxActiveMinus1) + 1;                     // num_ref_idx_l1_active_minus1
                }
            }

            builder.ActiveReferencePictureCount0 = activeReferencePictureCount0;
            builder.ActiveReferencePictureCount1 = activeReferencePictureCount1;

            RefPicListModification(reader, resultState, sliceType);

            if ((pictureState.WeightedPrediction && (sliceType == SliceType.P || sliceType == SliceType.Sp)) ||
                (pictureState.WeightedBidirectionalPrediction == WeightedBidirectionalPredictionType.ExplicitWeightedPrediction && sliceType == SliceType.B))
            {
                PredWeightTable(reader, sequenceState, sliceType, activeReferencePictureCount0, activeReferencePictureCount1);
            }
            if (reader.State.NalRefIdc != 0)
            {
                DecRefPicMarking(reader, resultState);
            }
            if (pictureState.EntropyCodingMode && !IsIntraCoded(sliceType))
            {
                builder.CabacInitIdc = reader.GetExpGolombCoded(2U);
            }

            builder.SliceQpDelta = reader.GetSignedExpGolombCoded();

            if ((sliceType == SliceType.Sp) || (sliceType == SliceType.Si))
            {
                if (sliceType == SliceType.Sp)
                {
                    reader.GetBit();                    // sp_for_switch_flag
                }

                reader.GetSignedExpGolombCoded();                // slice_qs_delta
            }
            if (pictureState.DeblockingFilterControlPresent)
            {
                uint disableDeblockingFilterIdc = reader.GetExpGolombCoded();                   // disable_deblocking_filter_idc
                if (disableDeblockingFilterIdc != 1)
                {
                    reader.GetSignedExpGolombCoded();                           // slice_alpha_c0_offset_div2
                    reader.GetSignedExpGolombCoded();                           // slice_beta_offset_div2
                }
            }
            if (pictureState.SliceGroupCount > 1 &&
                pictureState.SliceGroupMapType >= SliceGroupMapType.ChangingSliceGroups3 && pictureState.SliceGroupMapType <= SliceGroupMapType.ChangingSliceGroups5)
            {
                uint value = (sequenceState.PicSizeInMapUnits / pictureState.SliceGroupChangeRate);
                int  requiredBitsToRepresentValue = DetectorUtils.Log2(value) + 1;
                builder.SliceGroupChangeCycle = reader.GetBits(requiredBitsToRepresentValue);                 // slice_group_change_cycle;
            }

            // Check 'firstMacroblockInSlice' field
            uint picHeightInMbs = sequenceState.FrameHeightInMbs / (fieldPicFlag ? 2U : 1U);
            uint picSizeInMbs   = sequenceState.PicWidthInMbs * picHeightInMbs;
            bool mbAffFrameFlag = sequenceState.MbAdaptiveFrameFieldFlag && !fieldPicFlag;
            if ((firstMacroblockInSlice * (mbAffFrameFlag ? 2U : 1U)) >= picSizeInMbs)
            {
                resultState.Invalidate();
            }

            if (resultState.Valid)
            {
                // Since the 'pictureParameterSetId' is probably correct at this point,
                // we prevent the check for 'pictureParameterSetId > 10'.
                if (IsFalseHit(firstMacroblockInSlice, sliceType, Math.Min((byte)1, pictureParamaterSetId)))
                {
                    resultState.Invalidate();
                }
                else
                {
                    reader.State.SliceState = builder.Build();
                }
            }
        }
Exemple #22
0
        public void Parse(IMpeg2SystemReader reader, IResultNodeState resultState)
        {
            resultState.Name       = Name;
            resultState.ParentName = PackHeader.Name;

            uint pesPacketLength = reader.GetBits(16, Attribute.PesPacketLength, n => n <= reader.BytesRemaining);
            long pesPacketEnd    = reader.Position + pesPacketLength;

            resultState.Recover();             // Invalid PES packets should not end the current block!

            ushort streamId = (ushort)(reader.State.StartCode & 0xFF);

            if (streamId == 0xBE || streamId == 0xBF || streamId == 0xF0 ||
                streamId == 0xF1 || streamId == 0xF2 || streamId == 0xF8)
            {
                // These streams do not contain further header details
            }
            else if (reader.ShowBits(2) == 2)
            {
                #region MPEG-2
                reader.SetMpegFormat(CodecID.Mpeg2System);
                reader.GetBits(2, Attribute.Mpeg2Flag, f => f == 0x2);
                reader.GetBits(2, Attribute.PesScramblingControl);
                reader.GetBits(1, Attribute.PesPriority);
                reader.GetFlag(Attribute.DataAlignmentIndicator);
                reader.GetFlag(Attribute.Copyright);
                reader.GetFlag(Attribute.OriginalOrCopy);
                uint ptsDtsFlags            = reader.GetBits(2, Attribute.PtsDtsFlags, f => f != 0x1);
                bool escrFlag               = reader.GetFlag(Attribute.EscrFlag);
                bool esRateFlag             = reader.GetFlag(Attribute.ESRateFlag);
                bool dsmTrickModeFlag       = reader.GetFlag(Attribute.DsmTrickModeFlag);
                bool additionalCopyInfoFlag = reader.GetFlag(Attribute.AdditionalCopyInfoFlag);
                bool pesCrcFlag             = reader.GetFlag(Attribute.PesCrcFlag);
                bool pesExtensionFlag       = reader.GetFlag(Attribute.PesExtensionFlag);

                uint bytesRemaining      = pesPacketLength - 3;
                uint pesHeaderDataLength = reader.GetBits(8, Attribute.PesHeaderDataLength, n => n <= bytesRemaining);
                long pesHeaderDataEnd    = reader.Position + pesHeaderDataLength;

                if (!resultState.Valid)
                {
                    return;
                }

                // Decode optional header fields
                switch (ptsDtsFlags)
                {
                case 2:
                    reader.GetBits(4, 0x2);
                    reader.GetAttribute(_presentationTimeStampAttribute);
                    break;

                case 3:
                    reader.GetBits(4, 0x3);
                    reader.GetAttribute(_presentationTimeStampAttribute);
                    reader.GetBits(4, 0x1);
                    reader.GetAttribute(_decodingTimeStampAttribute);
                    break;
                }

                if (escrFlag)
                {
                    reader.GetAttribute(_escrAttribute);
                    reader.GetMarker();
                }
                if (esRateFlag)
                {
                    reader.GetMarker();
                    reader.GetBits(22, Attribute.ESRate);
                    reader.GetMarker();
                }
                if (dsmTrickModeFlag)
                {
                    switch (reader.GetBits(3, Attribute.TrickModeControl))
                    {
                    case 0:
                    case 3:
                        reader.GetBits(2, Attribute.FieldId);
                        reader.GetFlag(Attribute.IntraSliceRefresh);
                        reader.GetBits(1, Attribute.FrequencyTruncation);                                 // TODO: is this a flag??
                        break;

                    case 1:
                    case 4:
                        reader.GetBits(5, Attribute.RepCntrl);
                        break;

                    case 2:
                        reader.GetBits(2, Attribute.FieldId);
                        reader.GetBits(3, Attribute.TrickModeReserved);
                        break;

                    default:
                        reader.GetBits(5, Attribute.TrickModeReserved);
                        break;
                    }
                }
                if (additionalCopyInfoFlag)
                {
                    reader.GetMarker();
                    reader.GetBits(7, Attribute.AdditionalCopyInfo);
                }
                if (pesCrcFlag)
                {
                    reader.GetBits(16, Attribute.PreviousPesPacketCrc);
                }
                if (pesExtensionFlag)
                {
                    bool pesPrivateDataFlag  = reader.GetFlag(Attribute.PesPrivateDataFlag);
                    bool packHeaderFieldFlag = reader.GetFlag(Attribute.PackHeaderFieldFlag);
                    bool programPacketSequenceCounterFlag = reader.GetFlag(Attribute.ProgramPacketSequenceCounterFlag);
                    bool pStdBufferFlag = reader.GetFlag(Attribute.PStdBufferFlag);
                    reader.GetReservedBits(3);
                    bool pesExtensionFlag2 = reader.GetFlag(Attribute.PesExtensionFlag2);

                    if (pesPrivateDataFlag)
                    {
                        reader.GetData(Attribute.PesPrivateData, 16);
                    }
                    if (packHeaderFieldFlag)
                    {
                        reader.GetBits(8, Attribute.PackFieldLength);
                        // TODO: pack_header();
                    }
                    if (programPacketSequenceCounterFlag)
                    {
                        reader.GetMarker();
                        reader.GetBits(7, Attribute.ProgramPacketSequenceCounter);
                        reader.GetMarker();
                        reader.GetBits(1, Attribute.Mpeg1Mpeg2Identifier);
                        reader.GetBits(6, Attribute.OriginalStuffLength);
                    }
                    if (pStdBufferFlag)
                    {
                        reader.GetBits(2, 0x1);
                        reader.GetBits(1, Attribute.PStdBufferBoundScale);
                        reader.GetBits(13, Attribute.PStdBufferSizeBound);
                    }
                    if (pesExtensionFlag2)
                    {
                        reader.GetMarker();
                        uint pesExtensionFieldLength = reader.GetBits(7, Attribute.PesExtensionFieldLength);
                        reader.GetData(Attribute.PesExtensionField, (int)pesExtensionFieldLength);
                    }
                }

                if (reader.Position > pesHeaderDataEnd || reader.Position < (pesHeaderDataEnd - 32))
                {
                    // FIXME: reader.CheckAttribute(Attribute.PesHeaderDataLength, false);
                    resultState.Invalidate();
                    return;
                }

                int stuffingBytes = (int)(pesHeaderDataEnd - reader.Position);
                if (stuffingBytes > 0)
                {
                    // TODO issue 2323 MPEG-2 systems detector does not check header stuffing of private stream 1
                    if (streamId == 0xBD)
                    {
                        // Note: The format of these bytes is different!
                        reader.SkipBytes(stuffingBytes);
                    }
                    else
                    {
                        reader.GetStuffingBytes(stuffingBytes);
                    }
                }
                #endregion MPEG-2
            }
            else
            {
                #region MPEG-1
                reader.SetMpegFormat(CodecID.Mpeg1System);
                //FIXME: Attributes.Add(new FormattedAttribute<Attribute, bool>(Attribute.Mpeg2Flag, false));

                uint maxUnknownByteCount = (uint)Mpeg2SystemDetector.Configurable[Mpeg2SystemDetector.ConfigurationKey.PesPacketMaxUnknownByteCount];

                int count = 0;                  // Sanity check
                while (reader.ShowBits(1) == 1 && count++ < maxUnknownByteCount)
                {
                    reader.GetBits(8);                          // TODO: attribute?
                }
                if (reader.ShowBits(2) == 0x1)
                {
                    reader.GetBits(2, 0x1);
                    reader.GetBits(1, Attribute.PStdBufferBoundScale);
                    reader.GetBits(13, Attribute.PStdBufferSizeBound);
                }

                switch (reader.GetBits(4, Attribute.PtsDtsFlags))
                {
                case 0:
                    reader.GetBits(4, 0xF);
                    break;

                case 2:
                    reader.GetAttribute(_presentationTimeStampAttribute);
                    break;

                case 3:
                    reader.GetAttribute(_presentationTimeStampAttribute);
                    reader.GetBits(4, 0x1);
                    reader.GetAttribute(_decodingTimeStampAttribute);
                    break;

                default:
                    //reader.CheckAttribute(Attribute.PtsDtsFlags, false);
                    break;
                }
                #endregion MPEG-1
            }

            if (reader.Position >= pesPacketEnd)
            {
                // FIXME: reader.CheckAttribute(Attribute.PesPacketLength, reader.Position <= pesPacketEnd);
                resultState.Invalidate();
                return;
            }

            int dataLength = (int)Math.Min((pesPacketEnd - reader.Position), reader.BytesRemaining);
            if (streamId == 0xBE)               // Padding stream
            {
                // Read padding bytes
                if (reader.ShowBits(8) == 0x0F)
                {
                    reader.GetByte();                           // MPEG-1 padding stream
                    dataLength--;
                }
                for (int i = 0; i < dataLength; i++)
                {
                    if (reader.GetByte() != 0xFF)
                    {
                        // Truncate packet
                        // TODO: reader.CheckAttribute(Attribute.PesPacketLength, reader.GetByte() == 0xFF, false))
                        pesPacketEnd = reader.Position - 1;
                        reader.SkipBytes(dataLength - i - 1);
                        break;
                    }
                }
            }
            else
            {
                IDataPacket pesPacketData = reader.GetDataPacket(reader.Position, dataLength);
                reader.SkipBytes(dataLength);
                reader.State.Streams[streamId].AddPayload(pesPacketData);
            }

            // TODO: Check for truncated packet
        }
        // 7.3.2.1.1 SequenceState parameter set data syntax
        public void Parse(INalUnitReader reader, IResultNodeState resultState)
        {
            // Constraints from 7.4.2.11

            resultState.Name = Name;

            Profile profileIdc = reader.GetBits(8, Attribute.ProfileIdc, _profileValidator);

            reader.GetBits(6);             // constraint_set{0-5}_flag

            if (reader.GetBits(2) != 0)    // reserved_zero_2bits
            {
                resultState.Invalidate();
                return;
            }

            reader.GetByte(false, Attribute.LevelIdc, 59);             // level_idc, Table A-1 - Level limits
            uint sequenceParameterSetId = reader.GetExpGolombCoded(Attribute.SequenceParameterSetId, 31);

            ISequenceStateBuilder builder = new SequenceStateBuilder(sequenceParameterSetId);

            builder.ByteStreamFormat = reader.State.ByteStreamFormat;
            builder.ProfileIdc       = profileIdc;

            if (IsHighProfile(profileIdc))
            {
                uint chromaFormatIdc = reader.GetExpGolombCoded(Attribute.ChromaFormatIdc, 3);                 // Table 6-1
                builder.ChromaFormatIdc = chromaFormatIdc;

                if (chromaFormatIdc == 3)
                {
                    builder.SeparateColourPlaneFlag = reader.GetBit(Attribute.SeparateColorPlaneFlag);
                }

                builder.BitDepthLumaMinus8   = reader.GetExpGolombCoded(Attribute.BitDepthLumaArraySampleMinus8, 6);
                builder.BitDepthChromaMinus8 = reader.GetExpGolombCoded(Attribute.BitDepthChromaArraySampleMinus8, 6);
                reader.GetBit();                 // qpprime_y_zero_transform_bypass_flag

                if (reader.GetBit())             // seq_scaling_matrix_present_flag
                {
                    for (int i = 0; i < ((chromaFormatIdc != 3) ? 8 : 12); i++)
                    {
                        if (reader.GetBit())                         // seq_scaling_list_present_flag[i]
                        {
                            // FIXME: scaling_list() is not implemented!!

                            resultState.Invalidate();
                            return;
                        }
                    }
                }
            }

            builder.Log2MaxFrameNumMinus4 = reader.GetExpGolombCoded(Attribute.Log2MaxFrameNumMinus4, 28);

            DecodePictureOrderCount(reader, builder);

            uint maxDpbFramesUpperLimit = (profileIdc == Profile.MultiviewHigh) ? 160U : 16U;             //could use the exact maxDpbFrames, but this is easier

            builder.MaxNumRefFrames = reader.GetExpGolombCoded(Attribute.MaxNumberReferenceFrames, maxDpbFramesUpperLimit);
            reader.GetBit();             // gaps_in_frame_num_value_allowed_flag
            builder.PicWidthInMbsMinus1       = reader.GetExpGolombCoded(Attribute.PictureWidthInMacroBlocksMinus1, 543);
            builder.PicHeightInMapUnitsMinus1 = reader.GetExpGolombCoded(Attribute.PictureHeightInMapUnitsMinus1, 543);

            var frameMbsOnlyFlag = reader.GetBit(Attribute.FrameMbsOnlyFlag);

            builder.FrameMbsOnlyFlag = frameMbsOnlyFlag;
            if (!frameMbsOnlyFlag)
            {
                builder.MbAdaptiveFrameFieldFlag = reader.GetBit();
            }

            bool direct8X8InferenceFlag = reader.GetBit();

            builder.Direct8X8InferenceFlag = direct8X8InferenceFlag;
            if (!frameMbsOnlyFlag && !direct8X8InferenceFlag)
            {
                resultState.Invalidate();
                return;
            }

            if (reader.GetBit())             // frame_cropping_flag
            {
                // TODO: Cropping should not exceed the size of a frame!
                reader.GetExpGolombCoded(Attribute.FrameCropLeftOffset, 8703);
                reader.GetExpGolombCoded(Attribute.FrameCropRightOffset, 8703);
                reader.GetExpGolombCoded(Attribute.FrameCropTopOffset, 8703);
                reader.GetExpGolombCoded(Attribute.FrameCropBottomOffset, 8703);
            }
            if (reader.GetBit())             // vui_parameters_present_flag
            {
                GetVuiParameters(reader, resultState);
            }
            if (reader.ShowBits(1) == 1)
            {
                reader.GetBit();                 // rbsp_stop_one_bit (equal to 1)
                // trailing zero bits
            }

            if (resultState.Valid)
            {
                reader.State.SequenceStates[sequenceParameterSetId] = builder.Build();
            }
        }
        // 7.3.2.2 PictureState parameter set RBSP syntax
        public void Parse(INalUnitReader reader, IResultNodeState resultState)
        {
            resultState.Name = Name;

            uint pictureParameterSetId  = reader.GetExpGolombCoded(Attribute.PictureParameterSetId, 255 /*7.4.2.2*/);
            uint sequenceParameterSetId = reader.GetExpGolombCoded(Attribute.SequenceParameterSetId, 31 /*7.4.2.2*/);
            var  sequenceState          = reader.State.SequenceStates[sequenceParameterSetId];

            if (sequenceState == null)
            {
                resultState.Invalidate();
                return;
            }

            IPictureStateBuilder builder = new PictureStateBuilder(pictureParameterSetId, sequenceState);

            builder.EntropyCodingMode = reader.GetBit(Attribute.EntropyCodingMode);
            builder.BottomFieldPicOrderInFramePresentFlag = reader.GetBit(Attribute.PictureOrderPresent);
            uint numSliceGroupsMinus1 = reader.GetExpGolombCoded(Attribute.NumSliceGroupsMinus1, 7 /*A.2*/);

            builder.NumSliceGroupsMinus1 = numSliceGroupsMinus1;

            if (numSliceGroupsMinus1 > 0)
            {
                if (sequenceState.Profile == Profile.Main)
                {
                    resultState.Invalidate();
                    return;
                }

                ParseSliceGroupMap(reader, resultState, builder, (numSliceGroupsMinus1 + 1));

                // FIXME: this code contains too many bugs, so it is disabled for now!
                resultState.Invalidate();
                // (end of FIXME)
                if (!resultState.Valid)
                {
                    return;
                }
            }

            builder.NumRefIdxL0DefaultActiveMinus1 = reader.GetExpGolombCoded(Attribute.NumRefIdxl0DefaultActiveMinus1, 31 /*7.4.2.2*/);
            builder.NumRefIdxL1DefaultActiveMinus1 = reader.GetExpGolombCoded(Attribute.NumRefIdxl1DefaultActiveMinus1, 31 /*7.4.2.2*/);
            builder.WeightedPredFlag  = reader.GetBit(Attribute.WeightedPrediction);
            builder.WeightedBipredIdc = reader.GetBits(2, Attribute.WeightedBidirectionalPrediction, _weightBidirectionalPredictionFormatter);
            // SliceQPY = 26 + PicInitQpMinus26 + slice_qp_delta
            int qpBdOffset = (6 * ((int)sequenceState.BitDepthLuma - 8));

            builder.PicInitQpMinus26 = reader.GetSignedExpGolombCoded(Attribute.PictureInitialQPyMinus26, -(26 + qpBdOffset), 25);
            reader.GetSignedExpGolombCoded(Attribute.PictureInitialQSyMinus26, -26, 25); // pic_init_qs_minus26; relative to 26
            reader.GetSignedExpGolombCoded(Attribute.ChromaQpIndexOffset, -12, 12);      // chroma_qp_index_offset
            builder.DeblockingFilterControlPresentFlag = reader.GetBit(Attribute.DeblockingFilterControlPresent);
            reader.GetBit(Attribute.ConstrainedIntraPrediction);                         // constrained_intra_pred_flag
            builder.RedundantPicCntPresentFlag = reader.GetBit(Attribute.RedundantPictureControlPresent);

            // Note: Total size upto this point is between 11 and 59 bits (+ 'slice group map')

            if (reader.HasMoreRbspData())                                       // more_rbsp_data()
            {
                builder.Transform8X8ModeFlag = reader.GetBit();                 // transform_8x8_mode_flag
                bool picScalingMatrixPresentFlag = reader.GetBit();
                //if (picScalingMatrixPresentFlag)		// pic_scaling_matrix_present_flag
                //{
                //    for (int i = 0; i < 6 + 2 * pictureState.transform_8x8_mode_flag; i++)
                //    {
                //        bool picScalingListPresentFlag = reader.GetBit();
                //        if (picScalingListPresentFlag)	// pic_scaling_list_present_flag[i]
                //        {
                //            if (i < 6)
                //            {
                //                throw new NotImplementedException("scaling_list(ScalingList4x4[i], 16, UseDefaultScalingMatrix4x4Flag[i]);");	// TODO
                //            }
                //            else
                //            {
                //                throw new NotImplementedException("scaling_list(ScalingList8x8[i – 6], 64, UseDefaultScalingMatrix8x8Flag[i – 6]);");	// TODO
                //            }
                //        }
                //    }
                //}
                reader.GetSignedExpGolombCoded();                 // second_chroma_qp_index_offset
            }

            // rbsp_trailing_bits()

            if (reader.ShowBits(1) == 1)
            {
                reader.GetBit();                 // rbsp_stop_one_bit (equal to 1)
                // trailing zero bits
            }

            if (resultState.Valid)
            {
                reader.State.PictureStates[pictureParameterSetId] = builder.Build();
            }
        }
Exemple #25
0
        public void Parse(IMpeg2VideoReader reader, IResultNodeState resultState)
        {
            IMpeg2VideoState state = reader.State;

            // Check start code and determine header-specific parsing strategy
            uint startCode = reader.GetBits(32, Attribute.StartCode, "{0:X8}");

            state.StartCode = startCode;

            IVideoHeaderParser headerParser;

            if (!resultState.Valid || !_headerParsers.TryGetValue(startCode, out headerParser))
            {
                resultState.Invalidate();
                return;
            }

            // Check consistent use of MPEG-2 extensions and detect version (MPEG-1 or MPEG-2)
            if ((state.LastHeaderName == PictureHeader.Name) || (state.LastHeaderName == SequenceHeader.Name))
            {
                var detectedFormat = (startCode == ExtensionParser.ExtensionStartCode) ? CodecID.Mpeg2Video : CodecID.Mpeg1Video;
                if (state.MpegFormat == CodecID.Unknown)
                {
                    state.MpegFormat = detectedFormat;
                }
                else if (detectedFormat != state.MpegFormat)
                {
                    // Inconsistent use of MPEG-2 extensions:
                    // Extensions are not allowed in MPEG-1 streams and are mandatory in MPEG-2 streams!
                    resultState.Invalidate();
                    return;
                }
            }

            // Determine parent node for this result *BEFORE* parsing this result (and changing the internal state)!!
            resultState.ParentName = GetSuitableParent(reader.State);

            // Invoke the header-specific parsing strategy
            headerParser.Parse(reader, resultState);

            if (!reader.Valid)
            {
                return;
            }

            // Handle stuffing (leading 00's before the next start code)
            uint zeroByteStuffing = reader.GetZeroByteStuffing(Attribute.ZeroByteStuffing);

            // Break if the maximum number of headers has been reached
            var headerName = resultState.Name as string;

            if (IsFragmentBreakPoint(state, headerName))
            {
                reader.BreakFragment();
                return;
            }

            // Record the header and (possible) the extension
            if (state.LastHeaderName == null)
            {
                state.FirstHeaderName = headerName;
            }
            state.LastHeaderName             = headerName;
            state.LastHeaderZeroByteStuffing = zeroByteStuffing;
            state.ParsedHeaderCount++;

            if (headerName == Slice.Name)
            {
                if (resultState.Valid)
                {
                    state.ValidSliceCount++;
                }
                else
                {
                    state.InvalidSliceCount++;
                }
            }
        }