avcodec_decode_video2中FFmpeg内存增长

本文关键字:内存 FFmpeg decode video2 avcodec | 更新日期: 2023-09-27 18:03:50

我使用c#调用ffmpeg库。我使用示例代码来解码MP4格式的视频。

然而,当我调用avcodec_decode_video2函数时,我发现内存增长了很多(像10MB)。

内存一直在增长,直到我调用avcodec_close(&CodecContext)函数。

我想原因可能是AVCodecContext在调用avcodec_decode_video2函数时分配了10MB的数据。在AVCodecContext关闭之前,这些内存不会被释放。

我不知道我是否正确。

主要代码如下:

private bool readNextBuffer(int index)
    {
        /// Read frames into buffer
        //m_codecContext->refcounted_frames = 0;
        int frameNumber = 0;
        FrameBuffer[index].Clear();
        GC.Collect();
        while (frameNumber < m_bufferSize)
        {
            AVPacket Packet; /// vedio packet 
            AVPacket* pPacket = &Packet;
            //AVFrame* pDecodedFrame = FFmpegInvoke.avcodec_alloc_frame(); 
            AVFrame* pDecodedFrame = FFmpegInvoke.av_frame_alloc(); 
            if (FFmpegInvoke.av_read_frame(m_pFormatContext, pPacket) < 0)
            {
                Console.WriteLine("The end of the vedio.");
                break;
            }
            if (pPacket->stream_index == pStream->index)
            {
                /// Decode vedio frame
                int gotPicture = 0;
                int size = FFmpegInvoke.avcodec_decode_video2(m_codecContext, pDecodedFrame, &gotPicture, pPacket);
                if (size < 0)
                {
                    Console.WriteLine("End of the vedio.");
                    //throw new Exception(string.Format("Error while decoding frame {0}", frameNumber));
                    break;
                }
                if (gotPicture == 1)
                {
                    /// Allocate an AVFrame structure
                    if (convertFrame(pDecodedFrame, index))
                    {
                        frameNumber++;
                    }
                    else
                    {
                        Console.WriteLine("Error: convert failed.");
                    }
                }
            }
            FFmpegInvoke.av_frame_free(&pDecodedFrame);
            FFmpegInvoke.av_free_packet(pPacket);
            GC.Collect();
        }
        nowFrameIndex = 0;
        return FrameBuffer.Count > 0 ? true : false;
    }

avcodec_decode_video2中FFmpeg内存增长

break语句在两种情况下都会导致分配的帧丢失,而在第二种情况下会导致数据包丢失。除此之外,第一眼看上去还不错。10MB并不多,这取决于视频的类型。例如,1080p视频是1920x1080x1.5=3MB/帧,在整个视频生命周期中,你通常会有一些引用保持活跃,所以在任何时候,1080p都有5-10帧活跃=15-30MB。如果你启用了线程(默认情况下是开启的),每增加一个活动线程,这个帧就会增加1帧(一个典型的机器会有4个活动线程)。

你没有提到任何关于内存使用增长的视频生命周期。例如,当视频播放时,它是否随时间线性增长(甚至是100帧或1000帧)?这将是一个问题。如果这是c/c++,您通常会使用valgrind,但也许c#有其他内存分析工具。

至于你的解码器循环,你没有读取缓存帧后的解路器信号EOF,即你没有馈送NULL数据包到解码器。