示例#1
0
        override public IDataBlock DetectData(IDataReader dataReader, IDataBlockBuilder dataBlockBuilder, IScanContext context)
        {
            QtAtom root = new QtAtom(context.Detectors);

            // Try to parse a contiguous block of headers
            using (QtParser parser = new QtParser(new ByteStreamDataReader(dataReader)))
            {
                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 or large unparsable atoms
            QtAtom lastHeader        = root.LastHeader;
            long   firstHeaderOffset = ((QtAtom)root.Children[0]).Offset;

            while (lastHeader.IsUnknown && lastHeader.Parent != null)
            {
                if (lastHeader.RelativeEndOffset == ((QtAtom)lastHeader.Parent).RelativeEndOffset)
                {
                    break;                      // Last child perfectly aligned with parent atom
                }

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

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

                return(null);
            }

            context.Results = root;

            var  codecStream    = new CodecStream(dataReader, dataBlockBuilder, root);
            long?rescanPosition = codecStream.CreateCodecStreams();

            // TODO: check for (complete) mdat block (for IsFullFile)

            // Note: For consistency, always report the name of the detector itself, not a specific data format!
            //dataBlockBuilder.DataFormat = root.DataFormat;
            dataBlockBuilder.IsFullFile = IsFullFile(root);
            var firstChild = ((QtAtom)root.Children[0]);

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

            dataBlockBuilder.EndOffset = endOffset;
            dataReader.Position        = rescanPosition ?? endOffset;

            // If the last atom is an 'mdat' atom that was truncated for rescan to its minimum size, truncate the actual result!
            if ((rescanPosition == (lastChild.Offset + 8)) && (lastChild == root.FindChild(AtomName.MediaData)))
            {
                dataBlockBuilder.EndOffset = rescanPosition.Value;
            }
            return(dataBlockBuilder.Build());
        }
示例#2
0
 private string GetCodecStreamName()
 {
     return(CodecStream.GetCodecStreamName(_track, _sampleDescription, _truncated));
 }