###########################
# UVCデバイス(お散歩綾香) #
###########################

UVCデバイス(お散歩綾香)を作りました。P/ECEの画面を、PCのビデオキャプチャソフトに表示します。
Windowsからは、P/ECEがUSBビデオデバイスとして認識され、「デジタルカメラ」に見えます。

『UVCデバイス』は独立したアプリではなく、ライブラリの機能として作成しました。
『UVCデバイス』の応用例として、お散歩綾香の映像を、P/ECEからPCへ送信するようにしてみました。

================
インストール方法
================

「uvcayaka.pex」をP/ECEに転送してください。

======
使い方
======

1. USBケーブルで、P/ECEをPCに接続してください。
2. P/ECEのメニュー画面で、「UVC(お散歩綾香)」を実行してください。
3. Windowsが、USBビデオデバイスを認識します。
   初回は、デバイスが認識されるまでに、数分間かかります。二回目以降は、すぐに認識します。
   デバイスマネージャの「イメージングデバイス」に、「USBビデオデバイス」のアイコンが出たら、認識完了です。
4. PCのビデオキャプチャソフトを実行してください。
   Windows Xpの場合は、OSにビデオキャプチャ機能が含まれていて、マイコンピュータの中にある「USBビデオデバイス」のアイコンをダブルクリックすると、簡単に表示できます。
   Windows 7の場合は、OSにビデオキャプチャ機能が含まれていないので、別途、ビデオキャプチャソフトをインストールする必要が有ります。
   僕は、DirectShowのサンプルアプリケーションの、AMCAP.EXEを使いました。
   AMCAP.EXEの入手方法としては、DirectShow SDKをインストールしなくても、市販のUSBカメラのドライバをインストールすると、AMCAP.EXEが含まれている事があるようです。
   http://buffalo.jp/download/driver/supply_old/bwc-130h01.html
5. P/ECEの方向ボタン,又は,A,Bボタンを押すと、お散歩綾香の背景が変わります。
6. P/ECEのSELECTボタンを押すと、「UVC(お散歩綾香)」が終了して、Windows上の「USBビデオデバイス」も消えます。

========
あとがき
========

これまでに何度かUSBデバイスを作ったのですが、今回は特に苦戦しました…
特に悩んだ点が、三点あります。

一点目は、ネゴシエーションに失敗した後の挙動です。
UVCクラスの仕様では、デバイス(=P/ECE)とホスト(=Windows)が、動画形式について特定の手順でやりとりをし、両方が対応可能な形式を決定します。
この動作を、ネゴシエーションと呼びます。
ネゴシエーションが成功すれば良いのですが、失敗した場合、Windowsから謎のデバイスリクエストが発行されて、正しいUSB通信が出来なくなる問題が生じました。
具体的には、'GET_CUR'というリクエストは26バイトのデータであるべきところ、Windowsから1バイトのデータが要求される…みたいな感じです。
いやたぶん僕のプログラムのバグだとは思うのですが(^^;、どうしても原因が判りませんでした。
結局、常にネゴシエーションが失敗しないような動画形式を、デバイス側からホスト側へ提案する事によって、問題を回避し解決しました。

二点目は、Windowsが対応可能な動画形式についてです。
UVCクラスの仕様では、無圧縮の動画形式として、YUY2とNV12が定義されています。
NV12の方がデータが小さくなるので、NV12を使おうと思ったのですが、パラメータをどんなに調整してもネゴシエーションが失敗しました。
Web上の情報をいろいろ調べたところ、どうやら、WindowsはNV12形式に対応していないみたいです。
YUY2形式に変えたところ、うまく動作しました。

三点目は、最大転送サイズの指定です。
具体的には、'GET_CUR'への応答の、dwMaxPayloadTransferSizeフィールドの値です。
フルスピードモードでアイソクロナス転送を用いる場合は、dwMaxPayloadTransferSizeの値は、エンドポイントのwMaxPacketSizeと同じでなくてはなりません。
wMaxPacketSizeよりも大きな値を指定すると、ネゴシエーションが失敗します。
一方、フルスピードモードでバルク転送を用いる場合は、エンドポイントのwMaxPacketSizeよりも大きくても構いません。
USBの通信方式を改めて考えてみると確かにその通りなのですが、ホストからはネゴシエーションの失敗理由が通知されないので、なかなか判らず悩みました。
ちなみに、最終的にはバルク転送を使うことにしたので、上記のアイソクロナス転送の制約は関係無くなったのですけれど、ひとつ勉強にはなりました。

ともかく、上手く動いて良かったです。
今回のプログラム作成の、参考にさせて頂いた資料やツールは、以下の通りです:

・「USB.org」(http://www.usb.org/)の『Video Class』(http://www.usb.org/developers/docs/devclass_docs/USB_Video_Class_1_1_090711.zip)の資料
　本家USBコンソーシアムのUVC仕様書です。
　特に「Video Device Examples」が参考になります。
　ただし、少し間違いが有って、他の資料も合わせて確認する必要が有りました。

・「諏訪工房」(http://www.suwa-koubou.jp/)さんの、『UVCカメラドライバーの製作』(http://www.suwa-koubou.jp/micom/UVCwebcam/uvc.html)の記事
　PICマイコンで、UVCカメラドライバーを制作なさったかたの記事です。
　今回、僕はデバイス側を制作したので、上記の記事とは作る部分が逆なのですけれど、UVCの挙動の調べ方を参考にさせて頂きました。
　この記事を見て、僕も「ELECOM DLK130TBK」(http://www2.elecom.co.jp/multimedia/pc-camera/ucam-dlk130t/)を購入して、USBパケットキャプチャで挙動を調べました。
　ちなみに、「ELECOM DLK130TBK」はハイスピードデバイスなので、そのままではハイスピードモードに適したネゴシエーションを行います。
　「ELECOM DLK130TBK」とPCとの間にフルスピードハブを挟むと、フルスピードモードに適したネゴシエーションを行います。
　P/ECEはフルスピードデバイスですから、参考にするには、後者の接続方法でUSBパケットキャプチャをするのが良いです。

・「サイプレス」(http://japan.cypress.com/)社の、『AN75779 - How to Implement an Image Sensor Interface with EZ-USB FX3 in a USB Video Class (UVC) Framework』(http://japan.cypress.com/?rID=62824)の資料
　EZ-USBを使ってUVCデバイスを実装した、サンプルプログラムがダウンロードできます。
　僕はEZ-USBを持っていないので実際に試して見る事は出来なかったのですけれど、マイコンメーカーの資料だからきっと信頼性が高く参考にしました。

・「HHD Software」(http://www.hhdsoftware.com/)社の、『Free USB Analyzer』(http://freeusbanalyzer.com/)
　無料のUSBパケットキャプチャソフトです。
　同社の有償ソフトの、一部の機能だけが利用できるバージョンみたいです。
　僕の用途ではこの無料版の機能だけで十分で、むしろ機能が少ない分、使い方が判り易かったです。
　無料のUSBパケットキャプチャソフトと言うと、『Usb Sniffer for Windows』(http://sourceforge.net/projects/usbsnoop/)がメジャーですけれど、64bit版Windowsで動作しない問題が有ります。
　『Free USB Analyzer』は、64bit版Windowsでも問題無く動作しました。

==================
Wed May 13 2015
Naoyuki Sawa
nsawa@piece-me.org
==================
