AVCaptureSession和相机线程没有关闭[iOS]

AVCaptureSession和相机线程没有关闭[iOS],第1张

概述问题 当我停止运行AVCaptureSession时,我的AVCaptureSession期间创建的线程不会关闭. 症状 通常我的dispatch_queue会立即开始从相机获取帧.但是打开和关闭打开/关闭AVCaptureSession的ViewController大约四次后,dispatch_queue大约需要十秒钟才能启动. 预测 似乎与AVCaptureSession关联的线程未清除. 关 问题
当我停止运行AVCaptureSession时,我的AVCaptureSession期间创建的线程不会关闭.

症状
通常我的dispatch_queue会立即开始从相机获取帧.但是打开和关闭打开/关闭AVCaptureSession的VIEwController大约四次后,dispatch_queue大约需要十秒钟才能启动.

预测
似乎与AVCaptureSession关联的线程未清除.

关闭AVCaptureSession后,我看到这些线程仍然存在:

com.apple.coremedia.capturesource.connections(serial) 1 Pending Blockcom.apple.coremedia.capturesession.connections(serial) 1 Pending Block<AVCMNotificationdispatcher: 0x16bce00> serial queue(serial) 4 Pending Blockscom.apple.avfoundation.vIDeocapturedevice.observed_propertIEs_queue(serial)com.apple.tcc.cache_queue(serial) 1 Pending Blockcom.apple.tcc.preflight.kTCCServiceCamera(serial) 1 Pending Block

在我使用AVCaptureSession打开/关闭VIEwController之后,仍保留相同的线程,但是这三个线程的Pending块数量增加了

<AVCMNotificationdispatcher: 0x17c441a0> serial queue (serial) 9 Pending Blockscom.apple.avfoundation.vIDeocapturedevice.observed_propertIEs_queue(serial)com.apple.tcc.preflight.kTCCServiceCamera(serial)  5 Pending Blocks

代码设置

VIDeoSource.h和VIDeoSource.mm

在我的VIEwController中,我将它初始化为:

self.vIDeoSource = [[VIDeoSource alloc] init];self.vIDeoSource.delegate = self;[self.vIDeoSource setResolution:AVCaptureSessionPreset352x288]; // was 640[self.vIDeoSource startWithDeviceposition:AVCaptureDevicepositionFront];

我开始和停止captureSession如下,它开始和停止非常好.实际的帧抓取效果非常好.

[self.vIDeoSource.captureSession startRunning];    [self.vIDeoSource.captureSession stopRunning];

VIDeoSource的相关部分,如果您需要了解更多,请告诉我.

来自VIDeoSource.mm

- (voID)dealloc {NSLog(@"Cleaning Up VIDeo Source");[_captureSession stopRunning];AVCaptureinput* input = [_captureSession.inputs objectAtIndex:0];[_captureSession removeinput:input];input = nil;AVCaptureVIDeoDataOutput* output = (AVCaptureVIDeoDataOutput*)[_captureSession.outputs objectAtIndex:0];[_captureSession removeOutput:output];output = nil;_captureSession = nil;_deviceinput = nil;_delegate = nil;//  [super dealloc]; // compiler handles this for you with ARC}- (voID) addVIDeoDataOutput {// (1) Instantiate a new vIDeo data output objectAVCaptureVIDeoDataOutput * captureOutput = [[AVCaptureVIDeoDataOutput alloc] init ];//    captureOutput.alwaysdiscardsLateVIDeoFrames = YES;NSLog(@"Create dispatch Queue");// (2) The sample buffer delegate requires a serial dispatch queuedispatch_queue_t queue;queue = dispatch_queue_create("com.name.test",disPATCH_QUEUE_SERIAL);[captureOutput setSampleBufferDelegate:self queue:queue];//    dispatch_release(queue); // compiler handles this for you with ARC// (3) define the pixel format for the vIDeo data outputNsstring * key = (Nsstring*)kCVPixelBufferPixelFormatTypeKey;NSNumber * value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA];NSDictionary * settings = @{key:value};NSLog(@"Set VIDeo Settings");[captureOutput setVIDeoSettings:settings];NSLog(@"Always discard Late VIDeo Frames");[captureOutput setAlwaysdiscardsLateVIDeoFrames:YES];// (4) Configure the output port on the captureSession property[self.captureSession addOutput:captureOutput];}

来自VIDeoSource.h

@interface VIDeoSource : NSObject@property (nonatomic,strong) AVCaptureSession * captureSession;  @property (nonatomic,strong) AVCaptureDeviceinput * deviceinput;@property (nonatomic,weak) ID<VIDeoSourceDelegate> delegate;- (BOol)startWithDeviceposition:(AVCaptureDeviceposition)deviceposition;- (voID) setResolution:(Nsstring*)resolution;@end

请求

当我取消分配VIDeoSource时,如何确保这些线程关闭?

解决方法 解决了!

解决方案:从与用于captureOutput的SampleBuffer队列相同的dispatch_queue调用startRunning和stopRunning.

这是我的新设置:

#import "VIDeoSource.h"@interface VIDeoSource () <AVCaptureVIDeoDataOutputSampleBufferDelegate>// Session management.@property (nonatomic) dispatch_queue_t sessionQueue;@property (nonatomic) AVCaptureSession *captureSession;@property (nonatomic) AVCaptureDeviceinput *deviceinput;/*@property (nonatomic,strong) AVCaptureSession * captureSession;@property (nonatomic,strong) AVCaptureDeviceinput * deviceinput; */@end@implementation VIDeoSource-(ID) init{    if(self = [super init]){        self.captureSession = [[AVCaptureSession alloc] init];        self.sessionQueue = dispatch_queue_create( "session queue",disPATCH_QUEUE_SERIAL );    }    return self;}

然后为setSampleBufferDelegate队列使用相同的sessionQueue.

[captureOutput setSampleBufferDelegate:self queue:self.sessionQueue];

现在,对于最重要的部分,请确保从SAME队列中调用startRunning / stopRunning:

dispatch_async( self.sessionQueue,^{    [self.captureSession startRunning];});

同样,您可以创建一个很好的小函数来清理并停止captureSession:

-(voID)closeCaptureSession {     dispatch_async(self.sessionQueue,^{         if([_captureSession isRunning])[_captureSession stopRunning];         [_captureSession stopRunning];         // Remove all inputs         for(AVCaptureinput *input1 in _captureSession.inputs) {             [_captureSession removeinput:input1];         }         // Remove all outputs         for(AVCaptureVIDeoDataOutput *output1 in _captureSession.outputs) {             [output1 setSampleBufferDelegate:nil queue:NulL];             [_captureSession removeOutput:output1];         }         // Set to Nil to make ARC's job a little easIEr         self.captureSession = nil;         self.deviceinput = nil;         self.delegate = nil;         self.sessionQueue=nil;     });}
总结

以上是内存溢出为你收集整理的AVCaptureSession和相机线程没有关闭[iOS]全部内容,希望文章能够帮你解决AVCaptureSession和相机线程没有关闭[iOS]所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1048074.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存