Cod*_*odo 31 iphone camera multithreading avfoundation ios
我正在使用AV Foundation类从相机捕获实时视频流并处理视频样本.这很好用.但是,一旦完成,我确实无法正确释放AV基础实例(捕获会话,预览层,输入和输出).
当我不再需要会话和所有关联对象时,我会停止捕获会话并释放它.这大部分时间都有效.但是,有时应用程序崩溃时会在调度队列(以及处理视频样本的位置)创建的第二个线程中引发EXEC_BAD_ACCESS信号.崩溃主要是由于我自己的类实例,它作为样本缓冲区委托,并在我停止捕获会话后被释放.
Apple文档提到了问题:停止捕获会话是一种异步操作.那就是:它不会立即发生.特别是,第二个线程继续处理视频样本并访问不同的实例,如捕获会话或输入和输出设备.
那么如何正确释放AVCaptureSession和所有相关实例呢?是否有通知可靠地告诉我AVCaptureSession已完成?
这是我的代码:
声明:
AVCaptureSession* session;
AVCaptureVideoPreviewLayer* previewLayer;
UIView* view;
Run Code Online (Sandbox Code Playgroud)
实例设置:
AVCaptureDevice* camera = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];
session = [[AVCaptureSession alloc] init];
AVCaptureDeviceInput* input = [AVCaptureDeviceInput deviceInputWithDevice: camera error: &error];
[session addInput: input];
AVCaptureVideoDataOutput* output = [[[AVCaptureVideoDataOutput alloc] init] autorelease];
[session addOutput: output];
dispatch_queue_t queue = dispatch_queue_create("augm_reality", NULL);
[output setSampleBufferDelegate: self queue: queue];
dispatch_release(queue);
previewLayer = [[AVCaptureVideoPreviewLayer layerWithSession: session] retain];
previewLayer.frame = view.bounds;
[view.layer addSublayer: previewLayer];
[session startRunning];
Run Code Online (Sandbox Code Playgroud)
清理:
[previewLayer removeFromSuperlayer];
[previewLayer release];
[session stopRunning];
[session release];
Run Code Online (Sandbox Code Playgroud)
Cod*_*odo 18
这是迄今为止我发现的最佳解决方案.基本思想是使用调度队列的终结器.当调度队列退出时,我们可以确定在处理样本缓冲区的第二个线程中不会再有任何操作.
static void capture_cleanup(void* p)
{
AugmReality* ar = (AugmReality *)p; // cast to original context instance
[ar release]; // releases capture session if dealloc is called
}
...
dispatch_queue_t queue = dispatch_queue_create("augm_reality", NULL);
dispatch_set_context(queue, self);
dispatch_set_finalizer_f(queue, capture_cleanup);
[output setSampleBufferDelegate: self queue: queue];
dispatch_release(queue);
[self retain];
...
Run Code Online (Sandbox Code Playgroud)
不幸的是,我现在必须明确停止捕获.否则释放我的实例将不会释放它,因为第二个线程现在递增并递减计数器.
另一个问题是我的类现在从两个不同的线程中释放.这是可靠的还是导致崩溃的下一个问题?
| 归档时间: |
|
| 查看次数: |
27831 次 |
| 最近记录: |