Take’s diary

Macとマイコンに関すること--ワクワクの製作日記

Edison + Henry 基板でSimpleCVを使って動画配信する(その1)

最新版のyoctoで再度インストールしましたが、各所で微妙に変化しているようです。以下修正しました(2016.01.08、2016.03.09) 

  趣味として使う場合のIntel Edisonの弱点。動画ソフトが思うように作れないこと。

 特にOpenCVで動く顔認識動画なんか夢のまた夢なんて思ってたのですが、スピードが遅いながらも成功したので、一部始終をご紹介します。一応成功した動画はこれです!!(正真正銘Edison配信画像をiPhoneSafariで表示してます。)

 

                              

 さらに、動画配信とは関係ありませんが、後で紹介するOMRON製 非接触温度センサー値をEdisonと Henryを使ってiPhoneに表示させて(非接触温度センサー解像度はiPhoneで4X4から63X63補間できます!!)、

                        f:id:TAKEsan:20150805174651j:plain

で、SimpleCVを使った動体認識プログラムを同時に実行して動画配信すると

                            

こうなります。SimpleCVの動画配信は、顔認識以外では相当実用的のようです。この例では動体に比較的タイムリーに反応するので、ソフトを工夫すればカメラをセンサーとして十分に使えます。Web配信部分はあくまでも確認のためと考えて、Web部分をを外せばさらにスピードアップするのでこれはGood!!です。何よりプログラム開発が簡単です。

 SimpleCVのEdisonでの実行例は、顔認識も含めてその2でメモします。

 Edisonの顔認識についてはこんな記事Python - Edisonで顔認識 - Qiita

あんな記事DIY Facial Recognition with Intel Edison - Photography | Make:おまけに動画配信成功例で

www.youtube.com

てな記事(早くてくやしい。が、ソース非公開)がありますが、静止画ではつまんないし、どうすれば動画として成功するのかわからない。説明があったとしても、OpenCv標準+αだと私には理解が及ばない。そんな訳でお手軽なPythonでやれないかと探してたら、SimpleCVがありました。自分の持っている本「Raspberry Piをはじめよう」でもSimpleCVを取り上げてました。

 まさかEdisonで動くとは.........。ただし、PiのようにどこかのWeb記事を見て、サッと実行できるみたいに甘いもんじゃーありませんでした。

 今回はHenry基板に取り付けたEdisonへmjpeg-streamerのインストールと実験、SimpleCVのインストールまで。次回はSimpleCVのプログラムテストをおこなう予定。

まずEdison初期設定の注意事項

 まず必ず、yoctoの最新版をインストールすること。インストール方法は、

最新版のインストーラを使います。初期バージョンと違いUSBコネクタの抜き差しなしでもyoctoのクリーンインストールが可能です。

 尚、スタートアップには、最低でもEdison Breakout Boardは必要です。

 その他の重要な注意点

  • 当然なんでしょうが「configure_edison --setup」でパスワードを設定しないとSSH接続できない。
  • もし/bootの容量を増やしたいときは

    How to install a kernel from my repo onto Edison with the official imageを参考にする。(あくまでも最悪の場合。中途半端にインストールするとEdisonがMacからUSB認識されなくなりますぞ。sshはOK)

  • もしEdisonのOSインストールが失敗して、起動しなくなったときは

    スタートアップ Intel Edison - Qiitaを見て復旧。私の場合2回ほどお世話になりました。(Edison Breakout Board で OTG接続 ただし ./flashall.sh はsudoで実行しないとダメ!!  。 

  • SSH接続が安定せず遅くなる場合がありますが、EdisonのWifiパワーマネージメントが働いているためなので、「iwconfig wlan0 power off」を実行しましょう。pingで調べてみると、場合によっては100倍!!くらい早くなります。Arduino動作させていると遅くなるなんて記事がありますが、Arduino動作は、CPU稼働率が相当低いので、ほとんど関係ないようです。

Henry基板とmjpeg-streamer実行まで

 Henry基板は、今販売されているEdison Eagletの一つで、USB外部機器との接続やi2c通信に特化したボードです。最初は他のボードで正常にOSをインストールさせてから使うのがベターのようです。Arduino機能は最初から当てにしないほうが無難です。(i2cを使ったプログラムは他のボードでコンパイルした実行ファイルをコピーすれば動きますが)

 Henryボードは、私の趣味でちょっとレザーでデコしてます。見た目もまーまーですし、取り扱いや放熱性の問題もクリヤするので、私的には満足しています。

                      f:id:TAKEsan:20150803122414j:plain

 mjpeg-streamerのインストールは、ここを参考にしました。

neuralassemblyのメモ: Intel EdisonでWebカメラを有効にしmjpg-streamerで映像を配信してみた

 素晴らしい方ですね。Henryボードにロジクールのカメラを接続するだけで、何の問題もなく動きました、Henryボードに必要なのは、USBからの給電だけです。つまり動画配信環境は、すごくシンプルです。

                      f:id:TAKEsan:20150803122340j:plain

 Edisonは、YUV変換オプションがいらないせいか、体感スピードはPi2より確実に早くなります。これからインストールするSIimpleCVとのスピード比較用に何かと重宝しました。

ここからが大変SimpleCVインストール

 edison-image-ww25.5-15にバージョンアップした場合のインストール方法です。OSは、クリーンインストールをお勧めします。以下の手順でインストールし、SimpleCVの動作を確認しました。(10/17)。以下に書いてありますが、まずlibv4l1-videodev.hを手に入れてください。--->現在あまり手に入らないようなので、ソースを最後に付けました。

 こだわったのはyocto環境。SIimpleCVは、Edisonにpipで簡単にインストールできるのですが、それからが苦難の始まりでした。SIimpleCVがインストールできて、python内でimportできても、簡単に動かないのです。 numpy、scipyの他に、pygame、pil、SDLをうまくインストールしないと、動いてくれません。この中でも 予想通りscipyと、予想外であるpygameのインストール(SimpleCVに合わせたインストール方法=少なくともフォントや図形を動画に合成表示)が非常に難しく、Web上では、EdisonでのSimpleCVの稼働やscipyのコンパイルは、現状ほぼ絶望的な状況です。

 で、結論は、忘れかけていたつたない英語力でweb上の記事をしらみつぶしに探した結果、数件の記事の合成で、ほぼ成功したんです!!。

 以下手順を書きます。私はEdisonを2個持ってるのですが、2個目でもインストールできたので多分OKです。

1. Edisonにpython 2.9.10、 numpy、opencvをインストール

 Minicondaというデータ分析用パッケージをまとめたディストリビューションを使ってインストールします。

Miniconda Python on Intel Edison | SciVisionで紹介しています。内容は以下の通りです。

 まず、パッケージマネージャーを設定します。すでに設定していれば飛ばして下さい。私はエディタにnanoを使用していますが、インストール方法はググってみてください。

 2つのconfファイルを作って、一方に3行、もう一方に4行を記入します。

nano /etc/opkg/base-feeds.conf

   src/gz all http://repo.opkg.net/edison/repo/all

   src/gz edison http://repo.opkg.net/edison/repo/edison

   src/gz core2-32 http://repo.opkg.net/edison/repo/core2-32

nano /etc/opkg/intel-iotdk.conf

   src intel-iotdk http://iotdk.intel.com/repos/1.1/intelgalactic

   src intel-all http://iotdk.intel.com/repos/1.1/iotdk/all

   src intel-i586 http://iotdk.intel.com/repos/1.1/iotdk/i586

   src intel-x86 http://iotdk.intel.com/repos/1.1/iotdk/x86

最後に 

opkg update

ここで絶対upgrage を実行しないこと。

一応tarとbashをインストール。 

opkg install tar

opkg install bash

次にMinicondaをインストール。 /home/root に移動して実行します。

以下は、web記事より。

wget http://repo.continuum.io/miniconda/Miniconda-3.8.3-Linux-x86.sh

BASH_ENV=/home/root/.bashrc bash Miniconda-3.8.3-Linux-x86.sh

echo "export PATH=/home/root/miniconda/bin:$PATH" >> ~/.profile

 途中python入力モードになり ライセンス記述があるので enterで最後まで読みyes 入力 。インストール実施後最後にyesでOK。

 Home にminikondaができてる。次にrebootして、pythonを実行してみて最初のコメントがpython 2.7.11と表示されたらOK。

さらにMinicondaを使ってnumpy scipy opencvをインストール

conda update conda

                   Proceed([y]/n)? で yを入力

                                                       このコマンドはエラーがで雨かもしれませんが

                  その時は無視

conda install numpy scipy astropy opencv  

                   Solving packegr specifications:の後しばらく反応を待つ

インストールに10分程度必要。次にpipをインストールしてください。(方法は調べて見て)

 pip list で確認 全部インストールされてたらOK。 (opencvは pip list で表示されません。)

     numpy 1.8.2

     scipy 0.14.0

     opencv 2.4.6

 全体的にバージョンが古いが、私のスキルではあまり問題にならないので、妥協。

 これらにより新たにpython 2.9.10が/home以下にインストールされます。最初から仮想環境でインストールすれば良かったのですが、今更めんどくさいのと、私の場合このままでも特に問題ないので、このままにします。この新しい環境では、以前インストールしたPythonライブラリは、認識されないので再インストールする必要があります。次に、

https://communities.intel.com/thread/55703

の回答コメント中に記述してある

opkg install libsdl-1.2-dev libv4l-dev 

を実行。この段階ではPygameはインストールしません

 この後、自分のEdisonに /usr/include/libv4l1-videodev.h があるかどうか確認。なければWeb で手に入れるか、私の場合Pi2の中にvideodev.hが入っていたので、試しにこれを使ったらうまくいきました。(無ければ最後にソースを付けましたのでこれを使う)

ln -s /usr/include/libv4l1-videodev.h /usr/include/linux/videodev.h

つまり最終的には、/usr/include/linux/にvideodev.hが入っていればOKということです。

(/usr/include/linux/にvideodev.hが入っていないと後のPygameがインストールできません。)

2. Edisonにpygameをインストール

How do I install pygame? - WebFaction Community

を参考に以下の手順でpygameをインストール。

 この後自分の環境が原因でエラーが出ると、最終的にSimpleCVがうまく実行できないので、インストールできない場合は自分で調べまくってください。

mkdir -p $HOME/src $HOME/tmp

export TMPDIR="$HOME/tmp"

export PATH="$HOME/bin:$PATH"

export C_INCLUDE_PATH="$HOME/include:$C_INCLUDE_PATH"

export LIBRARY_PATH="$HOME/lib:$LIBRARY_PATH"

export LD_LIBRARY_PATH="$HOME/lib:$LD_LIBRARY_PATH"

export CPPFLAGS="-I$HOME/include $CPPFLAGS"

export LDFLAGS="-L$HOME/lib $LDFLAGS"

cd $HOME/src

wget 'http://mirror.ryansanden.com/pygame-1.9.1/SDL-1.2.15.tar.gz'

tar -xf SDL-1.2.15.tar.gz

cd SDL-1.2.15

./configure --prefix=$HOME

make -j8

make install

 

cd $HOME/src

wget http://download.savannah.gnu.org/releases/freetype/freetype-2.5.3.tar.gz

     たまにサイトがダウンしているみたいなのでfreetype-2.5.3.tar.gzをネット上で探して

    インストールしてください

tar -zxf freetype-2.5.3.tar.gz

cd freetype-2.5.3

./configure --prefix=${LOCAL_PREFIX}      

             make: Nothing to be done for 'unix'. とかで終わるが無視

make 

            makeは、結構時間がかかる     

make install

ここでmakeが通らないと、SimpleCV、pygameでフォント表示ができなくなる。うまくいったら次に進みます。

 

cd $HOME/src

wget 'http://mirror.ryansanden.com/pygame-1.9.1/SDL_ttf-2.0.11.tar.gz'

tar -xf SDL_ttf-2.0.11.tar.gz

cd SDL_ttf-2.0.11

./configure --prefix=$HOME

make -j8

make install

 

cd $HOME/src

wget 'http://mirror.ryansanden.com/pygame-1.9.1/SDL_image-1.2.12.tar.gz'

tar -xf SDL_image-1.2.12.tar.gz

cd SDL_image-1.2.12

./configure --prefix=$HOME

make -j8

make install

 

cd $HOME/src

wget 'http://mirror.ryansanden.com/pygame-1.9.1/SDL_mixer-1.2.12.tar.gz'

tar -xf SDL_mixer-1.2.12.tar.gz

cd SDL_mixer-1.2.12

./configure --prefix=$HOME

make -j8

make install

 

cd $HOME/src

wget 'http://mirror.ryansanden.com/pygame-1.9.1/pygame-1.9.1release.tar.gz'

tar -xf pygame-1.9.1release.tar.gz

cd pygame-1.9.1release

python setup.py install

(python2.7 setup.py install --prefix=$HOMEだとフォントがインストールされない。)

 インストールの最初にこんな画面が出るので内容を確認(foundが以下のようになっていること。なっていなかったら上記のどれかがインストールされていないので最初からもう一度!!)

WARNING, No "Setup" File Exists, Running "config.py"

Using UNIX configuration...

 

 

Hunting dependencies...

sh: smpeg-config: command not found

WARNING: "smpeg-config" failed!

SDL     : found 1.2.15

FONT    : found

IMAGE   : found

MIXER   : found

SMPEG   : not found

PNG     : not found

JPEG    : found

SCRAP   : found

PORTMIDI: not found

PORTTIME: not found

 

 

Warning, some of the pygame dependencies were not found. Pygame can still

compile and install, but games that depend on those missing dependencies

will not run. Would you like to continue the configuration? [Y/n]:y

OKなら y を入力するとコンパイルが始まる。

 warningが結構出るが無視。で、pygame インストール終了。ご苦労様でした。

 

3. EdisonにpipでPILとSimpleCVをインストール

 最後にPILとSympleCVのインストールを実行

pip install PIL --allow-external PIL --allow-unverified PIL

 

上記コマンドPILインストールでこけた時は(多分エラーになる)、Python Imaging Library (PIL)から最新ソースをダウンロードして解凍し、解凍したディレクトリに入ってpython setup.py install でPILをインストールして下さい。

 無事インストールできたら、

pip install SimpleCV      (以前はスペルが違ってましたスンマセン)

2016/11/6追記

現状pipではインストールできない模様。以下コマンドでインストールしてください。

sudo pip install https://github.com/ingenuitas/SimpleCV/zipball/master

 

4. Edisonにmraaを再インストール

 前述の通り新しい環境では、python のmraa ライブラリのパスが消えてしまうので、import できなくなってしまいます。

https://learn.sparkfun.com/tutorials/installing-libmraa-on-ubilinux-for-edison

を参考にして Build and Install mraa 部分の手順で mraaを再ビルド。Export Library Path for Pythonまで実行するとOK。

 この中での注意点は

ldconfig -p | grep mraa

を実行して/usr/ 以下を確認してからnanoで .bashrc を変更してください。私の場合 .profile も変更しないと、再起動後mraaをimportできませんでした。

 sparkfunの説明は、UbilinuxをインストールしているEdisonなので apt-get部分を opkgに変えます。

  あーつかれた。これだけヒントを書いたんだから、エラーが出たら自分でなんとか調べて下さい。

 次回はいよいよSimpleCVを使った動画配信と応用です。 

 この後、 (2016/3/9)WebでEdisonを操作できるようになりました。興味のある方はこのページを

takesan.hatenablog.com

 今(2016/2/28)、Edisonよりはるかに安いボードで、こんなことができました。OpenCVは実行できませんが、独立して動くことを考慮すると、世界最小のサーモグラフィーカメラです!!。しかもボードの制御もできちゃいます。

takesan.hatenablog.com

以下 libv4l1-videodev.h の内容

-----------------------------------------------------------------------------------

/*  DO NOT EDIT THIS FILE.

 

    It has been auto-edited by fixincludes from:

 

"/silver/galileo/devkit/build-devkit-16/tmp/sysroots/quark/usr/include/libv4l1-videodev.h"

 

    This had to be done to correct non-standard usages in the

    original, manufacturer supplied header file.  */

 

/* libv4l1 linux/videodev.h replacement file */

#ifndef __LINUX_VIDEODEV_H

#define __LINUX_VIDEODEV_H

 

#ifdef __linux__

#include <linux/ioctl.h>

#endif

 

#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)

#include <sys/ioctl.h>

#endif

 

#include <stdint.h>

 

#define VID_TYPE_CAPTURE 1 /* Can capture */

#define VID_TYPE_TUNER 2 /* Can tune */

#define VID_TYPE_TELETEXT 4 /* Does teletext */

#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */

#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */

#define VID_TYPE_CLIPPING 32 /* Can clip */

#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */

#define VID_TYPE_SCALES 128 /* Scalable */

#define VID_TYPE_MONOCHROME 256 /* Monochrome only */

#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */

#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */

#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */

#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */

#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */

 

struct video_capability

{

char name[32];

int type;

int channels; /* Num channels */

int audios; /* Num audio devices */

int maxwidth; /* Supported width */

int maxheight; /* And height */

int minwidth; /* Supported width */

int minheight; /* And height */

};

 

 

struct video_channel

{

int channel;

char name[32];

int tuners;

uint32_t flags;

#define VIDEO_VC_TUNER 1 /* Channel has a tuner */

#define VIDEO_VC_AUDIO 2 /* Channel has audio */

uint16_t type;

#define VIDEO_TYPE_TV 1

#define VIDEO_TYPE_CAMERA 2

uint16_t norm; /* Norm set by channel */

};

 

struct video_tuner

{

int tuner;

char name[32];

unsigned long rangelow, rangehigh; /* Tuner range */

uint32_t flags;

#define VIDEO_TUNER_PAL 1

#define VIDEO_TUNER_NTSC 2

#define VIDEO_TUNER_SECAM 4

#define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */

#define VIDEO_TUNER_NORM 16 /* Tuner can set norm */

#define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */

#define VIDEO_TUNER_RDS_ON      256     /* Tuner is seeing an RDS datastream */

#define VIDEO_TUNER_MBS_ON      512     /* Tuner is seeing an MBS datastream */

uint16_t mode; /* PAL/NTSC/SECAM/OTHER */

#define VIDEO_MODE_PAL 0

#define VIDEO_MODE_NTSC 1

#define VIDEO_MODE_SECAM 2

#define VIDEO_MODE_AUTO 3

uint16_t signal; /* Signal strength 16bit scale */

};

 

struct video_picture

{

uint16_tbrightness;

uint16_thue;

uint16_tcolour;

uint16_tcontrast;

uint16_t whiteness; /* Black and white only */

uint16_t depth; /* Capture depth */

uint16_t palette; /* Palette in use */

#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */

#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */

#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */

#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */

#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */

#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */

#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */

#define VIDEO_PALETTE_YUYV 8

#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */

#define VIDEO_PALETTE_YUV420 10

#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */

#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */

#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */

#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */

#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */

#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */

#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */

#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */

};

 

struct video_audio

{

int audio; /* Audio channel */

uint16_tvolume;/* If settable */

uint16_tbass, treble;

uint32_tflags;

#define VIDEO_AUDIO_MUTE 1

#define VIDEO_AUDIO_MUTABLE 2

#define VIDEO_AUDIO_VOLUME 4

#define VIDEO_AUDIO_BASS 8

#define VIDEO_AUDIO_TREBLE 16

#define VIDEO_AUDIO_BALANCE 32

char name[16];

#define VIDEO_SOUND_MONO 1

#define VIDEO_SOUND_STEREO 2

#define VIDEO_SOUND_LANG1 4

#define VIDEO_SOUND_LANG2 8

uint16_tmode;

uint16_t balance; /* Stereo balance */

uint16_t step; /* Step actual volume uses */

};

 

struct video_clip

{

int32_tx,y;

int32_twidth, height;

struct video_clip *next; /* For user use/driver use only */

};

 

struct video_window

{

uint32_t x,y; /* Position of window */

uint32_twidth,height;/* Its size */

uint32_tchromakey;

uint32_tflags;

struct video_clip *clips; /* Set only */

int clipcount;

#define VIDEO_WINDOW_INTERLACE 1

#define VIDEO_WINDOW_CHROMAKEY 16 /* Overlay by chromakey */

#define VIDEO_CLIP_BITMAP -1

/* bitmap is 1024x625, a '1' bit represents a clipped pixel */

#define VIDEO_CLIPMAP_SIZE (128 * 625)

};

 

struct video_buffer

{

void *base;

int height,width;

int depth;

int bytesperline;

};

 

struct video_mmap

{

unsigned int frame; /* Frame (0 - n) for double buffer */

int height,width;

unsigned int format; /* should be VIDEO_PALETTE_* */

};

 

struct video_mbuf

{

int size; /* Total memory to map */

int frames; /* Frames */

int offsets[32];

};

 

struct vbi_format {

uint32_tsampling_rate;/* in Hz */

uint32_tsamples_per_line;

uint32_t sample_format; /* VIDEO_PALETTE_RAW only (1 byte) */

int32_t start[2]; /* starting line for each frame */

uint32_t count[2]; /* count of lines for each frame */

uint32_tflags;

#define VBI_UNSYNC 1 /* can distingues between top/bottom field */

#define VBI_INTERLACED 2 /* lines are interlaced */

};

 

#define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */

#define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */

#define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */

#define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */

#define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */

#define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */

#define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */

#define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */

#define VIDIOCGWIN _IOR('v',9, struct video_window) /* Get the video overlay window */

#define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */

#define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */

#define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */

#define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */

#define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */

#define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */

#define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */

#define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */

#define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */

#define VIDIOCGMBUF _IOR('v',20, struct video_mbuf) /* Memory map buffer info */

#define VIDIOCGVBIFMT _IOR('v',28, struct vbi_format) /* Get VBI information */

#define VIDIOCSVBIFMT _IOW('v',29, struct vbi_format) /* Set VBI information */

 

#endif 

takesan.hatenablog.com