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; } }
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; }