Webカメラなどから撮影した動画を取り込んで××するんならWindowsなら今時はMedia Foundationでしょうか?いまだにDirectShowが便利なんでしょうか?
以前にDirectShowでフィルターを書いて色々実装しましたが、フィルターグラフの接続とかが面倒だったりしました。最近の私の場合はLinux(Ubuntu)なので、DirectShowのお世話になっていません。
以前Linuxでカメラでキャプチャした画像を××するのに実際に私が行ったのは、BlackMagicDesign社のビデオボードDecklink/Intensityシリーズにカメラを接続する形で行いました。BlackMagic Decklink/IntensityにはBlackmagic DeckLink SDKを利用してアクセスし、画像の生データを得ました。
BlackMagic Decklink/Intensityにカメラをさしても/dev/videoXが生えてくるわけじゃないので使えませんでしたが、今度はV4lです
※実際にはOpenCvでキャプチャ処理とかも書きましたが、これはOpenCv内部からv4lを呼んでるんですね
1.オープン
int open(const char *pathname, int flags); で行う。pathnameに"/dev/video0"とか、flagsにはO_RDONLY, O_RDWR とか設定
2.カメラ操作
※カメラで操作可能な設定をいじったり、バッファを関連付けたり、画素データを取り込んだりします
int ioctl(int fd, int request, ...); で行う。リクエスト(request)については下に例示
リクエストの例
VIDIOC_QUERYCAP | カメラデバイスに保有する機能を問い合わせます |
VIDIOC_S_FMT | カメラデバイスに画像データのフォーマットを設定 |
VIDIOC_G_FMT | カメラデバイスに画像データのフォーマットを取得 |
VIDIOC_REQBUFS | 画像データ用のバッファをカメラデバイスに要求 |
VIDIOC_QUERYBUF | VIDIOC_REQBUFSで要求したバッファの情報を取得 |
VIDIOC_QBUF | バッファをエンキューします |
VIDIOC_DQBUF | バッファをデキューします |
VIDIOC_STREAMON | キャプチャ開始 |
VIDIOC_STREAMOFF | キャプチャ停止 |
3.select()で待つ(ってことはpoll()も使えんのか)ことで、キューにデータ入ったか確認する
4.(カメラの)バッファをユーザープログラムにマッピングする
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); で行う
※ユーザー定義のポインタにバッファアドレスをマッピングする
★で、手順的には
- カメラデバイスオープン
- 設定(解像度など)
- バッファ要求
- バッファにポインタ割り当て
- バッファをキュー(あらかじめ)
- キャプチャ開始
- デキュー/エンキュー繰り返し→フレームデータの処理
- キャプチャ終了
- 後始末
となります。
以上ですが、今度は、ちゃんと何かつくりますね。これとffmpegのlibで何か作るとか、OpenCvと組み合わせるとかで・・・・