FFmpeg内存在avcodec_decode_video2

时间:2015-07-21 10:22:15

标签: c# ffmpeg

我使用C#来调用ffmpeg lib。 我使用示例代码解码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;
    }

1 个答案:

答案 0 :(得分:1)

在两种情况下,您的break语句都会导致丢失已分配的帧,并且仅在第二种情况下导致数据包丢失。除此之外,它一见钟情。 10MB不是很多,具体取决于视频的类型。例如,1080p视频是1920x1080x1.5 = 3MB /帧,并且您通常会在视频的整个生命周期内保留一些参考,因此在任何时候您都会有5-10帧活着= 1080p为15-30MB。如果启用了线程(默认情况下已启用),则每个额外活动线程将增加1帧(典型计算机将激活4个线程)。

您没有提及有关视频生命周期内内存使用量增长的任何信息。例如,在播放视频时(即使是100帧或1000帧),它会随着时间的推移呈线性增长吗?那将是一个问题。如果这是c / c ++,你通常会使用valgrind,但也许c#有其他的内存分析工具。

对于你的解码器循环,在解复用器发出信号EOF之后你不会读取缓存帧,即你没有将NULL数据包送入解码器。建议这样做。