示例#1
0
        public IDataPacket GetVideoData(IResultNode resultNode)
        {
            if (!IsIntraSlice(resultNode))
            {
                return(null);
            }
            if (resultNode.Parent == null)
            {
                // Slice without headers (won't decode!)
                return(resultNode.Append(resultNode));
            }

            uint?firstMacroblockInSlice = GetFirstMacroblockInSlice(resultNode);

            if (!firstMacroblockInSlice.HasValue)
            {
                return(resultNode.Append(resultNode));
            }

            int index = GetParentIndex(resultNode);
            IList <IResultNode> siblings   = resultNode.Parent.Children;
            IDataPacket         dataPacket = resultNode;

            for (int i = (index + 1); i < siblings.Count; i++)
            {
                IResultNode sibling = siblings[i];
                if (!IsIntraSlice(sibling))
                {
                    break;                     // Not an intra-coded slice, so not part of the same IDR picture
                }

                uint?nextFirstMacroblockInSlice = GetFirstMacroblockInSlice(sibling);
                if (!nextFirstMacroblockInSlice.HasValue || (nextFirstMacroblockInSlice <= firstMacroblockInSlice))
                {
                    break;                     // Slice is not part of the same picture
                }

                firstMacroblockInSlice = nextFirstMacroblockInSlice.Value;
                dataPacket             = dataPacket.Append(sibling);
            }

            // Duplicate the frame data, because otherwise, FFmpeg won't decode it.
            return(dataPacket.Append(dataPacket));
        }
示例#2
0
        public 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 = _carver.Carve(new BitStreamDataReader(dataReader), new ReferenceHeaderDataBlockBuilder(), scanContext);
                if (dataBlock == null)
                {
                    break;                     // No (more) data blocks detected
                }

                IResultNode sequenceParameterSet = scanContext.Results.FindChild(SequenceParameterSet.Name);
                if (sequenceParameterSet != null)
                {
                    IResultNode pictureParameterSet = sequenceParameterSet.FindChild(PictureParameterSet.Name);
                    if (pictureParameterSet != null)
                    {
                        // TODO: perhaps we need to include the headers between the SPS and PPS !?
                        IDataPacket data = sequenceParameterSet.Append(pictureParameterSet);

                        // Report codec parameters for reference header
                        codecParameters.Codec  = CodecID.H264;
                        codecParameters.Width  = GetWidth(sequenceParameterSet);
                        codecParameters.Height = GetHeight(sequenceParameterSet);
                        var entropyCodingMode = GetAttributeValue <bool>(pictureParameterSet, PictureParameterSet.Attribute.EntropyCodingMode);
                        codecParameters["EntropyCodingMode"] = entropyCodingMode ? "CABAC" : "CAVLC";
                        // TODO: codecParameters["FrameRate"] = GetAttributeStringValue(sequenceParameterSet, ???);

                        return(data);
                    }
                }

                // Sequence- or Picture Parameter Set is missing: Continue scanning after current data block ...
                dataReader.Position = dataBlock.EndOffset;
            }

            return(null);            // No reference header detected
        }
 public IDataPacket Append(IDataPacket dataPacket)
 {
     return(_result.Append(dataPacket));
 }