• スポンサードリンク

USBカメラから音&動画の同時キャプチャした〜い(その2)

Android Camera MediaCodec USB 非同期

静止画のキャプチャ

前回の記事で載せた静止画のキャプチャ処理のUVCCameraTextureView側です。全部をMainActivity側へ持って行くことも出来ますけど今回は別々に分けてます。
まずフィールドを3つ定義します。このうちの2つ目のBitmapは必須では無いですが、呼び出し頻度が高い場合を考慮してOOMを避けるためにこういう実装の方が良いと思います。
その代わり複数スレッドからほぼ同時に静止画キャプチャ要求をすると、最初に取得したビットマップを処理中に次のスレッドが中身を書き換えてしまうかもしれません。複数スレッドから呼び出す可能性があるのなら、UVCCameraTextureViewのプライベートフィールドでBitmapオブジェクトを保持するのではなく、呼び出し側からBitmapオブジェクトを供給できるように作り変えるほうがよいと思います。

次にMainActivityから呼び出していた#captureStillImageメソッドです。これはRenderHandler#getPreviewTextureと似ていますが、メッセージを送るのでは無く単純にフラグを立てて待機します。最新状態でなくても構わなければ直接TextureView#getBitmapを呼び出しても良かったと思いますが、ここでは要求直後の最新画像を取得するためにこのような実装にしています。

実際のビットマップの取得処理がどこで行われるかというと、TextureView.SurfaceTextureListener#onSurfaceTextureUpdatedになります。UVCCameraTextureViewのコンストラクタで#setSurfaceTextureListenerを呼び出して登録しています。このメソッドは、TextureViewの描画用SurfaceTextureが更新された時(直接的または間接的にSurfaceTexture#updateTexImageが呼び出された時)に呼ばれます。

ここも同じように排他制御した上でTextureView#getBitmapを呼び出して、表示内容をビットマップとして取得します。後はnotifyAllを呼び出して呼び出し元の待機解除すれば終了です。
2014/09/23 追記
上のソースでキャプチャしたビットマップは、Viewと同じ大きさになります。もし、特定の大きさにしたいのであれば、7行目を

に変更して下さい。以降の呼び出しては、mTempBitmapが最初に生成された時の大きさになります。もし取得するビットマップのサイズを変更したい時には、mTempBitmapを開放すると、もう一度サイズ指定が可能になります。
2014/09/23 追記ここまで

ところで、TextureView#getBitmapの呼び出しはちょっと注意が必要です。TextureView#getBitmapには次の3通りが有ります。

この内上2つのメソッドは、毎回新たにBitmapオブジェクトを生成します。今回のような低頻度のワンショット処理であればあまり気にしなくても大丈夫ですが、#onSurfaceTextureUpdatedはSurfaceTextureが更新されるたびに呼び出されることを覚えておいて下さい。仮に毎回上2つの#getBitmapメソッドのいずれかを呼び出してしまうと、あっという間にOOMでクラッシュします。一方、3つ目の#getBitmapは同じBitmapオブジェクトを使いまわすので毎回呼び出してもOOMにはなりにくいです。

もっともAndroidのBitmapと言えばかなり遅いことで有名なので、高頻度でイメージを取得しないといけない理由が有るのなら他の方法を考えたほうが良いと思います。

細かいメソッドはまだ少し有りますが、主なものは以上ですね。
RenderThread内のレンダリングコンテキスト生成・破棄・描画のタイミングに合わせて呼び出すようなリスナーインターフェース(GLSurfaceView.Rendererみたいな奴)を作れば、TextureView版のGLSurfaceViewになります。まぁ需要があるかどうかは別というか、グルグル先生的には必要無い・優先度が低いと言う事でSDKに含まれていないんでしょうけどね(-_-;)

AudioVideoRecordingSample / USBCameraTest / USBCameraTest2の記事で大部分は説明しているので、意外と簡単に終わってしまいました。相変わらずマルチスレッドバリバリなので、そこら辺が苦手な人には簡単どころではないのかもしれないですけどね。

と言う事で、おしまいです。
お疲れ様でした。

« »

  • スポンサードリンク

%d人のブロガーが「いいね」をつけました。