• スポンサードリンク

AndroidのGLES20.glUseProgramでプチハマり

Android

端末内蔵のマイクからの音と内蔵カメラからの動画をMediaCodecとMediaMuxerを使ってMPEG4ファイルとして保存しようとしててプチハマり(´・ω・`)

事の発端

音と動画の同時キャプチャはネットでウロウロしても良いサンプルがなさそうなんですよね。別々であれば、動画向けは沢山あるし、音だけってのも少しは見つかるけど。
と言う事で、最終的にはUSB接続のWebカメラとUSB接続のマイク(Webカメラ内蔵も含む)からの音と映像のキャプチャが目的なんだけど、とりあえずは内蔵マイク・内蔵カメラからの音と動画の同時キャプチャ時の挙動を確かめたくてテストプログラムを作成しました。

2014/08/27追記:
テストプログラムをGitHubで公開しました。リンクはこちらAudioVideoRecordingSample
記事も有りますので良ければ見て下さい。相変わらず字とソースばかりですけど(-_-;)
音&動画の同時キャプチャがした〜い(その1)
音&動画の同時キャプチャがした〜い(その2)
音&動画の同時キャプチャがした〜い(その3)

こんなところで・・・

細かい話は全部すっとばかす事にして、OpenGLでカメラから映像を描画をすることになるのですが、その描画クラスを作っててプチハマりでした。
問題となった部分のソースは、これ。

変数とかは気にしないで呼んでる関数だけを見て下さい。頂点配列とかも全部別で割り当ててあるのでそれも関係ないです。
GLSurfaceViewの標準のコンテキスト内で描画する分には上のコードでも特に問題なし。
問題が起こったのは、別スレッドで描画するために、GLSurfaceViewの標準のコンテキストを共有してEGLで生成した別のコンテキスト内で描画する場合です。
このままでも動く機種も有りますが、おかしなことになる機種もあるのです。
Nexus7(2012, Android4.4.4)だと大抵はちゃんと表示されるけどなぜかたまに白黒になってしまいます(元画像はもちろんカラーです)。
Nexus5(Android4.4.4)だと、色は正常なものの超カクカクした表示になりました。
最初は描画にすご〜く時間がかかってフレームがとんでいるのかと思い、GLSurfaceView内で描画した回数と、録画用に別スレッドで描画した回数を数えてみたり時間を測ってみたりして。でも1ミリ秒程で描画は終わる上に回数も同じ…なんでだろ〜(゜レ゜)判る人〜

はーい(^_^)/

いえ、想像は出来ますが本当のところ何でかは判りません(-_-;)でもどうすれば治るかは判りました(^^)v
とりあえずはこうすれば大丈夫でした。

7行目のように

を呼び出してシェーダーの割り当てを無効にするだけです。テストプログラムだと思って手を抜いたのが間違いでした。ちなみに、

として、テクスチャの割り当てを無効にしても関係有りませんでした。
似たようなのをもう何度も作っているのに、こんなところでハマったのは初めてです。
いつもは何で大丈夫だったかって?頂点配列も何もかも描画前に有効にして描画後に無効にしてたから〜他からコピペすればよかった(´・ω・`)…

結論

複数のスレッドで並行してOpenGLを使って描画する時は後始末をちゃんとしましょう。横着してはいけない↓
テクスチャも頂点配列もテクスチャ座標配列もみんな毎回割り当てを有効/無効にした方がいいのかもしれないです。
でもこんな事OpenGL/OpenGL|ESの仕様に書いてあったかなぁ?

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

« »

  • スポンサードリンク

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