http://blog.csdn.net/tankai19880619/article/details/17259525
一、rgb插值算法
说明:验证可用,算法效率一般;其中pDest为扩帧后内存地址,nDestWidth和nDestHeight为扩帧后分辨率,nDestBits为色深(如rgb24则为24)。
- void rgbInterpolation(void* pDest, int nDestWidth, int nDestHeight, int nDestBits, void* pSrc, int nSrcWidth, int nSrcHeight, int nSrcBits)
- {
- //ASSERT_EXP(pDest != NULL);
- //ASSERT_EXP((nDestBits == 32) || (nDestBits == 24));
- //ASSERT_EXP((nDestWidth > 0) && (nDestHeight > 0));
- //ASSERT_EXP(pSrc != NULL);
- //ASSERT_EXP((nSrcBits == 32) || (nSrcBits == 24));
- //ASSERT_EXP((nSrcWidth > 0) && (nSrcHeight > 0));
- double dfAmplificationX = ((double)nDestWidth)/nSrcWidth;
- double dfAmplificationY = ((double)nDestHeight)/nSrcHeight;
- const int nSrcColorLen = nSrcBits/8;
- const int nDestColorLen = nDestBits/8;
- for(int i = 0; i<nDestHeight; i++)
- for(int j = 0; j<nDestWidth; j++)
- {
- double tmp = i/dfAmplificationY;
- int nLine = (int)tmp;
- if(tmp - nLine > 0.5)
- ++nLine;
- if(nLine >= nSrcHeight)
- --nLine;
- tmp = j/dfAmplificationX;
- int nRow = (int)tmp;
- if(tmp - nRow > 0.5)
- ++nRow;
- if(nRow >= nSrcWidth)
- --nRow;
- unsigned char *pSrcPos = (unsigned char*)pSrc + (nLine*nSrcWidth + nRow)*nSrcColorLen;
- unsigned char *pDestPos = (unsigned char*)pDest + (i*nDestWidth + j)*nDestColorLen;
- *pDestPos++ = *pSrcPos++;
- *pDestPos++ = *pSrcPos++;
- *pDestPos++ = *pSrcPos++;
- if(nDestColorLen == 4)
- *pDestPos = 0;
- }
- }
说明:该算法经过验证可行;效率较上边略高,是将rgb的转化省略、进而嵌套在jpeg编码中。
- /* private member functions */
- /*
- struct params {
- uint8_t* src;
- int src_size;
- uint8_t* dst; //需要插帧时,该buffer大小为3264*2448*3Byte
- int dst_size; //需要插帧时,大小为3264*2448*3Byte
- int quality;
- int in_width;
- int in_height;
- int out_width; //需要插帧时,该位为3264
- int out_height; //需要插帧时,该位为2448
- const char* format;
- size_t jpeg_size;
- };
- */
- size_t Encoder_libjpeg::encode(params* input) {
- jpeg_compress_struct cinfo;
- jpeg_error_mgr jerr;
- jpeg_destination_mgr jdest;
- uint8_t* src = NULL, *resize_src = NULL;
- uint8_t* row_tmp = NULL;
- uint8_t* row_src = NULL;
- uint8_t* row_uv = NULL; // used only for NV12
- int row_stride;
- int out_width = 0, in_width = 0;
- int out_height = 0, in_height = 0;
- int bpp = 2; // for uyvy
- Encoder_libjpeg::format informat = Encoder_libjpeg::YUV422I;
- if (!input) {
- return 0;
- }
- out_width = input->out_width;
- in_width = input->in_width;
- out_height = input->out_height;
- in_height = input->in_height;
- src = input->src;
- input->jpeg_size = 0;
- libjpeg_destination_mgr dest_mgr(input->dst, input->dst_size);
- // param check...
- if ((in_width < 2) || (out_width < 2) || (in_height < 2) || (out_height < 2) ||
- (src == NULL) || (input->dst == NULL) || (input->quality < 1) || (input->src_size < 1) ||
- (input->dst_size < 1) || (input->format == NULL)) {
- goto exit;
- }
- if (strcmp(input->format, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
- //add by tankai
- if(in_width < out_height){
- informat = Encoder_libjpeg::RGB24;
- }
- else{
- //end tankai
- informat = Encoder_libjpeg::YUV420SP;
- bpp = 1;
- if ((in_width != out_width) || (in_height != out_height)) {
- resize_src = (uint8_t*) malloc(input->dst_size);
- resize_nv12(input, resize_src);
- if (resize_src) src = resize_src;
- }
- }//add by tankai
- } else if (strcmp(input->format, CameraProperties::PIXEL_FORMAT_RGB24) == 0) {
- informat = Encoder_libjpeg::RGB24;
- bpp = 1;
- if ((in_width != out_width) || (in_height != out_height)) {
- resize_src = (uint8_t*) malloc(input->dst_size);
- if(NULL != resize_src){
- extraSmallImg(input->src, in_width, in_height,
- resize_src, out_width, out_height);
- src = resize_src;
- }else{
- CAMHAL_LOGDA("failed to malloc space to extra thumbnail\n");
- goto exit;
- }
- }
- } else if ((in_width != out_width) || (in_height != out_height)) {
- CAMHAL_LOGEB("Encoder: resizing is not supported for this format: %s", input->format);
- goto exit;
- } else if (strcmp(input->format, CameraParameters::PIXEL_FORMAT_YUV422I)) {
- // we currently only support yuv422i and yuv420sp
- CAMHAL_LOGEB("Encoder: format not supported: %s", input->format);
- goto exit;
- }
- cinfo.err = jpeg_std_error(&jerr);
- jpeg_create_compress(&cinfo);
- CAMHAL_LOGDB("encoding... \n\t"
- "width: %d \n\t"
- "height:%d \n\t"
- "dest %p \n\t"
- "dest size:%d \n\t"
- "mSrc %p",
- out_width, out_height, input->dst,
- input->dst_size, src);
- cinfo.dest = &dest_mgr;
- cinfo.image_width = out_width;
- cinfo.image_height = out_height;
- cinfo.input_components = 3;
- if (informat == Encoder_libjpeg::RGB24)
- cinfo.in_color_space = JCS_RGB;
- else
- cinfo.in_color_space = JCS_YCbCr;
- cinfo.input_gamma = 1;
- jpeg_set_defaults(&cinfo);
- jpeg_set_quality(&cinfo, input->quality, TRUE);
- cinfo.dct_method = JDCT_IFAST;
- jpeg_start_compress(&cinfo, TRUE);
- row_tmp = (uint8_t*)malloc(out_width * 3);
- row_src = src;
- row_uv = src + out_width * out_height * bpp;
- row_stride = out_width * 3;
- //add by tankai 插帧部分
- if(in_width < out_height){
- int i,j,z,ratex,ratey=0; unsigned char *ptr;
- while ((cinfo.next_scanline < cinfo.image_height) && !mCancelEncoding) {
- JSAMPROW row_pointer[1];
- if ((ratey-=10)<0){
- ratey+=51;
- ratex=0;
- ptr=row_tmp;
- z = 0;
- for (j=0; j<3264; j++){
- if ((ratex-=10)<0){
- ratex+=51;
- {
- int r, g, b;
- int y, u, v;
- if (!z)
- y = src[0] << 8;
- else
- y = src[2] << 8;
- u = src[1] - 128;
- v = src[3] - 128;
- r = (y + (359 * v)) >> 8;
- g = (y - (88 * u) - (183 * v)) >> 8;
- b = (y + (454 * u)) >> 8;
- *(ptr++) = (r > 255) ? 255 : ((r < 0) ? 0 : r);
- *(ptr++) = (g > 255) ? 255 : ((g < 0) ? 0 : g);
- *(ptr++) = (b > 255) ? 255 : ((b < 0) ? 0 : b);
- if (z++){
- z = 0;
- src += 4;
- }
- }
- }else{
- register unsigned char rgbchar;
- rgbchar=*(ptr-3);
- *(ptr++)=rgbchar;
- rgbchar=*(ptr-3);
- *(ptr++)=rgbchar;
- rgbchar=*(ptr-3);
- *(ptr++)=rgbchar;
- }
- }
- }
- row_pointer[0] = row_tmp;
- jpeg_write_scanlines (&cinfo, row_pointer, 1);
- }
- }
- else
- //end tankai 插帧部分
- while ((cinfo.next_scanline < cinfo.image_height) && !mCancelEncoding) {
- JSAMPROW row[1]; /* pointer to JSAMPLE row[s] */
- if (informat == Encoder_libjpeg::RGB24) {
- row[0] = &src[cinfo.next_scanline * row_stride];
- (void) jpeg_write_scanlines(&cinfo, row, 1);
- } else {
- // convert input yuv format to yuv444
- if (informat == Encoder_libjpeg::YUV420SP) {
- nv21_to_yuv(row_tmp, row_src, row_uv, out_width);
- } else if (informat == Encoder_libjpeg::YUV422I) {
- //uyvy_to_yuv(row_tmp, (uint32_t*)row_src, out_width);
- yuyv_to_yuv(row_tmp, (uint32_t*)row_src, out_width);
- }
- row[0] = row_tmp;
- jpeg_write_scanlines(&cinfo, row, 1);
- row_src = row_src + out_width*bpp;
- // move uv row if input format needs it
- if (informat == Encoder_libjpeg::YUV420SP) {
- if (!(cinfo.next_scanline % 2))
- row_uv = row_uv + out_width * bpp;
- }
- }
- }
- // no need to finish encoding routine if we are prematurely stopping
- // we will end up crashing in dest_mgr since data is incomplete
- if (!mCancelEncoding)
- jpeg_finish_compress(&cinfo);
- jpeg_destroy_compress(&cinfo);
- if (resize_src) free(resize_src);
- if (row_tmp) free(row_tmp);
- exit:
- input->jpeg_size = dest_mgr.jpegsize;
- return dest_mgr.jpegsize;
- }
Android4.2之Camera系统HAL调用流程
http://blog.csdn.net/tankai19880619/article/details/17348637
一、重要结构体
1.模块
hardware/libhardware/include/hardware/camera_common.h
- typedef struct camera_module {
- hw_module_t common;
- int (*get_number_of_cameras)(void);
- int (*get_camera_info)(int camera_id, struct camera_info *info);
- } camera_module_t;
2.设备
hardware/libhardware/include/hardware/camera.h
- typedef struct camera_device {
- /**
- * camera_device.common.version must be in the range
- * HARDWARE_DEVICE_API_VERSION(0,0)-(1,FF). CAMERA_DEVICE_API_VERSION_1_0 is
- * recommended.
- */
- hw_device_t common;
- camera_device_ops_t *ops;
- void *priv;
- } camera_device_t;
1.模块获取
frameworks/av/services/camera/libcameraservice/CameraService.cpp
- void CameraService::onFirstRef(){
- BnCameraService::onFirstRef();
- if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
- (const hw_module_t **)&mModule) < 0) { //获取Module
- ALOGE("Could not load camera HAL module");
- mNumberOfCameras = 0;
- }
- else {
- mNumberOfCameras = mModule->get_number_of_cameras();
- // if(mNumberOfCameras <= 0) mNumberOfCameras = 1 ;
- char istv [10];
- memset(istv,0,sizeof(istv));
- if (property_get("tv.tvstart_status", istv, NULL) > 0){
- ALOGD("tv.tvstart_status = %s ,mNumberOfCameras = %d \n",istv,mNumberOfCameras+1);
- }
- if(strcmp(istv,"false") == 0)
- mNumberOfCameras = mNumberOfCameras+1 ;
- if (mNumberOfCameras > MAX_CAMERAS) {
- ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
- mNumberOfCameras, MAX_CAMERAS);
- mNumberOfCameras = MAX_CAMERAS;
- }
- for (int i = 0; i < mNumberOfCameras; i++) {
- setCameraFree(i);
- }
- }
- }
frameworks/av/services/camera/libcameraservice/CameraService.cpp
- sp<ICamera> CameraService::connect(
- const sp<ICameraClient>& cameraClient, int cameraId) {
- int deviceVersion;
- if (mModule->common.module_api_version == CAMERA_MODULE_API_VERSION_2_0) {
- deviceVersion = info.device_version;
- } else {
- deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
- }
- switch(deviceVersion) {
- case CAMERA_DEVICE_API_VERSION_1_0:
- client = new CameraClient(this, cameraClient, cameraId, info.facing, callingPid, getpid());
- break;
- case CAMERA_DEVICE_API_VERSION_2_0:
- client = new Camera2Client(this, cameraClient, cameraId, info.facing, callingPid, getpid());
- break;
- default:
- ALOGE("Unknown camera device HAL version: %d", deviceVersion);
- return NULL;
- }
- if (client->initialize(mModule) != OK) {
- return NULL;
- }
- }
frameworks/av/services/camera/libcameraservice/CameraClient.cpp
- status_t CameraClient::initialize(camera_module_t *module) {
- mHardware = new CameraHardwareInterface(camera_device_name);
- res = mHardware->initialize(&module->common);
- }
- status_t initialize(hw_module_t *module){
- int rc = module->methods->open(module, mName.string(), (hw_device_t **)&mDevice); //获得Device
- }