2013-03-22 58 views
6

我有一個Android應用程序,它將視頻解碼爲yuv420p格式,然後使用OpenGLES渲染視頻幀。 我使用glTexSubImage2D()將y/u/v緩衝區上傳到GPU,然後使用着色器進行YUV2RGB轉換。所有EGL/OpenGL設置/渲染代碼都是本機代碼。Nexus 10/Android 4.2.2上的slow glTexSubImage2D性能(三星Exynos 5 w/Mali-T604)

現在我不是說我的代碼沒有問題,但考慮到相同的代碼運行在iOS(iPad/iPhone),Nexus 7,Kindle HD 8.9,三星Note 1和其他一些便宜的中文運行Android 4.0/4.1/4.2的平板電腦(A31/RockChip 3188)。我會說這是不太可能我的代碼是錯的。在這些設備上,glTexSubImage2D()使用不到16ms來上傳SD或720P HD紋理。

但是,在Nexus 10上,glTexSubImage2D()對於SD或720P HD紋理大約需要50〜90ms,對於30fps或60fps的視頻而言,速度太慢。

我想知道

1),如果我要選擇一個不同的紋理格式(RGBA或BGRA)。有沒有辦法來檢測哪一個是GPU使用的最佳紋理格式?

2)如果有一個特點,就是「OFF」上的所有其它的SOC,但設置爲「ON」上的Exynos 5.例如,自動生成MIPMAP選項。 (我把它關閉,順便說一句)

3)如果這是三星的Exynos SOC的一個已知的問題 - 我無法找到一個支持論壇的Exynos CPU

4)是否有我需要設置任何選項何時配置EGL表面?像,透明度,表面格式等? (我不知道我在說什麼)

5)這可能意味着GPU做一個隱含的格式轉換,但我查GL_LUMINANCE總是使用。它再次適用於所有其他平臺。

6)其他?

我的EGL配置:

const EGLint attribs[] = { 
    EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 
    EGL_BLUE_SIZE, 8, 
    EGL_GREEN_SIZE, 8, 
    EGL_RED_SIZE, 8, 
    EGL_NONE 
}; 

初始設置:

glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, ctx->frameW, ctx->frameH, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); /* also for U/V */ 

後續部分替代:

glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ctx->frameW, ctx->frameH, GL_LUMINANCE, GL_UNSIGNED_BYTE, yBuffer); /*also for U/V */ 

我想呈現的視頻在〜30FPS或〜在SD 60FPS或720P高清分辨率。

+0

考慮Android的SurfaceTexture 11:http://developer.android.com/reference/android/graphics/Sur​​faceTexture.html – Jave 2013-03-22 23:05:00

+0

謝謝,但我仍然想弄清楚爲什麼glTexSubImage2D()是慢的,因爲我不想維護多個代碼路徑 - 它適用於除Exynos之外的所有人 – 2013-03-22 23:07:46

+0

我們觀察到相同(或非常相似)的問題,並通過https://code.google.com/p/android/issues/detail?id報告= 53135,但它似乎是基於我們的測試4.2.1和4.2.2之間的迴歸。 – chuoling 2013-04-02 21:18:05

回答

6

這是我們已經報道的已知驅動程序問題的胳膊。未來的更新應該修復它。

+0

這是4.2還是4.2.1的迴歸?如果是的話,我會回滾固件版本,並繼續發展... – 2013-03-23 02:28:19

+0

@ romain-guy - 你有什麼想法什麼時候會更新此更新?我的公司有完全相同的問題。 – BlueVoodoo 2013-03-27 10:47:42

+0

固定將在4.2.3或5.0 – 2013-03-27 16:35:08

1

編輯狀態更新

現在,我們已經成功地繁殖緩慢上傳條件的非公版固件,您所可能打一個路徑,這將是固定在未來的驅動程序版本。

如果您對上傳到其中的紋理雙重緩衝紋理ID(例如,幀N = ID X,N + 1 = ID Y,N + 2 = ID X,N + 3 = ID Y等)應該有助於在當前固件上避免這種情況。

感謝, 異

+1

看到我編輯的問題 – 2013-03-23 02:50:16

+0

非常感謝。因此,只需確認您將兩個8位亮度紋理(一個具有8位Y,另一個具有兩個4位U/V值)打包到一個8位通道中,即可上傳半平面YUV表面。 – solidpixel 2013-03-23 11:29:33

+0

嗯,我沒有足夠的代表評論羅曼的答案,所以我會在這裏發表。不,這不是4.2到4.2.1之間的迴歸,所以回滾不會有幫助。 – solidpixel 2013-03-23 11:41:05

1

我可以證實這一點已被固定在Android 4.3的 - 我看到由2-3與RGBA格式的因素和10-50與其它因素的性能提升Android 4.2.2以上的紋理格式。這些結果適用於glTexImage2D和glTexSubImage2D。 (不能添加評論,所以我不得不把這個在這裏)

編輯:如果你堅持4.2.2,你可以嘗試使用RGBA紋理,而應該有更好的性能(3-10x左右具有更大的二次冪紋理尺寸)。

+0

顯然,它仍然不夠快。我的應用程序開始使用帶有RGBA紋理的glTexSubImage2D,從該版本開始,它在Nexus 10上崩潰。它不會在任何其他Android上崩潰! – HRJ 2013-11-06 10:42:17