private void AddKeyFramesToList(IResultNode node, KeyFrameList keyFrames) { if (node.IsKeyframe()) { ICodecDetector detector = node.Detectors.Where(d => d is ICodecDetector).SingleOrDefault() as ICodecDetector; keyFrames.Add(new KeyFrame(BuildRangeList(detector.GetVideoHeaders(node)), BuildRangeList(detector.GetVideoData(node)))); } else { foreach (var childNode in node.Children) { AddKeyFramesToList(childNode, keyFrames); } } }
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)); } }
public CodecStreamNode(IDataBlock block, CodecID dataFormat, bool isH264AVCC, KeyFrameList keyFrameList, RangeList dataRanges) : this(block.DataFormat.GetName(), dataFormat, isH264AVCC, block.StartOffset, block.EndOffset - block.StartOffset, keyFrameList, dataRanges) { }
public CodecStreamNode(ICodecStream stream, CodecID dataFormat, bool isH264AVCC, KeyFrameList keyFrameList, RangeList dataRanges) : this(stream.Name, dataFormat, isH264AVCC, stream.AbsoluteStartOffset, stream.Length, keyFrameList, dataRanges) { }
// TODO: save fragment, resultnode here private CodecStreamNode(string name, CodecID dataFormat, bool isH264AVCC, long offset, long length, KeyFrameList keyFrameList, RangeList dataRanges) : base(name, dataFormat, isH264AVCC, offset, length, dataRanges) { _keyFrames = keyFrameList; }
public CodecStream(ICodecStream iCodecStream) { _iCodecStream = iCodecStream; _keyFrames = new KeyFrameList(); }
// TODO: clean up public void SetKeyFrames(KeyFrameList keyFrames) { _keyFrames = keyFrames; }