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);
}
}
}
}