summaryrefslogtreecommitdiff
authorbrian.zhu <brian.zhu@amlogic.com>2013-07-16 11:58:49 (GMT)
committer brian.zhu <brian.zhu@amlogic.com>2013-07-16 11:59:55 (GMT)
commit0f8aaedf899ae5c3e400340794eefa2dc126aae0 (patch)
tree2dad6c4c38e6075117f6072ced4e9c95289a8d9e
parent77c43e6150ad1b68ae1dd2f648d7c0189db2be0e (diff)
downloadcamera-0f8aaedf899ae5c3e400340794eefa2dc126aae0.zip
camera-0f8aaedf899ae5c3e400340794eefa2dc126aae0.tar.gz
camera-0f8aaedf899ae5c3e400340794eefa2dc126aae0.tar.bz2
merge from branch amlogic-pd-74752, for optimize frame rate.
Squashed commit of the following: commit 3dd6f32bc8e19e3f9476816e1e7e41e535eb500c Author: brian.zhu <brian.zhu@amlogic.com> Date: Tue Jul 16 19:38:46 2013 +0800 PD#74752 optimize frame rate control commit 2d1b836a956ab03648a4c5ce7214d1a4c06a1ca6 Author: brian.zhu <brian.zhu@amlogic.com> Date: Wed Jul 10 13:26:41 2013 +0800 PD#74752 fix parser supported frame rate bug commit 4d310eab183b784eea0db490ec9aff98d18b016b Author: brian.zhu <brian.zhu@amlogic.com> Date: Wed Jul 10 00:56:15 2013 +0800 PD#74752 improve frame rate control commit 4acd774a7bd46b7e2acda58f2641a8ed7b669a30 Author: brian.zhu <brian.zhu@amlogic.com> Date: Fri Jul 5 19:17:05 2013 +0800 improve the framerate for camera
Diffstat
-rwxr-xr-xCameraHal.cpp2
-rwxr-xr-xV4LCameraAdapter/V4LCameraAdapter.cpp224
-rwxr-xr-xinc/V4LCameraAdapter/V4LCameraAdapter.h10
3 files changed, 163 insertions, 73 deletions
diff --git a/CameraHal.cpp b/CameraHal.cpp
index cacafaa..c8364ea 100755
--- a/CameraHal.cpp
+++ b/CameraHal.cpp
@@ -593,7 +593,7 @@ int CameraHal::setParameters(const CameraParameters& params)
//Perform parameter validation
if(!isParameterValid(valstr
, mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_SUPPORTED))
- || !isParameterInRange(framerate,
+ || !isParameterValid(framerate,
mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES)))
{
CAMHAL_LOGEA("Invalid frame rate range or frame rate");
diff --git a/V4LCameraAdapter/V4LCameraAdapter.cpp b/V4LCameraAdapter/V4LCameraAdapter.cpp
index 3ca7a05..526408f 100755
--- a/V4LCameraAdapter/V4LCameraAdapter.cpp
+++ b/V4LCameraAdapter/V4LCameraAdapter.cpp
@@ -263,26 +263,46 @@ status_t V4LCameraAdapter::initialize(CameraProperties::Properties* caps)
#ifdef AMLOGIC_CAMERA_NONBLOCK_SUPPORT
int fps=0, fps_num=0;
+ int PreviewFrameRate = 0;
char *fpsrange=(char *)calloc(32,sizeof(char));
ret = get_framerate(mCameraHandle, &fps, &fps_num);
if((fpsrange != NULL)&&(NO_ERROR == ret) && ( 0 !=fps_num )){
- mPreviewFrameRate = fps/fps_num;
- sprintf(fpsrange,"%s%d","10,",fps/fps_num);
+ PreviewFrameRate = fps/fps_num;
+ int tmp_fps = fps/fps_num/5;
+ int iter = 0;
+ int shift = 0;
+ for(iter = 0;iter < tmp_fps;)
+ {
+ iter++;
+ if(iter == tmp_fps)
+ sprintf(fpsrange+shift,"%d",iter*5);
+ else
+ sprintf(fpsrange+shift,"%d,",iter*5);
+ if(iter == 1)
+ shift += 2;
+ else
+ shift += 3;
+
+ }
+ if((fps/fps_num)%5 != 0)
+ sprintf(fpsrange+shift-1,",%d",fps/fps_num);
CAMHAL_LOGDB("supported preview rates is %s\n", fpsrange);
mParams.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,fps/fps_num);
mParams.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,fpsrange);
+ memset(fpsrange,0,32*sizeof(char));
+ sprintf(fpsrange,"%s%d","5000,",fps/fps_num*1000);
mParams.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,fpsrange);
mParams.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,fpsrange);
}else{
- mPreviewFrameRate = 15;
+ PreviewFrameRate = 15;
- sprintf(fpsrange,"%s%d","10,", mPreviewFrameRate);
+ sprintf(fpsrange,"%s%d","5,", PreviewFrameRate);
CAMHAL_LOGDB("default preview rates is %s\n", fpsrange);
- mParams.set(CameraParameters::KEY_PREVIEW_FRAME_RATE, mPreviewFrameRate);
+ mParams.set(CameraParameters::KEY_PREVIEW_FRAME_RATE, PreviewFrameRate);
mParams.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,fpsrange);
mParams.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,fpsrange);
@@ -1135,6 +1155,13 @@ status_t V4LCameraAdapter::startPreview()
CAMHAL_LOGDA("Created preview thread");
//Update the flag to indicate we are previewing
mPreviewing = true;
+#ifdef AMLOGIC_CAMERA_NONBLOCK_SUPPORT
+ mFirstBuff = true;
+ mFrameInvAdjust = 0;
+ mFrameInv = 0;
+ mCache.bufPtr = NULL;
+ mCache.index = -1;
+#endif
return ret;
}
@@ -1388,70 +1415,110 @@ int V4LCameraAdapter::previewThread()
int width, height;
CameraFrame frame;
unsigned delay;
- unsigned uFrameInvals;
-
- if (mPreviewing)
- {
- int index = 0;
-
+ unsigned previewframeduration = 0;
+ int active_duration = 0;
+ uint8_t* ptr = NULL;
+ bool noFrame = true;
+ if (mPreviewing){
+
+ int index = -1;
+ previewframeduration = (unsigned)(1000000.0f / float(mParams.getPreviewFrameRate()));
#ifdef AMLOGIC_CAMERA_NONBLOCK_SUPPORT
- uFrameInvals = (unsigned)(1000000.0f / float(mPreviewFrameRate));
- delay = uFrameInvals >>2;
+ delay = previewframeduration>>2;
#else
- int previewFrameRate = mParams.getPreviewFrameRate();
- delay = (unsigned)(1000000.0f / float(previewFrameRate));
+ delay = previewframeduration;
#endif
+ usleep(delay);
-#ifdef AMLOGIC_USB_CAMERA_DECREASE_FRAMES
- usleep(delay*5);
-#else
- usleep(delay);
+ char *fp = this->GetFrame(index);
+
+ if((-1==index)||!fp){
+ noFrame = true;
+ }else{
+ noFrame = false;
+#ifdef AMLOGIC_USB_CAMERA_SUPPORT
+ if(mVideoInfo->buf.length != mVideoInfo->buf.bytesused){
+ fillThisBuffer((uint8_t*) mPreviewBufs.keyAt(mPreviewIdxs.valueFor(index)), CameraFrame::PREVIEW_FRAME_SYNC);
+ CAMHAL_LOGDB("length=%d bytesused=%d index=%d\n", mVideoInfo->buf.length, mVideoInfo->buf.bytesused, index);
+ noFrame = true;
+ index = -1;
+ }
#endif
+ }
- char *fp = this->GetFrame(index);
+ if(noFrame == true){
+ index = -1;
+ fp = NULL;
#ifdef AMLOGIC_CAMERA_NONBLOCK_SUPPORT
- if((-1==index)||!fp)
- {
- return 0;
- }
+ if(mFirstBuff == true) // need wait for first frame
+ return 0;
#else
- if(!fp){
- int previewFrameRate = mParams.getPreviewFrameRate();
- delay = (unsigned)(1000000.0f / float(previewFrameRate)) >> 1;
- CAMHAL_LOGDB("Preview thread get frame fail, need sleep:%d",delay);
- usleep(delay);
- return BAD_VALUE;
- }
-#endif
-
- uint8_t* ptr = (uint8_t*) mPreviewBufs.keyAt(mPreviewIdxs.valueFor(index));
-
- if (!ptr)
- {
- CAMHAL_LOGEA("Preview thread mPreviewBufs error!");
+ delay = previewframeduration >> 1;
+ CAMHAL_LOGEB("Preview thread get frame fail, need sleep:%d",delay);
+ usleep(delay);
return BAD_VALUE;
- }
-#ifdef AMLOGIC_USB_CAMERA_SUPPORT
- if(mVideoInfo->buf.length != mVideoInfo->buf.bytesused){
- fillThisBuffer( ptr, CameraFrame::PREVIEW_FRAME_SYNC);
- CAMHAL_LOGDB("length=%d bytesused=%d index=%d\n",
- mVideoInfo->buf.length, mVideoInfo->buf.bytesused, index);
- return 0;
- }
#endif
+ }else{
+ ptr = (uint8_t*) mPreviewBufs.keyAt(mPreviewIdxs.valueFor(index));
+ if (!ptr){
+ CAMHAL_LOGEA("Preview thread mPreviewBufs error!");
+ return BAD_VALUE;
+ }
+ }
#ifdef AMLOGIC_CAMERA_NONBLOCK_SUPPORT
- gettimeofday( &previewTime2, NULL);
- unsigned bwFrames = previewTime2.tv_sec - previewTime1.tv_sec;
- bwFrames = bwFrames*1000000 + previewTime2.tv_usec -previewTime1.tv_usec;
- if( bwFrames + 10000 < uFrameInvals ) {
- //cts left 20ms(Android 4.1), we left 10ms, Android may cut this 20ms;
- CAMHAL_LOGDB("bwFrames=%d, uFrameInvals=%d\n", bwFrames, uFrameInvals);
- fillThisBuffer( ptr, CameraFrame::PREVIEW_FRAME_SYNC);
- return 0;
+ if(mFirstBuff == true){
+ mFrameInvAdjust = 0;
+ mFrameInv = 0;
+ mFirstBuff = false;
+ mCache.index = -1;
+ mCache.bufPtr == NULL;
+ ptr = (uint8_t*) mPreviewBufs.keyAt(mPreviewIdxs.valueFor(index));
+ gettimeofday(&previewTime1, NULL);
}else{
- memcpy( &previewTime1, &previewTime2, sizeof( struct timeval));
+ gettimeofday( &previewTime2, NULL);
+ int bwFrames_tmp = previewTime2.tv_sec - previewTime1.tv_sec;
+ bwFrames_tmp = bwFrames_tmp*1000000 + previewTime2.tv_usec -previewTime1.tv_usec;
+ mFrameInv += bwFrames_tmp;
+ memcpy( &previewTime1, &previewTime2, sizeof( struct timeval));
+
+ active_duration = mFrameInv - mFrameInvAdjust;
+
+ if((mFrameInv >= 20000) //the interval between two frame more than 20 ms for cts
+ &&((active_duration>previewframeduration)||((active_duration + 5000)>previewframeduration))){ // more preview duration -5000 us
+ if(noFrame == false){ //current catch a picture,use it and release tmp buf;
+ if( mCache.index != -1){
+ fillThisBuffer((uint8_t*) mPreviewBufs.keyAt(mPreviewIdxs.valueFor(mCache.index)), CameraFrame::PREVIEW_FRAME_SYNC);
+ }
+ mCache.index = -1;
+ }else if(mCache.index != -1){ //current catch no picture,but have a tmp buf;
+ fp = mCache.bufPtr;
+ ptr = (uint8_t*) mPreviewBufs.keyAt(mPreviewIdxs.valueFor(mCache.index));
+ mCache.index = -1;
+ }else{
+ return 0;
+ }
+ } else{ // during this period,should not show any picture,so we cache the current picture,and release the old one firstly;
+ if(noFrame == false){
+ mCache.bufPtr = fp;
+ if(mCache.index != -1){
+ fillThisBuffer((uint8_t*) mPreviewBufs.keyAt(mPreviewIdxs.valueFor(mCache.index)), CameraFrame::PREVIEW_FRAME_SYNC);
+ }
+ mCache.index = index;
+ }
+ return 0;
+ }
}
+
+ while(active_duration>=(int) previewframeduration){ // skip one or more than one frame
+ active_duration -= previewframeduration;
+ }
+
+ if((active_duration+10000)>previewframeduration)
+ mFrameInvAdjust = previewframeduration - active_duration;
+ else
+ mFrameInvAdjust = -active_duration;
+ mFrameInv = 0;
#endif
uint8_t* dest = NULL;
@@ -1462,7 +1529,6 @@ int V4LCameraAdapter::previewThread()
private_handle_t* gralloc_hnd = (private_handle_t*)ptr;
dest = (uint8_t*)gralloc_hnd->base; //ptr;
#endif
- int width, height;
uint8_t* src = (uint8_t*) fp;
if((mPreviewWidth <= 0)||(mPreviewHeight <= 0)){
mParams.getPreviewSize(&width, &height);
@@ -1477,26 +1543,27 @@ int V4LCameraAdapter::previewThread()
}else if(DEFAULT_PREVIEW_PIXEL_FORMAT == V4L2_PIX_FMT_NV21){ //420sp
frame.mLength = width*height*3/2;
#ifdef AMLOGIC_USB_CAMERA_SUPPORT
- if ( CameraFrame::PIXEL_FMT_NV21 == mPixelFormat){
+ if ( CameraFrame::PIXEL_FMT_NV21 == mPixelFormat){
//convert yuyv to nv21
- yuyv422_to_nv21(src,dest,width,height);
- }else{
- yuyv_to_yv12( src, dest, width, height);
- }
+ yuyv422_to_nv21(src,dest,width,height);
+ }else{
+ yuyv_to_yv12( src, dest, width, height);
+ }
#else
- if ( CameraFrame::PIXEL_FMT_NV21 == mPixelFormat){
- memcpy(dest,src,frame.mLength);
- }else{
- yv12_adjust_memcpy(dest,src,width,height);
- }
+ if ( CameraFrame::PIXEL_FMT_NV21 == mPixelFormat){
+ memcpy(dest,src,frame.mLength);
+ }else{
+ yv12_adjust_memcpy(dest,src,width,height);
+ }
#endif
}else{ //default case
+
frame.mLength = width*height*3/2;
memcpy(dest,src,frame.mLength);
}
frame.mFrameMask |= CameraFrame::PREVIEW_FRAME_SYNC;
-
+
if(mRecording){
frame.mFrameMask |= CameraFrame::VIDEO_FRAME_SYNC;
}
@@ -1517,9 +1584,8 @@ int V4LCameraAdapter::previewThread()
//LOGD("previewThread /sendFrameToSubscribers ret=%d", ret);
}
if( (mIoctlSupport & IOCTL_MASK_FOCUS_MOVE) && mFocusMoveEnabled ){
- getFocusMoveStatus();
+ getFocusMoveStatus();
}
-
return ret;
}
@@ -2641,9 +2707,25 @@ extern "C" void loadCaps(int camera_id, CameraProperties::Properties* params) {
ret = enumFramerate(camera_fd, &fps, &fps_num);
if((fpsrange != NULL)&&(NO_ERROR == ret) && ( 0 !=fps_num )){
- sprintf(fpsrange,"%s%d","5,",fps/fps_num);
CAMHAL_LOGDA("O_NONBLOCK operation to do previewThread\n");
-
+ int tmp_fps = fps/fps_num/5;
+ int iter = 0;
+ int shift = 0;
+ for(iter = 0;iter < tmp_fps;)
+ {
+ iter++;
+ if(iter == tmp_fps)
+ sprintf(fpsrange+shift,"%d",iter*5);
+ else
+ sprintf(fpsrange+shift,"%d,",iter*5);
+ if(iter == 1)
+ shift += 2;
+ else
+ shift += 3;
+
+ }
+ if((fps/fps_num)%5 != 0)
+ sprintf(fpsrange+shift-1,",%d",fps/fps_num);
params->set(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES, fpsrange);
params->set(CameraProperties::PREVIEW_FRAME_RATE, fps/fps_num);
diff --git a/inc/V4LCameraAdapter/V4LCameraAdapter.h b/inc/V4LCameraAdapter/V4LCameraAdapter.h
index f69470f..4bb5ea7 100755
--- a/inc/V4LCameraAdapter/V4LCameraAdapter.h
+++ b/inc/V4LCameraAdapter/V4LCameraAdapter.h
@@ -208,6 +208,11 @@ typedef enum camera_focus_mode_e {
CAM_FOCUS_MODE_CONTI_PIC,
}camera_focus_mode_t;
+typedef struct cam_cache_buf{
+ char *bufPtr;
+ int index;
+}cache_buf_t;
+
#define V4L2_ROTATE_ID 0x980922 //V4L2_CID_ROTATE
#define V4L2_CID_AUTO_FOCUS_STATUS (V4L2_CID_CAMERA_CLASS_BASE+30)
@@ -402,8 +407,11 @@ private:
static const int FOCUS_PROCESS_FRAMES = 17;
#ifdef AMLOGIC_CAMERA_NONBLOCK_SUPPORT
- int mPreviewFrameRate;
struct timeval previewTime1, previewTime2;
+ bool mFirstBuff;
+ int mFrameInvAdjust;
+ int mFrameInv;
+ cache_buf_t mCache;
#endif
#ifndef AMLOGIC_USB_CAMERA_SUPPORT
int mRotateValue;