Пример #1
0
        private void Reset()
        {
            if (_pFormatContext != IntPtr.Zero)
            {
                IntPtr ppFormatContext = Marshal.AllocHGlobal(4);
                Marshal.WriteInt32(ppFormatContext, _pFormatContext.ToInt32());
                FFmpeg.avformat_close_input(ppFormatContext);
                Marshal.FreeHGlobal(ppFormatContext);
            }

            DisposeFrame(ref _pendingFrame);

            FreeHGlobal(ref _pPacket);

            if (_scalerY != null)
            {
                _scalerY.Dispose();
                _scalerY = null;
            }
            if (_scalerRGB != null)
            {
                _scalerRGB.Dispose();
                _scalerRGB = null;
            }

            if (_pFrameOrig != IntPtr.Zero)
            {
                FFmpeg.avcodec_free_frame(ref _pFrameOrig);
                _pFrameOrig = IntPtr.Zero;
            }

            if (_pFormatContext != IntPtr.Zero)
            {
                _pFormatContext = IntPtr.Zero;
            }
        }
Пример #2
0
        public void Open(string filename)
        {
            int ret;

            Reset();

            _filename = filename;

            var dictionary = new FFmpeg.AVDictionary();

            dictionary.count = 0;
            ret = FFmpeg.avformat_open_input(out _pFormatContext, filename, IntPtr.Zero, dictionary);
            if (ret < 0)
            {
                throw new Exception("Failed to open input file: " + ret.ToString());
            }

            ret = FFmpeg.av_find_stream_info(_pFormatContext);
            if (ret < 0)
            {
                throw new Exception("Failed to find stream information: " + ret.ToString());
            }

            _formatContext = (FFmpeg.AVFormatContext)Marshal.PtrToStructure(_pFormatContext, typeof(FFmpeg.AVFormatContext));

            for (int streamIndex = 0; streamIndex < _formatContext.nb_streams; ++streamIndex)
            {
                //IntPtr pStream = _formatContext.streams[streamIndex];
                IntPtr pStream      = Marshal.ReadIntPtr(_formatContext.streams, streamIndex * 4);
                var    stream       = (FFmpeg.AVStream)Marshal.PtrToStructure(pStream, typeof(FFmpeg.AVStream));
                var    codecContext = (FFmpeg.AVCodecContext)Marshal.PtrToStructure(stream.codec, typeof(FFmpeg.AVCodecContext));

                if (codecContext.codec_type == FFmpeg.CodecType.CODEC_TYPE_VIDEO)
                {
                    _videoStreamIndex   = streamIndex;
                    _pVideoStream       = pStream;
                    _videoStream        = stream;
                    _pVideoCodecContext = stream.codec;
                    _videoCodecContext  = codecContext;

                    if (Resolution != ResolutionOption.Full)
                    {
                        Marshal.WriteInt32(_pVideoCodecContext, Marshal.OffsetOf(typeof(FFmpeg.AVCodecContext), "lowres").ToInt32(), (int)Resolution);
                    }

                    _pVideoCodecDecoder = FFmpeg.avcodec_find_decoder(_videoCodecContext.codec_id);
                    if (_pVideoCodecDecoder == IntPtr.Zero)
                    {
                        throw new Exception("Failed to find decoder");
                    }

                    ret = FFmpeg.avcodec_open(stream.codec, _pVideoCodecDecoder);
                    if (ret < 0)
                    {
                        throw new Exception("Failed to open codec: " + ret.ToString());
                    }

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

                    //Allocate buffers for original frame
                    _pFrameOrig = FFmpeg.avcodec_alloc_frame();

                    //Allocate buffers for RGB frame
                    _scalerY = new SwsScaler(_videoCodecContext);
                    _scalerY.DstPixelFormat = SwsScaler.PixelFormat.Y;

                    //Allocate buffers for RGB frame
                    _scalerRGB = new SwsScaler(_videoCodecContext);

                    // Allocate packet memory
                    int sizeOfPacket = Marshal.SizeOf(typeof(FFmpeg.AVPacket));
                    _pPacket = Marshal.AllocHGlobal(sizeOfPacket);
                    RtlZeroMemory(_pPacket, sizeOfPacket);
                }
                //else if (codecContext.codec_type == FFmpeg.CodecType.CODEC_TYPE_AUDIO)
                //{
                //    _audioStreamIndex = i;
                //    _pAudioStream = _formatContext.streams[i];
                //    _audioStream = stream;
                //    _pAudioCodec = stream.codec;
                //    _audioCodecContext = codecContext;
                //}
            }

            // Seek to the start of the file to reset dts values.
            ret = FFmpeg.avformat_seek_file(_pFormatContext, _videoStreamIndex, 0, 0, Int64.MaxValue, 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);

            // Read the first frame to set initial dts values
            ReadVideoFrame();

            if (_lastFieldNumber == -1)
            {
                if (_filename == @"F:\Convert\ComskipTest\Chuck - 4x02 - Retune\(2012-09-10 03-55) Chuck - 4x02 - Chuck Versus the Suitcase.m2v")
                {
                    _lastFieldNumber = 160295;
                }
                else
                {
                    SeekToPTS(Int64.MaxValue, false);
                    _lastFieldNumber = _pendingFrame.Fields.Last().FieldNumber;
                }
            }

            SeekToPTS(0, false);
            return;
        }