コード例 #1
0
        public override IDataPacket FindReferenceHeader(IDataReader dataReader, ICodecParametersSpec codecParameters)
        {
            // Note: Loop to detect reference headers preceeded by a block of video frames
            //       (e.g. for 3GP files with 'mdat' before the 'moov' atom, so that the slices are located before the SPS/PPS pair)
            while (dataReader.State == DataReaderState.Ready)
            {
                IScanContext scanContext = new ReferenceHeaderScanContext {
                    Detectors = new[] { this }
                };

                var dataBlock = Carve(dataReader, new ReferenceHeaderDataBlockBuilder(), scanContext);
                if (dataBlock == null)
                {
                    break;                     // No (more) data blocks detected
                }

                IResultNode videoObject = scanContext.Results.FindChild(VideoObjectName);
                if ((videoObject != null) && videoObject.HasChildren())
                {
                    IResultNode videoObjectLayer = videoObject.GetFirstChild();
                    if (videoObjectLayer.Name == VideoObjectLayerName)
                    {
                        return(CreateReferenceHeader(dataBlock.DataFormat, videoObject, videoObjectLayer, codecParameters));
                    }
                }

                // VideoObject or VideoObjectLayer is missing: Continue scanning after current data block ...
                dataReader.Position = dataBlock.EndOffset;
            }

            return(null);            // No reference header detected
        }
コード例 #2
0
        private static IDataPacket CreateReferenceHeader(CodecID codec, IResultNode sequenceHeader, ICodecParametersSpec codecParameters)
        {
            IDataPacket data = sequenceHeader;

            // Include sequence extensions
            foreach (IResultNode childResultNode in sequenceHeader.Children)
            {
                if (!IsSequenceExtension(childResultNode.Name))
                {
                    break;
                }

                data = data.Append(childResultNode);
            }

            // Report codec parameters for reference header
            var width  = GetAttribute <uint>(sequenceHeader, SequenceHeader.Attribute.HorizontalSizeValue);
            var height = GetAttribute <uint>(sequenceHeader, SequenceHeader.Attribute.VerticalSizeValue);

            if (sequenceHeader.HasChildren())
            {
                IResult sequenceExtension = sequenceHeader.GetFirstChild();
                if (sequenceExtension.Name == SequenceExtension.Name)
                {
                    width  |= GetAttribute <uint>(sequenceExtension, SequenceExtension.Attribute.HorizontalSizeExtension) << 12;
                    height |= GetAttribute <uint>(sequenceExtension, SequenceExtension.Attribute.VerticalSizeExtension) << 12;
                }
            }

            codecParameters.Codec     = codec;
            codecParameters.Width     = width;
            codecParameters.Height    = height;
            codecParameters.FrameRate = GetAttributeStringValue(sequenceHeader, SequenceHeader.Attribute.FrameRateCode);

            return(data);
        }