2011-03-15 4 views
0

FireWire 카메라의 비디오 출력 스트림을 모니터하려고합니다. 버튼과 NSImageView이있는 Interface Builder 인터페이스를 만들었습니다.NSOperation 또는 NSRunLoop을 사용해야합니까?

  • 변화에 즉시 일부 카메라 파라미터 (등 이득, 감마)
  • 그렇게 중지 모니터링을 말해 나는에 이미지를 저장할 수 있습니다 이미지 모니터링이 무한 루프 내에서 발생하는 동안, 내가 원하는 파일 (while 루프를 멈추게하는 플래그 설정)

버튼 기능을 사용하면서 버튼 프레스를 찾고있는 동안 비디오 프레임 모니터를 루프 할 수 없었습니다 (C의 키 입력 기능을 사용하는 것과 같습니다).) 두 가지 옵션이 있습니다.

  1. 새로운 실행 루프를 시작하십시오 (기능을 수행하기 위해 자동 복구 풀을 가져올 수 없음 ...)
  2. NSOperation 시작 - Xcode 버튼 푸시로 연결할 수있는 방법으로 어떻게해야합니까?

설명서는 이러한 개체를 만드는 데 매우 애매한 도구입니다. 내가 찾은 예제에 따라 NSOperation을 만들면 인터페이스 빌더의 객체와 통신 할 수있는 방법이없는 것으로 보입니다. NSRunLoop을 만들면 객체 누수 오류가 발생하고 실제로 작성한 RunLoop에 응답하는 autoreleasepool을 만드는 방법에 대한 예제를 찾을 수 없습니다. 두 번째 실행 루프에 의해 샘플링되는 객체를 선택하려고 시도조차하지 않았다고 생각하지 마십시오 ...

Objective C는 (모르게!) 모국어가 아니기 때문에 아기 단계가있는 솔루션을 찾고 있습니다. 말하자면 ... 미리 감사드립니다.

답변

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은 더 나은 성능을 위해 DMA를 사용하여 이러한 프레임을 텍스처로 제공하는 일부 extensions you can use 있습니다.

불행히도 여기서 설명한 내용은 소개 수준의 내용이 아닙니다. 소프트웨어에서 이러한 카메라 처리 기능을 구현하는 데 필요한 약 2,000 줄의 코드가 있으며 이로 인해 많은 시간이 소요되었습니다. Apple이 수동 카메라 설정 조정을 QTKit Capture API에 추가 할 수 있다면 거의 모든 것을 제거 할 수있었습니다.

0

연결된 카메라의 출력을보고/잡는 것 뿐인데 그 대답은 아마도 아닙니다.

QTKit's QTCaptureView을 사용하십시오. 문제 해결됨. grab a frame으로 보내시겠습니까? 또한 문제 없습니다. QTKit의 기능은 최적화되어 있으며 OS의 일부입니다. 원하는대로 카메라 속성에 영향을 줄 수 있다고 확신하지만 그렇지 않은 경우 계획 B가 작동해야합니다.

플랜 B는 : 모든 너무 자주 프레임을 잡아 QTKit이 물어 NSTimer을 반복하는 스케줄 사용 (위에 링크 된 "어떻게")와 NSImageView에 표시하기 전에 (어쩌면 Core Image 포함) 프레임에 이미지 조작을 적용합니다.

+0

현재 QTKit 캡처 API를 통해 연결된 FireWire 카메라의 노출, 게인 등의 매개 변수를 변경할 수있는 방법이 없습니다 (중복 rdar : // 5760371 "QTKit 캡처의 카메라에 밝기, 게인 등을 설정할 수있는 기능 API "). –

+0

QTKit을 사용하여 "Cocoa is my Girlfriend"라는 다음 예제를 보았습니다 : [link] http://www.cimgf.com/2008/02/23/nsoperation-example/ 이것은 유망 해 보입니다. 나는 또한 libdc1394 항목을 사용하고 이미지를 캡처 한 것처럼 보입니다. 내가 사용할 수있는 형식으로 데이터에 액세스하는 데 문제가 있습니다. (부호없는 char에 대한 포인터를 14 비트 카메라의 16 비트 정수 배열로 변환하여 궁극적으로 Tiff 파일로 저장합니다 ...) –

+0

원한다면 절대 통제, 브래드의 방법은 건전한 접근이지만 QTKit이 갈 길이 멀다고 생각합니다. 이 작업을 수행하는 데 NSOperation을 사용하는 것이 좋지만 너무 빠르므로 별도의 스레드를 사용하지 않아도됩니다. –

관련 문제