V4L は初めてなので、C でカメラからフレームをキャプチャするために、video4linux2 ライブラリの使用を開始することにしました (Ricoh Co. のカメラで uvcvideo モジュールを使用しています)。いくつかのガイドとチュートリアルに従い、実行中のプログラムを取得することができました。私の質問は、主にこの通常のコード行に関するものです:
struct v4l2_format format = {0};
format.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
// ...
ここで、キャプチャ時に使用する実際のビデオ形式を設定します。ご覧のとおり、このサンプルでは MJPEG ( http://lxr.free-electrons.com/source/include/uapi/linux/videodev2.h#L390 ) を使用しています。これは素晴らしいフォーマットかもしれませんが、私のアプリケーションではおそらくピクセルごとに単純な RGB フォーマットが必要になるでしょう。このため、 などの RGB 形式の定数を使用してみましV4L2_PIX_FMT_RGB24
た。どういうわけか... v4l2はそれが好きではありません。これはハードウェア関連だと思いますが、MJPEG の操作はできるだけ避けたいと思います。テスト目的で、他の定数と形式を使用してみましたが、何をしても、v4l2 はpixelformat
フィールドの値を変更し続けました。
xioctl(fd, VIDIOC_S_FMT, &format); // This call succeeds with errno != EINTR.
if(format.fmt.pix.pixelformat != V4L2_PIX_FMT_RGB24){
// My program always enters this block when not using MJPEG.
fprintf(stderr, "Format wasn't accepted by v4l2.");
exit(4);
}
ここで私の質問は次のとおりです。受け入れられたビデオ形式のリストを取得する方法はありますか (つまり、カメラ/v4l2 で受け入れられます)、そこから MJPEG 以外のものを選択できますか? MJPEG に固執する必要があると思われる場合は、MJPEG を操作し、最終的にはキャプチャを GUI フレームに戻すことができるライブラリをお勧めしますか?
バーバリアンのテスト コード
次のトリックを使用して、ハードウェアで利用可能なすべてのフォーマットをテストしました。まず、すべてのフォーマットのリストを取得するためのシェルスクリプト...
grep 'V4L2_PIX_FMT' /usr/include/linux/videodev2.h | grep define | tr '\t' ' ' | cut -d' ' -f2 | sed 's/$/,/g'
...このCプログラムで使用される出力:
int formats[] = {/* result of above command */};
int i = 0;
struct v4l2_format format = {0};
for(i = 0; i < /* number of lines in previous command output */; i++){
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
format.fmt.pix.width = 320;
format.fmt.pix.height = 240;
format.fmt.pix.pixelformat = formats[i];
format.fmt.pix.field = V4L2_FIELD_NONE;
if(xioctl(fd, VIDIOC_S_FMT, &format) != -1 && format.fmt.pix.pixelformat == formats[i])
fprintf(stderr, "Accepted : %d\n", i);
}
このテストは、 と のみが機能していることを示していV4L2_PIX_FMT_YUYV
ますV4L2_PIX_FMT_MJPEG
。これを改善する方法はありますか、それともハードウェア関連ですか?