• スポンサードリンク

Nexus7(2012)で1920×1080解像度の映像

UsbWebCamera/UsbWebCameraPrで解像度を1920×1080に設定すると、Nexus7(2012)だと起動直後に映像を表示できない時があるみたい。と言うか縦の解像度が16の倍数じゃない時にダメになるみたい。←これはどうなんかよくわからなくなりました。1920×1080かそれ以上の解像度だとダメになる時が多いと言う方がより真実に近いかも。
ON/OFFボタンで一旦停止視させてから再度表示させると大抵は大丈夫。

カメラの種類によっては100%表示できるけど別のカメラだと9割ぐらいだめ(´・ω・`)
カメラの種類で違うってことはカメラとの接続・プレビュー開始のタイミングと、TextureView/SurfaceTexture/Surfaceの初期化のタイミングとによって変わるってことかなぁ(゜レ゜)

追加:
現状わかってることはこんな感じ。

  1. UVCのビデオペイロードヘッダーのエラービットが立ったままになる
    エラービットがたってたらそれを含むパケットは全部スキップするようにしていたので全然表示できなくなったみたい。でもエラービットを無視して処理すれば映像自体は取得できる。
    UVC機器側でエラービットを立てているのだと思ってたんだけどなぁ。
    UVCの規格だと、「ホストソフトウエアは、以下の条件の場合にはGET_CUR要求をError Code Controlへ送らなければならない。…」と書いてあって、その条件の1つが「ビデオ/スチルイメージペイロードヘッダーのエラービットが立った時(アイソクロナス転送時)」なので、Error Code ControlへGET_CURを送ってるんだけど。
    ちなみにlinuxのUVCドライバは単にスキップしてるだけ(-_-;)。ええんか?
  2. TextureViewで上半分にしか表示できなくなる
    1920×1080とそれ以上の解像度(バッファサイズ)で表示させようとした時のみ起こる。
    SurfaceTextureListener#onSurfaceTextureAvailableが呼び出された時点ではまだ初期化がちゃんと終わってなくてViewPort設定辺りがおかしくなっちゃうんだろうか?

この2つが必ず同時に起こる。手持ちの端末ではNexus7(2012)だけ。どんな関係があるんかさっぱりわからへん(T_T) Tegra3固有の問題なんかな? ちなみに、オレオレUSB/UVCライブラリでもlibusb/libuvcでも起こる。

今のところ推測では、起動処理とカメラへの接続開始時の無駄を省いて最初の頃よりかなり処理が速くなったからみたい。
SurfaceTextureListener#onSurfaceTextureAvailableが呼び出されて数百ミリ秒ぐらいたってからのんべんだらりんとUVCカメラへの接続処理を開始すれば殆どの場合はエラーにならないんだけどなぁ。

追加2:
標準設定だとTextureViewへの描画の際にEGLを使ってOpenGL|ESのテクスチャとして映像を表示しているのが原因かと思って、高解像度設定(この時はピクセルフォーマットの変換とSurfaceへの転送をCPUで行っている、言うなればJavaでSurfaceViewの描画をするのにlockCanvas/unlockCanvasAndPostを使うのと一緒)にしてみたけどやっぱりダメだった。
て事は自分のコード内のどこかでOpenGL|ESのViewportの設定を間違っている訳じゃないと言う事で。TextureView(あるいはSurfaceTexture)の処理の中にタイミングクリティカルな所があるってことやねぇ(´・ω・`)

追加3:
libusb+libuvcだと不具合無く動く条件が見つかった\(^o^)/ でもオレオレUSB/UVCライブラリだとまだ上半分表示&ペイロードヘッダーのエラービットが立ってしまう時が多い。
確かめるすべは無いので想像だけど、TextureView/SurfaceTexture(あるいは内部で行っているEGL関係の処理)の少なくとも直近にUSBの処理を行っているとうまく初期化出来ないみたい。プログラム上は並行して実行される部分はないんだけど、EGLはコマンド受けて裏で動く部分があるのかも。libusb+libuvcの方が特に初期化周りは色々処理が多くて相対的に時間がかかるのでかえってうまくいくのかも。

« »

  • スポンサードリンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

*