gpt4 book ai didi

iphone - AVCaptureDeviceOutput 不调用委托(delegate)方法 captureOutput

转载 作者:行者123 更新时间:2023-12-03 18:23:44 24 4
gpt4 key购买 nike

我正在构建一个 iOS 应用程序(我的第一个),它可以动态处理视频静止帧。为了深入研究这个问题,我遵循了example from the AV* documentation来自苹果公司。

该过程涉及设置输入(相机)和输出。输出与委托(delegate)一起工作,在本例中是 Controller 本身(它符合并实现所需的方法)。

我遇到的问题是委托(delegate)方法永远不会被调用。下面的代码是 Controller 的实现,它有几个 NSLog。我可以看到“已启动”消息,但“调用的委托(delegate)方法”从未显示。

此代码全部位于实现“AVCaptureVideoDataOutputSampleBufferDelegate”协议(protocol)的 Controller 内。

- (void)viewDidLoad {

[super viewDidLoad];

// Initialize AV session
AVCaptureSession *session = [AVCaptureSession new];

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
[session setSessionPreset:AVCaptureSessionPreset640x480];
else
[session setSessionPreset:AVCaptureSessionPresetPhoto];

// Initialize back camera input
AVCaptureDevice *camera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

NSError *error = nil;

AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:camera error:&error];

if( [session canAddInput:input] ){
[session addInput:input];
}


// Initialize image output
AVCaptureVideoDataOutput *output = [AVCaptureVideoDataOutput new];

NSDictionary *rgbOutputSettings = [NSDictionary dictionaryWithObject:
[NSNumber numberWithInt:kCMPixelFormat_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey];
[output setVideoSettings:rgbOutputSettings];
[output setAlwaysDiscardsLateVideoFrames:YES]; // discard if the data output queue is blocked (as we process the still image)


//[output addObserver:self forKeyPath:@"capturingStillImage" options:NSKeyValueObservingOptionNew context:@"AVCaptureStillImageIsCapturingStillImageContext"];

videoDataOutputQueue = dispatch_queue_create("VideoDataOutputQueue", DISPATCH_QUEUE_SERIAL);
[output setSampleBufferDelegate:self queue:videoDataOutputQueue];


if( [session canAddOutput:output] ){
[session addOutput:output];
}

[[output connectionWithMediaType:AVMediaTypeVideo] setEnabled:YES];


[session startRunning];

NSLog(@"started");


}


- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {

NSLog(@"delegate method called");

CGImageRef cgImage = [self imageFromSampleBuffer:sampleBuffer];

self.theImage.image = [UIImage imageWithCGImage: cgImage ];

CGImageRelease( cgImage );

}

注意:我正在以 iOS 5.0 作为目标进行构建。

编辑:

我找到了 question尽管要求解决不同问题,但正是在做我的代码应该做的事情。我已将该问题的代码逐字复制到一个空白的 xcode 应用程序中,将 NSLogs 添加到 captureOutput 函数中,但它没有被调用。这是配置问题吗?我有什么遗漏的吗?

最佳答案

您的 session 是一个局部变量。它的范围仅限于viewDidLoad。由于这是一个新项目,我认为可以肯定地说您正在使用 ARC。在这种情况下,该对象不会泄漏,因此会像在链接问题中那样继续存在,而编译器将确保在 viewDidLoad 退出之前释放该对象。

因此您的 session 未运行,因为它不再存在。

(旁白:self.theImage.image = ... 是不安全的,因为它执行主队列的 UIKit 操作;您可能想要 dispatch_asyncdispatch_get_main_queue())

因此,示例更正:

@implementation YourViewController
{
AVCaptureSession *session;
}

- (void)viewDidLoad {

[super viewDidLoad];

// Initialize AV session
session = [AVCaptureSession new];

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
[session setSessionPreset:AVCaptureSessionPreset640x480];
else
/* ... etc ... */
}


- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {

NSLog(@"delegate method called");

CGImageRef cgImage = [self imageFromSampleBuffer:sampleBuffer];

dispatch_sync(dispatch_get_main_queue(),
^{
self.theImage.image = [UIImage imageWithCGImage: cgImage ];
CGImageRelease( cgImage );
});
}

现在大多数人提倡在实例变量名称的开头使用下划线,但为了简单起见我省略了它。在验证诊断正确后,您可以使用 Xcode 的内置重构工具来修复该问题。

我将 CGImageRelease 移动到发送到主队列的 block 内,以确保其生命周期超出其捕获到 UIImage 的范围。我无法立即找到任何文档来确认 CoreFoundation 对象在 block 中捕获时其生命周期会自动延长。

关于iphone - AVCaptureDeviceOutput 不调用委托(delegate)方法 captureOutput,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13508171/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com