私はあなたとほぼ同じことをする必要がありましたが、FireWire カメラからの連続ビデオ表示だけが必要でした。私の場合、libdc1394 ライブラリを使用して、FireWire カメラのフレーム キャプチャとカメラ プロパティの調整を実行しました。一部の Carbon Quicktime 関数を使用してこれを行うこともできますが、libdc1394 の方が少し理解しやすいことがわかりました。
ビデオ キャプチャ ループについては、カメラをポーリングして共有リソースをロックする別のスレッドから、カメラとの対話に 1 つの 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 に追加できれば、私はこのほとんどすべてを削除できます。