int PhysMemAdapter::allocatePictureBuffer(int width, int height, int format, int numBufs) { if (mIonFd <= 0) { FLOGE("try to allocate buffer from ion in preview or ion invalid"); return BAD_VALUE; } int size = 0; if ((width == 0) || (height == 0)) { FLOGE("allocateBufferFromIon: width or height = 0"); return BAD_VALUE; } switch (format) { case HAL_PIXEL_FORMAT_YCbCr_420_SP: size = width * ((height + 16) & (~15)) * 3 / 2; break; case HAL_PIXEL_FORMAT_YCbCr_420_P: size = width * height * 3 / 2; break; case HAL_PIXEL_FORMAT_YCbCr_422_I: size = width * height * 2; break; default: FLOGE("Error: format not supported int ion alloc"); return BAD_VALUE; } unsigned char *ptr = NULL; int sharedFd; int phyAddr; struct ion_handle *ionHandle; size = (size + PAGE_SIZE - 1) & (~(PAGE_SIZE - 1)); FLOGI("allocateBufferFromIon buffer num:%d", numBufs); for (int i = 0; i < numBufs; i++) { ionHandle = NULL; int err = ion_alloc(mIonFd, size, 8, 1, &ionHandle); if (err) { FLOGE("ion_alloc failed."); return BAD_VALUE; } err = ion_map(mIonFd, ionHandle, size, PROT_READ | PROT_WRITE, MAP_SHARED, 0, &ptr, &sharedFd); if (err) { FLOGE("ion_map failed."); return BAD_VALUE; } phyAddr = ion_phys(mIonFd, ionHandle); if (phyAddr == 0) { FLOGE("ion_phys failed."); return BAD_VALUE; } FLOG_RUNTIME("phyalloc ptr:0x%x, phy:0x%x, size:%d", (int)ptr, phyAddr, size); mCameraBuffer[i].reset(); mCameraBuffer[i].mIndex = i; mCameraBuffer[i].mWidth = width; mCameraBuffer[i].mHeight = height; mCameraBuffer[i].mFormat = format; mCameraBuffer[i].mVirtAddr = ptr; mCameraBuffer[i].mPhyAddr = phyAddr; mCameraBuffer[i].mSize = size; mCameraBuffer[i].mBufHandle = (buffer_handle_t *)ionHandle; close(sharedFd); } mBufferCount = numBufs; mQueueableCount = numBufs; mFormat = format; mBufferSize = mCameraBuffer[0].mSize; mFrameWidth = width; mFrameHeight = height; dispatchBuffers(&mCameraBuffer[0], numBufs, BUFFER_CREATE); return NO_ERROR; }
status_t TVINDevice::initSensorInfo(const CameraInfo& /*info*/) { if (mCameraHandle < 0) { FLOGE("TVINDevice: initParameters sensor has not been opened"); return BAD_VALUE; } int res = 0; int maxWait = 6; // Get the PAL/NTSC STD do { res = ioctl(mCameraHandle, VIDIOC_G_STD, &mSTD); if (res < 0) { FLOGE("VIDIOC_G_STD failed with more try %d\n", maxWait - 1); sleep(1); } maxWait --; }while ((res != 0) || (maxWait <= 0)); if (mSTD == V4L2_STD_PAL) FLOGI("Get current mode: PAL"); else if (mSTD == V4L2_STD_NTSC) FLOGI("Get current mode: NTSC"); else { FLOGI("Error!Get invalid mode: %llu", mSTD); return BAD_VALUE; } if (ioctl(mCameraHandle, VIDIOC_S_STD, &mSTD) < 0) { FLOGE("VIDIOC_S_STD failed\n"); return BAD_VALUE; } // first read sensor format. int ret = 0, index = 0; int sensorFormats[MAX_SENSOR_FORMAT]; memset(mAvailableFormats, 0, sizeof(mAvailableFormats)); memset(sensorFormats, 0, sizeof(sensorFormats)); #if 0 struct v4l2_fmtdesc vid_fmtdesc; while (ret == 0) { vid_fmtdesc.index = index; vid_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = ioctl(mCameraHandle, VIDIOC_ENUM_FMT, &vid_fmtdesc); FLOG_RUNTIME("index:%d,ret:%d, format:%c%c%c%c", index, ret, vid_fmtdesc.pixelformat & 0xFF, (vid_fmtdesc.pixelformat >> 8) & 0xFF, (vid_fmtdesc.pixelformat >> 16) & 0xFF, (vid_fmtdesc.pixelformat >> 24) & 0xFF); if (ret == 0) { sensorFormats[index++] = vid_fmtdesc.pixelformat; } } sensorFormats[index++] = v4l2_fourcc('B', 'L', 'O', 'B'); sensorFormats[index++] = v4l2_fourcc('R', 'A', 'W', 'S'); #endif // v4l2 does not support enum format, now hard code here. sensorFormats[index++] = v4l2_fourcc('N', 'V', '1', '2'); sensorFormats[index++] = v4l2_fourcc('Y', 'V', '1', '2'); sensorFormats[index++] = v4l2_fourcc('B', 'L', 'O', 'B'); sensorFormats[index++] = v4l2_fourcc('R', 'A', 'W', 'S'); //mAvailableFormats[2] = v4l2_fourcc('Y', 'U', 'Y', 'V'); mAvailableFormatCount = index; changeSensorFormats(sensorFormats, index); index = 0; char TmpStr[20]; int previewCnt = 0, pictureCnt = 0; struct v4l2_frmsizeenum vid_frmsize; struct v4l2_frmivalenum vid_frmval; while (ret == 0) { memset(TmpStr, 0, 20); memset(&vid_frmsize, 0, sizeof(struct v4l2_frmsizeenum)); vid_frmsize.index = index++; vid_frmsize.pixel_format = v4l2_fourcc('N', 'V', '1', '2'); ret = ioctl(mCameraHandle, VIDIOC_ENUM_FRAMESIZES, &vid_frmsize); if (ret == 0) { FLOG_RUNTIME("enum frame size w:%d, h:%d", vid_frmsize.discrete.width, vid_frmsize.discrete.height); memset(&vid_frmval, 0, sizeof(struct v4l2_frmivalenum)); vid_frmval.index = 0; vid_frmval.pixel_format = vid_frmsize.pixel_format; vid_frmval.width = vid_frmsize.discrete.width; vid_frmval.height = vid_frmsize.discrete.height; // ret = ioctl(mCameraHandle, VIDIOC_ENUM_FRAMEINTERVALS, // &vid_frmval); // v4l2 does not support, now hard code here. if (ret == 0) { FLOG_RUNTIME("vid_frmval denominator:%d, numeraton:%d", vid_frmval.discrete.denominator, vid_frmval.discrete.numerator); if ((vid_frmsize.discrete.width > 1920) || (vid_frmsize.discrete.height > 1080)) { vid_frmval.discrete.denominator = 15; vid_frmval.discrete.numerator = 1; } else { vid_frmval.discrete.denominator = 30; vid_frmval.discrete.numerator = 1; } mPictureResolutions[pictureCnt++] = vid_frmsize.discrete.width; mPictureResolutions[pictureCnt++] = vid_frmsize.discrete.height; if (vid_frmval.discrete.denominator / vid_frmval.discrete.numerator > 15) { mPreviewResolutions[previewCnt++] = vid_frmsize.discrete.width; mPreviewResolutions[previewCnt++] = vid_frmsize.discrete.height;; } } } } // end while mPreviewResolutionCount = previewCnt; mPictureResolutionCount = pictureCnt; mMinFrameDuration = 33331760L; mMaxFrameDuration = 30000000000L; int i; for (i=0; i<MAX_RESOLUTION_SIZE && i<pictureCnt; i+=2) { FLOGI("SupportedPictureSizes: %d x %d", mPictureResolutions[i], mPictureResolutions[i+1]); } adjustPreviewResolutions(); for (i=0; i<MAX_RESOLUTION_SIZE && i<previewCnt; i+=2) { FLOGI("SupportedPreviewSizes: %d x %d", mPreviewResolutions[i], mPreviewResolutions[i+1]); } FLOGI("FrameDuration is %lld, %lld", mMinFrameDuration, mMaxFrameDuration); i = 0; mTargetFpsRange[i++] = 10; mTargetFpsRange[i++] = 15; mTargetFpsRange[i++] = 25; mTargetFpsRange[i++] = 30; setMaxPictureResolutions(); FLOGI("mMaxWidth:%d, mMaxHeight:%d", mMaxWidth, mMaxHeight); mFocalLength = 10.001; return NO_ERROR; }
status_t TVINDevice::initParameters(CameraParameters& params, int *supportRecordingFormat, int rfmtLen, int *supportPictureFormat, int pfmtLen) { int ret = 0, index = 0; int maxWait = 6; int sensorFormat[MAX_SENSOR_FORMAT]; if (mCameraHandle < 0) { FLOGE("TVINDevice: initParameters sensor has not been opened"); return BAD_VALUE; } if ((supportRecordingFormat == NULL) || (rfmtLen == 0) || (supportPictureFormat == NULL) || (pfmtLen == 0)) { FLOGE("TVINDevice: initParameters invalid parameters"); return BAD_VALUE; } // Get the PAL/NTSC STD do { ret = ioctl(mCameraHandle, VIDIOC_G_STD, &mSTD); if (ret < 0) { FLOGE("VIDIOC_G_STD failed with more try %d\n", maxWait - 1); sleep(1); } maxWait --; }while ((ret != 0) || (maxWait <= 0)); if (mSTD == V4L2_STD_PAL) FLOGI("Get current mode: PAL"); else if (mSTD == V4L2_STD_NTSC) FLOGI("Get current mode: NTSC"); else { FLOGI("Error!Get invalid mode: %llu", mSTD); return BAD_VALUE; } if (ioctl(mCameraHandle, VIDIOC_S_STD, &mSTD) < 0) { FLOGE("VIDIOC_S_STD failed\n"); return BAD_VALUE; } // first read sensor format. #if 0 struct v4l2_fmtdesc vid_fmtdesc; while (ret == 0) { vid_fmtdesc.index = index; vid_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = ioctl(mCameraHandle, VIDIOC_ENUM_FMT, &vid_fmtdesc); FLOG_RUNTIME("index:%d,ret:%d, format:%c%c%c%c", index, ret, vid_fmtdesc.pixelformat & 0xFF, (vid_fmtdesc.pixelformat >> 8) & 0xFF, (vid_fmtdesc.pixelformat >> 16) & 0xFF, (vid_fmtdesc.pixelformat >> 24) & 0xFF); if (ret == 0) { sensorFormat[index++] = vid_fmtdesc.pixelformat; } } #endif // if 0 // v4l2 does not support enum format, now hard code here. sensorFormat[0] = v4l2_fourcc('N', 'V', '1', '2'); sensorFormat[1] = v4l2_fourcc('Y', 'U', '1', '2'); sensorFormat[2] = v4l2_fourcc('Y', 'U', 'Y', 'V'); index = 3; // second check match sensor format with vpu support format and picture // format. mPreviewPixelFormat = getMatchFormat(supportRecordingFormat, rfmtLen, sensorFormat, index); mPicturePixelFormat = getMatchFormat(supportPictureFormat, pfmtLen, sensorFormat, index); setPreviewStringFormat(mPreviewPixelFormat); ret = setSupportedPreviewFormats(supportRecordingFormat, rfmtLen, sensorFormat, index); if (ret) { FLOGE("setSupportedPreviewFormats failed"); return ret; } index = 0; char TmpStr[20]; int previewCnt = 0, pictureCnt = 0; struct v4l2_frmsizeenum vid_frmsize; struct v4l2_frmivalenum vid_frmval; while (ret == 0) { memset(TmpStr, 0, 20); memset(&vid_frmsize, 0, sizeof(struct v4l2_frmsizeenum)); vid_frmsize.index = index++; vid_frmsize.pixel_format = v4l2_fourcc('N', 'V', '1', '2'); ret = ioctl(mCameraHandle, VIDIOC_ENUM_FRAMESIZES, &vid_frmsize); if (ret == 0) { FLOG_RUNTIME("enum frame size w:%d, h:%d", vid_frmsize.discrete.width, vid_frmsize.discrete.height); memset(&vid_frmval, 0, sizeof(struct v4l2_frmivalenum)); vid_frmval.index = 0; vid_frmval.pixel_format = vid_frmsize.pixel_format; vid_frmval.width = vid_frmsize.discrete.width; vid_frmval.height = vid_frmsize.discrete.height; // ret = ioctl(mCameraHandle, VIDIOC_ENUM_FRAMEINTERVALS, // &vid_frmval); // v4l2 does not support, now hard code here. if (ret == 0) { FLOG_RUNTIME("vid_frmval denominator:%d, numeraton:%d", vid_frmval.discrete.denominator, vid_frmval.discrete.numerator); if ((vid_frmsize.discrete.width > 1280) || (vid_frmsize.discrete.height > 720)) { vid_frmval.discrete.denominator = 15; vid_frmval.discrete.numerator = 1; } else { vid_frmval.discrete.denominator = 30; vid_frmval.discrete.numerator = 1; } sprintf(TmpStr, "%dx%d", vid_frmsize.discrete.width, vid_frmsize.discrete.height); // Set default to be first enum w/h, since tvin may only // have one set if (pictureCnt == 0){ mParams.setPreviewSize(vid_frmsize.discrete.width, vid_frmsize.discrete.height); mParams.setPictureSize(vid_frmsize.discrete.width, vid_frmsize.discrete.height); } if (pictureCnt == 0) strncpy((char *)mSupportedPictureSizes, TmpStr, CAMER_PARAM_BUFFER_SIZE); else { strncat(mSupportedPictureSizes, PARAMS_DELIMITER, CAMER_PARAM_BUFFER_SIZE); strncat(mSupportedPictureSizes, TmpStr, CAMER_PARAM_BUFFER_SIZE); } pictureCnt++; if (vid_frmval.discrete.denominator / vid_frmval.discrete.numerator >= 15) { if (previewCnt == 0) strncpy((char *)mSupportedPreviewSizes, TmpStr, CAMER_PARAM_BUFFER_SIZE); else { strncat(mSupportedPreviewSizes, PARAMS_DELIMITER, CAMER_PARAM_BUFFER_SIZE); strncat(mSupportedPreviewSizes, TmpStr, CAMER_PARAM_BUFFER_SIZE); } previewCnt++; } } } // end if (ret == 0) else { FLOGI("enum frame size error %d", ret); } } // end while strcpy(mSupportedFPS, "15,30"); FLOGI("SupportedPictureSizes is %s", mSupportedPictureSizes); FLOGI("SupportedPreviewSizes is %s", mSupportedPreviewSizes); FLOGI("SupportedFPS is %s", mSupportedFPS); mParams.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, mSupportedPictureSizes); mParams.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, mSupportedPreviewSizes); mParams.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, mSupportedFPS); mParams.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(12000,17000),(25000,33000)"); // Align the default FPS RANGE to the DEFAULT_PREVIEW_FPS mParams.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "12000,17000"); mParams.setPreviewFrameRate(DEFAULT_PREVIEW_FPS); params = mParams; return NO_ERROR; }