Native/Hal层处理GraphicBuffer数据

1.Native层从ANativeWindowBuffer中获取GraphicBuffer,然后再处理数据

//get ANativeWindowBuffer and transform GraphicBuffer
ANativeWindowBuffer *anwBuffer;
sp buffer = GraphicBuffer::from(anwBuffer);
if (buffer != nullptr) {
    //android app通常使用的两种格式是rgba_8888和nv21,分别用于预览和算法处理,
    //上层app传下来的format分别是34和35,到native层变成1和35.
    if (format != 1) {
        //format of nv21
        android_ycbcr ycbcr = android_ycbcr();
        res = buffer->lockYCbCr(GRALLOC_USAGE_SW_READ_OFTEN, &ycbcr);
        if (res != OK) {
            ALOGE("%s: graphicBuffer cannot lock ycbcr buffer", __FUNCTION__);
            return res;
        }
        //TODO get nv21 data and store in ycbcr
        //nv21中uv是交叉排列的,其中v在前, u在后,填充数据时,只需要填充
        //ycbcr.y和ycbcr.cr分量即可
    } else {
        uint8_t* rgbaBuffer = nullptr;
        res = buffer->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void **)&rgbaBuffer);
        if (res != OK) {
            ALOGE("%s: graphicBuffer cannot lock buffer", __FUNCTION__);
            return res;
        }

        //TODO get rgba data and store in rgbaBuffer
    }
    res = buffer->unlock();
    if (res != OK) {
        ALOGE("%s: graphicBuffer cannot unlock buffer", __FUNCTION__);
        return res;
    }
}

2.Hal层使用GraphicBufferMapper处理GraphicBuffer对应的buffer_handle_t结构体

//get buffer_handle_t
buffer_handle_t *hnd_output;
android::GraphicBufferMapper& bufferMap(android::GraphicBufferMapper::get());
android::status_t res;
if (hnd_output != nullptr) {
     //width和height是surface的宽和高
     const android::Rect lockBounds(width, height);
     if (format != 1) {
          android_ycbcr ycbcr = android_ycbcr();
          res = bufferMap.lockYCbCr(*hnd_output, GRALLOC_USAGE_SW_READ_OFTEN, 
               lockBounds, &ycbcr);
          if (res != android::OK) {
               HAL_LOGE("%s: graphicBuffer cannot lock ycbcr buffer", __FUNCTION__);
               return false;
          }
          //TODO get nv21 data and store in ycbcr 
     } else {
          uint8_t* rgbaBuffer = nullptr;
          res = bufferMap.lock(*hnd_output, GRALLOC_USAGE_SW_WRITE_OFTEN, 
               lockBounds, (void **)&rgbaBuffer);
          if (res != android::OK) {
               HAL_LOGE("%s: graphicBuffer cannot lock buffer", __FUNCTION__);
               return false;
          }
          //TODO get rgba data and store in rgbaBuffer 
     }

     res = bufferMap.unlock(*hnd_output);
     if (res != android::OK) {
          HAL_LOGE("%s: graphicBuffer cannot unlock buffer", __FUNCTION__);
          return false;
     }
}

你可能感兴趣的:(Camera,camera,android)