コールバック関数を使用する
ここではコールバック関数を使用して画像処理をするために、 FrameQueueSinkListenerクラスライブラリリファレンス>クラス>FrameQueueSinkListenerをFrameQueueSinkクラスライブラリリファレンス>クラス>FrameQueueSinkで使用する方法を示します。
このプログラムはディレクトリ%TOPLEVEL%\Samples\VC\Callbackにあります。
プログラムを実行するには、 ソリューションファイルCallback.slnを開きメニューからビルド -> ビルド Callbackと選択します。
そこからデバッグ -> スタートと選択することでプログラムを実行することができます。
概要
この例ではsetupDeviceFromFileという関数を使用します。ソースコードは%TOPLEVEL%\Samples\VC\Common\CmdHelper.h内にあります。この関数はユーザーにデバイス、ビデオ規格、ビデオフォーマット、入力チャンネルの選択を求めるものです。選択された設定は保存できるため、プログラムを実行するたびに選択をする必要はありません。
次のコードはキャプチャされた画像を毎回受け取るためにCallbackを取得よう、FrameQueueSinkクラスライブラリリファレンス>クラス>FrameQueueSinkを設定する方法を示しています。
sink_listener listener_instance;
// 利用可能なカラーフォーマットを表すFrameTypeInfoArray構造体を作成
FrameTypeInfoArray acceptedTypes = FrameTypeInfoArray::createRGBArray();
// Frame Sinkを作成
tFrameQueueSinkPtr pSink = FrameQueueSink::create( listener_instance, acceptedTypes );
// sinkをgrabberに適用
grabber.setSinkType( pSink );
プログラムはFrameQueueSinkListenerから、sink_listenerとされるクラスを派生しています。
Sinkの入力キュー用のバッファ数を指定するために、FrameQueueSink::allocAndQueueBuffersクラスライブラリリファレンス>クラス>FrameQueueSink>FrameQueueSink::allocAndQueueBuffers Methodを使用します。
virtual void sink Connected( FrameQueueSink& sink, const FrameTypeInfo& frameType )
{
UNREFERENCED_PARAMETER( frameType );
sink.allocAndQueueBuffers( 10 );
}
FrameQueueSinkListener::frameQueuedクラスライブラリリファレンス>クラス>FrameQueueSinkListener>FrameQueueSinkListener::framesQueued Methodの中で、 FrameQueueSink::popOutputQueueBufferクラスライブラリリファレンス>クラス>FrameQueueSink>FrameQueueSink::popOutputQueueBuffer Methodをコールすることで最も古いバッファから取得されていきます。
このバッファはsaveImageメソッドによりBMPファイルに保存されます。
// イメージをストレージに保存するために、saveImageメソッドをコールします。
virtual void framesQueued( FrameQueueSink& sink )
{
tFrameQueueBufferPtr buffer = sink.popOutputQueueBuffer();
unsigned int frame number = buffer->getFrameMetaData() .mediaSampleDesc.FrameNumber;
std::cout << "Buffer " << frame_number << " processed in sink_listener::framesQueued()." << std::endl;
saveImage( buffer, frame_number );
Sleep( 250 );
}
この例では、高負荷な処理をシミュレートするためにSleep( 250 )を入れています。この場合も連続したフレームが Sinkの出力キューに蓄積され、逐次処理することができます。
全ての入力バッファが満たされると、main()関数内で、イメージの取得を終了します。Sleep( 100 )は、処理遅延があった場合をシミュレートしています。この後で残ったバッファを処理します。
grabber.startLive();
// 設定したSinkのキューバッファ(先ほど10フレームを設定した)がいっぱいになるまで待ちます。
while( pSink->getInputQueueSize() != 0 )
{
Sleep( 100 );
}
grabber.stopLive();
FrameQueueSink::popAllOutputQueueBuffersクラスライブラリリファレンス>クラス>FrameQueueSink>FrameQueueSink::popAllOutputQueueBuffers Methodを使って、まだframesQueuedでコールされていない全てのバッファを、保存します。
// まだCListener::frameReady()がコールされていないバッファを保存します
tFrameQueueBufferList remaining_buffers = pSink->popAllOutputQueueBuffers();
for( size_t i = 0; i < remaining_buffers.size(); i++ )
{
unsigned int frame_number = remaining_buffers[i]->getFrameMetaData() .mediaSampleDesc.FrameNumber;
std::cout << "Buffer " << frame_number << " processed in main()." << std::endl;
listener_instance.saveImage( remaining_buffers[i], frame_number );
}