Exemplo n.º 1
0
        public List <FrameField> GetVideoFrameFields(List <int> fieldNumbers)
        {
            var result = new List <FrameField>();

            fieldNumbers = (from f in fieldNumbers orderby f select f).ToList();
            foreach (var frameNumber in fieldNumbers)
            {
                if ((frameNumber < 0) || (frameNumber >= TotalFields))
                {
                    result.Add(null);
                    continue;
                }

                SeekToField(frameNumber, SeekModes.Accurate);
                if (_pendingFrame != null)
                {
                    FrameField frame = _pendingFrame.Fields[_pendingFrame.CurrentIndex];
                    //frame.Image.Save(@"D:\temp\image-" + frame.FrameNumber.ToString("00000") + ".png", System.Drawing.Imaging.ImageFormat.Png);
                    result.Add(frame);
                }
                else
                {
                    result.Add(null);
                }
                _pendingFrame.CurrentIndex++;
                if (_pendingFrame.CurrentIndex >= _pendingFrame.Fields.Length)
                {
                    _pendingFrame = ReadVideoFrame();
                }
            }

            return(result);
        }
Exemplo n.º 2
0
 private void SeekToPTS(long pts, SeekModes seekMode)
 {
     if (seekMode == SeekModes.PreviousKeyFrame)
     {
         SeekToPTS(pts, true);
     }
     else if (seekMode == SeekModes.NextKeyFrame)
     {
         SeekToPTS(pts, false);
         while (!_pendingFrame.IsKeyFrame)
         {
             var previousFrame = _pendingFrame;
             _pendingFrame = ReadVideoFrame();
             if (_pendingFrame == null)
             {
                 _pendingFrame = previousFrame;
                 return;
             }
             DisposeFrame(ref previousFrame);
         }
     }
     else
     {
         SeekToPTS(pts, false);
     }
 }
Exemplo n.º 3
0
 private static void DisposeFrame(ref PendingFrame frame)
 {
     if (frame != null)
     {
         frame.Dispose();
         frame = null;
     }
 }
Exemplo n.º 4
0
        public FrameField GetVideoFrameField(int fieldNumber, SeekModes seekMode = SeekModes.Accurate)
        {
            FrameField frame = null;

            SeekToField(fieldNumber, seekMode);
            if (_pendingFrame != null)
            {
                frame = _pendingFrame.Fields[_pendingFrame.CurrentIndex];
                //frame.Image.Save(@"D:\temp\image-" + frame.FrameNumber.ToString("00000") + ".png", System.Drawing.Imaging.ImageFormat.Png);
            }
            _pendingFrame.CurrentIndex++;
            if (_pendingFrame.CurrentIndex >= _pendingFrame.Fields.Length)
            {
                _pendingFrame = ReadVideoFrame();
            }
            return(frame);
        }
Exemplo n.º 5
0
        private PendingFrame ProcessFrame()
        {
            _frameOrig = (FFmpeg.AVFrame)Marshal.PtrToStructure(_pFrameOrig, typeof(FFmpeg.AVFrame));

            IntPtr pStream = Marshal.ReadIntPtr(_formatContext.streams, _videoStreamIndex * 4);
            var    stream  = (FFmpeg.AVStream)Marshal.PtrToStructure(pStream, typeof(FFmpeg.AVStream));

            _videoCodecContext = (FFmpeg.AVCodecContext)Marshal.PtrToStructure(stream.codec, typeof(FFmpeg.AVCodecContext));

            if (_videoFrameFirstDTS == null)
            {
                _videoFrameFirstDTS = _frameOrig.pkt_dts;
            }
            if (_videoFieldDTSDuration == null)
            {
                _videoFieldDTSDuration = _frameOrig.pkt_duration / _videoCodecContext.ticks_per_frame;
            }

            var fieldList = new List <FrameField>();

            //---------- Start YUV Image ----------
            if (OutputYData || OutputYImage)
            {
                _scalerY.ProcessImage(_pFrameOrig, _frameOrig);
            }
            //---------- End YUV Image ----------

            //---------- Start RGB Image ----------
            if (OutputRGBImage && !OutputYImage)
            {
                _scalerRGB.ProcessImage(_pFrameOrig, _frameOrig);
            }
            //---------- End RGB Image ----------

            for (int fieldIndex = 0; fieldIndex < _videoCodecContext.ticks_per_frame; fieldIndex++)
            {
                var field = new FrameField();

                if (OutputYData || OutputYImage)
                {
                    field.YData = _scalerY.GetYData(fieldIndex);
                    if (OutputYImage)
                    {
                        field.Image = _scalerY.GetImage(fieldIndex);
                        //field.Image.Save(@"D:\temp\image.png", System.Drawing.Imaging.ImageFormat.Png);
                    }
                }

                if (OutputRGBImage && !OutputYImage)
                {
                    field.Image = _scalerRGB.GetImage(fieldIndex);
                    //field.Image.Save(@"D:\temp\image.png", System.Drawing.Imaging.ImageFormat.Png);
                }

                field.PTS          = (_frameOrig.pkt_dts - _videoFrameFirstDTS.Value) + (fieldIndex * _videoFieldDTSDuration.Value);
                field.Seconds      = field.PTS * _videoCodecContext.pkt_timebase.num / (double)_videoCodecContext.pkt_timebase.den;
                field.FieldIndex   = fieldIndex;
                field.FieldNumber  = (int)(field.PTS / _videoFieldDTSDuration.Value);
                field.FrameNumber  = (int)(field.FieldNumber / _videoCodecContext.ticks_per_frame);
                field.FilePosition = _frameOrig.pkt_pos;
                field.AVFrame      = _frameOrig;

                fieldList.Add(field);
            }

            var frame = new PendingFrame();

            frame.Fields = fieldList.ToArray();

            return(frame);
        }
Exemplo n.º 6
0
        private void SeekToPTS(long pts, bool stopAtKeyframe, bool forceSeek = false)
        {
            if (forceSeek == false)
            {
                if ((_pendingFrame != null) && (_pendingFrame.Fields != null))
                {
                    for (int fieldIndex = 0; fieldIndex < _pendingFrame.Fields.Length; fieldIndex++)
                    {
                        var field = _pendingFrame.Fields[fieldIndex];
                        if ((field.PTS == pts))
                        {
                            _pendingFrame.CurrentIndex = fieldIndex;
                            return;
                        }
                    }
                }
            }

            long seekPTS = pts;

            if (seekPTS < long.MaxValue)
            {
                seekPTS = seekPTS / PTSPerField / _videoCodecContext.ticks_per_frame * _videoCodecContext.ticks_per_frame * PTSPerField;
                if (long.MaxValue - seekPTS > _videoFrameFirstDTS.Value)
                {
                    seekPTS += _videoFrameFirstDTS.Value;
                }
            }

            var  originalPendingFrame = _pendingFrame;
            long lastSeekFilePosition = -1L;

            while (true)
            {
                if (seekPTS < 0)
                {
                    seekPTS = 0;
                }

                int ret = FFmpeg.avformat_seek_file(_pFormatContext, _videoStreamIndex, 0, seekPTS, seekPTS, FFmpeg.AVSEEK_FLAG.AVSEEK_FLAG_NONE);
                if (ret < 0)
                {
                    throw new Exception("Failed to seek to first frame: " + ret.ToString());
                }
                FFmpeg.avcodec_flush_buffers(_pVideoCodecContext);

                var pb = (FFmpeg.ByteIOContext)Marshal.PtrToStructure(_formatContext.pb, typeof(FFmpeg.ByteIOContext));
                if (lastSeekFilePosition != -1L)
                {
                    if ((lastSeekFilePosition == pb.pos) && (seekPTS != 0))
                    {
                        seekPTS -= (PTSPerField * _videoCodecContext.ticks_per_frame);
                        continue;
                    }
                }
                lastSeekFilePosition = pb.pos;

                if (_pendingFrame != originalPendingFrame)
                {
                    DisposeFrame(ref _pendingFrame);
                }

                _pendingFrame = ReadVideoFrame();

                if (_pendingFrame != null)
                {
                    if (_pendingFrame.Fields.First().PTS == pts)
                    {
                        return;
                    }

                    if (_pendingFrame.Fields.First().PTS > pts)
                    {
                        if (seekPTS == 0)
                        {
                            return;
                        }

                        seekPTS -= PTSPerField * _videoCodecContext.ticks_per_frame;

                        continue;
                    }

                    while (true)
                    {
                        if (stopAtKeyframe && _pendingFrame.IsKeyFrame)
                        {
                            _pendingFrame.CurrentIndex = 0;
                            return;
                        }

                        for (int fieldIndex = 0; fieldIndex < _pendingFrame.Fields.Length; fieldIndex++)
                        {
                            var field = _pendingFrame.Fields[fieldIndex];

                            if (field.PTS >= pts)
                            {
                                _pendingFrame.CurrentIndex = fieldIndex;
                                return;
                            }
                        }

                        var previousFrame = _pendingFrame;
                        _pendingFrame = ReadVideoFrame();
                        if (_pendingFrame == null)
                        {
                            _pendingFrame = previousFrame;
                            _pendingFrame.CurrentIndex = _pendingFrame.Fields.Length - 1;
                            return;
                        }
                        if (previousFrame != originalPendingFrame)
                        {
                            DisposeFrame(ref previousFrame);
                        }
                    }
                }
            }
        }