コード例 #1
0
        private static bool IsFragmentBreakPoint(IMpeg2VideoState state, string headerName)
        {
            if (state.ParsedHeaderCount <= state.Configuration.MaxVideoHeaderCount)
            {
                return(false);
            }
            if (headerName == SequenceHeader.Name)
            {
                return(true);
            }
            if (headerName == GroupOfPicturesHeader.Name)
            {
                return(!state.Sequence.Initialized);
            }
            if (headerName == PictureHeader.Name)
            {
                return(!state.Sequence.Initialized && !state.SeenGop);
            }
            if (headerName == Slice.Name)
            {
                return(!state.Picture.Initialized);
            }

            return(false);
        }
コード例 #2
0
        private static object GetSuitableParent(IMpeg2VideoState state)
        {
            uint startCode = state.StartCode;

            if (startCode == SequenceHeader.SequenceStartCode || startCode == SequenceEndCode.SequenceEndStartCode)
            {
                return(null);                // root
            }
            if (startCode == GroupOfPicturesHeader.GopStartCode)
            {
                return(SequenceHeader.Name);                // or root, if no sequence is open
            }
            if (startCode == PictureHeader.PictureStartCode)
            {
                return(state.SeenGop ? GroupOfPicturesHeader.Name : SequenceHeader.Name);                // or root, if no sequence is open
            }
            if (state.Picture.Initialized)
            {
                return(PictureHeader.Name);
            }
            if (state.SeenGop)
            {
                return(GroupOfPicturesHeader.Name);
            }
            if (state.Sequence.Initialized)
            {
                return(SequenceHeader.Name);
            }

            return(null);            // Place the result in the root
        }
コード例 #3
0
 public Mpeg2VideoCarver(IMpeg2VideoReader reader, IResultParser <IMpeg2VideoReader> videoHeaderParser, IScanContext scanContext)
 {
     _reader            = reader;
     _videoHeaderParser = videoHeaderParser;
     _scanContext       = scanContext;
     _state             = reader.State;
     _minHeaderCount    = (uint)Mpeg2VideoDetector.Configurable[Mpeg2VideoDetector.ConfigurationKey.MinVideoHeaderCount];
 }
コード例 #4
0
        public Mpeg2VideoReader(BitStreamDataReader dataReader, IMpeg2VideoState state, IReaderState readerState)
        {
            _dataReader  = dataReader;
            _state       = state;
            _readerState = readerState;

            _maxZeroByteStuffingLength = (uint)Mpeg2VideoDetector.Configurable[Mpeg2VideoDetector.ConfigurationKey.ParserMaxZeroByteStuffingLength];

            ReferenceHeaders = NoDefaultHeaders;
        }
コード例 #5
0
        private static bool CheckExtensionOccurance(IMpeg2VideoState state, ExtensionId extensionId)
        {
            if (extensionId == ExtensionId.SequenceExtensionId)
            {
                return(true);
            }
            if (extensionId == ExtensionId.PictureCodingExtensionId)
            {
                return(true);
            }

            // Extensions other than 'SequenceExtension' and 'PictureCodingExtension',
            // which are the first extension to follow a sequence or picture header
            // respectively in a valid MPEG-2 stream, can only occur after extension of
            // the same type (sequence or picture). Duplicates are not allowed!
            if (state.Picture.Initialized)
            {
                // No duplicates allowed!
                if (state.Picture.HasExtension(extensionId))
                {
                    return(false);
                }
                // FIXME: 'extensionId' must be a picture extension!!
                // Last header must be a picture extension
                return(IsPictureExtension(state.LastHeaderName));
            }
            else
            {
                // No duplicates allowed!
                if (state.Sequence.HasExtension(extensionId))
                {
                    return(false);
                }
                // FIXME: 'extensionId' must be a sequence extension!!
                // Last header must be a sequence extension
                return(IsSequenceExtension(state.LastHeaderName));
            }
        }
コード例 #6
0
        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);
        }
コード例 #7
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++;
                }
            }
        }