我正在尝试监控FireWire相机的视频输出流。我创建了一个带有按钮和NSImageView
的Interface Builder界面。虽然图像监控是在无限循环中发生的,但我想:
使用按钮功能,我无法循环播放视频帧显示器,同时仍然需要按下按钮(非常类似于使用C中的按键功能)。有两个选项可供选择:
NSOperation
- 如何以允许我连接Xcode按钮的方式执行此操作?文档对于创建此类对象非常迟钝。如果我根据我发现的示例创建NSOperation
,则似乎无法使用Interface Builder中的对象与其进行通信。当我创建NSRunLoop
时,我得到一个对象泄漏错误,我找不到如何创建实际响应我创建的RunLoop的自动释放池的示例。没关系,我甚至没有尝试选择哪个对象被二次运行循环采样......
因为目标C(显然!)不是我的母语,我正在寻找有婴儿步骤的解决方案,抱歉说... 提前致谢
答案 0 :(得分:2)
我需要与您完全一样,只需使用FireWire相机的连续视频显示。就我而言,我使用libdc1394 library为我们的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有一些extensions you can use使用DMA将这些帧作为纹理提供以获得更好的性能。
不幸的是,我在这里描述的并不是介绍性的东西。在我们的软件中,我有大约2,000行代码用于这些相机处理功能,这需要很长时间才能解决问题。如果Apple可以将手动相机设置调整添加到QTKit Capture API中,我几乎可以删除所有这些。
答案 1 :(得分:0)
如果您要做的只是查看/抓取已连接相机的输出,答案可能都不是。
使用QTKit's QTCaptureView。问题解决了。想要grab a frame?也没问题。不要试图自己动手 - QTKit的东西是优化的,是操作系统的一部分。我很确定你可以按照自己的意愿影响相机属性,但如果没有,那么B计划就可以了。
计划b:使用计划的,定期的NSTimer让QTKit每隔一段时间抓取一个框架(上面的“如何”链接)并将图像处理应用到框架中(可能使用Core Image)在显示在NSImageView中之前。