You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Sink Writer录制WMV时内存过高及文件合并问题咨询

关于Sink Writer录制WMV内存泄漏与分段录制合并的解决方案

问题1:录制过程中刷新Sink Writer释放内存

内存飙升的核心原因多为未及时释放媒体样本/缓冲区,或Sink Writer缓存未被强制写入磁盘。以下是针对性解决步骤:

  • 强制写入磁盘并清空缓存:每写入若干帧(例如每5帧,对应1秒时长)后,调用IMFSinkWriter::Flush方法,指定目标流索引(通常视频流为0,或用MF_SINK_WRITER_ALL_STREAMS处理所有流)。该操作会强制将缓存数据写入文件并释放内存,示例代码:
    HRESULT hr = pSinkWriter->Flush(MF_SINK_WRITER_ALL_STREAMS);
    if (FAILED(hr)) {
        // 处理错误逻辑
    }
    
  • 确保媒体样本及时释放:每次调用IMFSinkWriter::WriteSample完成帧写入后,必须调用IMFSample::Release()释放样本对象,同时确保关联的IMFMediaBuffer也被正确释放——这是多数内存泄漏案例的根源。
  • 限制缓存时长:通过设置MF_SINK_WRITER_MAX_BUFFER_DURATION属性,限制Sink Writer的最大缓存时长(例如设为1秒,单位为100纳秒),让系统自动触发写入,避免缓存无限增长:
    PROPVARIANT var;
    PropVariantInit(&var);
    var.vt = VT_I8;
    var.hVal.QuadPart = 10000000; // 1秒
    HRESULT hr = pSinkWriter->SetProperty(MF_SINK_WRITER_MAX_BUFFER_DURATION, var);
    PropVariantClear(&var);
    

问题2:分段录制与WMV文件合并

分段录制实现

完全支持每10分钟生成一个独立WMV文件,实现步骤如下:

  1. 计算分段触发条件:按5FPS计算,10分钟对应3000帧;或通过系统时间戳判断录制时长。
  2. 达到分段条件时:
    • 调用IMFSinkWriter::Finalize完成当前文件写入,随后调用Release()释放当前Sink Writer实例。
    • 复用之前的媒体类型参数(分辨率、帧率、码率、编码格式必须完全一致),重新创建Sink Writer并指定新的输出文件名,继续录制流程。

WMV文件合并

WMV基于ASF容器,直接拼接文件会导致播放异常,需保证所有分段编码参数完全一致后,通过以下方式合并:

方式1:命令行工具(推荐)

使用FFmpeg工具完成合并,无需编写代码:

  • 直接拼接命令:
    ffmpeg -i "concat:segment1.wmv|segment2.wmv|segment3.wmv" -c copy merged.wmv
    
  • 若遇到格式检测问题,先创建文件列表filelist.txt:
    file 'segment1.wmv'
    file 'segment2.wmv'
    file 'segment3.wmv'
    
    再执行:
    ffmpeg -f concat -safe 0 -i filelist.txt -c copy merged.wmv
    

方式2:Media Foundation编程实现

通过Media Foundation读取分段流并写入合并文件:

  1. 为每个分段创建IMFSourceReader,验证所有分段的媒体类型参数一致。
  2. 创建新的IMFSinkWriter,设置与分段相同的输出媒体类型。
  3. 依次读取每个分段的媒体样本,调用IMFSinkWriter::WriteSample写入合并文件。
  4. 所有分段读取完成后,调用Finalize完成写入。

内容的提问来源于stack exchange,提问作者Drewski7280

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 02:01:17