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); }
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)); } }