[ 2013/06/12 renewals ] ☆☆☆ かってに Linux5 (続き4) ☆☆☆ *** Freely Linux5. (it continues, 4) ***情報化社会の発展を図る活動として、 ( 単にNPO協賛活動として ) 無料で利用可能な、Linuxの普及の為、当ページへの、多数のアクセスありがとう。 当ページは、多くの関連HPを参考に、Linux ( Fedora等) での利用や、 応用方法、開発等をし、結果・無料公開してます。 この場を借りて、各関連HP、各検索サイト、各開発者、多くの訪問者 等々へ Linuxの普及を願いつつ、感謝と、エールを送ります。 ・PC9801, DOS/V, Win9X, Win2000,WinXP, UNIX, Linux の各種ソフト作成、 メインは、C(言語)、現在は、Linux 30台位使用して、システム研究開発中。 27年近く(PC8001 〜 現在まで)、各種業務システム構築の現役者が提供。(松本英男) "マックミル" は、(有)松商商会 の登録商標です。( MACMIL.CO.JP )★ Linuxで、インターネット等を、 "MS-Windows" と同じ様に 快適にする情報を無料提供。410-0022 JAPAN by H.MATSUMOTO ( MACMIL.CO.JP (有)松商商会 ) 〒410-0022 マックミルズ 1F ( MACMIL.CO.JP MATSUSHOW CO.,LTD.)●検索は、Ctrl + F で。( アルファベットは、半角文字で検索のこと ) * As for search,with Ctrl + F .*******<< ★ かってに Linux [ 開始 ] >>*******============================================================== *******<< ★ かってに V4L2 ビデオキャプチャー [ 開始 ] >>*******Fedora 7 から、Fedora core7(FC7) でなく、Fedora 7(F-7) に名称変更 Fedora core4,5,6, Fedora 7,8 の、 ダウンロード、インストール、update の方法含む(構築)は、ここをクリックFedora 18 (F18, F-18)(FC18)Fedora 17 (F17, F-17)(FC17)Fedora 17 Preview (test3)Fedora 17 Beta (test2)Fedora 17 Alpha (test1)Fedora 16 (F16, F-16)(FC16) 2011/11/08 Fedora 15 (F15, F-15)(FC15) 2011/05/25 Fedora 14 (F14, F-14)(FC14) 2010/11/02 Fedora 13 (F13, F-13)(FC13) 2010/05/25 Fedora 12 (F12, F-12)(FC12) 2009/11/17 Fedora 11 (F11, F-11)(FC11) 2009/06/09 Fedora 10 (F10, F-10)(FC10) 2008/11/25 Fedora 9 (F9, F-9)(FC9) 2008/05/13Fedora 8 (F8, F-8)(FC8)Fedora 7 (F7, F-7)(FC7)Fedora 7 test4Fedora core6 (FC6)Fedora core5, 6, Fedora 7, 8, 9 の検索で、ここに来た場合は ( DVD.iso ダウンロード等) "かってに Linux4" が、 Fedora core5, 6, Fedora 7, 8, 9 の、インストール等の実践記録です。 Fedora core5,6, Fedora 7,8 の検索で、来た方は、 お手数ですが、ここをクリックして下さい。Fedora 17 (F-17) リリース(release) スケジュール 2012/05/22 http://fedoraproject.org/wiki/Releases/17/Schedule注) Qcam Orbit MP QVR-13 と、QVX-13NS は、pwc ではなく、 uvc となるので、下記へ行って下さい。● uvc で、V4L2 キャプチャー ( Fedora core6 で、Qcam Orbit MP QVR-13 と、QVX-13NS 動作確認済み ) ★ かってに V4L2 ビデオキャプチャー(uvc) を参照のこと。注) V4L, V4L2 で、 ビデオキャプチャー ソフトを 作成する場合の話しです。*******<< ★ かってに V4L2 ビデオキャプチャー [ 終了 ] >>******* ==============================================================Fedora core3, core4, core5 で、QV-4000 を使用する。 QV-4000 使用の為の、 pwc の、インストール ( ドライバー ) は、ここを、クリック ( core4, core5 標準の、pwc.ko で、問題ある時、使用する ) ( Fedora core6 標準の、pwc.ko は、問題なく使用できた [ 2006/10/26 ] ) 参考) Quickcam Pro 5000 USB2.0 ( 2006/10/09 現在、USER SIDE )◆ QV-4000WH を、xawtv にて、表示してみる。へは、ここを、クリック。注) USB カメラ(QV-4000) 等は、USB ハブを使わずに、 直接、パソコンの、USB ポートに接続すること。 動作しないで、すぐ終了となりする (エラー、映らない、写らない)ことがある為。◆ Fedora core3 まで、 # cp -p pwc.ko /lib/modules/$(uname -r)/kernel/drivers/usb/media/◆ Fedora core4, core5 以降 # cp -p pwc.ko /lib/modules/$(uname -r)/kernel/drivers/usb/media/pwc/ ( Fedora core4, core5 以降 は、標準で、pwc.ko が、入っており、 場所を、間違えても、 # /sbin/lsmod | grep pwc pwc が、表示される( この場合、標準の pwc.ko ) が、 ここで作成したものと異なり、うまくいかないので注意。と、インストール位置が異なる。xawtv の、ダウンロード、インストールは、 かってに Linux2 (続き1) にあります。 下記を、クリックして下さい。 ★ かってに xawtv を参照のこと。◆ /dev/video0 を、root 以外で、アクセス可にする。$ su # chmod go+rw /dev/video0 ( 以下は、存在した時のみ ) # chmod go+rw /dev/video1http://v4l2spec.bytesex.org/spec/capture-example.html 上記に、V4L2 の、サンプルがあるが、 例えば、これを、sample.c とした時、 ◆ V4L2 必要 ( Fedora core3, core4, core5 OK ) ◆ "videodev2.h" 必要 注) 上記クリックで、videodev2.h が、ダウンロードできます。 "vid_dev2.tar" となってますが、ダウンロード後、 ( 圧縮してないので、解凍不要です。ダウンロード可能にする為 xxx.tar ) videodev2.h に、リネームして下さい。 $ vi sample.c dev_name = "/dev/video" を、 dev_name = "/dev/video0" に修正し、◆ 参考)# chmod go+rw /dev/video? 以外で、 立上時に、/dev/video? を、root 以外で、アクセス可にするにはへ/* * dev_name = "/dev/video"; */ dev_name = "/dev/video0";下記のように、修正、追加し、static void process_image(const void *p) { /* * fputc ('.', stdout); * fflush (stdout); */ int i, j; /* raw ppm フォーマット */ fprintf(stdout,"P6\n %d %d\n 255\n", 640, 480); fflush(stdout); for(i= 0; i< 480; i++) { for(j= 0; j< 640; j++) { /* BGR --> RGB 順番の入れかえ */ fwrite(p + (i * 640 + j) * 3 + 2, 1, 1, stdout); fwrite(p + (i * 640 + j) * 3 + 1, 1, 1, stdout); fwrite(p + (i * 640 + j) * 3 , 1, 1, stdout); } } exit (0); }fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; を、 fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24; に修正し、/* * fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; */ fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24;xawtv, tvtime 等で、 一度、映像がでるように CH を設定しておくこと。 ◆ QV-4000WH を、xawtv にて、表示してみる。へは、ここを、クリック。$ gcc sample.c $ ./a.out > test.ppmとすれば、OK。( 取り込むだけなので、画像は出ない ) KView 等で、 test.ppm を表示できる。● Linuxで、Bt878 カードで、キャプチャーするには、 ★ かってに Bt878 カードで、キャプチャー を参照のこと。 注) Fedora core3, core4, core5 は、/etc/modules.conf ではなく、 /etc/modprobe.conf になった。設定方法も異なるものもある。の、設定は、すでにしてあること。 ● Bt878(Bt848) を使用して、RGBで、キャプチャすると時々、 横線ノイズがでる。◆ 画像表示を、する場合、 X-Video Extensionが有効の場合 YUV [ Y(輝度)CbCr(色差)] のダイレクト表示 ハードでスケーリング 全画面表示できるので、 V4L2_PIX_FMT_YUYV [ YUY2(YUV4:2:2) ] でよいが、 ビットマッブ等、RGBが必要な時、 V4L2_PIX_FMT_BGR32(24) の、 RGBで、キャプチャすると時々、横線ノイズがでる。 YUY2(YUV4:2:2)なら問題なし。 したがって、YCbCr->RGB する必要がある。 その際の、変換方法を、調査検討した。 とりあえず、変換ツールが、見つからなかったので、 変換式と、ソフトを、自分で、かってに作ることとした。 現在、かってに式、作って Fedora core2, 3, core4, core5 の、 監視システムで、実際に使用してます。以下に、集めた情報を、バラバラだが、メモってみた。 ● <<< BT848, BT878 の RGB が 変 >>>◆ YC 伸張する場合の RGBへの、かってに変換式? V4L, V4L2 (BT878等) の YUYV(yuy2),YUV420P から、 RGBへの、かってに変換式? ( BT878(BT848) を使用して、 RGBで、キャプチャすると時々、横線ノイズがでる。 YUY2(YUV4:2:2)なら問題なし。 したがって、下記の、かってに変換式で、変換し、 画像処理してます。) ・V4L VIDEO_PALETTE_YUYV --> VIDEO_PALETTE_RGB32(24)、 VIDEO_PALETTE_YUV420P --> VIDEO_PALETTE_RGB32(24) で、 ・V4L2 V4L2_PIX_FMT_YUYV --> V4L2_PIX_FMT_BGR32(24)、 V4L2_PIX_FMT_YUV420 --> V4L2_PIX_FMT_BGR32(24) で、 問題なく使用してます。 ( かってに式、作って使用してますが、保証はありません...) ( R, G, B は 0 〜 255 の範囲のデジタルデータ ) ( Y は 16 〜 235 の範囲のデジタルデータ ) ( Cb, Cr は 16 〜 240 の範囲のデジタルデータ ) R = 1.164(Y-16) + 1.567(Cr-128) G = 1.164(Y-16) - 0.798(Cr-128) - 0.384(Cb-128) B = 1.164(Y-16) + 1.980(Cb-128) RGB は、ほぼ、0〜255 の間を取るように変換、 実際は、0 より小さい時、0 にし、 255 より大きい時、255 の処理必要。◆ YUY2(YUYV)[YUV4:2:2] (YUNV, V422) 16bit Y0, U0, Y1, V0 ・V4L VIDEO_PALETTE_YUYV ・V4L2 V4L2_PIX_FMT_YUYV で、取り込むと、width x height x 2 の、サイズに、 Y0, U0, Y1, V0 の、順番で、入っている。 下記に、簡単に示す。あくまで、考え方用で、 実際は、小数点を使用しないで、 整数で、作成しないと、処理時間がかかる。 ex.) 1164 * (Y0-16) / 1000 等、又は、1024 掛けた常数を使用し、 >>10 で、/ 1024 の代りとする等。 int i, j; int Y0; int V0; int U0; int R; int G; int B; int img_addr; int width= 640; int height= 480; for(i= 0; i< (height / 2); i++) { for(j= 0; j< width; j++) { img_addr= (i * width + j) * 4; Y0= yuy2_image[ img_addr ] & 0xff; V0= yuy2_image[ img_addr + 3 ] & 0xff; /* Cr 色差成分(赤) */ U0= yuy2_image[ img_addr + 1 ] & 0xff; /* Cb 色差成分(青) */ /* * V0, U0 横、2 dot につき、1 つの情報となる */ R = 1.164(Y0-16) + 1.567(V0-128) G = 1.164(Y0-16) - 0.798(V0-128) - 0.384(U0-128) B = 1.164(Y0-16) + 1.980(U0-128) if (R < 0) R= 0; if (R > 255) R= 255; if (G < 0) G= 0; if (G > 255) G= 255; if (B < 0) B= 0; if (B > 255) B= 255; /* * R, G, B を目的に応じて、バッファーに書込む */ Y1= yuy2_image[ img_addr + 2 ] & 0xff; R = 1.164(Y0-16) + 1.567(V0-128) G = 1.164(Y0-16) - 0.798(V0-128) - 0.384(U0-128) B = 1.164(Y0-16) + 1.980(U0-128) if (R < 0) R= 0; if (R > 255) R= 255; if (G < 0) G= 0; if (G > 255) G= 255; if (B < 0) B= 0; if (B > 255) B= 255; /* * R, G, B を目的に応じて、バッファーに書込む */ } /* loop */ } /* loop */◆ YUV420P ( USB WebCam YUV420P )、キャプチャ・サンプルプログラムは、 ★ かってに V4L(V4L1) ビデオキャプチャー を参照のこと。BT848, BT878 へ Basic YCbCr で RGB に展開していることになる。 本来ならCCIR(ITU-R)601で展開すべき RGBで、キャプチャするとどうしても横線ノイズが・・・。 YUY2(YUV4:2:2)なら別に問題なし。● メモ ( いろいろな式がある )X-Video( XVideo ) 対応 ( xvinfo )$ /usr/X11R6/bin/xvinfo X-Video Extension version 2.2 | number of encodings: 2 encoding ID #0: "ntsc" size: 720 x 480 rate: 59.940060 encoding ID #1: "pal" size: 720 x 576 rate: 50.000000# ++++++++++++++++++++++++++++++++++++++++++++++++++++ # ●●●●●● start xv ●●●●●● # ++++++++++++++++++++++++++++++++++++++++++++++++++++version= 2, release= 2 X-Video Extensionが有効の場合 YUV [ Y(輝度)CbCr(色差)] のダイレクト表示 ハードでスケーリング 全画面表示できる 日本で放送されている NTSC 信号の場合、 525 本の走査線中、483 本に映像信号を入れる ( これ以外には制御信号や文字放送信号が入る ) "ximglib4.c" rgb_to_yc() R、G、Bから輝度、色差信号に変換する yc_to_rgb() 輝度,色差信号からR,G,B信号に変換する yc: Y 輝度信号 ( CIE の色度図のY軸だから ) c1: V (R-Y) 色差信号(Cr) [ 色差成分(赤) ] c2: U (B-Y) 色差信号(Cb) [ 色差成分(青) ] CCIR601 (TVスケール) 輝度(Y) 16〜235(220) [ 16が真っ黒、235が真っ白 ] [ 輝度は 220 の量子化レベル ] 色差(UV) 16〜240 (225) 無彩色(白,黒,灰色)が128 [ 色差は無彩色レベルが 128 を中心に 225 の量子化レベル ] 色相(Hue),彩度(Saturation),明度(Value) YUVのフォーマット ( 多くのビデオカードは YUY2 オーバーレイをサポート ) YUY2[YUV4:2:2] (YUNV, V422) 16bit Y0, U0, Y1, V0 ( YUY2 で Y= 235, U= 128, V= 128 ) http://www.marumo.ne.jp/bt601/ PC 上では YC 伸張・圧縮を行う。 ITU-R BT.601 に規定されているのは、 あくまでも、 アナログ RGB データからデジタル YUV 形式に変換する方法であって、 デジタル 8 ビットフルスケール RGB データから YUV に変換する方法ではない。 ◆ YCbCr <--> RGB (CCIR601) 両方の式は YUV → RGB において非可逆 ( RGB に再度変換すると、はみ出た部分が切捨 )/etc/X11/xorg.conf の Module セクションに Load "extmod"を加える 無いと、下記、エラーとなる $ /usr/bin/xvinfo Xlib: extension "XVideo" missing on display ":0.0". xvinfo: No X-Video Extension on :0.0$ su # vi /etc/X11/xorg.conf● /etc/X11/xorg.conf に、Load "extmod" が無いと、下記、エラーとなるSection "Module" Load "glx" ### for X-Video Extension version 2.2 Load "extmod" Load "extmod" EndSection$ /usr/bin/xvinfo Xlib: extension "XVideo" missing on display ":0.0". xvinfo: No X-Video Extension on :0.0参考) http://d.hatena.ne.jp/cesium133/?of=5 # ++++++++++++++++++++++++++++++++++++++++++++++++++++ # ●●●●●● end xv ●●●●●● # ++++++++++++++++++++++++++++++++++++++++++++++++++++YCCカラーベース RGB->YCbCr ( アナログ RGB 信号 -> アナログ Y, (B-Y), (R-Y) 信号 ) ( アナログ RGB 信号は 0.0 〜 1.0 の範囲のアナログデータ ) Y= 0.2989*R+0.5866*G+0.1145*B Cb=-0.1687*R-0.3312*G+0.5000*B Cr= 0.5000*R-0.4183*G-0.0816*B YCbCr->RGB R = Y + 1.4022Cr G = Y - 0.7145Cr - 0.3456Cb B = Y + 1.7710Cb ( アナログ (B-Y), (R-Y) 信号 ) Y = 0.299R + 0.587G + 0.114B C1= R-Y = 0.7011R - 0.5866G - 0.1145B C2= B-Y = -0.2989R - 0.5866G + 0.8856B "ximglib4.c" yc[du + j]= 0.3 * fr + 0.59 * fg + 0.11 * fb; c1[du + j]= 0.7 * fr - 0.59 * fg - 0.11 * fb; c2[du + j]= -0.3 * fr - 0.59 * fg + 0.89 * fb; ( アナログ (B-Y), (R-Y) 信号 -> アナログ Cb, Cr 信号 ) ( R, G, B, Y が 0.0 〜 1.0 の範囲、 Cb, Cr は -0.5 〜 0.5 の範囲 ) Cr= 0.714(R-Y) = 0.5000R - 0.4183G - 0.0816B Cb= 0.564(B-Y) = -0.1687R - 0.3312G + 0.5000B ( アナログ Y, Cb, Cr 信号の量子化によるデジタル変換式 ) Y(d) = 219 * Y(a) + 16 Cb(d) = 224 * Cb(a) + 128 Cr(d) = 224 * Cr(a) + 128 ( アナログ RGB 信号の量子化によるデジタル変換式 ) R(d) = 219 * R(a) + 16 G(d) = 219 * G(a) + 16 B(d) = 219 * B(a) + 16 ( R(a), G(a), B(a) は 0.0 〜 1.0 の範囲のアナログデータ、 R(d), G(d), B(d) は 16 〜 235 の範囲のデジタルデータ ) ( デジタル RGB 信号 -> デジタル Y, Cb, Cr 信号 ) Y = 0.299R + 0.587G + 0.114B 輝度成分(RGB各帯域の比視感度を適用) Cr= 0.511R - 0.428G - 0.083B 色差成分(赤) Cb=-0.172R - 0.339G + 0.511B 色差成分(青)CCIR601 (TVスケール) RGB->YCbCr ( CCIR601 [ ITU-R BT.601 ] ) ( デジタル RGB 信号 -> デジタル Y, Cb, Cr 信号 ) ( R(d), G(d), B(d), Y は 16 〜 235 の範囲のデジタルデータ ) ( Cb, Cr は 16 〜 240 の範囲のデジタルデータ ) Y = 0.299R + 0.587G + 0.114B 輝度成分(RGB各帯域の比視感度を適用) Cr= 0.511R - 0.428G - 0.083B 色差成分(赤) Cb=-0.172R - 0.339G + 0.511B 色差成分(青) 輝度(Y) 16〜235(220) [ 16が真っ黒、235が真っ白 ] [ 輝度は 220 の量子化レベル ] 色差(UV) 16〜240 (225) 無彩色(白,黒,灰色)が128 [ 色差は無彩色レベルが 128 を中心に 225 の量子化レベル ] 255 / 219 [ 輝度量子化レベル ] = 1.1643.. --> 1.164 0.511.. / 1.164 --> 0.439 0.428.. / 1.164 --> 0.368 0.083.. / 1.164 --> 0.071 0.172.. / 1.164 --> 0.148 0.339.. / 1.164 --> 0.291 ◆ YC 圧縮する場合の RGBからの、変換式 http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html ( R, G, B は 0 〜 255 の範囲のデジタルデータ ) ( Y は 16 〜 235 の範囲のデジタルデータ ) ( Cb, Cr は 16 〜 240 の範囲のデジタルデータ ) Y = 0.257R + 0.504G + 0.098B + 16 Cr = 0.439R - 0.368G - 0.071B + 128 Cb = -0.148R - 0.291G + 0.439B + 128 YCbCr->RGB ( R(d), G(d), B(d) Y は 16 〜 235 の範囲のデジタルデータ ) ( Cb, Cr は 16 〜 240 の範囲のデジタルデータ ) R = Y + 1.371Cr G = Y - 0.698Cr - 0.336Cb B = Y + 1.732Cb 輝度(Y) 16〜235(220) [ 16が真っ黒、235が真っ白 ] [ 輝度は 220 の量子化レベル ] 色差(UV) 16〜240 (225) 無彩色(白,黒,灰色)が128 [ 色差は無彩色レベルが 128 を中心に 225 の量子化レベル ] 255 / 219 [ 輝度量子化レベル ] = 1.1643.. --> 1.164 127 / 112 [ 色差量子化レベル ] = 1.1339.. --> 1.134 128 / 112 [ 色差量子化レベル ] = 1.1428.. --> 1.143 1.371.. * 1.143 --> 1.567 0.698.. * 1.143 --> 0.798 0.336.. * 1.143 --> 0.384 1.732.. * 1.143 --> 1.980 ◆ YC 伸張する場合の RGBへの、かってに変換式? V4L, V4L2 (BT878) の YUYV(yuy2) から、RGBへの、かってに変換式? ( BT878(BT848) を使用して、 RGBで、キャプチャすると時々、横線ノイズがでる。 YUY2(YUV4:2:2)なら問題なし。 したがって、下記の、かってに変換式で、変換し、 画像処理してます。) ・V4L VIDEO_PALETTE_YUYV --> VIDEO_PALETTE_RGB32(24) で、 ・V4L2 V4L2_PIX_FMT_YUYV --> V4L2_PIX_FMT_BGR32(24)、 V4L2_PIX_FMT_YUV420 --> V4L2_PIX_FMT_BGR32(24) で、 問題なく使用してます。 (かってに式、作って使用してますが、保証はありません...) ( R, G, B は 0 〜 255 の範囲のデジタルデータ ) ( Y は 16 〜 235 の範囲のデジタルデータ ) ( Cb, Cr は 16 〜 240 の範囲のデジタルデータ ) R = 1.164(Y-16) + 1.567(Cr-128) G = 1.164(Y-16) - 0.798(Cr-128) - 0.384(Cb-128) B = 1.164(Y-16) + 1.980(Cb-128) RGB は、ほぼ、0〜255 の間を取るように変換、 実際は、0 より小さい時、0 にし、 255 より大きい時、255 の処理必要。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html ◆ 8bitフルスケール YUV と 8bitフルスケール RGB の 相互変換データ範囲 Y 0 - 255 U/V -128 127 1394TA IIDC spec. 0から255にするには U,VをU-128,V-128に置き換える RGB 0 - 255 RGB to YUV Y = 0.299R + 0.587G + 0.114B U = -0.169R - 0.331G + 0.500B V = 0.500R - 0.419G - 0.081B YUV to RGB R = 1.000Y + 1.402V G = 1.000Y - 0.344U - 0.714V B = 1.000Y + 1.772Uストレート変換の場合はTMPGEncに「Basic YCbCr」として 出力すればロスが少ない。 Yが16〜235、CbやCrが16〜240の範囲を激しくオーバーしてしまい、 白飛びや黒つぶれや色が濃くなりすぎ R = Y + Cr G = Y - 0.508Cr - 0.186Cb B = Y + Cb "ximglib4.c" ir= yc[du + j] + c1[du + j]; if (ir > HIGH) ir= HIGH; if (ir < LOW) ir= LOW; ig= yc[du + j] - 0.508 * c1[du + j] - 0.186 * c2[du + j]; ib= yc[du + j] + c2[du + j];● オリジナル http://v4l2spec.bytesex.org/spec/capture-example.html ◆ V4L2 必要 ( Fedora core3, core4, core5 OK ) ◆ "videodev2.h" 必要 注) 上記クリックで、videodev2.h が、ダウンロードできます。 "vid_dev2.tar" となってますが、ダウンロード後、 ( 圧縮してないので、解凍不要です。ダウンロード可能にする為 xxx.tar ) videodev2.h に、リネームして下さい。============================================================== *******<< ★ かってに V4L(V4L1) ビデオキャプチャー [ 開始 ] >>*******#define TEST 1 #if TEST #else /* TEST */ #endif /* TEST */の、部分を、上記で説明のように、 オリジナルを、変更してあります。 $ gcc sample.c $ ./a.out > test.ppm KView 等で、 test.ppm を表示できる。/* * "sample.c" * http://v4l2spec.bytesex.org/spec/capture-example.html */ /* * V4L2 mmap capture example */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <getopt.h> /* getopt_long() */ #include <fcntl.h> /* low-level i/o */ #include <unistd.h> #include <errno.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/time.h> #include <sys/mman.h> #include <sys/ioctl.h> #include <asm/types.h> /* for videodev2.h */ #include "videodev2.h" #define TEST 1 #define CLEAR(x) memset (&(x), 0, sizeof (x)) struct buffer { void * start; size_t length; }; static char * dev_name = NULL; static int fd = -1; struct buffer * buffers = NULL; static unsigned int n_buffers = 0; static void errno_exit (const char * s) { fprintf (stderr, "%s error %d, %s\n", s, errno, strerror (errno)); exit (EXIT_FAILURE); } static int xioctl (int fd, int request, void * arg) { int r; do r = ioctl (fd, request, arg); while (-1 == r && EINTR == errno); return r; } static void process_image(const void *p) { #if TEST int i, j; /* raw ppm format */ fprintf(stdout,"P6\n %d %d\n 255\n", 640, 480); fflush(stdout); for(i= 0; i< 480; i++) { for(j= 0; j< 640; j++) { /* BGR --> RGB */ fwrite(p + (i * 640 + j) * 3 + 2, 1, 1, stdout); fwrite(p + (i * 640 + j) * 3 + 1, 1, 1, stdout); fwrite(p + (i * 640 + j) * 3 , 1, 1, stdout); } } /* * exit (0); */ #else /* TEST */ fputc ('.', stdout); fflush (stdout); #endif /* TEST */ } static void mainloop (void) { unsigned int count; #if TEST count = 1; #else /* TEST */ count = 100; #endif /* TEST */ while (count-- > 0) { struct v4l2_buffer buf; for (;;) { fd_set fds; struct timeval tv; int r; FD_ZERO (&fds); FD_SET (fd, &fds); /* Timeout. */ tv.tv_sec = 2; tv.tv_usec = 0; r = select (fd + 1, &fds, NULL, NULL, &tv); if (-1 == r) { if (EINTR == errno) continue; errno_exit ("select"); } if (0 == r) { fprintf (stderr, "select timeout\n"); exit (EXIT_FAILURE); } break; } CLEAR (buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; if (-1 == xioctl (fd, VIDIOC_DQBUF, &buf)) { switch (errno) { case EAGAIN: continue; case EIO: /* Could ignore EIO, see spec. */ /* fall through */ default: errno_exit ("VIDIOC_DQBUF"); } } assert (buf.index < n_buffers); process_image (buffers[buf.index].start); if (-1 == xioctl (fd, VIDIOC_QBUF, &buf)) errno_exit ("VIDIOC_QBUF"); } } static void stop_capturing (void) { enum v4l2_buf_type type; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == xioctl (fd, VIDIOC_STREAMOFF, &type)) errno_exit ("VIDIOC_STREAMOFF"); } static void start_capturing (void) { unsigned int i; enum v4l2_buf_type type; for (i = 0; i < n_buffers; ++i) { struct v4l2_buffer buf; CLEAR (buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (-1 == xioctl (fd, VIDIOC_QBUF, &buf)) errno_exit ("VIDIOC_QBUF"); } type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == xioctl (fd, VIDIOC_STREAMON, &type)) errno_exit ("VIDIOC_STREAMON"); } static void uninit_device (void) { unsigned int i; for (i = 0; i < n_buffers; ++i) { if (-1 == munmap (buffers[i].start, buffers[i].length)) errno_exit ("munmap"); } } static void init_device (void) { struct v4l2_capability cap; struct v4l2_cropcap cropcap; struct v4l2_crop crop; struct v4l2_format fmt; struct v4l2_requestbuffers req; if (-1 == xioctl (fd, VIDIOC_QUERYCAP, &cap)) { if (EINVAL == errno) { fprintf (stderr, "%s is no V4L2 device\n", dev_name); exit (EXIT_FAILURE); } else { errno_exit ("VIDIOC_QUERYCAP"); } } if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { fprintf (stderr, "%s is no video capture device\n", dev_name); exit (EXIT_FAILURE); } if (!(cap.capabilities & V4L2_CAP_STREAMING)) { fprintf (stderr, "%s does not support streaming I/O\n", dev_name); exit (EXIT_FAILURE); } /* Select video input, video standard and tune here. */ cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == xioctl (fd, VIDIOC_CROPCAP, &cropcap)) { /* Errors ignored. */ } crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; crop.c = cropcap.defrect; /* reset to default */ if (-1 == xioctl (fd, VIDIOC_S_CROP, &crop)) { switch (errno) { case EINVAL: /* Cropping not supported. */ break; default: /* Errors ignored. */ break; } } CLEAR (fmt); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = 640; fmt.fmt.pix.height = 480; #if TEST fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24; #else /* TEST */ /* * fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR32; * fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; * USB WebCamera (YUV420P) --> V4L2_PIX_FMT_YUV420 */ fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; #endif /* TEST */ fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; if (-1 == xioctl (fd, VIDIOC_S_FMT, &fmt)) errno_exit ("VIDIOC_S_FMT"); /* Note VIDIOC_S_FMT may change width and height. */ CLEAR (req); req.count = 4; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; if (-1 == xioctl (fd, VIDIOC_REQBUFS, &req)) { if (EINVAL == errno) { fprintf (stderr, "%s does not support " "memory mapping\n", dev_name); exit (EXIT_FAILURE); } else { errno_exit ("VIDIOC_REQBUFS"); } } if (req.count < 2) { fprintf (stderr, "Insufficient buffer memory on %s\n", dev_name); exit (EXIT_FAILURE); } buffers = calloc (req.count, sizeof (*buffers)); if (!buffers) { fprintf (stderr, "Out of memory\n"); exit (EXIT_FAILURE); } for (n_buffers = 0; n_buffers < req.count; ++n_buffers) { struct v4l2_buffer buf; CLEAR (buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = n_buffers; if (-1 == xioctl (fd, VIDIOC_QUERYBUF, &buf)) errno_exit ("VIDIOC_QUERYBUF"); buffers[n_buffers].length = buf.length; buffers[n_buffers].start = mmap (NULL /* start anywhere */, buf.length, PROT_READ | PROT_WRITE /* required */, MAP_SHARED /* recommended */, fd, buf.m.offset); if (MAP_FAILED == buffers[n_buffers].start) errno_exit ("mmap"); } } static void close_device (void) { if (-1 == close (fd)) errno_exit ("close"); fd = -1; } static void open_device (void) { struct stat st; if (-1 == stat (dev_name, &st)) { fprintf (stderr, "Cannot identify '%s': %d, %s\n", dev_name, errno, strerror (errno)); exit (EXIT_FAILURE); } if (!S_ISCHR (st.st_mode)) { fprintf (stderr, "%s is no device\n", dev_name); exit (EXIT_FAILURE); } fd = open (dev_name, O_RDWR /* required */ | O_NONBLOCK, 0); if (-1 == fd) { fprintf (stderr, "Cannot open '%s': %d, %s\n", dev_name, errno, strerror (errno)); exit (EXIT_FAILURE); } } static void usage (FILE * fp, int argc, char ** argv) { fprintf (fp, "Usage: %s [options]\n\n" "Options:\n" "-d | --device name Video device name [/dev/video]\n" "-h | --help Print this message\n", argv[0]); } static const char short_options [] = "dh"; static const struct option long_options [] = { { "device", required_argument, NULL, 'd' }, { "help", no_argument, NULL, 'h' }, { 0, 0, 0, 0 } }; int main (int argc, char ** argv) { #if TEST dev_name = "/dev/video0"; #else /* TEST */ dev_name = "/dev/video"; #endif /* TEST */ for (;;) { int index; int c; c = getopt_long (argc, argv, short_options, long_options, &index); if (-1 == c) break; switch (c) { case 0: /* getopt_long() flag */ break; case 'd': dev_name = optarg; break; case 'h': usage (stdout, argc, argv); exit (EXIT_SUCCESS); default: usage (stderr, argc, argv); exit (EXIT_FAILURE); } } open_device (); init_device (); start_capturing (); mainloop (); stop_capturing (); uninit_device (); close_device (); exit (EXIT_SUCCESS); return 0; } /* * GNU Free Documentation License */( Fedora core4 にて、Qcam Pro 4000 QV-4000WH 動作確認済み ) [ サンプルプログラム 2004/10/10 更新 ] 注) V4L(V4L1) で、 ビデオキャプチャー ソフトを 作成する場合の話しです。 ◆ QV-4000WH を、xawtv にて、表示してみる。へは、ここを、クリック。*******<< ★ かってに V4L(V4L1) ビデオキャプチャー [ 終了 ] >>******* ==============================================================640x480 で、15 frame / sec で、表示できてます。 ( /sbin/modprobe pwc size=vga fps=15 mbufs=1 compression=0 を指定しないと、640x480 で、10 frame / sec の性能 ) USBカメラQcam [ 30万画素CCD搭載のWebカメラ(white) ] http://www.logicool.co.jp/products/videocamera/qv_4000wh.html 左側の数字は、当方所有台数 7 Qcam Pro 4000 QV-4000WH ロジクール 2003/12/05 True30万画素CCDセンサー YUV420P 12bit の高画質のシリーズhttp://www.jsk.t.u-tokyo.ac.jp/~takeshi/Video4Linux/ http://search.luky.org/linux-users.7/msg01495.html 上記、参考に、した人から、 Video4Linuxでトップにくる日本語のページ を実行しても、VIDIOCSCHANではじかれてしまいます。 また、Linuxに画像処理入門という本のも、 VIDIOCMCAPTUREの部分ではじかれちゃいます。 xawtvではエラーは出るものの、ちゃんと表示できるので、 Video4Linuxには対応してる感じがするのですが・・・。 何か感じることがあったら教えてください。 USBでのVideo for Linuxのことはなぜかどのサイトにも載っておらず... との、要望が、ありましたので、● Linuxで、Bt878 カードで、キャプチャーするには、 ★ かってに Bt878 カードで、キャプチャー を参照のこと。 注) Fedora core3, core4, core5 は、/etc/modules.conf ではなく、 /etc/modprobe.conf になった。設定方法も異なるものもある。USB ( YUV420P 12bit の高画質のシリーズタイプ ) の、設定は、すでにしてあること。 当方で、確認用に、( NTSC ) 作製した、リストを、掲載します。 あくまで、参考です。 Fedora core3, core4, core5 にて、確認済。 尚、当方では、現在、V4L2, Xvideo を使って、Fedora core4, core5 で、 監視システム作製稼動中。 ◆ Fedora core3, core4, core5 用、pwc 必要$ gcc -Wall -O -o bttvtest bttvtest.c -lm $ bttvtest > test.ppmKView 等で、 test.ppm を表示できる。/* bttvtest.c ( V4L1 使用 [ BT878 にて、YUV420P 確認済 ) ( USB[YUV420P 12bit の高画質のシリーズタイプ] 使用 ) ( ロジクール QV-4000WH 2004/10/09 Fedora core2 にて、 確認 OK [ PWCドライバー 追加必要 ] ) ver 1.2 oct.10,2004 feb.26,2004 edit by H.MATSUMOTO ( macmil.co.jp ) */ /* * gcc -Wall -O -o bttvtest bttvtest.c -lm * ( gcc -Wall -O -o bttvtest c/bttvtest.c -lm ) * * * 注) * A) V4L1_grab_ch.channel= 0; は、 * 通常 0: Television, 1: Composite1, 2: S-Video * 使用 CH に、変更して、使用の亊。 * * B) 対応フォーマット * 320 x 240 のみ、サポート時 * #define ALLOC_X_WIDTH 320 * #define ALLOC_Y_WIDTH 240 * に、する亊。 */ /* * 変更履歴 by H.MATSUMOTO ( macmil.co.jp ) * * 3) 24bit RGB ビデオフォーマット使用不可の時、 * 自動で、YUV420Pに、切替。 * oct.10,2004 変更 * * 2) BUFF_SIZE 中止にして、下記に、変更。 * *Bttv_buf_0= (unsigned char*)mmap(0, (size_t)gb_buffers.size, * oct. 9,2004 変更 * * 1) YUV420P 追加 * USB ( YUV420P 12bit の高画質のシリーズタイプ ) * [ USB WebCamera 用 (各社で、異なる) インストール必要 ] * YUV420Pとは * P は Planar format という意味 * YUV420P[YUV4:2:0] (I420) 12bit Y(WxH), U(WxH/4), V(WxH/4) * 全体で 1.5 * Width * Height のサイズとなる。 * ex) メモリ配列 --> Y(640x480), U(640x480/4), V(640x480/4) * Fedora core2 USB camera * http://abuail.ddo.jp/FC2/FC2_1.htm * * (かってに式、作って使用してますが、保証はありません...) * ( 問題なく使用してます。) * YC 伸張する場合の RGBへ変換式 * R = 1.164(Y-16) + 1.567(Cr-128) * G = 1.164(Y-16) - 0.798(Cr-128) - 0.384(Cb-128) * B = 1.164(Y-16) + 1.980(Cb-128) * RGB は 0〜255 の間を取るように伸張。 * 実際は、0 より小さい時、0 にし、 * 255 より大きい時、255 の処理必要。 * oct. 8,2004 変更 */ /* * http://www.jsk.t.u-tokyo.ac.jp/~takeshi/Video4Linux/ * http://search.luky.org/linux-users.7/msg01495.html * * 上記、参考に、した人から、 * * Video4Linuxでトップにくる日本語のページ * を実行しても、VIDIOCSCHANではじかれてしまいます。 * * また、Linuxに画像処理入門という本のも、 * VIDIOCMCAPTUREの部分ではじかれちゃいます。 * * xawtvではエラーは出るものの、ちゃんと表示できるので、 * Video4Linuxには対応してる感じがするのですが・・・。 * 何か感じることがあったら教えてください。 * * USBでのVideo for Linuxのことはなぜかどのサイトにも載っておらず... * * との、要望が、ありましたので、 * * Linuxで、Bt878 カードで、キャプチャーするには、 * ★ かってに Bt878 カードで、キャプチャー を参照のこと。 * 注) Fedora core2 は、/etc/modules.conf ではなく、 * /etc/modprobe.conf になった。設定方法も異なるものもある。 * * USB ( YUV420P 12bit の高画質のシリーズタイプ ) * の、設定は、すでにしてあることし、 * * 当方で、確認用に、( NTSC ) * 作製した、リストを、掲載します。 * あくまで、参考です。 * * * Fedora Core2 にて、確認済。 * 尚、当方では、現在、V4L2, Xvideo を使って、Fedora Core2 で、 * 監視システム作製稼動中。 * * * $ gcc -Wall -O -o bttvtest bttvtest.c -lm * * ( "/dev/video0" ) * $ bttvtest 0 > test.ppm * * ( "/dev/video1" ) * $ bttvtest 1 > test.ppm * * ( "/dev/video2" ) * $ bttvtest 2 > test.ppm * * KView 等で、 test.ppm を表示できる。 * * ( /dev/video0 を、root 以外で、アクセス可にする。 * $ su * # chmod go+rw /dev/video0 * # chmod go+rw /dev/video1 * # chmod go+rw /dev/video2 ) */ /* * NTSC ( National TV Standards Committee ) * 768 x 494 CCD * 640 x 480 * 日本や北米、中南米、台湾、韓国、 * 水平走査周波数は 15.734MHz、垂直走査周波数は 60Hz * * http://elm-chan.org/docs/rs170a/spec_j.html * 水平同期周波数(fH): fsc/227.5 = 15734Hz * 垂直同期周波数(fV): fH/262.5 = 59.94Hz * * 1フィールドは 262.5ライン * 1フレームは 29.97Hz * 1フレームのライン数は奇数(525ライン) * 走査線数 525本, 59.94フィールド。 * 輝度信号は Y= 0.30R+0.59G+0.11B */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <fcntl.h> #include <signal.h> #include <math.h> #include <unistd.h> #include <errno.h> #include <linux/videodev.h> /* * 対応フォーマット * 320 x 240 のみ、サポート時 * [ QV-60HS 等 ( spca5xx ドライバ ) ] * #define ALLOC_X_WIDTH 320 * #define ALLOC_Y_WIDTH 240 * に、する亊。 */ #define ALLOC_X_WIDTH 640 #define ALLOC_Y_WIDTH 480 #define VIDEO_MODE_NTSC 1 struct video_capability V4L1_grab_chap; struct video_channel V4L1_grab_ch; struct video_picture grab_pict; struct video_mmap mm; /* BT878 がデータを転送するメモリ空間 */ struct video_mbuf gb_buffers; int Bttv_used_yuv420= 0; int Grab_fd; int main(argc, argv) short argc; char *argv[]; { unsigned char *Bttv_buf_0; int i, j; int ch_no; char *dev_name; dev_name= "/dev/video0"; if (argc == 2) { ch_no= atoi(argv[1]); switch (ch_no) { case 1: dev_name= "/dev/video1"; break; case 2: dev_name= "/dev/video2"; break; case 3: dev_name= "/dev/video3"; break; default: dev_name= "/dev/video0"; break; } } /* Grab_fd= open(dev_name, O_RDWR); */ Grab_fd= open(dev_name, O_RDWR | O_NONBLOCK, 0); fprintf(stderr, "Grab_fd= %d\n", Grab_fd); if (Grab_fd <= 0) { perror("open"); return (-1); } /* * Video4Linux デバイス仕様の取得 */ if (ioctl(Grab_fd, VIDIOCGCAP, &V4L1_grab_chap) < 0) { perror("VIDIOCGCAP"); return (-1); } fprintf(stderr,"Video Capture Device Name : %s\n",V4L1_grab_chap.name); /* * 使用可能なチャネル情報の取得 */ for(i=0; i< V4L1_grab_chap.channels; i++) { V4L1_grab_ch.channel= i; if (ioctl(Grab_fd, VIDIOCGCHAN, &V4L1_grab_ch) < 0) { perror("VIDIOCGCHAN"); return (-1); } fprintf(stderr,"Video Source (%d) Name : %s\n",i, V4L1_grab_ch.name); } /* mmap 情報の取得 */ if(ioctl(Grab_fd, VIDIOCGMBUF, &gb_buffers) < 0) { perror("ioctl(VIDIOCGMBUF)"); return -1; } fprintf(stderr, "gb_buffers.size= 0x%x\n", gb_buffers.size); fprintf(stderr, "gb_buffers.frames= %d\n", gb_buffers.frames); fprintf(stderr, "gb_buffers.offsets[0]= 0x%x\n", gb_buffers.offsets[0]); fprintf(stderr, "gb_buffers.offsets[1]= 0x%x\n", gb_buffers.offsets[1]); fprintf(stderr, "gb_buffers.offsets[2]= 0x%x\n", gb_buffers.offsets[2]); /* * mmap * * Bttv_buf_0 を先頭とするメモリ空間確保。 */ Bttv_buf_0= (unsigned char*)mmap(0, (size_t)gb_buffers.size, (int)(PROT_READ | PROT_WRITE), (int)MAP_SHARED, (int)Grab_fd, (size_t)0); fprintf(stderr, "Bttv_buf_0= %d\n", (int)Bttv_buf_0); if (Bttv_buf_0 == MAP_FAILED) { perror("mmap"); return (-1); } /* * V4L1_grab_ch.channel=1; * 0: V4L1_grab_ch.name="Television" * 1: V4L1_grab_ch.name="Composite1"; * 2: V4L1_grab_ch.name="S-Video" */ /* "Television" を選択する時 */ /* * V4L1_grab_ch.channel= 0; * V4L1_grab_ch.name="Television" * V4L1_grab_ch.type= VIDEO_TYPE_TV; */ /* "Composite1" を選択する時 */ /* * V4L1_grab_ch.channel= 1; * V4L1_grab_ch.name="Composite1"; * V4L1_grab_ch.type= VIDEO_TYPE_CAMERA; */ V4L1_grab_ch.channel= 0; V4L1_grab_ch.tuners= 0; V4L1_grab_ch.type= VIDEO_TYPE_CAMERA; V4L1_grab_ch.norm= VIDEO_MODE_NTSC; /* * キャプチャするチャネルの設定 */ if (ioctl(Grab_fd, VIDIOCSCHAN, &V4L1_grab_ch) < 0) { perror("VIDIOCSCHAN"); return (-1); } /* BT878 がデータを転送するメモリ空間 */ mm.frame = 0; mm.height = ALLOC_Y_WIDTH; mm.width = ALLOC_X_WIDTH; mm.format = VIDEO_PALETTE_RGB24; /* * frame #0 にキャプチャ開始指示 */ if (ioctl(Grab_fd, VIDIOCMCAPTURE, &mm) < 0) { /* V4L2 の時 --> imgfmt.fmt.pix.pixelformat= V4L2_PIX_FMT_YUV420; */ mm.format = VIDEO_PALETTE_YUV420P; if (ioctl(Grab_fd, VIDIOCMCAPTURE, &mm) < 0) { printf("iocto(VIDIOCMCAPTURE) \n"); /* return */ return (-1); } /* if */ else { Bttv_used_yuv420= 1; } } /* * frame #0 キャプチャ終了待ち */ if (ioctl(Grab_fd, VIDIOCSYNC, &mm.frame) < 0) { perror("VIDIOCSYNC"); return (-1); } /* raw ppm フォーマット */ fprintf(stdout,"P6\n %d %d\n 255\n", ALLOC_X_WIDTH, ALLOC_Y_WIDTH); fflush(stdout); if (Bttv_used_yuv420 != 1) { for(i= 0; i< ALLOC_Y_WIDTH; i++) { for(j= 0; j< ALLOC_X_WIDTH; j++) { /* BGR --> RGB 順番の入れかえ */ fwrite(Bttv_buf_0 + (i * ALLOC_X_WIDTH + j) * 3 + 2, 1, 1, stdout); fwrite(Bttv_buf_0 + (i * ALLOC_X_WIDTH + j) * 3 + 1, 1, 1, stdout); fwrite(Bttv_buf_0 + (i * ALLOC_X_WIDTH + j) * 3 , 1, 1, stdout); } } } else { /*+++++++++++++++++++++++++++++++++*/ /*=======<< start YUV420P >>=======*/ /* by H.MATSUMOTO ( macmil.co.jp ) */ /*+++++++++++++++++++++++++++++++++*/ int y_data; int c1_data; /* c1: V (R-Y) 色差信号(Cr) [ 色差成分(赤) ] */ int c2_data; /* c2: U (B-Y) 色差信号(Cb) [ 色差成分(青) ] */ int r_data; int g_data; int b_data; int img_addr; int c1_start; int c2_start; int c1_start_org; int c2_start_org; int add_cnt; unsigned char rgb_data[2]; /* * YUV420Pとは * P は Planar format という意味 * YUV420P[YUV4:2:0] (I420) 12bit Y(WxH), U(WxH/4), V(WxH/4) * 全体で 1.5 * Width * Height のサイズとなる。 * ex) メモリ配列 --> Y(640x480), U(640x480/4), V(640x480/4) * img_addr, c2_start_org, c1_start_org */ img_addr= 0; c2_start_org= img_addr + (ALLOC_X_WIDTH * ALLOC_Y_WIDTH); c1_start_org= img_addr + (ALLOC_X_WIDTH * ALLOC_Y_WIDTH) + (ALLOC_X_WIDTH * ALLOC_Y_WIDTH / 4); for(i= 0; i< ALLOC_Y_WIDTH; i++) { add_cnt= i / 2; add_cnt *= (ALLOC_X_WIDTH / 2); c1_start= c1_start_org + add_cnt; c2_start= c2_start_org + add_cnt; for(j= 0; j< ALLOC_X_WIDTH; j += 2) { /* * by H.MATSUMOTO ( macmil.co.jp ) * * (かってに式、作って使用してますが、保証はありません...) * ( 問題なく使用してます。) * YC 伸張する場合の RGBへ変換式 * R = 1.164(Y-16) + 1.567(Cr-128) * G = 1.164(Y-16) - 0.798(Cr-128) - 0.384(Cb-128) * B = 1.164(Y-16) + 1.980(Cb-128) * RGB は 0〜255 の間を取るように伸張。 * 実際は、0 より小さい時、0 にし、 * 255 より大きい時、255 の処理必要。 * * 実際は、小数点を使用しないで、 * 整数で、作成しないと、処理時間がかかる。 * * ex.) 1164 * (Y0-16) / 1000 等、 * 又は、1024 掛けた常数を使用し、 * >>10 で、/ 1024 の代りとする等。 * 当方で、実際に、使用しているものは、 * 1024 掛けた常数を使用し、 * >>10 で、/ 1024 の代りとして使用している。 * * 尚、当方では、現在、V4L2, Xvideo を使って、Fedora Core2 で、 * 監視システム作製稼動中。 */ y_data= Bttv_buf_0[ img_addr++ ] & 0xff; c1_data= Bttv_buf_0[ c1_start++ ] & 0xff; /* c1_data - 128 */ c2_data= Bttv_buf_0[ c2_start++ ] & 0xff; /* c1_data - 128 */ y_data= 1164 * (y_data - 16); c1_data -= 128; c2_data -= 128; r_data= (y_data + 1567 * c1_data) / 1000; if (r_data > 255) r_data= 255; if (r_data < 0) r_data= 0; g_data= (y_data - 798 * c1_data - 384 * c2_data) / 1000; if (g_data > 255) g_data= 255; if (g_data < 0) g_data= 0; b_data= (y_data + 1980 * c2_data) / 1000; if (b_data > 255) b_data= 255; if (b_data < 0) b_data= 0; rgb_data[0]= r_data; fwrite(rgb_data, 1, 1, stdout); rgb_data[0]= g_data; fwrite(rgb_data, 1, 1, stdout); rgb_data[0]= b_data; fwrite(rgb_data, 1, 1, stdout); y_data= Bttv_buf_0[ img_addr++ ] & 0xff; y_data= 1164 * (y_data - 16); r_data= (y_data + 1567 * c1_data) / 1000; if (r_data > 255) r_data= 255; if (r_data < 0) r_data= 0; g_data= (y_data - 798 * c1_data - 384 * c2_data) / 1000; if (g_data > 255) g_data= 255; if (g_data < 0) g_data= 0; b_data= (y_data + 1980 * c2_data) / 1000; if (b_data > 255) b_data= 255; if (b_data < 0) b_data= 0; rgb_data[0]= r_data; fwrite(rgb_data, 1, 1, stdout); rgb_data[0]= g_data; fwrite(rgb_data, 1, 1, stdout); rgb_data[0]= b_data; fwrite(rgb_data, 1, 1, stdout); } /* loop */ } /* loop */ /*+++++++++++++++++++++++++++++++++*/ /*=======<< end YUV420P >>=======*/ /* by H.MATSUMOTO ( macmil.co.jp ) */ /*+++++++++++++++++++++++++++++++++*/ } /* elseif (Bttv_used_yuv420 != 1) */ munmap((void *)Bttv_buf_0, (size_t)gb_buffers.size); close(Grab_fd); return (0); } /* main */上記で、動作しない場合、 $ xawtv -hwscan と、実行し、下記のように、 /dev/video0, /dev/video1 が、 表示されたものを使用。 2枚差しの場合の、2枚目の時は、 "/dev/video1" で、open 。/dev/video0: OK [ -device /dev/video0 ] type : v4l name : Logitech QuickCam Pro 4000 flags: capture /dev/video1: OK [ -device /dev/video1 ] type : v4l2 name : BT878 video (IODATA GV-BCTV5/PC flags: overlay capture tuner● USBでのVideo for Linuxのことはなぜかどのサイトにも載っておらず... http://www.media.t-kougei.ac.jp/~nagae/v4l/qv/v4letude/v4letude.html との、Mailが、ありましたので、 USBカメラ、 2004/10/09 購入しました。 640x480 で、15 frame / sec で、表示できてます。 ( /sbin/modprobe pwc size=vga fps=15 mbufs=1 compression=0 を指定しないと、640x480 で、10 frame / sec の性能 )USBカメラQcam [ 30万画素CCD搭載のWebカメラ(white) ] http://www.logicool.co.jp/products/videocamera/qv_4000wh.html Qcam Pro 4000 QV-4000WH ロジクール 2003/12/05 True30万画素CCDセンサー フォーカス マニュアル焦点 16cm〜∞ ケーブル長 178cm 重量 200g(本体)70g(クリップ) YUV420P 12bit の高画質YUV420Pとは P は Planar format という意味 YUV420P[YUV4:2:0] (I420) 12bit Y(WxH), U(WxH/4), V(WxH/4) 全体で 1.5 * Width * Height のサイズとなる。 ex) メモリ配列 --> Y(640x480), U(640x480/4), V(640x480/4) VIDEO_PALETTE_YUV420P ( V4L ) V4L2_PIX_FMT_YUV420 ( V4L2 ) YUV420P は PWC 等の ドライバが、必要 ◆ YUV422はYUV420に比べて2倍の色差信号を持つ YUYV キャプチャ後 YUV420P への変換 ffmpeg の rawvideo 形式 (YUV420Pの画像が連続して配置してありヘッダーも何も無い形式) ◆ YUV12 YUV411方式とYUV420方式の総称。 1ピクセル当たり12ビットのデータ量になるためYUV12と呼ぶ。 ◆ YUV411方式は、 2x2の4ピクセルの中から輝度情報(Y)を4サンプル、 輝度と赤色成分の差(U)、 輝度と青色成分の差(V)をそれぞれ1サンプル採る方式。 この方式はDVやMPEGに使われている。 ◆ YUV420方式は、 2x2の4画素の最初のラインの2 ピクセルからU成分を1サンプル、 次のラインの2ピクセルからV成分を1サンプル採る方式。 http://www2h.biglobe.ne.jp/~hnakamur/technolab/linux/video/qcam/qcam.htm● pwc の、インストール ( pwcx 不要 ) Fedora core3, 4, core5 で、QV-4000 を使用する。 注) Fedora core6, Fedora 7,8 では、linux/config.h が、 なくなった関係で、エラーがでるが、 標準の、pwc.ko は、問題なく使用できるので、 標準の、pwc.ko のままで使用する。[ 2006/10/26 ] ( USB ハブ は、使用しないこと )◆ Fedora core3、core4, core5 用、pwc ( core4, core5 標準の、pwc.ko で、問題ある時、使用する )◆ Fedora core4 は、標準で、v4l(v4l1) 版の、ドライバーが、入っている。 /lib/modules/$(uname -r)/kernel/drivers/usb/media/pwc/pwc.ko [ /lib/modules/$(uname -r)/kernel/drivers/usb/media/pwc.ko とは異なる ] Cannot open '/dev/video3': 12, Cannot allocate memory 等の、エラーがでる。その際、上記のものを使用する )Philipsの WebCamera の PWCドライバー http://www.saillard.org/pwc/ pwc-10.0.11.tar.bz2 を、ダウンロード。 [ pwc-10.0.11.tar.bz2 ( 2006/01/08 ) 45.85KB ]注) v4l2 対応版は、xawtv 起動後、サイズを変更すると、観れなくなる。ダウンロードした、ディレクトリに移動し、注) kernel-develが、インストールされていること。# rpm -qa | grep kernel-devel インストールされていない場合、(kernel と同じバージョン) kernel-develを、先に、インストールしておくこと。 ( /usr/bin/yum install kernel-devel 又は、rpm 等 )注) pwc.ko の、インストール位置が異なる。◆ Fedora core3 まで、 # cp -p pwc.ko /lib/modules/$(uname -r)/kernel/drivers/usb/media/◆ Fedora core4, core5 以降 # cp -p pwc.ko /lib/modules/$(uname -r)/kernel/drivers/usb/media/pwc/ ( Fedora core4, core5 以降 は、標準で、pwc.ko が、入っており、 場所を、間違えても、 # /sbin/lsmod | grep pwc pwc が、表示される( この場合、標準の pwc.ko ) が、 ここで作成したものと異なり、うまくいかないので注意。と、インストール位置が異なる。Fedora core6, Fedora 7,8 では、 パッチをあてないと、make エラーとなるので、 標準の、pwc.ko を使用のこと$ tar -jxvf pwc-10.0.11.tar.bz2 $ cd pwc-10.0.11 $ make $ su # cp -p pwc.ko /lib/modules/$(uname -r)/kernel/drivers/usb/media/ # chown root:root /lib/modules/$(uname -r)/kernel/drivers/usb/media/pwc.ko( 万一、 Fedora core4, 5, core6 に、v4l2 対応版を、インストールする時は、 $ su # cp -p pwc.ko /lib/modules/$(uname -r)/kernel/drivers/usb/media/pwc/ # chown root:root /lib/modules/$(uname -r)/kernel/drivers/usb/media/pwc/pwc.ko となり、 media/pwc.ko が、media/pwc/pwc.ko となるので、注意のこと。 注) v4l2 対応版は、xawtv 起動後、サイズを変更すると、観れなくなる )# /sbin/depmod -a # /sbin/modprobe pwc size=vga fps=15 mbufs=1 compression=0 # /sbin/lsmod | grep pwc pwc が、含まれていれば、OK pwc 76656 0 videodev 9665 2 pwc,bttv ++++++++++++++++++++++++++++++++++++++++ === Fedora core4, core5 は、ここから === ++++++++++++++++++++++++++++++++++++++++ ( Fedora core4, core5 は、[ v4l(v4l1) のみ対応 ] /lib/modules/$(uname -r)/kernel/drivers/usb/media/pwc/pwc.ko が、 [ /lib/modules/$(uname -r)/kernel/drivers/usb/media/pwc.ko とは異なる ] 標準であるが、 Cannot open '/dev/video?': 12, Cannot allocate memory 等の、エラーがでる。その際、上記のものを使用する ) # vi /etc/rc.d/rc.local の、最後にFedora 7 に(パッチ必要)、v4l2 対応版を、インストールする時は、$ su # cp -p pwc.ko /lib/modules/$(uname -r)/kernel/drivers/media/video/pwc/pwc.ko # chown root:root /lib/modules/$(uname -r)/kernel/drivers/media/video/pwc/pwc*/sbin/modprobe pwc size=vga fps=15 mbufs=1 compression=0と、記述 ( 追加 )。 ◆ 上記完了後、再立上する。 ◆ /dev/video0 は root しかアクセスできないので $ su # chmod go+rw /dev/video0 又は、下記を参照。参考)# chmod go+rw /dev/video? 以外で、 立上時に、/dev/video? を、root 以外で、アクセス可にするにはへ◆ 当方用メモ ( Feodar core6, Fedora 7,8 用パッチ済 ) pwc-10.0.11.tar.bz2 用● Fedora 7 は、pwc-10.0.12 が入っている(下記は、当方専用メモ) pwc-10.0.12.fed7 +++++++ pwcmak11.tar pwc-h11.tar pwc-uh11.tar cp -p pwcmak11.tar pwc-10.0.11/Makefile cp -p pwc-h11.tar pwc-10.0.11/pwc.h cp -p pwc-uh11.tar pwc-10.0.11/pwc-uncompress.h +++++++ cp -p Makefile.pwc.10.0.11.fed7 pwc-10.0.11/Makefile cp -p pwc.h.10.0.11.fed7 pwc-10.0.11/pwc.h cp -p pwc-uncompress.h.10.0.11.fed7 pwc-10.0.11/pwc-uncompress.h◆ xawtv に関して。( Fedora core3 の、tvtime では、観れなかったので、 下記、xawtv 必要 ) ★ かってに xawtv を参照のこと。( 下記に、注意 )注) Fedora core2, 3, core4, core5 は、/usr/bin/xawtv の起動時、-nogl 必要 ( -nogl -noxv -nodga を、組合わせてみる [ CF-A2 の、FC5では、不要だった ] ) Fedora core2 から、xawtv が、tvtime になった。 したがって、xawtv は、ダウンロード必要。 ◆ xawtv にて、チェックしてみる。 $ xawtv -hwscan ( $ /usr/bin/xawtv -hwscan ) ( $ /usr/local/bin/xawtv -hwscan ) [ xawtv をダウンロードし、インストールの時 --> /usr/local/bin/xawtv ]/dev/video0: OK [ -device /dev/video0 ] type : v4l name : Logitech QuickCam Pro 4000 flags: capture等の、認識されていれば、OK。 ◆ xawtv にて、表示してみる。 注) pwc の、v4l2 対応版は、xawtv 起動後、サイズを変更すると、観れなくなる。$ xawtv -nogl -c /dev/video0 -geometry 640x480 & ( xawtv -nogl で、映らない時、下記、実施。 $ xawtv -nogl -noxv -c /dev/video0 -geometry 640x480 & -nogl -noxv -nodga を、組合わせてみる ) ( $ xawtv -nogl -noxv -c /dev/video0 -geometry 320x240 & ) ・/dev/video1 使用の時。 $ xawtv -nogl -c /dev/video1 -geometry 640x480 &注) 他のソフトが、Xvideo を使用している場合など、xawtv の起動時、-noxv 必要 $ xawtv -nogl で、映らない時、実施。 注) Fedora core2, core3, core4 は、xawtv の起動時、-nogl 必要 注) Fedora core5 は、-nodga 必要な場合有り [ nvidia の、ドライバー使用時 -nodga ] $ xawtv -nogl -noxv -nodga -c /dev/video0 -geometry 640x480 & [ -nogl disable OpenGL ] [ -noxv disable Xvideo extention altogether ] [ -nodga disable DGA extention ] ( -nogl -noxv -nodga を、組合わせてみる。CF-A2 の、Fedora core5 では、 $ xawtv -c /dev/video0 -geometry 640x480 & で、OK だった。) 注) Xvideo が、うまくいかない時、-noxv 必要 ◆ モジュールの切り離し # /sbin/rmmod pwc ◆ モジュールの再登録 /sbin/modprobe pwc size=vga fps=15 mbufs=1 compression=0 ( pwc-10.0.11.tar.bz2 で、v4l2 になり、mbufs=3 ではなく、mbufs=1 )参考) [ カーネル等の、バージョンアップ ( yum ) ] ● Fedora core アップデート[ update の方法 ] ( yum ) 参考) ◆ Fedora core の、kernel を、yum にて、バージョンアップ した時は、 kernel-devel も、バージョンアップ し、 その後、ivtv の、再 make で、*.ko を作成しなおすこと。USBはその規格により、 途中ハブか、リピータケーブル (IO-DATA USB-RP500[Aプラグ凹, Aプラグ凸])を 接続することで最大20mまで延長させることが出来る。 またハブ等の間の最大長は5mまで Luma は映像信号のうち輝度信号、 Chroma は色信号のことをさします。注) kernel-develが、インストールされていること。# rpm -qa | grep kernel-devel インストールされていない場合、(kernel と同じバージョン) /usr/src/redhat 以下に、必要なファイルが作成されないので、 kernel-develを、インストールすること。● PCに接続されているUSBデバイスの情報 $ cat /proc/bus/usb/devices | grep P:
★ ソフトダウンロードへ● 本サイトに掲載されている情報は個人の責任において、 使用のこと。 利用により、問題が発生しても、 当方は一切責任を負いかねます。 リンクは、自由に。 The information carried by this site is set with individual responsibility. Use it. Even if a problem occurs by use We cannot take any responsibility. A link is free. 410-0022 JAPAN by H.MATSUMOTO ( MACMIL.CO.JP 有限会社 松商商会 ) 410-0022 JAPAN by H.MATSUMOTO ( MACMIL.CO.JP MATSUSHOW CO.,LTD.) (C) 1998-2013 H.MATSUMOTO All Rights Reserved ( MACMIL.CO.JP )新会社法施行(2006/05/01施行)後、有限会社 松商商会 は、 特例有限会社という、新会社法の、株式会社です。(商号は、有限会社 を継続) 資本金 2017/05 5千万円→1千万円に減資 創業 1983/05/20 法人設立 1984/09/29