[RK3288][Android6.0] 调试笔记 --- Camera实现Soft Resize

Platform: RK3288
OS: Android 6.0
Kernel: 3.10.92

背景:
同一型号摄像头,由于供应商的更换导致支持的分辨率不是全部一致,而其中一个分辨率320x240在项目上就有需求。这种情况下只能通过软件来实现了。

实现步骤:
1. 先在preview size中添加一个320x240的伪支持,因为不是硬件真正读到的。

+
+/* 180301, Kris, Add support which is used by software resize. {*/
+#ifdef USE_SW_RESIZE
+   if (parameterString.size() != 0)
+       parameterString.append(",320x240");
+#endif
+/* 180301, Kris, Add support which is used by software resize. }*/
+
    params.set(KEY_PREVIEW_W_FORCE,"0");
    params.set(KEY_PREVIEW_H_FORCE,"0");
    params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, parameterString.string());
    params.setPreviewSize(640,480);

2.实现soft resize算法

调用处:

int AppMsgNotifier::captureEncProcessPicture(FramInfo_s* frame){
......
#ifdef USE_SW_RESIZE
            if (......)
                rga_nv12_scale_crop(frame->frame_width, frame->frame_height,
                    (char*)(frame->vir_addr), (short int *)(tmpPreviewMemory->data),
                    mPreviewDataW,mPreviewDataH,frame->zoom_value,mDataCbFrontMirror,true,0);
            else
                useSoftResizeBuffer((char*)(frame->vir_addr), (char *)tmpPreviewMemory->data, mPreviewDataW, mPreviewDataH);
#endif
......
}

void AppMsgNotifier::useSoftResizeBuffer(char *srcbuf, char *dstbuf, int dst_width, int dst_height)
{
......
    } else if (dst_width == 320 && dst_height == 240) {
        Conv1280x720to320x240(srcbuf, dstbuf);
......
}

算法:

void AppMsgNotifier::Conv1280x720to320x240(char* pSrc, char* pDest)
{
  static const int SCALE = 196608;
  static const int SRC_WIDTH = 1280;
  static const int SRC_HEIGHT = 720;
  static const int DEST_WIDTH = 320;
  static const int DEST_HEIGHT = 240;
  static const int SRC_SIZE = SRC_WIDTH*SRC_HEIGHT;
  static const int DEST_SIZE = DEST_WIDTH*DEST_HEIGHT;

  unsigned int* pIntSrc = (unsigned int*)pSrc;
  unsigned int* pIntDest = (unsigned int*)pDest;
  unsigned int* pIntSrcUV = (unsigned int*)(pSrc + SRC_SIZE);
  unsigned int* pIntDestUV = (unsigned int*)(pDest + DEST_SIZE);

  unsigned int nRow;
  for(int i = 0; i < DEST_HEIGHT; ++i)
  {
    nRow = (SCALE*i) >> 16;
    pIntSrc = (unsigned int*)(pSrc + nRow*SRC_WIDTH);
    pIntSrcUV = (unsigned int*)(pSrc + SRC_SIZE + ((nRow >> 1)*SRC_WIDTH));
    for(int j = 0; j < 20; ++j)
    {
      SAVE_1IN4_BYTES_INT(pIntSrc, pIntDest);
      SAVE_1IN4_BYTES_INT(pIntSrc, pIntDest);
      SAVE_1IN4_BYTES_INT(pIntSrc, pIntDest);
      SAVE_1IN4_BYTES_INT(pIntSrc, pIntDest);

      if((i & 1) == 0)
      {
        SAVE_1IN4_SHORT_INT(pIntSrcUV, pIntDestUV);
        SAVE_1IN4_SHORT_INT(pIntSrcUV, pIntDestUV);
        SAVE_1IN4_SHORT_INT(pIntSrcUV, pIntDestUV);
        SAVE_1IN4_SHORT_INT(pIntSrcUV, pIntDestUV);
      }
    }
  }
}

你可能感兴趣的:(子类__Camera)