0

我正在尝试监视 FireWire 摄像机的视频输出流。我创建了一个带有按钮的 Interface Builder 界面和一个NSImageView. 在无限循环中进行图像监视时,我想:

  • 动态更改一些相机参数(增益、伽马等)
  • 告诉监控停止,以便我可以将图像保存到文件中(设置一个停止 while 循环的标志)

使用按钮功能,我无法循环视频帧监视器,同时仍在寻找按钮按下(很像使用 C 中的按键功能。)出现两个选项:

  1. 启动一个新的运行循环(我无法让自动释放池运行......)
  2. 启动NSOperation- 我如何以允许我连接 Xcode 按钮的方式执行此操作?

该文档对于此类对象的创建非常迟钝。如果我根据我找到的示例创建一个NSOperation,似乎无法与 Interface Builder 中的对象进行通信。当我创建一个NSRunLoop,我得到一个对象泄漏错误,我找不到如何创建一个实际响应我创建的 RunLoop 的自动释放池的示例。没关系,我什至没有尝试选择辅助运行循环对哪些对象进行采样......

因为Objective C(显然!)不是我的母语,所以我正在寻找带有婴儿步骤的解决方案,抱歉......提前致谢

4

2 回答 2

2

我需要做的几乎和你一样,只是使用 FireWire 摄像头的连续视频显示。在我的例子中,我使用libdc1394 库为我们的 FireWire 相机执行帧捕获和相机属性调整。我知道你也可以使用一些 Carbon Quicktime 函数来做到这一点,但我发现 libdc1394 更容易理解。

对于视频捕获循环,我尝试了许多不同的方法,从轮询相机并锁定共享资源的单独线程,到使用一个 NSOperationQueue 与相机交互,最后决定使用 CVDisplayLink 轮询相机以与屏幕刷新率相匹配的方式。

CVDisplayLink 使用以下代码进行配置:

CGDirectDisplayID   displayID = CGMainDisplayID();  
CVReturn            error = kCVReturnSuccess;
error = CVDisplayLinkCreateWithCGDisplay(displayID, &displayLink);
if (error)
{
    NSLog(@"DisplayLink created with error:%d", error);
    displayLink = NULL;
}
CVDisplayLinkSetOutputCallback(displayLink, renderCallback, self);  

它调用以下函数来触发新相机帧的检索:

static CVReturn renderCallback(CVDisplayLinkRef displayLink, 
                               const CVTimeStamp *inNow, 
                               const CVTimeStamp *inOutputTime, 
                               CVOptionFlags flagsIn, 
                               CVOptionFlags *flagsOut, 
                               void *displayLinkContext)
{
    return [(SPVideoView *)displayLinkContext renderTime:inOutputTime];
}

CVDisplayLink 使用以下命令启动和停止:

- (void)startRequestingFrames;
{
    CVDisplayLinkStart(displayLink);    
}

- (void)stopRequestingFrames;
{
    CVDisplayLinkStop(displayLink);
}

每当我需要调整曝光、增益等时,我不会在 FireWire 相机通信上使用锁定,而是更改相应的实例变量并在标志变量中设置适当的位以指示要更改的设置。在下一次检索帧时,来自 CVDisplayLink 的回调方法会更改相机上的适当设置以匹配本地存储的实例变量并清除该标志。

通过 NSOpenGLView 处理屏幕显示(CAOpenGLLayer 在以这种速率更新时引入了太多的视觉伪影,并且它的更新回调在主线程上运行)。Apple 提供了一些扩展,您可以使用DMA 将这些帧作为纹理提供,以获得更好的性能。

不幸的是,我在这里描述的都不是入门级的东西。我在我们的软件中有大约 2,000 行用于这些相机处理功能的代码,这需要很长时间才能弄清楚。如果 Apple 可以将手动相机设置调整添加到 QTKit Capture API,我可以删除几乎所有这些。

于 2011-03-15T21:36:11.370 回答
0

如果您要做的只是查看/获取已连接相机的输出,那么答案可能两者都不是。

使用QTKit 的 QTCaptureView。问题解决了。想抢框架?也没有问题。不要试图自己动手——QTKit 的东西已经过优化并且是操作系统的一部分。我很确定您可以随心所欲地影响相机属性,但如果不能,那么计划 B 应该可以工作。

计划 b:使用计划的、重复的NSTimer要求 QTKit 每隔一段时间抓取一个帧(上面链接的“如何”)并将图像操作应用于帧(可能使用Core Image),然后再显示在您的 NSImageView 中。

于 2011-03-15T19:55:28.170 回答