7

ビデオ フレームを OpenGL テクスチャとして使用できるように、アプリに SurfaceTexture.OnFrameAvailableListener インターフェイスを実装しています。すべてが正常にセットアップされ、完全に機能しますが、数秒後に onFrameAvailable(SurfaceTexture surfaceTexture) の呼び出しが停止し、SurfaceTexture.updateTextImage を介して新しいテクスチャデータがアップロードされていないため、OpenGL でビデオが効果的にフリーズしているように見えます。

onFrameAvailable にフラグを設定して、必要な場合にのみ GL スレッドから updateTextImage 呼び出しを実行しています。現在、すべての描画呼び出しでフラグを true に設定しているため、onFrameAvailable チェックがスキップされるため、ビデオ テクスチャデータがフレームごとにアップロードされます。このように、すべてが正常に実行されますが、同じ (ムービー フレーム) の場合、新しいテクスチャ データをアップロードする必要がないため、非効率的です。

私の知る限り、メモリリークはなく、logcat にはエラーが表示されていません。また、メディア プレーヤーはループするように設定されていますが、1 回の実行が完了する前に問題が発生します。

数秒後に onFrameAvailable が呼び出されなくなる原因は何ですか?

4

2 に答える 2

17

一部のデバイスでまったく同じ問題が発生しました。修正を見つけたので、共有したいと思いました。基本的には、@ user2254894 が提案したことですが、カウンターは 2 つの異なるスレッドによって変更される可能性があるため、2 つの異なる変数を使用することをお勧めします。コード例を次に示します。

private int             _updateTexImageCounter = 0;
private int             _updateTexImageCompare = 0;

onFrameAvailable() はシンプルです。

@Override
public void onFrameAvailable(SurfaceTexture surfaceTexture) 
{
    // increment every time a new frame is avail
    _updateTexImageCounter++;
}

次に、GL更新で次のようなことを行います...

public void update() 
{

    .... create texture... etc.
    ..
    // compare _updateTexImageCompare and _updateTexImageCounter
    if( _surfaceTexture!=null && _updateTexImageCompare != _updateTexImageCounter ) 
    {
        // loop and call updateTexImage() for each time the onFrameAvailable() method was called below.
        while(_updateTexImageCompare != _updateTexImageCounter) {
            _surfaceTexture.updateTexImage();
            _surfaceTexture.getTransformMatrix(x);

            _updateTexImageCompare++;  // increment the compare value until it's the same as _updateTexImageCounter
        }
    }


}

これは私にとってはうまくいきました。より良い方法があれば教えてください。

于 2013-12-17T23:50:48.633 に答える