- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
AVAssetWriterInput appendSampleBuffer
我有一个奇怪的内存“泄漏”。我同时编写视频和音频,所以我有一个带有两个输入的 AVAssetWriter
,一个用于视频,一个用于音频:
self.videoWriter = [[[AVAssetWriter alloc] initWithURL:[self.currentVideo currentVideoClipLocalURL]
fileType:AVFileTypeMPEG4
error:&error] autorelease];
...
self.videoWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo
outputSettings:videoSettings];
self.videoWriterInput.expectsMediaDataInRealTime = YES;
[self.videoWriter addInput:self.videoWriterInput];
...
self.audioWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio
outputSettings:audioSettings];
self.audioWriterInput.expectsMediaDataInRealTime = YES;
[self.videoWriter addInput:self.audioWriterInput];
我开始写作,表面上一切正常。视频和音频被写入并对齐等。但是,我将我的代码放入分配工具并注意到以下内容:
音频字节会保留在内存中,稍后我会证明这一点。这就是内存中的斜坡。音频字节仅在我调用 [self.videoWriter endSessionAtSourceTime:...]
后释放,您将其视为内存使用量的急剧下降。这是我的音频编写代码,它作为一个 block 被分派(dispatch)到一个串行队列中:
@autoreleasepool
{
// The objects that will hold the audio data
CMSampleBufferRef sampleBuffer;
CMBlockBufferRef blockBuffer1;
CMBlockBufferRef blockBuffer2;
size_t nbytes = numSamples * asbd_.mBytesPerPacket;
OSStatus status = noErr;
status = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault,
data,
nbytes,
kCFAllocatorNull,
NULL,
0,
nbytes,
kCMBlockBufferAssureMemoryNowFlag,
&blockBuffer1);
if (status != noErr)
{
NLog(@"CMBlockBufferCreateWithMemoryBlock error at buffer 1");
return;
}
status = CMBlockBufferCreateContiguous(kCFAllocatorDefault,
blockBuffer1,
kCFAllocatorDefault,
NULL,
0,
nbytes,
kCMBlockBufferAssureMemoryNowFlag | kCMBlockBufferAlwaysCopyDataFlag,
&blockBuffer2);
if (status != noErr)
{
NSLog(@"CMBlockBufferCreateWithMemoryBlock error at buffer 2");
CFRelease(blockBuffer1);
return;
}
// Finally, create the CMSampleBufferRef
status = CMAudioSampleBufferCreateWithPacketDescriptions(kCFAllocatorDefault,
blockBuffer2,
YES, // Yes data is ready
NULL, // No callback needed to make data ready
NULL,
audioFormatDescription_,
1,
timestamp,
NULL,
&sampleBuffer);
if (status != noErr)
{
NSLog(@"CMAudioSampleBufferCreateWithPacketDescriptions error.");
CFRelease(blockBuffer1);
CFRelease(blockBuffer2);
return;
}
if ([self.audioWriterInput isReadyForMoreMediaData])
{
if (![self.audioWriterInput appendSampleBuffer:sampleBuffer])
{
NSLog(@"Couldn't append audio sample buffer: %d", numAudioCallbacks_);
}
} else {
NSLog(@"AudioWriterInput isn't ready for more data.");
}
// One release per create
CFRelease(blockBuffer1);
CFRelease(blockBuffer2);
CFRelease(sampleBuffer);
}
如您所见,我在每次创建时释放每个缓冲区一次。我已将“泄漏”追踪到附加音频缓冲区的行:
[self.audioWriterInput appendSampleBuffer:sampleBuffer]
我通过注释掉该行向自己证明了这一点,之后我得到了以下“无泄漏”分配图(当然,尽管录制的视频现在没有音频):
我尝试了另一件事,即添加回 appendSamplebuffer
行,而不是双释放 blockBuffer2
:
CFRelease(blockBuffer1);
CFRelease(blockBuffer2);
CFRelease(blockBuffer2); // Double release to test the hypothesis that appendSamplebuffer is retaining this
CFRelease(sampleBuffer);
这样做不会导致双重释放,表明 blockBuffer2
在该点的保留计数为 2。这产生了相同的“无泄漏”分配图,除了当我调用 [self.videoWriter endSessionAtSourceTime:...]
时,我从双重释放中崩溃(表明 self .videoWriter
正在尝试释放它所有指向已传入的 blockBuffer2
的指针。
如果相反,我会尝试以下操作:
CFRelease(blockBuffer1);
CFRelease(blockBuffer2);
CMSampleBufferInvalidate(sampleBuffer); // Invalidate sample buffer
CFRelease(sampleBuffer);
然后 [self.audioWriterInput appendSampleBuffer:sampleBuffer]
和此后每次调用附加视频帧的调用开始失败。
所以我的结论是 AVAssetWriter
或 AVAssetWriterInput
保留 blockBuffer2
直到视频完成录制。显然,如果视频录制时间足够长,这可能会导致真正的内存问题。我做错了什么吗?
编辑:我得到的音频字节是 PCM 格式,而我正在编写的视频格式是 MPEG4,该视频的音频格式是 MPEG4AAC。视频编写者是否可能正在执行 PCM --> AAC 格式,这就是它被缓冲的原因?
最佳答案
由于您已经等了一个月才得到答案,所以我会给您一个不太理想但可行的答案。
您可以使用 ExtendedAudioFile 函数编写单独的文件。然后,您可以将视频和音频与 AVComposition 一起播放。我认为如果您需要在录制结束时合成 caf 和视频,您可以使用 AVFoundation 将它们合成在一起而无需重新编码。
这会让你开始运行,然后你可以在闲暇时解决内存泄漏问题。
关于ios - 带有音频 AVAssetWriterInput "leaks"内存的 appendSampleBuffer 直到 endSessionAtSourceTime,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14847466/
我的应用有时会抛出奇怪的日志,例如: :通知名称“com.apple.iapd.notify.extendedMode”已被注册 40 次 - 这可能是泄漏:通知名称“com.apple.iapd.n
我在 dotcloud 上使用 redis 内存存储,但尽管 key 已过期,但它的 used_memory 再也不会下降。从 redis-cli 使用 flushdb 或 flushall 不会导致
所以我一直在寻找这个问题的解决方案有一段时间了。我编写了一个程序来从两个单独的文本文件中获取数据,对其进行解析,然后输出到另一个文本文件和一个 ARFF 文件以供 Weka 分析。我遇到的问题是我编写
随着我继续学习 Rust,我正在从事一个涉及广泛使用谓词函数的项目。我决定用 Rust 闭包实现这些谓词,例如: type Predicate = Box bool> . 我的程序使用应用于这些谓词的
我的应用程序中有一个非常简单的 CUDA 组件。 Valgrind 报告了很多泄漏和仍然可以访问的问题,所有这些都与 cudaMalloc 调用有关。 这些泄漏是真的吗?我打电话cudaFree每 c
在 chrome latest 和其他浏览器中测试。此页面启动一个 timer() 每 60 秒刷新一次。在 init() 和每个 refresh() 上,它从服务器获取数据并在页面中显示相同的数据。
我正在尝试使用 pprof 来验证内存泄漏。 能否解释一下如何阅读您在以下位置找到的堆配置文件:http://localhost:6060/debug/pprof/heap?debug=1 此外,在启
我们遇到了由 GroovyShell/Groovy 脚本引起的内存泄漏(请参阅最后的 GroovyEvaluator 代码)。主要问题是(从 MAT 分析器复制粘贴): The class "java
我在 Ubuntu 中使用带有延迟长度字符变量的 gfortran 8.4,如下例所示: PROGRAM test IMPLICIT NONE CHARACTER(LEN=:),ALLOC
我正在阅读 Efficient Android Threading,上面写着 Instead of using nested classes with outer class references,
我们最近将我们的应用程序从 Java 7 迁移到 Java 8。从切换之日起,我们开始看到内存不足的元空间问题。我们尝试增加元空间空间大小,但没有帮助。 Jvisual VM(和 Jconsole)显
使用最新版本的 FFmpeg 读取图像文件时我遇到了内存泄漏,我无法追踪。 好像填完AVFrame与 avcodec_send_packet和 avcodec_receive_frame ,我调用av
我们有某种泄漏,我不明白其性质。 Gen0/1/2 堆的大小不会增加,但是工作集会增加,直到我们 OOM。 DebugDiag 告诉我 CLR.DLL 拥有不断增加的内存,并告诉我我们有一个不断增长的
一位系统管理员告诉 med,内存泄漏是不可见的。即,如果应用程序正在泄漏内存,则应用程序使用的所有内存可能在任务管理器或等效工具中不可见。 他似乎对此非常肯定。我一直认为在任务管理器(或进程资源管理器
我们正在自动化大多数可以自动化的已知问题(用于回归测试)。但是,我们确实通过第三方软件发现了内存泄漏。但是,我不知道如何自动执行我们发现并修复它们的内存泄漏测试。 有什么建议吗? 最佳答案 通常最好的
如果我有一个垃圾收集器来跟踪分配的每个对象并在它们不再具有对它们的可用引用时立即释放它们,您是否仍然存在内存泄漏? 考虑到内存泄漏是没有任何引用的分配不是不可能的还是我错过了什么? 编辑:所以我算作内
我有一个托管在 IIS 中的 WCF 应用程序(用 C#/.Net 4 编写)。随着时间的推移,进程的句柄计数或多或少以线性方式增加(在进程回收之前增加到 30,000)。根据 SysInternal
我从LeakSanitizer工具获得以下输出。正如工具所了解的那样,直接泄漏和间接泄漏有什么区别? 13: ==29107==ERROR: LeakSanitizer: detected memor
首先我是这样跑的: valgrind --leak-check=full --show-leak-kinds=all test_proc 和日志: ==30349== For counts of de
我知道每个进程都有操作系统分配的自己的地址空间。所以当程序终止时,整个地址空间都被标记为无效(或者可以再次自由重用)。现在,如果上述进程正在泄漏内存,那么在程序终止后会产生什么影响吗? 也就是说,如果
我是一名优秀的程序员,十分优秀!