首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >VTDecompressionSession - IOSurface拨款逐步增加

VTDecompressionSession - IOSurface拨款逐步增加
EN

Stack Overflow用户
提问于 2019-02-18 08:40:10
回答 1查看 453关注 0票数 1

我正在使用VTDecompressionSession来解码.h264流。解码器正常工作,我得到了正确的解码缓冲区。然而,我看到XCode工具“分配”中的“创建和持续”分配逐渐增加。如屏幕截图所示,这可以归因于解码器内部分配的IOSurface缓冲区,即使在释放VTDecompressionSession之后,这些缓冲区也不会被释放。我在同步解码和异步回调decompressionSessionDecodeFrameCallback中都看到了这种情况。剩馀帧数在发生时间上是随机的。这些缓冲区的大小与解码帧的大小完全相等。在使解码器会话无效之前,我确实调用了,但是这些分配不会消失。有办法在解码器会话结束时释放这些IOSurface缓冲区吗?

这是我的解码器运行的大纲。创建解码器会话

代码语言:javascript
复制
const void *values[] = { CFNumberCreate(NULL, kCFNumberSInt32Type, &v) };       
attrs                = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);


VTDecompressionOutputCallbackRecord callBackRecord;
callBackRecord.decompressionOutputCallback = decompressionSessionDecodeFrameCallback;
callBackRecord.decompressionOutputRefCon = (__bridge void *)self;
VTDecompressionSessionCreate(kCFAllocatorDefault,
                                          _decoderFormatDescription,
                                          NULL,   
                                          attrs,
                                          &callBackRecord,
                                          &_decoderSession);

当NALU分组准备就绪时,调用执行解码

代码语言:javascript
复制
CMSampleBufferRef sampleBuffer = nil;
const size_t sampleSizeArray[] = {packetLen};    
CMSampleTimingInfo sampleTimeinfo ={CMTimeMake(1,FPS), CMTimeMake(presentationTS, 1000000), kCMTimeInvalid};
CMSampleBufferCreateReady(kCFAllocatorDefault, blockBuffer, _decoderFormatDescription ,
                                       1, 1, &sampleTimeinfo, 1, sampleSizeArray, &sampleBuffer);
flags = kVTDecodeFrame_EnableAsynchronousDecompression;

VTDecompressionSessionDecodeFrame(_decoderSession,
                                          sampleBuffer,
                                          flags,
                                          &sampleBuffer,
                                          &flagOut);

回调

代码语言:javascript
复制
void decompressionSessionDecodeFrameCallback{

    CVPixelBufferLockBaseAddress(imageBuffer,0);
    .... 
    send to display
    ....
    CVPixelBufferUnlockBaseAddress(imageBuffer,0);
}

结束解码器会话

代码语言:javascript
复制
VTDecompressionSessionWaitForAsynchronousFrames(_decoderSession);
VTDecompressionSessionInvalidate(_decoderSession);
CFRelease(_decoderSession);

EN

回答 1

Stack Overflow用户

发布于 2020-05-09 01:39:32

这是不正常的,您的代码中肯定有漏洞。

这并不是释放decompressionSession的问题,这样的内存泄漏是不同的,在关闭和打开流时会变得很明显。

我注意到您在调用中将sampleBuffer引用为sourceFrameRefCon:

代码语言:javascript
复制
VTDecompressionSessionDecodeFrame(_decoderSession,
                                          sampleBuffer,
                                          flags,
                                          &sampleBuffer, //here
                                          &flagOut);

这是错误的,除非您希望在那里提供一个指针以便能够引用框架本身(而不是缓冲区),否则将此值保留为NULL。这很可能是你的问题。

由于我们只能看到您代码的一部分,所以我将指出其他问题通常会发生在哪里。

如果你打过电话:

代码语言:javascript
复制
CVBufferRetain(imageBuffer);

代码语言:javascript
复制
CFRetain(imageBuffer);

那么,您还必须调用:

代码语言:javascript
复制
CVBufferRelease(imageBuffer);

代码语言:javascript
复制
CFRelease(imageBuffer);

之后,分别。

请确保接收缓冲区的播放机不会以任何方式保留缓冲区,在接收缓冲区时,它应该立即将缓冲区复制到自己的缓冲区,不管是什么(除非您使用金属缓冲区直接将缓冲区提供给显示机制,在这种情况下,您应该在显示后释放缓冲区)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54743266

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档