예제 #1
0
        internal CodecStream(IDataReader dataReader, IDataBlockBuilder dataBlockBuilder, QtAtom root)
        {
            if (dataReader == null)
            {
                throw new ArgumentNullException("dataReader");
            }
            if (dataBlockBuilder == null)
            {
                throw new ArgumentNullException("dataBlockBuilder");
            }
            if (root == null)
            {
                throw new ArgumentNullException("root");
            }

            _dataReader       = dataReader;
            _dataBlockBuilder = dataBlockBuilder;
            _root             = root;
            _moov             = _root.FindChild(AtomName.Movie);
            _mdat             = _root.FindChild(AtomName.MediaData);
            _fileOffset       = _root.FirstChild.Offset;

            if (_mdat == null)
            {
                _mdatChunk = new Chunk(((QtAtom)_root.GetLastDescendant()).Offset - _fileOffset, 0);
            }
            else
            {
                _mdatChunk = new Chunk(_mdat.Offset - _fileOffset + 8, (_mdat.Length - 8));
            }

            _mdatMaxUnparsedBytes = (uint)QtDetector.Configurable[QtDetector.ConfigurationKey.MediaDateMaxUnparsedBytes];
        }
        public void BuildEndOffsetNegative()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.EndOffset = -1;
            dataBlockBuilder.Build();
        }
        public IDataBlock DetectData(IDataReader dataReader, IDataBlockBuilder dataBlockBuilder, IScanContext context)
        {
            if (dataReader.State != DataReaderState.Ready)
            {
                return(null);
            }

            try
            {
                long       startPosition = dataReader.Position;
                IDataBlock dataBlock     = _detector.DetectData(dataReader, dataBlockBuilder, context);

                if (dataReader.State == DataReaderState.Cancelled)
                {
                    dataReader.Position = dataReader.Length;
                }
                else if (dataReader.Position <= startPosition)
                {
                    // Force advance stream reader one byte
                    Log.Error(string.Format("Detector {0} did not advance the stream reader position.", _detector.Name));
                    dataReader.Position = startPosition + 1;
                }

                return(dataBlock);
            }
            catch (OutOfMemoryException)
            {
                // TODO improve out of memory exception handling and remove reference to System.Windows.Forms
                System.Windows.Forms.MessageBox.Show("There is not enough memory available to continue scanning current data block (2); Position: " + dataReader.Position + "; Detector: " + _detector.Name + "; Header count: ?", "Out Of Memory");

                // Skip rest of the stream
                dataReader.Position = dataReader.Length;
                return(null);
            }
        }
        public void BuildEndOffsetAfterEndOfFile()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.EndOffset = (FileLength1 + 1);
            dataBlockBuilder.Build();
        }
        public void EqualsDifferentDetector()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.Detectors = new[] { _detector2 };
            Assert.IsFalse(_dataBlock1.Equals(dataBlockBuilder.Build()));
        }
        public void BuildEndOffsetEqualToStartOffset()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.EndOffset = StartOffset1;
            dataBlockBuilder.Build();
        }
        public void BuildInputFileNull()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.InputFile = null;
            dataBlockBuilder.Build();
        }
예제 #8
0
        public IDataBlock DetectData(IDataReader dataReader, IDataBlockBuilder dataBlockBuilder, IScanContext context)
        {
            bool isFragmented = context.IsFragmented;

            if (ReferenceHeaders != null)
            {
                var referenceHeaders = new Dictionary <IDataPacket, ISequenceState>();
                foreach (IReferenceHeader header in ReferenceHeaders)
                {
                    IInputFile headerFile = context.CreateReferenceHeaderFile(header);
                    using (var reader = headerFile.CreateDataReader())
                    {
                        var headerDataBlock = _carver.Carve(new BitStreamDataReader(reader), dataBlockBuilder, context);
                        if (headerDataBlock != null)
                        {
                            referenceHeaders[headerFile.CreateDataPacket()] = context.ReferenceHeader as ISequenceState;
                        }
                    }
                }

                context.ReferenceHeader = referenceHeaders;
            }

            // Restore scan context
            context.Results      = null;
            context.IsFragmented = isFragmented;
            // context.ReferenceHeader

            return(_carver.Carve(new BitStreamDataReader(dataReader), dataBlockBuilder, context));
        }
예제 #9
0
        public bool ValidateDataBlock(IDataBlockBuilder dataBlockBuilder, long startOffset, long endOffset)
        {
            if (!IsValidResult())
            {
                return(false);
            }

            dataBlockBuilder.DataFormat   = _state.IsMpeg2() ? CodecID.Mpeg2Video : CodecID.Mpeg1Video;
            dataBlockBuilder.IsFullFile   = IsFullFile();
            dataBlockBuilder.IsFragmented = _state.IsFragmented;

            // Trim zero byte stuffing from last header (if any)
            if (_state.LastHeaderZeroByteStuffing > 0)
            {
                dataBlockBuilder.EndOffset = endOffset - _state.LastHeaderZeroByteStuffing;
            }
            if (_state.ReferenceHeader != null)
            {
                dataBlockBuilder.ReferenceHeaderOffset = _state.ReferenceHeaderPosition - startOffset;
                dataBlockBuilder.ReferenceHeader       = _state.ReferenceHeader;
            }
            if (_state.Sequence.Initialized)
            {
                var sequenceState = new SequenceState();
                _state.Sequence.CopyTo(sequenceState);
                _scanContext.ReferenceHeader = sequenceState;
            }
            return(true);
        }
        public void BuildDetectorNull()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.Detectors = null;
            dataBlockBuilder.Build();
        }
        public bool ValidateDataBlock(IDataBlockBuilder dataBlockBuilder, long startOffset, long endOffset)
        {
            if (!IsValidResult(_scanContext.Results))
            {
                return(false);
            }

            endOffset += TrimResult();
            dataBlockBuilder.DataFormat  = CodecID.H264;
            dataBlockBuilder.StartOffset = startOffset;
            dataBlockBuilder.EndOffset   = endOffset;
            // TODO: _dataBlockBuilder.IsFullFile = false;

            if (_state.ReferenceHeader != null)
            {
                dataBlockBuilder.ReferenceHeaderOffset = _state.ReferenceHeaderPosition - startOffset;
                dataBlockBuilder.ReferenceHeader       = _state.ReferenceHeader;
            }
            if (_state.PictureStates.Initialized)
            {
                // TODO: make a defensive copy of  the picture state
                var pictureParameterSetId = _state.PictureStates.First();
                _scanContext.ReferenceHeader = _state.PictureStates[pictureParameterSetId];
            }
            return(true);
        }
        public void EqualsDifferentInputFile()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.InputFile = _inputFile2;
            Assert.IsFalse(_dataBlock1.Equals(dataBlockBuilder.Build()));
        }
        public void EqualsDifferentIsFullFile()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.IsFullFile = true;
            Assert.IsFalse(_dataBlock1.Equals(dataBlockBuilder.Build()));
        }
        public void EqualsDifferentEndOffset()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.EndOffset = (EndOffset1 + 1);
            Assert.IsFalse(_dataBlock1.Equals(dataBlockBuilder.Build()));
        }
예제 #15
0
        public bool ValidateDataBlock(IDataBlockBuilder dataBlockBuilder, long startOffset, long endOffset)
        {
            if (!IsValidResult())
            {
                return(false);
            }

            dataBlockBuilder.DataFormat   = _state.IsMpeg2() ? CodecID.Mpeg2System : CodecID.Mpeg1System;
            dataBlockBuilder.IsFullFile   = IsFullFile();
            dataBlockBuilder.IsFragmented = _state.IsFragmented;

            // Trim zero byte stuffing from last header (if any)
            if (_state.LastHeaderZeroByteStuffing > 0)
            {
                dataBlockBuilder.EndOffset = endOffset - _state.LastHeaderZeroByteStuffing;
            }
            foreach (ushort streamId in _state.Streams.StreamIds)
            {
                IDataPacket streamData = _state.Streams[streamId].GetStreamData();
                if (streamData != null)
                {
                    string name = GetStreamName(streamId);
                    if (name != null)
                    {
                        ICodecStreamBuilder codecStreamBuilder = dataBlockBuilder.AddCodecStream();
                        codecStreamBuilder.Name                = name;
                        codecStreamBuilder.DataFormat          = name.StartsWith("Video") ? CodecID.Mpeg2Video : CodecID.Unknown;
                        codecStreamBuilder.StreamNumber        = streamId;
                        codecStreamBuilder.Data                = streamData;
                        codecStreamBuilder.AbsoluteStartOffset = codecStreamBuilder.Data.StartOffset;
                    }
                }
            }
            return(true);
        }
        /// <summary>
        /// This method looks for the beginning of an MPEG-4 header and if one is found it will parse it
        /// by calling Parser.Parse().
        /// </summary>
        override public IDataBlock DetectData(IDataReader dataReader, IDataBlockBuilder dataBlockBuilder, IScanContext context)
        {
            if (ReferenceHeaders != null)
            {
                var referenceHeaders = new Dictionary <IDataPacket, VideoObjectLayer>();
                foreach (IReferenceHeader header in ReferenceHeaders)
                {
                    IInputFile headerFile = context.CreateReferenceHeaderFile(header);
                    using (var parser = new Mpeg4Parser(new BitStreamDataReader(headerFile.CreateDataReader())))
                    {
                        Mpeg4Header root;
                        while (parser.ParseRoot(root = new Mpeg4Header(context.Detectors), parser.Length))
                        {
                            VideoObjectLayer vol = root.FindChild(Mpeg4HeaderName.VideoObjectLayer, true) as VideoObjectLayer;
                            if (vol != null)
                            {
                                referenceHeaders[headerFile.CreateDataPacket()] = vol;
                            }
                        }
                    }
                }

                context.ReferenceHeader = referenceHeaders;
            }

            return(Carve(dataReader, dataBlockBuilder, context));
        }
        private IDataBlock DetectData1(IDataReader dataReader, IDataBlockBuilder dataBlockBuilder, IScanContext context)
        {
            if ((dataReader.Position + 51) > dataReader.Length)
            {
                return(null);
            }

            IResultNode root   = new MockResult(this);
            IResultNode parent = root;
            int         i      = (int)(dataReader.GetDataPacket(0, 1).StartOffset + (dataReader.Position) / 51);

            for (int j = 0; j < 3; j++)
            {
                long       offset = dataReader.Position;
                const long length = 17;
                parent = new MockResult(parent, dataReader, offset, length, "result: " + i + ", " + j);
                dataReader.Position += length;
            }
            context.Results = root;
            var firstChild = ((MockResult)context.Results.Children[0]);

            dataBlockBuilder.StartOffset = firstChild.Offset;
            var lastChild = ((MockResult)context.Results.GetLastDescendant());

            dataBlockBuilder.EndOffset = (lastChild.Offset + lastChild.Length);
            return(dataBlockBuilder.Build());
        }
        public void EqualsDifferentDataFormat()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.DataFormat = CodecID.Mpeg1System;
            Assert.IsFalse(_dataBlock1.Equals(dataBlockBuilder.Build()));
        }
        public void BuildEndOffsetBeforeStartOffset()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.EndOffset = (StartOffset1 - 1);
            dataBlockBuilder.Build();
        }
        override public IDataBlock DetectData(IDataReader dataReader, IDataBlockBuilder dataBlockBuilder, IScanContext context)
        {
            AsfObject root = new AsfObject(context.Detectors);

            // Try to parse a contiguous block of ASF objects
            using (AsfParser parser = new AsfParser(new ByteStreamDataReader(dataReader, Endianness.Little)))
            {
                if (!parser.ParseRoot(root, dataReader.Length))
                {
                    dataReader.Position = dataReader.Length;
                    return(null);
                }

                // Synchronize the position of the data reader
                dataReader.Position = parser.Position;
            }

            // Trim trailing unknown, padding byte or large unparsable ASF objects
            AsfObject lastAsfObject = root.LastHeader;

            while (lastAsfObject.IsUnknown && lastAsfObject.Parent != null)
            {
                if (lastAsfObject.RelativeEndOffset == ((AsfObject)lastAsfObject.Parent).RelativeEndOffset)
                {
                    break;                      // Last child perfectly aligned with parent object
                }

                lastAsfObject.Parent.RemoveChild(lastAsfObject);
                lastAsfObject = root.LastHeader;
            }

            if ((dataReader.State == DataReaderState.Cancelled) ||
                (root.Children.Count == 0) ||
                (root.Children.Count == 1 && !root.FirstChild.HasChildren()))                   // Discard data blocks of only 1 ASF object
            {
                // Rewind data reader
                dataReader.Position = lastAsfObject.Offset + lastAsfObject.Length;                      // != lastHeader.RelativeEndOffset; !!!

                return(null);
            }

            context.Results = root;

            dataBlockBuilder.DataFormat = root.DataFormat;
            var firstChild = ((AsfObject)root.Children[0]);

            dataBlockBuilder.StartOffset = firstChild.Offset;
            var lastChild = ((AsfObject)root.GetLastDescendant());
            var endOffset = (lastChild.Offset + lastChild.Length);

            dataBlockBuilder.EndOffset = endOffset;

            CodecStream codecStream = new CodecStream(root);

            codecStream.CreateCodecStreams(dataBlockBuilder);

            dataReader.Position = endOffset;
            return(dataBlockBuilder.Build());
        }
예제 #21
0
 public CarverState(IReaderState readerState, IDataBlockCarver dataBlockCarver, IResultMetadata resultMetadata, IDataReader dataReader, IDataBlockBuilder dataBlockBuilder)
 {
     _readerState      = readerState;
     _dataBlockCarver  = dataBlockCarver;
     _resultMetadata   = resultMetadata;
     _dataReader       = dataReader;
     _dataBlockBuilder = dataBlockBuilder;
 }
예제 #22
0
 /// <summary>
 /// This method looks for the beginning of an NAL unit and if one is found it will parse it
 /// by calling Parser.Parse().
 /// </summary>
 public IDataBlock DetectData(IDataReader dataReader, IDataBlockBuilder dataBlockBuilder, IScanContext context)
 {
     if (ReferenceHeaders != null)
     {
         BuildReferenceHeaders(context, dataBlockBuilder);
     }
     return(_carver.Carve(new BitStreamDataReader(dataReader), dataBlockBuilder, context));
 }
예제 #23
0
        private IDataBlockBuilder CreateBuilder(IInputFile file)
        {
            IDataBlockBuilder builder = TestFramework.CreateDataBlockBuilder();

            builder.Detectors = new[] { _detector };
            builder.InputFile = file;
            return(builder);
        }
        public void Equals()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            Assert.IsTrue(_dataBlock1.Equals(dataBlockBuilder.Build()));
            Assert.IsFalse(_dataBlock1.Equals(_dataBlock2));
            Assert.IsFalse(_dataBlock2.Equals(_dataBlock1));
        }
        private IDataBlockBuilder CreateDataBlockBuilder2()
        {
            IDataBlockBuilder dataBlockBuilder2 = TestFramework.CreateDataBlockBuilder();

            dataBlockBuilder2.DataFormat  = CodecID.Avi;
            dataBlockBuilder2.Detectors   = new[] { _detector2 };
            dataBlockBuilder2.InputFile   = _inputFile2;
            dataBlockBuilder2.StartOffset = StartOffset2;
            dataBlockBuilder2.EndOffset   = EndOffset2;
            dataBlockBuilder2.IsFullFile  = true;
            return(dataBlockBuilder2);
        }
        private IDataBlockBuilder CreateDataBlockBuilder1()
        {
            IDataBlockBuilder dataBlockBuilder1 = TestFramework.CreateDataBlockBuilder();

            dataBlockBuilder1.DataFormat  = CodecID.Mpeg2System;
            dataBlockBuilder1.Detectors   = new[] { _detector1 };
            dataBlockBuilder1.InputFile   = _inputFile1;
            dataBlockBuilder1.StartOffset = StartOffset1;
            dataBlockBuilder1.EndOffset   = EndOffset1;
            dataBlockBuilder1.IsFullFile  = false;
            return(dataBlockBuilder1);
        }
        private static void AddUnknownCodecStream(IDataBlockBuilder dataBlockBuilder, ICodecStream completeCodecStream)
        {
            ICodecStreamBuilder relativeCodecStreamBuilder = dataBlockBuilder.AddCodecStream();

            relativeCodecStreamBuilder.StreamNumber        = completeCodecStream.StreamNumber;
            relativeCodecStreamBuilder.Name                = completeCodecStream.Name;
            relativeCodecStreamBuilder.DataFormat          = CodecID.Unknown;
            relativeCodecStreamBuilder.Detector            = new UnknownFormatDetector();
            relativeCodecStreamBuilder.Data                = completeCodecStream.InputFile.CreateDataPacket().GetSubPacket(0L, completeCodecStream.Length);
            relativeCodecStreamBuilder.IsFragmented        = false;
            relativeCodecStreamBuilder.AbsoluteStartOffset = completeCodecStream.AbsoluteStartOffset;
        }
예제 #28
0
        internal static IDataBlock CreateDataBlock(IDetector detector, IDataPacket data, bool isFullFile, IDataBlock lastDataBlock)
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder();

            dataBlockBuilder.DataFormat   = CodecID.Unknown;
            dataBlockBuilder.Detectors    = new[] { detector };
            dataBlockBuilder.InputFile    = data.InputFile;
            dataBlockBuilder.StartOffset  = data.StartOffset;
            dataBlockBuilder.EndOffset    = data.EndOffset;
            dataBlockBuilder.IsFullFile   = isFullFile;
            dataBlockBuilder.IsFragmented = false;
            return(dataBlockBuilder.Build());
        }
        private static IDataBlock Carve(IDataReader dataReader, IDataBlockBuilder dataBlockBuilder, IScanContext context)
        {
            // Try to parse a contiguous block of headers
            using (var parser = new Mpeg4Parser(new BitStreamDataReader(dataReader)))
            {
                if (context.ReferenceHeader is Dictionary <IDataPacket, VideoObjectLayer> )
                {
                    parser.ReferenceHeaders = context.ReferenceHeader as Dictionary <IDataPacket, VideoObjectLayer>;
                }

                Mpeg4Header root;
                while (parser.ParseRoot(root = new Mpeg4Header(context.Detectors), dataReader.Length))
                {
                    Mpeg4Header lastHeader = root.LastHeader;
                    if (lastHeader.ZeroByteStuffing > 0)
                    {
                        lastHeader.TrimZeroByteStuffing(parser);
                    }

                    // Discard results that do not contain a VOP, short video VOP or VOL.
                    // Discard data blocks of only one header that is not a H.263 Short Header VOP.
                    // The Short Header VOP counts for two headers because it is hard to correctly
                    // parse a Short Header VOP from random bits.
                    var requiredMpeg4Headers = new[] { Mpeg4HeaderName.VideoObjectLayer, Mpeg4HeaderName.Vop, Mpeg4HeaderName.VopWithShortHeader };
                    if (RequiredHeaderCount(root) && root.ContainsChildren(requiredMpeg4Headers, true) && RequiredShortHeaderCount(root))
                    {
                        context.Results = root;

                        dataBlockBuilder.DataFormat = root.DataFormat;
                        var firstChild = ((Mpeg4Header)root.Children[0]);
                        dataBlockBuilder.StartOffset = firstChild.Offset;
                        var lastChild = ((Mpeg4Header)root.GetLastDescendant());
                        var endOffset = (lastChild.Offset + lastChild.Length);
                        dataBlockBuilder.EndOffset = endOffset;
                        dataReader.Position        = endOffset;
                        if (parser.ReferenceHeader != null)
                        {
                            dataBlockBuilder.ReferenceHeaderOffset = parser.ReferenceHeaderPosition - firstChild.Offset;
                            dataBlockBuilder.ReferenceHeader       = parser.ReferenceHeader;
                        }
                        return(dataBlockBuilder.Build());
                    }

                    RewindParser(parser, lastHeader);
                }
            }

            dataReader.Position = dataReader.Length;
            return(null);            // Nothing detected!
        }
            private void AddRelativeCodecStream(IDataBlockBuilder dataBlockBuilder, IFragment codecStreamFragment)
            {
                ICodecStreamBuilder relativeCodecStreamBuilder = dataBlockBuilder.AddCodecStream();

                relativeCodecStreamBuilder.StreamNumber          = _completeCodecStream.StreamNumber;
                relativeCodecStreamBuilder.Name                  = _completeCodecStream.Name;
                relativeCodecStreamBuilder.DataFormat            = codecStreamFragment.DataFormat;
                relativeCodecStreamBuilder.Detector              = codecStreamFragment.Detectors.FirstOrDefault();
                relativeCodecStreamBuilder.Data                  = _completeCodecStream.InputFile.CreateDataPacket().GetSubPacket(codecStreamFragment.StartOffset, codecStreamFragment.Length);
                relativeCodecStreamBuilder.IsFragmented          = codecStreamFragment.IsFragmented;
                relativeCodecStreamBuilder.AbsoluteStartOffset   = _completeCodecStream.AbsoluteStartOffset + codecStreamFragment.StartOffset;
                relativeCodecStreamBuilder.ReferenceHeaderOffset = codecStreamFragment.ReferenceHeaderOffset;
                relativeCodecStreamBuilder.ReferenceHeader       = codecStreamFragment.ReferenceHeader;
            }