2015-06-20 43 views
0

我已經在Android 4.2.2上移植了遠程幀緩衝區接收C代碼,它以RGB565格式從主機接收幀緩衝區。能夠根據標準android示例框架/ native/services/surfaceflinger/tests/resize/resize.cpp呈現接收到的幀緩衝區。以下是使用的代碼片段如何在Android上升級和渲染遠程(RGB565)幀緩衝區?

sp<Surface> surface = client->createSurface(String8("resize"), 
     800, 480, PIXEL_FORMAT_RGB_565, 0); 


SurfaceComposerClient::openGlobalTransaction(); 
surface->setLayer(100000); 
SurfaceComposerClient::closeGlobalTransaction(); 

Surface::SurfaceInfo info; 
surface->lock(&info); 
ssize_t bpr = info.s * bytesPerPixel(info.format); 
/* rfb is the remote famebuffer filled by C stack*/ 
memcpy((uint16_t*)info.bits, rfb, 800*480*2); 
surface->unlockAndPost(); 

但我不能放大接收的緩衝區渲染全屏在android上。例如: - 主機發送800 * 480,但Android設備屏幕是1024 * 786 也有以下疑問,
1.本地創建表面以正確的方式處理這類問題?
2.如何在Android本機上進行高檔原始圖像和渲染?
3.在編寫應用程序時,應用程序是否可以控制它在本機上創建的表面?

我是新來的Android和這將是巨大的,如果有人能指導我正確的道路上,您目前正在使用私有API的SurfaceFlinger的,需要優先獲得處理這個問題

+0

你需要直接與SurfaceFlinger交互嗎?與創建具有顯示接收幀的應用程序相反。就縮放比例而言,您可以通過更改窗口大小來管理這種情況,以便在合成曲面時重新縮放曲面。 – fadden

+0

@fadden沒有必要,如果我可以使用應用程序渲染這些緩衝區。 Rright現在我不知道該怎麼做。你能給一些類似的例子應用程序提供一些鏈接嗎?順便說一句,這些緩衝區如何傳遞給應用程序來渲染? – t3rmin4tor

回答

0

。如果你需要這樣做,我認爲你想使用setSize()調用來改變窗口的大小(這是獨立於底層Surface的大小)。拱門文檔中的This section顯示如何閱讀adb shell dumpsys SurfaceFlinger輸出的一部分以查看實際尺寸是什麼 - 它會告訴您電話是否正常工作。 (通常情況下,您會通過Window Manager進行此操作,但您繞過了大部分Android框架。)

如果您可以在非特權應用程序中執行所需操作,那麼您的代碼將更具可移植性,而且遠遠不夠可能會因操作系統的變化而中斷。最好的方法是創建一個OpenGL ES紋理,並將glTexImage2D()的像素「上傳」到GL_UNSIGNED_SHORT_5_6_5紋理。 (我有理由相信GLES 565格式與Android gralloc格式相匹配,但我沒有嘗試過。)一旦您擁有GLES紋理中的圖像,您可以渲染它,但是您喜歡 - 您不再受限制到矩形。

一些示例可在Grafika中找到。特別是,「"texture upload benchmark」活動演示了上傳和渲染紋理(這是一個基準,因此它使用了非屏幕紋理,但其他活動(例如「來自相機的紋理」)顯示瞭如何在屏幕上做東西。)

基於GLES的方法有更多的工作,但是你可以從Grafika中抽取大部分的內容.Java語言的GLES代碼通常只是一個簡單的包裝器,所以如果你決定使用NDK對於GLES來說,它是一個相當直接的轉換,因爲所有的繁重工作都是由圖形驅動程序完成的,但是使用NDK沒有太多意義(如果像素是通過純本地代碼到達的,帶有「直接」ByteBuffer的緩衝區以便從Java語言代碼訪問)。

+0

感謝您的詳細解釋。我有一個基本的應用程序與一些控制和軟件分層以下方式,本地C堆棧 - > JNI->服務 - > AIDL-> JAVA API JAR->應用程序。如果我在這些層上傳遞ByteBuffer,會不會有性能下降? – t3rmin4tor

+0

只要您使用直接的ByteBuffer(只是指向內存和長度的指針),並且不復制數據本身,傳遞ByteBuffer不應該有明顯的影響。由於您上傳到紋理並在Surface上渲染紋理,而不是直接將數據複製到Surface本身,但是這些操作由GPU執行,因此可能會稍微多一些開銷。如果你的服務和你的應用程序在不同的進程中,那麼你需要使用共享內存來傳輸它,而不需要添加副本。 – fadden

+0

是的。該服務和應用程序在不同的進程中。 AFIK,AIDL是通過IPC機制的綁定來實現的。你能解釋一下,如果有跨多個進程共享緩衝區的其他共享內存機制嗎? – t3rmin4tor

相關問題