Android camera 預設顯示黑白的問題

來源:互聯網
上載者:User

在初次接觸
android

的時候就注意到通過模擬器,相機預覽的時候只能顯示黑白電影。這些天總算有點空閑時間了,決定研究下這個。

關於
android camera

的構造不再說了,模擬器上使用用的是一個虛擬
Camera-----FakeCamera

這個大家應該都知道。

首先初略的瞭解一下
camera preview

映像顯示的原理。
Camera application

初始化的時候會建立一個
surfaceview

,從
camera device

接收到的資料就可以通過它顯示在螢幕上。內部處理的流程是很複雜的,下面我只給出一個從初始化到繪圖函數調用的流程。

Surface


初始化:

Android_view_surface:: Surface_init-->


SurfaceComposerClient::CreateSurface-->


SurfaceFlinger:: createSurface-->


Android_view_surface::


setSurface


 

 

Camera

資料緩衝區
Heap

初始化:

CameraHardwareStub::initHeapLocked-->


new MemoryBase-->


new FakeCamera


 

 

Heap

緩衝區註冊到
surface:

Android_hardware_camera:: android_hardware_Camera_setPreviewDisplay-->


Camera:: setPreviewDisplay-->


CameraService::Client::setPreviewDisplay-->


CameraService::Client::registerPreviewBuffers-->


LayerBuffer::registerBuffers


 

 

FakeCamera

未經處理資料的傳遞與繪圖:

CameraHardwareStub::previewThread-->


CameraService::Client::previewCallback-->


CameraService::Client::postPreviewFrame-->


ISurface:: postBuffer-->


LayerBuffer::postBuffer-->


LayerBuffer::BufferSource::postBuffer-->





LayerBase::invalidate-->


SurfaceFlinger::signalEvent-->


SurfaceFlinger::threadLoop-->


SurfaceFlinger::handleRepaint-->


LayerBase::draw-->


LayerBuffer::BufferSource::onDraw-->


LayerBase::drawWithOpenGL


 

FakeCamera

得到資料為
Yuv422,

原以為是庫裡某個地方繪圖的時候出問題,但
LayerBuffer::OnDraw

往下走很複雜的:

                       t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) {
                // just show the Y plane of YUV buffers。 不明白為什麼google這麼做。。。。。

但要解決預覽為黑白電影的問題應該就比較簡單了。只要我們將
YUV

資料轉換為
RGB

丟給
cameraService

就可以了。用以下的代碼替代
ccrgb16toyuv_wo_colorkey




int32_t ccrgb16toyuv_wo_colorkey
(uint8_t *rgb16,uint8_t *yuv422,uint32_t *param,uint8_t *table[])

{

      
int32_t width_dst = param[0];


   
int32_t height_dst = param[1];


      
memcpy(yuv422, rgb16, width_dst*height_dst*2);


}

CameraService

中改動:

status_t CameraService::Client::registerPreviewBuffers
()

{

  


。。。。。。。。。。。。。。。。。。。。。。。

   
ISurface::BufferHeap buffers(w, h, w, h,

                               
PIXEL_FORMAT_RGB_565

,

//PIXEL_FORMAT_YCbCr_420_SP,

                                
transform,

                                
0,

                                
mHardware->getPreviewHeap());

 

  
status_t ret = mSurface->registerBuffers(buffers);

   
if (ret != NO_ERROR) {

       
LOGE("registerBuffers failed with status %d", ret);

   
}

   
return ret;

}


PIXEL_FORMAT_RGB_565


替換

PIXEL_FORMAT_YCbCr_420_SP

。這樣就可以了。不妨動手試一試吧,看看是不是預覽視頻變為彩色的了。

對於實際的
camera device

出來的資料如果是
yuv

的話,也可以通過演算法將
yuv

轉換為
RGB

,這樣做並不會導致轉換效率降低,因為即使將
yuv

得資料丟到
surfaceflinger

中,最終還是會轉換為
BMp


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.