2013-01-06 88 views
6

我在我的應用程序中實現了SurfaceTexture.OnFrameAvailableListener接口,因此我可以使用視頻幀作爲OpenGL紋理。所有的設置都像它應該和它完美的工作,但onFrameAvailable(SurfaceTexture surfaceTexture)幾秒鐘後停止調用,有效地看起來凍結在OpenGL中的視頻,因爲沒有新的texturedata通過SurfaceTexture.updateTextImage上傳。SurfaceTexture.OnFrameAvailableListener停止被調用

我在onFrameAvailable中設置一個標誌,以便從GL線程執行updateTextImage調用,並且只在需要時才執行。目前,我在每次平局調用中將標誌設置爲true,因此忽略onFrameAvailable檢查,視頻紋理數據每幀都會上傳。像這樣,一切都按照它應該運行,但它似乎效率低下,因爲如果它仍然是相同的(電影幀),沒有新的紋理數據需要上傳。

AFAIK沒有內存泄漏,logcat沒有顯示任何錯誤。此外,媒體播放器已設置爲循環播放,但問題發生在單次播​​放完成之前。

什麼會導致onFrameAvailable幾秒鐘後不再被調用?

+0

你解決了嗎? –

回答

10

我剛剛看到一個類似的問題,並調試它。我和你一樣,有一個布爾標誌,表示一個(或更多)幀準備好被使用。

當我在一對OpenGL幀之間收到兩個攝像機幀時(可能是因爲我的OpenGL重繪處理太慢),就會出現問題。這意味着我設置了兩次布爾標誌。但是,我只讀了一次這個幀數據,而且似乎updateTexImage實現了某種排隊功能。

用一個整數計數器的懸而未決的相機幀替換布爾標誌爲我解決了這個問題。也許這也適用於你?我認爲這比每幀調用updateTexImage更有效率,至少在我的代碼中,OpenGL幀需要足夠長的時間以至於跨越兩個相機幀,這是非常罕見的(1-2%)。)

+2

感謝您的工作調試。看來有數量的緩衝區被分配用於解碼,並且調用onFrameAvailable()檢出一個緩衝區,並且只通過調用updateTexImage()將該緩衝區檢查回可用池。一個不在文檔中的關鍵事實! – bleater

+0

@bleater - 您上面的評論是我最終需要了解我的特定問題的線索。我試圖忽略一些框架產生一個口吃效果,當我沒有畫一個框架,我會停止獲得新的。你的回答告訴我爲什麼。 – spartygw

11

我在某些設備上有完全相同的問題。找到了解決辦法,並認爲我會分享。基本上它是@ user2254894建議的,除了由於計數器可以由2個不同的線程改變,所以它是一個好主意,使用2個不同的變量。以下是一些示例代碼:

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

and 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 
     } 
    } 


} 

這爲我工作。讓我知道是否有更好的方法。

+1

這也幫助了我,謝謝! – voytez

+2

哇。這修正了原始Android代碼中存在的錯誤。 (即:CTS for MediaCodec) –

+2

@LéonPelletier很高興幫助。 –

相關問題