Android之Camera拍照插值算法 &&Android4.2之Camera系统HAL调用流程

http://blog.csdn.net/tankai19880619/article/details/17259525

一、rgb插值算法

说明:验证可用,算法效率一般;其中pDest为扩帧后内存地址,nDestWidth和nDestHeight为扩帧后分辨率,nDestBits为色深(如rgb24则为24)。

  1. void  rgbInterpolation(void* pDest, int nDestWidth, int nDestHeight, int nDestBits, void* pSrc, int nSrcWidth, int nSrcHeight, int nSrcBits)  
  2. {  
  3.  //ASSERT_EXP(pDest != NULL);  
  4.  //ASSERT_EXP((nDestBits == 32) || (nDestBits == 24));  
  5.  //ASSERT_EXP((nDestWidth > 0) && (nDestHeight > 0));  
  6.    
  7.  //ASSERT_EXP(pSrc != NULL);  
  8.  //ASSERT_EXP((nSrcBits == 32) || (nSrcBits == 24));  
  9.  //ASSERT_EXP((nSrcWidth > 0) && (nSrcHeight > 0));  
  10.    
  11.  double dfAmplificationX = ((double)nDestWidth)/nSrcWidth;  
  12.  double dfAmplificationY = ((double)nDestHeight)/nSrcHeight;  
  13.    
  14.  const int nSrcColorLen = nSrcBits/8;  
  15.  const int nDestColorLen = nDestBits/8;  
  16.    
  17.  for(int i = 0; i<nDestHeight; i++)       
  18.   for(int j = 0; j<nDestWidth; j++)    
  19.   {  
  20.    double tmp = i/dfAmplificationY;  
  21.    int nLine = (int)tmp;  
  22.      
  23.    if(tmp - nLine > 0.5)  
  24.     ++nLine;  
  25.      
  26.    if(nLine >= nSrcHeight)  
  27.     --nLine;  
  28.      
  29.    tmp = j/dfAmplificationX;  
  30.    int nRow = (int)tmp;  
  31.      
  32.    if(tmp - nRow > 0.5)  
  33.     ++nRow;   
  34.      
  35.    if(nRow >= nSrcWidth)  
  36.     --nRow;     
  37.      
  38.    unsigned char *pSrcPos = (unsigned char*)pSrc + (nLine*nSrcWidth + nRow)*nSrcColorLen;  
  39.    unsigned char *pDestPos = (unsigned char*)pDest + (i*nDestWidth + j)*nDestColorLen;  
  40.      
  41.    *pDestPos++ = *pSrcPos++;  
  42.    *pDestPos++ = *pSrcPos++;  
  43.    *pDestPos++ = *pSrcPos++;  
  44.      
  45.    if(nDestColorLen == 4)  
  46.     *pDestPos = 0;  
  47.   }  
  48. }  
二、yuyv转rgb并jpeg编码的插帧算法

说明:该算法经过验证可行;效率较上边略高,是将rgb的转化省略、进而嵌套在jpeg编码中。

  1. /* private member functions */  
  2. /* 
  3. struct params { 
  4.   uint8_t* src; 
  5.   int src_size; 
  6.   uint8_t* dst; //需要插帧时,该buffer大小为3264*2448*3Byte 
  7.   int dst_size; //需要插帧时,大小为3264*2448*3Byte 
  8.   int quality; 
  9.   int in_width; 
  10.   int in_height; 
  11.   int out_width; //需要插帧时,该位为3264 
  12.   int out_height; //需要插帧时,该位为2448 
  13.   const char* format; 
  14.   size_t jpeg_size; 
  15. }; 
  16. */  
  17. size_t Encoder_libjpeg::encode(params* input) {  
  18.     jpeg_compress_struct    cinfo;  
  19.     jpeg_error_mgr jerr;  
  20.     jpeg_destination_mgr jdest;  
  21.     uint8_t* src = NULL, *resize_src = NULL;  
  22.     uint8_t* row_tmp = NULL;  
  23.     uint8_t* row_src = NULL;  
  24.     uint8_t* row_uv = NULL; // used only for NV12  
  25.     int row_stride;  
  26.     int out_width = 0, in_width = 0;  
  27.     int out_height = 0, in_height = 0;  
  28.     int bpp = 2; // for uyvy  
  29.     Encoder_libjpeg::format informat = Encoder_libjpeg::YUV422I;  
  30.   
  31.     if (!input) {  
  32.         return 0;  
  33.     }  
  34.   
  35.     out_width = input->out_width;  
  36.     in_width = input->in_width;  
  37.     out_height = input->out_height;  
  38.     in_height = input->in_height;  
  39.     src = input->src;  
  40.     input->jpeg_size = 0;  
  41.   
  42.     libjpeg_destination_mgr dest_mgr(input->dst, input->dst_size);  
  43.   
  44.     // param check...  
  45.     if ((in_width < 2) || (out_width < 2) || (in_height < 2) || (out_height < 2) ||  
  46.          (src == NULL) || (input->dst == NULL) || (input->quality < 1) || (input->src_size < 1) ||  
  47.          (input->dst_size < 1) || (input->format == NULL)) {  
  48.         goto exit;  
  49.     }  
  50.   
  51.     if (strcmp(input->format, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {  
  52.         //add by tankai  
  53.         if(in_width < out_height){   
  54.           informat = Encoder_libjpeg::RGB24;  
  55.         }  
  56.         else{  
  57.         //end tankai  
  58.         informat = Encoder_libjpeg::YUV420SP;  
  59.         bpp = 1;  
  60.         if ((in_width != out_width) || (in_height != out_height)) {  
  61.             resize_src = (uint8_t*) malloc(input->dst_size);  
  62.             resize_nv12(input, resize_src);  
  63.             if (resize_src) src = resize_src;  
  64.         }  
  65.         }//add by  tankai  
  66.     } else if (strcmp(input->format, CameraProperties::PIXEL_FORMAT_RGB24) == 0) {  
  67.         informat = Encoder_libjpeg::RGB24;  
  68.         bpp = 1;  
  69.         if ((in_width != out_width) || (in_height != out_height)) {  
  70.             resize_src = (uint8_t*) malloc(input->dst_size);  
  71.             if(NULL != resize_src){  
  72.                 extraSmallImg(input->src, in_width, in_height,  
  73.                              resize_src, out_width, out_height);  
  74.                 src = resize_src;  
  75.             }else{  
  76.                 CAMHAL_LOGDA("failed to malloc space to extra thumbnail\n");  
  77.                 goto exit;  
  78.             }  
  79.         }  
  80.     } else if ((in_width != out_width) || (in_height != out_height)) {  
  81.         CAMHAL_LOGEB("Encoder: resizing is not supported for this format: %s", input->format);  
  82.         goto exit;  
  83.     } else if (strcmp(input->format, CameraParameters::PIXEL_FORMAT_YUV422I)) {  
  84.         // we currently only support yuv422i and yuv420sp  
  85.         CAMHAL_LOGEB("Encoder: format not supported: %s", input->format);  
  86.         goto exit;  
  87.     }  
  88.   
  89.     cinfo.err = jpeg_std_error(&jerr);  
  90.   
  91.     jpeg_create_compress(&cinfo);  
  92.   
  93.     CAMHAL_LOGDB("encoding...  \n\t"  
  94.                  "width: %d    \n\t"  
  95.                  "height:%d    \n\t"  
  96.                  "dest %p      \n\t"  
  97.                  "dest size:%d \n\t"  
  98.                  "mSrc %p",  
  99.                  out_width, out_height, input->dst,  
  100.                  input->dst_size, src);  
  101.   
  102.     cinfo.dest = &dest_mgr;  
  103.     cinfo.image_width = out_width;  
  104.     cinfo.image_height = out_height;  
  105.     cinfo.input_components = 3;  
  106.     if (informat == Encoder_libjpeg::RGB24)  
  107.         cinfo.in_color_space = JCS_RGB;  
  108.     else  
  109.         cinfo.in_color_space = JCS_YCbCr;  
  110.     cinfo.input_gamma = 1;  
  111.   
  112.     jpeg_set_defaults(&cinfo);  
  113.     jpeg_set_quality(&cinfo, input->quality, TRUE);  
  114.     cinfo.dct_method = JDCT_IFAST;  
  115.   
  116.     jpeg_start_compress(&cinfo, TRUE);  
  117.   
  118.     row_tmp = (uint8_t*)malloc(out_width * 3);  
  119.     row_src = src;  
  120.     row_uv = src + out_width * out_height * bpp;  
  121.     row_stride = out_width * 3;  
  122.   
  123. //add by tankai 插帧部分  
  124. if(in_width < out_height){  
  125.   int i,j,z,ratex,ratey=0; unsigned char *ptr;  
  126.   while ((cinfo.next_scanline < cinfo.image_height) && !mCancelEncoding) {  
  127.     JSAMPROW row_pointer[1];  
  128. if ((ratey-=10)<0){  
  129.   ratey+=51;  
  130.   ratex=0;  
  131.   ptr=row_tmp;  
  132.   z = 0;  
  133.   for (j=0; j<3264; j++){  
  134.     if ((ratex-=10)<0){  
  135.       ratex+=51;  
  136.       {  
  137.     int r, g, b;  
  138.     int y, u, v;  
  139.     if (!z)  
  140.       y = src[0] << 8;  
  141.     else  
  142.           y = src[2] << 8;  
  143.     u = src[1] - 128;  
  144.     v = src[3] - 128;  
  145.   
  146.     r = (y + (359 * v)) >> 8;  
  147.     g = (y - (88 * u) - (183 * v)) >> 8;  
  148.     b = (y + (454 * u)) >> 8;  
  149.   
  150.     *(ptr++) = (r > 255) ? 255 : ((r < 0) ? 0 : r);  
  151.     *(ptr++) = (g > 255) ? 255 : ((g < 0) ? 0 : g);  
  152.     *(ptr++) = (b > 255) ? 255 : ((b < 0) ? 0 : b);  
  153.   
  154.     if (z++){  
  155.       z = 0;  
  156.       src += 4;  
  157.         }  
  158.       }  
  159.     }else{  
  160.       register unsigned char rgbchar;  
  161.       rgbchar=*(ptr-3);  
  162.       *(ptr++)=rgbchar;  
  163.       rgbchar=*(ptr-3);  
  164.       *(ptr++)=rgbchar;  
  165.       rgbchar=*(ptr-3);  
  166.       *(ptr++)=rgbchar;  
  167.      }  
  168.     }  
  169.   }  
  170.   row_pointer[0] = row_tmp;  
  171.   jpeg_write_scanlines (&cinfo, row_pointer, 1);  
  172.   }  
  173. }  
  174. else  
  175. //end tankai 插帧部分  
  176.   
  177.     while ((cinfo.next_scanline < cinfo.image_height) && !mCancelEncoding) {  
  178.         JSAMPROW row[1];    /* pointer to JSAMPLE row[s] */  
  179.   
  180.         if (informat == Encoder_libjpeg::RGB24) {  
  181.             row[0] = &src[cinfo.next_scanline * row_stride];  
  182.             (void) jpeg_write_scanlines(&cinfo, row, 1);  
  183.         } else {  
  184.             // convert input yuv format to yuv444  
  185.             if (informat == Encoder_libjpeg::YUV420SP) {  
  186.                 nv21_to_yuv(row_tmp, row_src, row_uv, out_width);  
  187.             } else if (informat == Encoder_libjpeg::YUV422I) {  
  188.                 //uyvy_to_yuv(row_tmp, (uint32_t*)row_src, out_width);  
  189.                 yuyv_to_yuv(row_tmp, (uint32_t*)row_src, out_width);  
  190.             }  
  191.   
  192.             row[0] = row_tmp;  
  193.             jpeg_write_scanlines(&cinfo, row, 1);  
  194.             row_src = row_src + out_width*bpp;  
  195.   
  196.             // move uv row if input format needs it  
  197.             if (informat == Encoder_libjpeg::YUV420SP) {  
  198.                 if (!(cinfo.next_scanline % 2))  
  199.                     row_uv = row_uv +  out_width * bpp;  
  200.             }  
  201.         }  
  202.     }  
  203.   
  204.     // no need to finish encoding routine if we are prematurely stopping  
  205.     // we will end up crashing in dest_mgr since data is incomplete  
  206.     if (!mCancelEncoding)  
  207.         jpeg_finish_compress(&cinfo);  
  208.     jpeg_destroy_compress(&cinfo);  
  209.   
  210.     if (resize_src) free(resize_src);  
  211.     if (row_tmp) free(row_tmp);  
  212.   
  213.  exit:  
  214.     input->jpeg_size = dest_mgr.jpegsize;  
  215.     return dest_mgr.jpegsize;  

Android4.2之Camera系统HAL调用流程

http://blog.csdn.net/tankai19880619/article/details/17348637

一、重要结构体

1.模块

hardware/libhardware/include/hardware/camera_common.h

  1. typedef struct camera_module {  
  2.     hw_module_t common;  
  3.     int (*get_number_of_cameras)(void);  
  4.     int (*get_camera_info)(int camera_id, struct camera_info *info);  
  5. } camera_module_t;  

2.设备

hardware/libhardware/include/hardware/camera.h

  1. typedef struct camera_device {  
  2.     /** 
  3.      * camera_device.common.version must be in the range 
  4.      * HARDWARE_DEVICE_API_VERSION(0,0)-(1,FF). CAMERA_DEVICE_API_VERSION_1_0 is 
  5.      * recommended. 
  6.      */  
  7.     hw_device_t common;  
  8.     camera_device_ops_t *ops;  
  9.     void *priv;  
  10. } camera_device_t;  
二、流程

1.模块获取

frameworks/av/services/camera/libcameraservice/CameraService.cpp

  1. void CameraService::onFirstRef(){  
  2.   BnCameraService::onFirstRef();  
  3.   
  4.   
  5.   if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,  
  6.                 (const hw_module_t **)&mModule) < 0) { //获取Module  
  7.     ALOGE("Could not load camera HAL module");  
  8.     mNumberOfCameras = 0;  
  9.   }  
  10.   else {  
  11.     mNumberOfCameras = mModule->get_number_of_cameras();  
  12.     // if(mNumberOfCameras <= 0) mNumberOfCameras = 1 ;  
  13.     char istv [10];  
  14.     memset(istv,0,sizeof(istv));  
  15.     if (property_get("tv.tvstart_status", istv, NULL) > 0){  
  16.       ALOGD("tv.tvstart_status = %s ,mNumberOfCameras = %d \n",istv,mNumberOfCameras+1);  
  17.     }  
  18.     if(strcmp(istv,"false") == 0)  
  19.       mNumberOfCameras = mNumberOfCameras+1 ;  
  20.   
  21.   
  22.     if (mNumberOfCameras > MAX_CAMERAS) {  
  23.       ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",  
  24.                     mNumberOfCameras, MAX_CAMERAS);  
  25.       mNumberOfCameras = MAX_CAMERAS;  
  26.     }  
  27.     for (int i = 0; i < mNumberOfCameras; i++) {  
  28.       setCameraFree(i);  
  29.     }  
  30.   }  
  31. }  
2.设备获取
frameworks/av/services/camera/libcameraservice/CameraService.cpp
  1. sp<ICamera> CameraService::connect(  
  2.         const sp<ICameraClient>& cameraClient, int cameraId) {  
  3.   int deviceVersion;  
  4.   if (mModule->common.module_api_version == CAMERA_MODULE_API_VERSION_2_0) {  
  5.     deviceVersion = info.device_version;  
  6.   } else {  
  7.      deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;  
  8.   }  
  9.   
  10.   
  11.   switch(deviceVersion) {  
  12.     case CAMERA_DEVICE_API_VERSION_1_0:  
  13.       client = new CameraClient(this, cameraClient, cameraId, info.facing, callingPid, getpid());  
  14.       break;  
  15.     case CAMERA_DEVICE_API_VERSION_2_0:  
  16.       client = new Camera2Client(this, cameraClient, cameraId, info.facing, callingPid, getpid());  
  17.       break;  
  18.     default:  
  19.       ALOGE("Unknown camera device HAL version: %d", deviceVersion);  
  20.       return NULL;  
  21.   }  
  22.   if (client->initialize(mModule) != OK) {  
  23.     return NULL;  
  24.   }  
  25. }  

frameworks/av/services/camera/libcameraservice/CameraClient.cpp

  1. status_t CameraClient::initialize(camera_module_t *module) {  
  2.   mHardware = new CameraHardwareInterface(camera_device_name);  
  3.   res = mHardware->initialize(&module->common);  
  4. }  
frameworks/av/services/camera/libcameraservice/CameraHardwareInterface.h
  1. status_t initialize(hw_module_t *module){  
  2.   int rc = module->methods->open(module, mName.string(), (hw_device_t **)&mDevice); //获得Device  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值