2015-07-21 72 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解碼循環,而對數據不做任何處理,你是否仍然看到泄漏? –