2015-07-21 134 views
0

我使用C#来调用ffmpeg库。 我使用示例代码来解码MP4格式的视频。FFmpeg内存越来越大avcodec_decode_video2

然而,我发现,在内存中变了很多(如10MB),当我打电话给avcodec_decode_video2功能。

存储持续增长,直到我叫avcodec_close(&编解码器环境)功能。

我想,其原因可能是avcodec_decode_video2函数的调用过程中AVCodecContext ALLOC 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; 
    } 
+0

什么解析mp4文件?什么视频编解码器包含它(h264?hevc?别的?)? –

+0

每帧的分辨率为2048 * 2048,编解码器为h264。内存似乎与我的m_bufferSize线性, –

回答

1

您的break语句会导致丢失分配的帧,在这两种情况下,只有第二种情况下会丢失数据包。除此之外,它看起来一见钟情。根据视频的类型不同,10MB不多。例如,1080p视频格式为1920x1080x1.5 = 3MB /帧,并且您通常会在视频的整个生命周期中保留一些参考文件,因此在任何时候您都会有5-10帧存活= 15-30MB 1080。如果启用了线程(默认为打开),则每增加一个活动线程(典型的机器将有4个线程处于活动状态),则会再增加1个帧。

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

至于你的解码器循环,你不读缓存帧后的分路器信号EOF,即你不喂空包到解码器。这是推荐的。

+0

非常感谢。您的评论是非常有帮助的。我的m_bufferSize是100,看起来AVCodecContext保持所有的100帧活着。 –

+0

这意味着600 MB(每个2048x2048帧6MB,100帧),你的帖子说10 MB - 它是10MB /帧吗? convertFrame()是做什么的?就像,如果你注释掉所有对外部代码的调用,并且只使用ffmpeg解码循环,而对数据不做任何处理,你是否仍然看到泄漏? –