private void Export(XmlNode parent, IFragment fragment, IDataReaderPool dataReaderPool, IProgressReporter progressReporter)
        {
            if (fragment == null)
            {
                return;
            }

            IResultNode results = _dataBlockScanner.GetResults(fragment, new NullProgressReporter(), dataReaderPool);

            if (results == null)
            {
                // No results were found in the data block
                // Add the bytes from this data block to the _byteCount variable
                // to keep the progress bar correct.
                _handledBytes += fragment.Length;
                progressReporter.ReportProgress(_totalBytes == 0 ? 0 : (int)((_handledBytes * 100) / _totalBytes));
                return;
            }

            List <NameValuePair> detectableNameValuePairs = new List <NameValuePair>();

            detectableNameValuePairs.Add(new NameValuePair("File", fragment.InputFile.Name));
            if (fragment.Detectors != null)
            {
                foreach (IDetector detector in fragment.Detectors)
                {
                    detectableNameValuePairs.Add(new NameValuePair(_detectorFormatter.DetectorType(detector), detector.Name));
                    detectableNameValuePairs.Add(new NameValuePair(_detectorFormatter.DetectorType(detector) + "Version", _detectorFormatter.FormatVersion(detector)));
                }
            }
            detectableNameValuePairs.Add(new NameValuePair("Offset", fragment.StartOffset.ToString()));
            detectableNameValuePairs.Add(new NameValuePair("Length", fragment.Length.ToString()));

            string nodeName = "UnknownContainerOrCodec";

            if (fragment is IDataBlock)
            {
                nodeName = "Container";
            }
            else
            {
                nodeName = "Codec";
            }
            XmlElement fragmentElement = CreateElement(parent.OwnerDocument, nodeName, detectableNameValuePairs.ToArray());

            parent.AppendChild(fragmentElement);

            Export(fragmentElement, results.Children, progressReporter);
        }
Exemple #2
0
        private ResultNode GetCodecStreamsAndKeyFrames(IDataBlock dataBlock)
        {
            DataBlockScanner scanner = CreateDataBlockScanner();

            if (dataBlock.Detectors.Where(d => d is ICodecDetector).Count() >= 1)
            {
                // Codec stream; rescan and return
                using (IDataReaderPool dataReaderPool = CreateDataReaderPool())
                {
                    IResultNode  results   = scanner.GetResults(dataBlock, new NullProgressReporter(), dataReaderPool);
                    KeyFrameList keyFrames = new KeyFrameList();
                    AddKeyFramesToList(results, keyFrames);

                    if (results.DataFormat == Interface.CodecID.H264)
                    {
                        // TODO: will this always work?
                        return(new CodecStreamNode(dataBlock, results.DataFormat, IsH264NalUnitResultFoThaRealzWhenAlreadyH264(results), keyFrames, CreateRanges(results)));
                    }

                    IDataPacket rescannedDataPacket = RescanDataPackets(new IDataPacket[] { dataBlock }, dataReaderPool, new NullProgressReporter());
                    if (rescannedDataPacket != null)
                    {
                        if (rescannedDataPacket is ICodecStream)
                        {
                            var codecStream = rescannedDataPacket as ICodecStream;
                            return(new CodecStreamNode(codecStream, codecStream.DataFormat, keyFrames, BuildRangeList(codecStream)));
                        }
                        else if (rescannedDataPacket is IDataBlock)
                        {
                            var dataPacket = rescannedDataPacket as IDataBlock;
                            return(new CodecStreamNode(dataPacket, dataPacket.DataFormat, keyFrames, BuildRangeList(rescannedDataPacket)));
                        }
                        // TODO: is this possible?
                        throw new Exception("not a codecstream, nor a datablock: " + rescannedDataPacket);
                    }
                    return(new CodecStreamNode(dataBlock, dataBlock.DataFormat, keyFrames, BuildRangeList(dataBlock)));
                }
            }
            else
            {
                // Container stream; iterate over children streams, rescan and return
                IList <CodecStreamNode> streams = new List <CodecStreamNode>();
                RangeList containerDataRanges   = new RangeList();

                using (IDataReaderPool dataReaderPool = CreateDataReaderPool())
                {
                    containerDataRanges = BuildRangeList(RescanDataPackets(new IDataPacket[] { dataBlock }, dataReaderPool, new NullProgressReporter()));
                }

                foreach (var stream in dataBlock.CodecStreams)
                {
                    using (IDataReaderPool dataReaderPool = CreateDataReaderPool())
                    {
                        IResultNode  results   = scanner.GetResults(stream, new NullProgressReporter(), dataReaderPool);
                        KeyFrameList keyFrames = new KeyFrameList();
                        AddKeyFramesToList(results, keyFrames);

                        if (results.DataFormat == Interface.CodecID.H264)
                        {
                            // TODO: will this always work?
                            var node = new CodecStreamNode(stream, stream.DataFormat, IsH264NalUnitResultFoThaRealzWhenAlreadyH264(results), keyFrames, CreateRanges(results));
                            streams.Add(node);
                        }
                        else
                        {
                            IDataPacket rescannedDataPacket = RescanDataPackets(new IDataPacket[] { stream }, dataReaderPool, new NullProgressReporter());
                            if (rescannedDataPacket != null)
                            {
                                if (!(rescannedDataPacket is ICodecStream))
                                {
                                    // TODO: is this possible?
                                    throw new Exception("not a codecstream " + rescannedDataPacket);
                                }
                                var codecStream = rescannedDataPacket as ICodecStream;
                                streams.Add(new CodecStreamNode(codecStream, codecStream.DataFormat, keyFrames, BuildRangeList(codecStream)));
                            }
                            else
                            {
                                streams.Add(new CodecStreamNode(stream, stream.DataFormat, keyFrames, BuildRangeList(stream)));
                            }
                        }
                    }
                }

                return(new ContainerNode(dataBlock, streams, containerDataRanges));
            }
        }