代码之家  ›  专栏  ›  技术社区  ›  Expressingx

Ffmpeg可能存在sws_scale内存泄漏

  •  0
  • Expressingx  · 技术社区  · 5 年前

    我正在解码任何相机编解码器,然后总是将其编码为 H264 更具体地说 qsv 如果得到支持。目前有两个摄像头需要测试。一个是 H264 编码,一个是 rawvideo 问题随之而来 原始视频 。像素格式为 BGR24 并扩展到 NV12

    我将简化代码,因为它和其他示例一样。

    avcodec_send_packet()
    // while
    avcodec_receive_frame()
    
    // if frame is not EAGAIN convert BGR24 to NV12
    if (_pConvertContext == null)
    {
        _pConvertContext = CreateContext(sourcePixFmt, targePixFmt);
    }
    
    if (_convertedFrameBufferPtr == IntPtr.Zero)
    {
        int buffSize = ffmpeg.av_image_get_buffer_size(targePixFmt, sourceFrame->width, sourceFrame->height, 1);
        _convertedFrameBufferPtr = Marshal.AllocHGlobal(buffSize);
         ffmpeg.av_image_fill_arrays(ref _dstData, ref _dstLinesize, (byte*)_convertedFrameBufferPtr, targePixFmt, sourceFrame->width, sourceFrame->height, 1);
    }
    
    return ScaleImage(_pConvertContext, sourceFrame, targePixFmt, _dstData, _dstLinesize);
    

    还有 缩放图像 方法

    ffmpeg.sws_scale(ctx, sourceFrame->data, sourceFrame->linesize, 0, sourceFrame->height, dstData, dstLinesize);
    
    AVFrame* f = ffmpeg.av_frame_alloc();
    
    var data = new byte_ptrArray8();
    data.UpdateFrom(dstData);
    var linesize = new int_array8();
    linesize.UpdateFrom(dstLinesize);
    
    f->data = data;
    f->linesize = linesize;
    f->width = sourceFrame->width;
    f->height = sourceFrame->height;
    f->format = (int)targePixelFormat;
    
    return f;
    

    之后,将缩放后的帧发送到编码器,接收并写入文件。之后我打电话 av_frame_free(&frame) 在从该方法返回的帧上。但是当我设置断点时,即使在调用后,我也可以看到帧的地址是相同的 av_frame_alloc() 每次都要清洁。我认为这就是内存泄漏的原因。如果我这样做 深拷贝 f 在归还之前,一切都很好。为什么同样的逻辑在另一台相机上运行良好时会发生这种情况?

    0 回复  |  直到 5 年前
        1
  •  2
  •   Expressingx    5 年前

    好吧,在浪费了3天时间试图弄清楚为什么只在某些相机上会发生这种情况之后,我用 调试诊断2 使用内存泄漏跟踪器。事实证明,到 _aligned_offset_malloc 如下图所示。我使用的是ffmpeg 4.2.2,降级到 4.0.2 帮我解决了这个问题。现在没有内存泄漏。我在用 32位 版本。

    enter image description here