Armadillo-500 FX用USBカメラ接続


概略

Armadillo-500 FXにUSBカメラを接続して、Android上で画像表示させる方法について記載する。
記載、および、動作確認には、cupcakeバージョンを対象としている。
バージョンによっては、処理が異なる為、別途処理が必要な場合もある。

目次



カメラアプリについて

画面表示するために使用するカメラアプリについて記載する。

  • 使用するカメラアプリ
    • Android(Cupcake)のソースに含まれているアプリ
    • ”generic”でビルドした場合、もしくは、”USE_CAMERA_STUB := true”で指定した場合に、デバイスがなくても動作するアプリ
    • エミュレータとして動かした場合、動作するアプリ

  • カメラアプリの起動方法
    1. homeからアプリ一覧を表示させる
    2. ”Camera”(カメラ)と表示されているアイコンをタップする

  • 既存の動作について
    • 表示される画像は、デバイスに依存しない画像
    • 表示される画像は、ライブラリ内で生成している
    • 画像形式は、YUV形式の特殊な形式だと予想される

  • 注意事項
    • Androidのソースで、”USE_CAMERA_STUB := true”の指定をはずしただけだとリンクエラーとなる
    • カメラアプリで表示される画像は、モノクロとなっている
    • 画像形式は、YUV形式のようだが、OpenGLESがモノクロ表示のみである為、正しい指定かどうか判断できていない


カメラ処理概要

カメラアプリ部分から実際の画像生成部分までの処理の概要を説明する。

カメラ処理全体の関係図は、こんな感じかな。

各処理概要

  • カメラアプリ処理部分
    • カメラアプリを選択した場合に動作するアプリケーション部分
    • いわゆるSDKで作成できる部分で、フレームワーク層のクラスを利用している
    • ソース該当箇所
      • cupcake/packages/apps/Camera/
  • カメラクラス(フレームワーク)
    • アプリケーション上で、カメラ機能を使う為のフレームワーク
    • フレームワークとしては、JNIを利用してのJAVA層とC/C++層の橋渡しを実施
    • 広い意味では、C/C++層内部でのカメラサービスライブラリまでの連結までを含めてよいのかもしれない
    • ソース該当箇所
      • (JNI・Java層)cupcake/frameworks/base/core/java/android/hardware/Camera.java
      • (JNI・C++層)cupcake/frameworks/base/core/jni/android_hardware_Camera.cpp
      • (UI内カメラクラス)cupcake/frameworks/base/libs/ui/Camera.cpp
      • (メディアサーバ)cupcake/frameworks/base/media/mediaserver/
  • カメラサービスライブラリ
    • カメラ機能を使う為のライブラリとなる
    • カメラハードウェアに対応させる場合、このライブラリをうまくカーネルとつなげば良いと考えることができる
    • genericビルド時やエミュレータビルド時には、ここがスタブとなる
    • ソース格納箇所:
      • cupcake/frameworks/base/camera/libcameraservice
      • (カメラサービス本体)CameraService.cpp
      • (ハードウェア代替スタブ)CameraHardwareStub.cpp
      • (上記の画像生成部)FakeCamera.cpp

  • 注意事項
    • 当たり前ですが、説明には主観が思いっきり入ってる
    • そして、ソースを眺めただけなので、実際の動作と異なる可能性がある


USBカメラ接続方針

カメラアプリに対して、実際のカメラデバイスを接続する基本方針について記載する。

  • 基本姿勢
    • 動けば、OK(いいのか・・)
    • なので、流用できる部分は流用する
    • 簡単そうなので、UVCカメラを使う

  • 基本方針
    • カメラサービス内でエミュレータ用処理をベースとする
      • ハードウェア代替処理(CameraHardwareStub.cpp)をUSBカメラ用にする
      • 画像形式・処理については、フェイクカメラ(FakeCamera.cpp)を参考にする
    • ハードウェアを操作する処理は、V4L2インタフェイスを使用する
      • ドライバ部分は、カーネルコンフィグで対応
      • ドライバ利用は、公開されているライブラリを流用

上記の方針を図にすると、こんな感じかな。



前提環境(ソフト)

基本方針にそって説明していく上で、前提となる開発環境について記載する。

前提となる開発環境は、開発環境構築で構築した環境とする。
実際構築したベースを記しておく。

  • 確認したベースバージョン
    • kernelは、Armadillo-500FX用(v2.6.26-at6)
    • kernel以外は、cupcake

  • 注意事項
    • 最新のほうが扱いやすいと思われるが、試してません・・。


前提環境(ハード)

基本方針にそって説明していく上で、前提となるハード要素を記載する。
実際に確認したハードに対して、必要そうな要素を記載する。
要素があってれば、応用はできるかも。

  • Armadillo-500FX
    • ハード要素としては、USBのホスト機能が必要(たぶん、USB2.0対応が必要)
      • Armadillo-500FXでは、CON3(小さい基盤の方のCON3)
      • また、ホストとして使用するので、JP1をショートさせる

  • 注意事項
    • CON3、JP1については、ハードウェアマニュアルを参照ください。
      • インタフェースマニュアルは、でかい基盤用なので、違うっぽい
    • High-Speedで使用しないと、遅いかも。
    • 念の為、Armadillo-500FXが今回の対象としているハード


  • USBカメラ
    • ハード的な要素としては、カメラがUSBの規格にそっていること
      • UVC(USBビデオクラス)に準拠したUSBカメラであれば問題ないはず!

  • 注意事項
    • UVC準拠とかかれたWebカメラを見たことがない。
    • でも、UVCカメラと名の付いた商品はみたことある。
    • いちおう、実際に使用したカメラは、実験環境に書いてる。
    • 「ドライバのインストール不要」と書かれてる商品は、準拠してる可能性が高いはず


修正概要

基本方針にそって修正していく上の概要を記載する。

  • カーネル修正
    • カーネルについては、コンフィグレーションの変更で対応する
      • UCV用処理等は、カーネル内にドライバソースとして存在している
      • 先駆者の修正にのっとり、USB OTG機能を有効にする
      • V4L2インタフェイスを利用できるようにする
  • ミドル修正
    • V4L2を利用できるようにCameraHardwareStubを改造
      • V4L2を利用するライブラリとして、uvccaptureのコードを使用
      • あとは、構造体とインタフェイスを合わせる
      • カラーにしたい場合は、画像変換を追加する

  • 注意事項
    • uvccaptureのネタは、ブリリアントサービス様のブログから拝借
    • 他に、いろいろあるけど、各詳細で記載する


カーネル修正

カーネルの修正については、概要にあるように、コンフィグレーションを追加するだけになる。

  • ターゲット環境(Armadillo-500FX)での方法
    1. 端末で、カーネルフォルダ(cupcake/kernel)内に移動する
    2. 「make menuconfig」をタイプする
      • 上記のコマンドで、コンフィグ設定画面が起動する
    3. UVCサポートが有効になるように設定する
      1. 「Device Drivers」をエンターで選択する
      2. 「Multimedia Devices」をエンターで選択する
      3. 「Video for Linux」を「Y」でチェックする
      4. 「Video capture adapters」をエンターで選択する
      5. 「V4L USB devices」をエンターで選択する
      6. 「USB Video Class (UVC)」を「Y」でチェックする
      7. 「UVC input events device support」を「Y」でチェックする
    4. USB OTG機能が有効(HOST設定が無効)になるように設定する
      1. 「Device Drivers」をエンターで選択する
      2. 「USB support」をエンターで選択する
      3. 「Allow High Speed (on OTG port)」をエンターで選択する
        • 「EUHI HCD (USB2.0) support」の下のほうにある
      4. 「on OTG port」をエンターで選択する
    5. 設定変更したコンフィグファイルを保存する
      1. コンフィグのトップ階層まで戻る(「ESC」2回でひとつ上の階層に戻れる)
      2. 「Save an alternative Configuration File」を選択する
    6. 「armadillo500fx_dev_android_defconfig」に変更点をマージする
      • kernel/arch/arm/configsにあるファイル

  • それ以外の環境(予想)
    1. configファイルをロードする
    2. UVC サポートとUSB OTG有効(HOST有効)に設定する
    3. configファイルをセーブする

  • 注意事項
    • Armadillo-500FXでもConfigファイルをロードして変更したほうが楽な気がする
    • 直接ファイルを編集しても問題ないが、依存関係があるので注意が必要
    • USB OTGの設定は先駆者の設定によるが、ホスト機能があれば動く気がする
      • ただ、USB2.0サポートは必要かもしれない(UVCの規格上)


ミドル修正

ミドルというか、CameraHardwareStubの代替処理作成の概要について記載する。
ソース整理ができてないのと、中途半端な実装なので、ソースは謎のままに・・。

  • FakeCamera代替
    • V4L2インタフェイスを利用したソースを取得
    • 以下2ファイルを cupcake/frameworks/base/camera/libcameraservice に格納
      • v4l2uvc.c
      • v4l2uvc.h
  • CameraHardwareStubの代替
    • FakeCameraを利用した処理を v4l2uvc,h にあるインタフェイスで置き換える
      • クラス生成処理をmallocなどに置き換える
      • Cソースの「#include ”~”」を「extern "C" {}」で囲む
      • その他、もろもろ調整(ハード次第で時間かかるかも。。)
  • Android.mkの修正
    • 代替ファイルになるように置き換え
    • 「LOCAL_SHARED_LIBRARIES:= libui」に「 libui libc」を追加
      • 場合によっては不要

  • 注意事項
    • まとめるのが遅かったので、少しあやふやな部分がある。
    • 「uvccaptureコード」の扱いに注意が必要
      • GPLライセンスなので、リンクさせると、コピーレフト
      • 利用せずに、直接書いたほうがすっきりするかも
    • C++ソースとCソースのリンクに注意
      • C++からCソースの関数を呼ぶ場合、おまじない(extern "C")が必要
    • V4L2インタフェイスに設定するパラメタは、ハードに依存する
      • 使用したデバイスは、YUVのみ出力、かつ、縦長だけだった
      • デバイスからのデータをどこかで加工する必要がある
      • OpenGLを利用する関係で、YUVはモノクロになる
      • カラー希望ならば、RGBなどにする必要がある


つまづいたこと

今回実装する上でつまづいたことをまとめておく

  • C/C++ソースのリンク
    • C++からC関数をコールする場合、おまじない(extern "C")が必要
  • カメラ画像表示
    • デバイス特有かもしれないが、設定したサイズを縦長とか横長にする場合有り
    • ログを仕込んだりして、期待通り設定されているか知る必要有り
  • カラー表示(画像形式)
    • FakeCameraがYUV(packed)で実装されているが、カラーにはRGBが必要
    • 知らないと、画像形式の勉強をした後に、知ることに。。


次回やるならば

今回実装する上で失敗、保留した点をまとめておく

  • V4L2インタフェイスの利用方針
    • 楽をするために流用したが、独自で実装したほうがわかりやすいかも
    • インタフェイス資料はあるため、次回はカスタマイズして利用してみたい
  • デバイスのアクセス権限
    • カメラ接続時に、/dev/video0 が作成されるが、アクセス権限がない
    • 毎回ターミナルで設定すればいいが、起動時に設定されるようにしたい
  • 実装範囲
    • プレビューがメインだったため、一部関数のみ実装したが、フル機能にしたい。
  • 実効速度
    • カラー表示のため、YUV→RGB処理を入れたが、計算に時間がかかる模様
    • 浮動小数→固定小数とかで、速度向上が必要
    • バッファの数見直しも必要


参考資料

USBカメラ接続において参考となる資料のリンク先をまとめて記載する。

最終更新:2010年03月02日 00:10