Android Qcom Display学习(八)

该系列文章总目录链接与各部分简介: Android Qcom Display学习(零)

显示系统[1] 简单的Surface测试程序
dequeueBuffer函数分析
Android Camera APP preview buffer 总体流程

基于Android12实现简单的Surface测试程序,部分类内的接口发生了变化,但大体上没啥问题。主要实现两类功能
(1)实现显示RGB图的红绿切换,这个主要来源于上面链接中的显示系统[1],以此为基础在Android S上实现
(2)实现Camera Preview的实时预览,基于Camera api1,源码从Camera的测试程序中剥离出的一些操作接口来实现

API_1 CameraService::connect
Camera.cpp                     /frameworks/av/camera/
    CameraBase.cpp             /frameworks/av/camera/
        CameraService.cpp      /frameworks/av/services/camera/libcameraservice/
            connectHelper API_1

API_2 CameraService::connectDevice 
    CameraManager.java     /frameworks/base/core/java/android/hardware/camera2/CameraManager.java    
        ICameraService.aidl    /frameworks/av/camera/aidl/android/hardware/ 
            CameraService.cpp      /frameworks/av/services/camera/libcameraservice/ 
                connectHelper API_2

device1 + cameraClient /device3 + camera2Client  API1 对应 HAL 1/3 

(3)待补充:实现Camera Preview的方式采用api2和v4l2,后续再看单独拿出来研究

API2 可以基于/frameworks/av/camera/tests/CameraBinderTests.cpp的示例去看,
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("media.camera"));
sp<hardware::ICameraService> service = interface_cast<hardware::ICameraService>(binder);
res = service->connectDevice(callbacks, cameraId, packageName,
                             {}, hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/ 0,
                             /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*out*/&device);

在这里插入图片描述

上图来源自链接Android Camera APP preview buffer 总体流程,非常推荐

IGraphicBufferProducer(生产者)  → 提供图像数据(surface)
           ↑↓
   BufferQueue(buffer队列)
           ↑↓
IGraphicBufferConsumer(消费者)  → 合成图像数据(surfacefinger)

Camera::setPreviewTarget
    Camera2Client::setPreviewWindow  //window = new surface surface继承自ANativeWindow
    //class Surface : public ANativeObjectBase<ANativeWindow, Surface, RefBase> 
        StreamingProcessor::setPreviewWindow    //mPreviewWindow
  
Camera::startPreview    
    Camera2Client::startPreview
    Camera2Client::updatePreviewStream   
        StreamingProcessor::updatePreviewStream // mPreviewWindow 
            Camera3Device::createStream    // new Camera3OutputStream HAL填充   
            Camera3Device::configureStreamsLocked  //configure_stream  
                 Camera3OutputStream::configureConsumerQueueLocked
                 //根据当前stream设置的buffer属性,将这些属性值通过ANativeWindow这个接口传递给consumer                   
        StreamingProcessor::startStream

以上窗口准备好后并设置后属性,在后续preview的线程中会一直dequeueBuffers(向BufferQueue申请一块内存用于绘制图像)
和queueBuffer(绘制好的buffer放入BufferQueue队列中并通知回调消费者去使用这块buffer)

1.Android.bp

cc_binary {
    name: "surfacetest",
    srcs: ["main.cpp"],
    shared_libs: [
        "libutils",
        "libandroidfw",
        "libcutils",
        "libbinder",
        "libui",
        "libgui",
        "liblog",
        "libcamera_client",
        "libmedia"
    ],
    header_libs: [
        "libsurfaceflinger_headers",
    ]
}

2.surfacetest

#include <cutils/memory.h>
 
#include <utils/Log.h>
#include <utils/SystemClock.h> 

#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
 
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <android/native_window.h>
 
#include <system/camera.h>
#include <camera/Camera.h>
#include <camera/CameraParameters2.h>

#include <hardware/hardware.h>
#include <hardware/camera_common.h>

#include <hardware/hwcomposer_defs.h>

using namespace android;

sp<Camera>  mCamera;
CameraParameters2 mParams;
String16 packageName("jerry");
sp<IGraphicBufferProducer> gbp;
int previewWidth, previewHeight;


void android_memset16(unsigned short * _ptr, unsigned short val, unsigned count)

{
    unsigned short * ptr = _ptr;
    count >>= 1;
    while(count--)
        *ptr++ = val;
}

int main()
{
    // set up the thread-pool
    sp<ProcessState> proc(ProcessState::self());
    ProcessState::self()->startThreadPool();
 
    // create a client to surfaceflinger SurfaceComposerClient.cpp
    sp<SurfaceComposerClient> client = new SurfaceComposerClient();
    
    // surface client get display size
    sp<IBinder> displayToken = client->getInternalDisplayToken();
    if(nullptr == displayToken)
        ALOGE("jerry failed to get the displayToken");
    ui::DisplayMode displayinfo = {};
    client->getActiveDisplayMode(displayToken, &displayinfo);

    ALOGD("jerry get the displayinfo w = %d, h= %d",displayinfo.resolution.getWidth(), displayinfo.resolution.getHeight());

    // surface client createsurface different size and format
#if 0
    sp<SurfaceControl> surfaceControl = client->createSurface(String8("resize"),
            1080, 2160, PIXEL_FORMAT_RGB_565, 0);
#else
    sp<SurfaceControl> surfaceControl = client->createSurface(String8("resize"),
            720, 1080, HAL_PIXEL_FORMAT_YCrCb_420_SP, 0);
#endif

    // surface use to (1)draw full color or (2)camera preview buffer
    sp<Surface> surface = surfaceControl->getSurface();    

#if 0
    //(1)ANativWindow draw full color the hegith*weight RED+GREEN
    ANativeWindow_Buffer outBuffer;

    surface->lock(&outBuffer, NULL);
    ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
    android_memset16((uint16_t*)outBuffer.bits, 0xF800, bpr*outBuffer.height);//RGB mask RED
    surface->unlockAndPost();
 
    sleep(3);
    surface->lock(&outBuffer, NULL);
    android_memset16((uint16_t*)outBuffer.bits, 0x07E0, bpr*outBuffer.height);//RGB mask Green
    surface->unlockAndPost();
#endif

    //(2)surface setPreviewTarget to startPreview on Screen
    //frameworks/av/camera/tests/CameraZSLTests.cpp
    //frameworks/av/camera/Camera.cpp
    //sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
    //       int clientUid, int clientPid, int targetSdkVersion)

    mCamera = Camera::connect(0, packageName, Camera::USE_CALLING_UID,
                                              Camera::USE_CALLING_PID, 30);

    // camera api get/set parameters
    mParams = mCamera->getParameters();
    mParams.setPreviewFormat("yuv420sp");
    //mParams.getPreviewSize(&previewWidth, &previewHeight);
    //mParams.setPreviewFrameRate(30);
    //mParams.setPreviewSize(previewWidth, previewHeight);
    //mCamera->setParameters(mParams.flatten());
    mCamera->sendCommand(CAMERA_CMD_SET_DISPLAY_ORIENTATION, 270, 0);

    // surface setPosition/apply
    SurfaceComposerClient::Transaction{}.setPosition(surfaceControl, 200, 200).apply();

    // surface pass the buffered IGraphicBufferProducer to the camera service
    gbp = surface->getIGraphicBufferProducer();
    mCamera->setPreviewTarget(gbp);
    mCamera->startPreview();



    IPCThreadState::self()->joinThreadPool();
    
    return 0;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值