AVCaptureOutput didOutputSampleBuffer 停止被调用
AVCaptureOutput didOutputSampleBuffer stops getting called
我对 AVCaptureOutput
的委托方法 didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
有疑问。
当我将 sampleBuffer 添加到 CFArray
时,它会在一两秒内停止调用。如果我删除 CFArray
代码,委托方法将继续被调用,所以我不知道为什么 CFArray
代码导致它停止。如果有任何帮助,我将不胜感激。
@property CFMutableArrayRef sampleBufferArray;
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
NSLog(@"Called");
if (!self.sampleBufferArray)
{
self.sampleBufferArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
CFArrayAppendValue(self.sampleBufferArray, sampleBuffer);
}
else
{
CFArrayAppendValue(self.sampleBufferArray, sampleBuffer);
}
}
控制台输出:
// Session start
2015-06-15 13:06:07.264 App[22467:5897858] Called
2015-06-15 13:06:07.286 App[22467:5897858] Called
2015-06-15 13:06:07.289 App[22467:5897858] Called
2015-06-15 13:06:07.315 App[22467:5897895] Called
2015-06-15 13:06:07.366 App[22467:5897895] Called
2015-06-15 13:06:07.384 App[22467:5897895] Called
2015-06-15 13:06:07.411 App[22467:5897895] Called
2015-06-15 13:06:07.449 App[22467:5897858] Called
2015-06-15 13:06:07.480 App[22467:5897858] Called
2015-06-15 13:06:07.513 App[22467:5897895] Called
2015-06-15 13:06:07.546 App[22467:5897895] Called
2015-06-15 13:06:07.579 App[22467:5897895] Called
2015-06-15 13:06:07.614 App[22467:5897895] Called
// No more calls after this point
你的问题其实在Docs里有提到,具体来说;
If your application is causing samples to be dropped by retaining the
provided CMSampleBufferRef objects for too long, but it needs access
to the sample data for a long period of time, consider copying the
data into a new buffer and then releasing the sample buffer (if it was
previously retained) so that the memory it references can be reused.
本质上,回调操作要尽量简单,回调中传给你的frame如果需要进一步处理,需要复制到新的buffer中进行处理在后台。另外,请记住,Core Foundation 对象必须显式保留和释放。
进一步考虑是内存压力。帧包含大量数据,保留太多会导致您的应用程序崩溃。
我在 Xamarin(C#) iOS 开发中遇到了类似的问题。在 Xamarin 中使用以下代码释放 CMSampleBuffer
if:
GC.Collect();
GC.WaitForPendingFinalizers();
我对 AVCaptureOutput
的委托方法 didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
有疑问。
当我将 sampleBuffer 添加到 CFArray
时,它会在一两秒内停止调用。如果我删除 CFArray
代码,委托方法将继续被调用,所以我不知道为什么 CFArray
代码导致它停止。如果有任何帮助,我将不胜感激。
@property CFMutableArrayRef sampleBufferArray;
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
NSLog(@"Called");
if (!self.sampleBufferArray)
{
self.sampleBufferArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
CFArrayAppendValue(self.sampleBufferArray, sampleBuffer);
}
else
{
CFArrayAppendValue(self.sampleBufferArray, sampleBuffer);
}
}
控制台输出:
// Session start
2015-06-15 13:06:07.264 App[22467:5897858] Called
2015-06-15 13:06:07.286 App[22467:5897858] Called
2015-06-15 13:06:07.289 App[22467:5897858] Called
2015-06-15 13:06:07.315 App[22467:5897895] Called
2015-06-15 13:06:07.366 App[22467:5897895] Called
2015-06-15 13:06:07.384 App[22467:5897895] Called
2015-06-15 13:06:07.411 App[22467:5897895] Called
2015-06-15 13:06:07.449 App[22467:5897858] Called
2015-06-15 13:06:07.480 App[22467:5897858] Called
2015-06-15 13:06:07.513 App[22467:5897895] Called
2015-06-15 13:06:07.546 App[22467:5897895] Called
2015-06-15 13:06:07.579 App[22467:5897895] Called
2015-06-15 13:06:07.614 App[22467:5897895] Called
// No more calls after this point
你的问题其实在Docs里有提到,具体来说;
If your application is causing samples to be dropped by retaining the provided CMSampleBufferRef objects for too long, but it needs access to the sample data for a long period of time, consider copying the data into a new buffer and then releasing the sample buffer (if it was previously retained) so that the memory it references can be reused.
本质上,回调操作要尽量简单,回调中传给你的frame如果需要进一步处理,需要复制到新的buffer中进行处理在后台。另外,请记住,Core Foundation 对象必须显式保留和释放。
进一步考虑是内存压力。帧包含大量数据,保留太多会导致您的应用程序崩溃。
我在 Xamarin(C#) iOS 开发中遇到了类似的问题。在 Xamarin 中使用以下代码释放 CMSampleBuffer
if:
GC.Collect();
GC.WaitForPendingFinalizers();