5

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。これを改善する方法はありますか、それともハードウェア関連ですか?

4

2 に答える 2

10

Linux では、コマンド ライン ユーティリティv4l2-ctlは、Web カメラのネイティブ サポートされているすべての形式を表示 します。これらの形式は、モジュールを介してカーネル モジュールに報告され、Web カメラ チップセットによってネイティブにサポートされます。リストされた形式のみが でサポートされ、それ以外はすべてユーザーがコーディングする必要があり、実質的にすべての CCD が Bayer RGGB で動作しているにもかかわらず、RGB が提供されることはほとんどありません最も一般的な形式は、YUV422 (YUYV またはYUY2 ) と MJPEG であり、特定のオーバーラップがあります。MJPEG は、高解像度でより大きなフレーム レートを実現します。sudo apt-get install v4l-utilsv4l2-ctl -dX --list-formats-extX/dev/videoXv4l2uvcvideov4l2

カメラ形式を一覧表示するための C++ コードは、こちらの Linux 用 Chromium GetDeviceSupportedFormats() 実装にあります。

YUV を RGB に変換するコードをプラグインする必要がある場合は、多くのアーキテクチャ用に最適化されたlibyuvをお勧めします。

于 2014-03-23T20:11:37.850 に答える
3

使用可能な形式を列挙するには、ioctl VIDIOC_ENUM_FMTを使用できます。

サポートされているキャプチャ形式の説明を出力するには、次の/dev/video0ように処理できます。

#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/videodev2.h>

int main()
{
    int fd = v4l2_open("/dev/video0", O_RDWR);
    if (fd != -1)
    {
        struct v4l2_fmtdesc fmtdesc;
        memset(&fmtdesc,0,sizeof(fmtdesc));
        fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        while (ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc) == 0)
        {    
            printf("%s\n", fmtdesc.description);
            fmtdesc.index++;
        }
        v4l2_close(fd);
    }
}
于 2015-12-06T13:24:01.617 に答える