0

FireWire カメラからのビデオ出力のストリームを監視しようとしています。ボタンとNSImageView. 画像監視が無限ループ内で発生している間、次のことを行います。

  • その場でいくつかのカメラ パラメータを変更します (ゲイン、ガンマなど)。
  • 監視を停止するように指示して、画像をファイルに保存できるようにします (while ループを停止するフラグを設定します)。

ボタン機能を使用して、ビデオ フレーム モニターをループすることができませんでしたが、ボタンの押下をまだ探しています (C の keypressed 機能を使用するのと同じように)。2 つのオプションが表示されます。

  1. 新しい実行ループを開始します(autoreleasepoolを機能させることができません...)
  2. 開始NSOperation- Xcode ボタンを押して接続できるようにするにはどうすればよいですか?

ドキュメントは、そのようなオブジェクトの作成について非常に鈍いです。私が見つけた例に従ってを作成するNSOperationと、Interface Builder のオブジェクトと通信する方法がないようです。を作成するNSRunLoopと、オブジェクト リーク エラーが発生し、作成した RunLoop に実際に応答する autoreleasepool を作成する方法の例が見つかりません。セカンダリ実行ループでサンプリングされるオブジェクトを選択しようとさえしていないことを気にしないでください...

Objective C は (明らかに!) 私の母国語ではないため、申し訳ありませんが、赤ちゃんのステップで解決策を探しています ... よろしくお願いします

4

2 に答える 2

2

私はあなたとほぼ同じことをする必要がありましたが、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 に追加できれば、私はこのほとんどすべてを削除できます。

于 2011-03-15T21:36:11.370 に答える
0

接続されたカメラの出力を表示/取得することだけが目的の場合、答えはおそらくどちらでもありません。

QTKit の QTCaptureViewを使用します。問題が解決しました。フレームをつかみたいですか?また、問題ありません。独自のものを作成しようとしないでください。QTKit のものは最適化されており、OS の一部です。思い通りにカメラのプロパティに影響を与えることができると確信していますが、そうでない場合は、プラン B が機能するはずです。

計画b:スケジュールされた定期的なNSTimerを使用して、QTKitにフレームを頻繁に取得し(上記の「方法」リンク)、NSImageViewに表示する前に画像操作をフレームに適用します(おそらくCore Imageを使用)。

于 2011-03-15T19:55:28.170 に答える