|
|
|
@ -86,6 +86,11 @@ protected: |
|
|
|
|
|
|
|
|
|
int emptyCameraCallbackReported; |
|
|
|
|
|
|
|
|
|
static const char* flashModesNames[ANDROID_CAMERA_FLASH_MODES_NUM]; |
|
|
|
|
static const char* focusModesNames[ANDROID_CAMERA_FOCUS_MODES_NUM]; |
|
|
|
|
static const char* whiteBalanceModesNames[ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM]; |
|
|
|
|
static const char* antibandingModesNames[ANDROID_CAMERA_ANTIBANDING_MODES_NUM]; |
|
|
|
|
|
|
|
|
|
void doCall(void* buffer, size_t bufferSize) |
|
|
|
|
{ |
|
|
|
|
if (cameraCallback == 0) |
|
|
|
@ -156,6 +161,68 @@ protected: |
|
|
|
|
camera->releaseRecordingFrame(dataPtr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Split list of floats, returns number of floats found
|
|
|
|
|
static int split_float(const char *str, float* out, char delim, int max_elem_num, |
|
|
|
|
char **endptr = NULL) |
|
|
|
|
{ |
|
|
|
|
// Find the first float.
|
|
|
|
|
char *end = const_cast<char*>(str); |
|
|
|
|
int elem_num = 0; |
|
|
|
|
for(; elem_num < max_elem_num; elem_num++ ){ |
|
|
|
|
char* curr_end; |
|
|
|
|
out[elem_num] = (float)strtof(end, &curr_end); |
|
|
|
|
// No other numbers found, finish the loop
|
|
|
|
|
if(end == curr_end){ |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
if (*curr_end != delim) { |
|
|
|
|
// When end of string, finish the loop
|
|
|
|
|
if (*curr_end == 0){ |
|
|
|
|
elem_num++; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
LOGE("Cannot find delimeter (%c) in str=%s", delim, str); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Skip the delimiter character
|
|
|
|
|
end = curr_end + 1; |
|
|
|
|
} |
|
|
|
|
if (endptr) |
|
|
|
|
*endptr = end; |
|
|
|
|
return elem_num; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int is_supported(const char* supp_modes_key, const char* mode) |
|
|
|
|
{ |
|
|
|
|
const char* supported_modes = params.get(supp_modes_key); |
|
|
|
|
return strstr(supported_modes, mode) > 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
float getFocusDistance(int focus_distance_type){ |
|
|
|
|
if (focus_distance_type >= 0 && focus_distance_type < 3) { |
|
|
|
|
float focus_distances[3]; |
|
|
|
|
const char* output = params.get(CameraParameters::KEY_FOCUS_DISTANCES); |
|
|
|
|
int val_num = CameraHandler::split_float(output, focus_distances, ',', 3); |
|
|
|
|
if(val_num == 3){ |
|
|
|
|
return focus_distances[focus_distance_type]; |
|
|
|
|
} else { |
|
|
|
|
LOGE("Invalid focus distances."); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int getModeNum(const char** modes, const int modes_num, const char* mode_name) |
|
|
|
|
{ |
|
|
|
|
for (int i = 0; i < modes_num; i++){ |
|
|
|
|
if(!strcmp(modes[i],mode_name)) |
|
|
|
|
return i; |
|
|
|
|
} |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
CameraHandler(CameraCallback callback = 0, void* _userData = 0): |
|
|
|
|
cameraId(0), |
|
|
|
@ -220,6 +287,42 @@ public: |
|
|
|
|
std::string cameraPropertyPreviewFormatString; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const char* CameraHandler::flashModesNames[ANDROID_CAMERA_FLASH_MODES_NUM] = |
|
|
|
|
{ |
|
|
|
|
CameraParameters::FLASH_MODE_AUTO, |
|
|
|
|
CameraParameters::FLASH_MODE_OFF, |
|
|
|
|
CameraParameters::FLASH_MODE_ON, |
|
|
|
|
CameraParameters::FLASH_MODE_RED_EYE, |
|
|
|
|
CameraParameters::FLASH_MODE_TORCH |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const char* CameraHandler::focusModesNames[ANDROID_CAMERA_FOCUS_MODES_NUM] = |
|
|
|
|
{ |
|
|
|
|
CameraParameters::FOCUS_MODE_AUTO, |
|
|
|
|
CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO, |
|
|
|
|
CameraParameters::FOCUS_MODE_EDOF, |
|
|
|
|
CameraParameters::FOCUS_MODE_FIXED, |
|
|
|
|
CameraParameters::FOCUS_MODE_INFINITY |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const char* CameraHandler::whiteBalanceModesNames[ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM] = |
|
|
|
|
{ |
|
|
|
|
CameraParameters::WHITE_BALANCE_AUTO, |
|
|
|
|
CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT, |
|
|
|
|
CameraParameters::WHITE_BALANCE_DAYLIGHT, |
|
|
|
|
CameraParameters::WHITE_BALANCE_FLUORESCENT, |
|
|
|
|
CameraParameters::WHITE_BALANCE_INCANDESCENT, |
|
|
|
|
CameraParameters::WHITE_BALANCE_SHADE, |
|
|
|
|
CameraParameters::WHITE_BALANCE_TWILIGHT |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const char* CameraHandler::antibandingModesNames[ANDROID_CAMERA_ANTIBANDING_MODES_NUM] = |
|
|
|
|
{ |
|
|
|
|
CameraParameters::ANTIBANDING_50HZ, |
|
|
|
|
CameraParameters::ANTIBANDING_60HZ, |
|
|
|
|
CameraParameters::ANTIBANDING_AUTO |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback, int cameraId, void* userData, CameraParameters* prevCameraParameters) |
|
|
|
|
{ |
|
|
|
@ -229,7 +332,7 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback, |
|
|
|
|
|
|
|
|
|
#ifdef ANDROID_r2_2_0 |
|
|
|
|
camera = Camera::connect(); |
|
|
|
|
#else |
|
|
|
|
#else |
|
|
|
|
/* This is 2.3 or higher. The connect method has cameraID parameter */ |
|
|
|
|
camera = Camera::connect(cameraId); |
|
|
|
|
#endif |
|
|
|
@ -435,7 +538,6 @@ double CameraHandler::getProperty(int propIdx) |
|
|
|
|
u.str = cameraPropertySupportedPreviewSizesString.c_str(); |
|
|
|
|
return u.res; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case ANDROID_CAMERA_PROPERTY_PREVIEW_FORMAT_STRING: |
|
|
|
|
{ |
|
|
|
|
const char* fmt = params.get(CameraParameters::KEY_PREVIEW_FORMAT); |
|
|
|
@ -456,7 +558,62 @@ double CameraHandler::getProperty(int propIdx) |
|
|
|
|
u.str = cameraPropertyPreviewFormatString.c_str(); |
|
|
|
|
return u.res; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case ANDROID_CAMERA_PROPERTY_EXPOSURE: |
|
|
|
|
{ |
|
|
|
|
int exposure = params.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION); |
|
|
|
|
return exposure; |
|
|
|
|
} |
|
|
|
|
case ANDROID_CAMERA_PROPERTY_FPS: |
|
|
|
|
{ |
|
|
|
|
return params.getPreviewFrameRate(); |
|
|
|
|
} |
|
|
|
|
case ANDROID_CAMERA_PROPERTY_FLASH_MODE: |
|
|
|
|
{ |
|
|
|
|
int flash_mode = getModeNum(CameraHandler::flashModesNames, |
|
|
|
|
ANDROID_CAMERA_FLASH_MODES_NUM, |
|
|
|
|
params.get(CameraParameters::KEY_FLASH_MODE)); |
|
|
|
|
return flash_mode; |
|
|
|
|
} |
|
|
|
|
case ANDROID_CAMERA_PROPERTY_FOCUS_MODE: |
|
|
|
|
{ |
|
|
|
|
int focus_mode = getModeNum(CameraHandler::focusModesNames, |
|
|
|
|
ANDROID_CAMERA_FOCUS_MODES_NUM, |
|
|
|
|
params.get(CameraParameters::KEY_FOCUS_MODE)); |
|
|
|
|
return focus_mode; |
|
|
|
|
} |
|
|
|
|
case ANDROID_CAMERA_PROPERTY_WHITE_BALANCE: |
|
|
|
|
{ |
|
|
|
|
int white_balance = getModeNum(CameraHandler::whiteBalanceModesNames, |
|
|
|
|
ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM, |
|
|
|
|
params.get(CameraParameters::KEY_WHITE_BALANCE)); |
|
|
|
|
return white_balance; |
|
|
|
|
} |
|
|
|
|
case ANDROID_CAMERA_PROPERTY_ANTIBANDING: |
|
|
|
|
{ |
|
|
|
|
int antibanding = getModeNum(CameraHandler::antibandingModesNames, |
|
|
|
|
ANDROID_CAMERA_ANTIBANDING_MODES_NUM, |
|
|
|
|
params.get(CameraParameters::KEY_ANTIBANDING)); |
|
|
|
|
return antibanding; |
|
|
|
|
} |
|
|
|
|
case ANDROID_CAMERA_PROPERTY_FOCAL_LENGTH: |
|
|
|
|
{ |
|
|
|
|
float focal_length = params.getFloat(CameraParameters::KEY_FOCAL_LENGTH); |
|
|
|
|
return focal_length; |
|
|
|
|
} |
|
|
|
|
case ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_NEAR: |
|
|
|
|
{ |
|
|
|
|
return getFocusDistance(ANDROID_CAMERA_FOCUS_DISTANCE_NEAR_INDEX); |
|
|
|
|
} |
|
|
|
|
case ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_OPTIMAL: |
|
|
|
|
{ |
|
|
|
|
return getFocusDistance(ANDROID_CAMERA_FOCUS_DISTANCE_OPTIMAL_INDEX); |
|
|
|
|
} |
|
|
|
|
case ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_FAR: |
|
|
|
|
{ |
|
|
|
|
return getFocusDistance(ANDROID_CAMERA_FOCUS_DISTANCE_FAR_INDEX); |
|
|
|
|
} |
|
|
|
|
default: |
|
|
|
|
LOGW("CameraHandler::getProperty - Unsupported property."); |
|
|
|
|
}; |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
@ -483,6 +640,80 @@ void CameraHandler::setProperty(int propIdx, double value) |
|
|
|
|
params.setPreviewSize(w, h); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case ANDROID_CAMERA_PROPERTY_EXPOSURE: |
|
|
|
|
{ |
|
|
|
|
int max_exposure = params.getInt("max-exposure-compensation"); |
|
|
|
|
int min_exposure = params.getInt("min-exposure-compensation"); |
|
|
|
|
if(max_exposure && min_exposure){ |
|
|
|
|
int exposure = (int)value; |
|
|
|
|
if(exposure >= min_exposure && exposure <= max_exposure){ |
|
|
|
|
params.set("exposure-compensation", exposure); |
|
|
|
|
} else { |
|
|
|
|
LOGE("Exposure compensation not in valid range (%i,%i).", min_exposure, max_exposure); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
LOGE("Exposure compensation adjust is not supported."); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case ANDROID_CAMERA_PROPERTY_FLASH_MODE: |
|
|
|
|
{ |
|
|
|
|
int new_val = (int)value; |
|
|
|
|
if(new_val >= 0 && new_val < ANDROID_CAMERA_FLASH_MODES_NUM){ |
|
|
|
|
const char* mode_name = flashModesNames[new_val]; |
|
|
|
|
if(is_supported(CameraParameters::KEY_SUPPORTED_FLASH_MODES, mode_name)) |
|
|
|
|
params.set(CameraParameters::KEY_FLASH_MODE, mode_name); |
|
|
|
|
else |
|
|
|
|
LOGE("Flash mode %s is not supported.", mode_name); |
|
|
|
|
} else { |
|
|
|
|
LOGE("Flash mode value not in valid range."); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case ANDROID_CAMERA_PROPERTY_FOCUS_MODE: |
|
|
|
|
{ |
|
|
|
|
int new_val = (int)value; |
|
|
|
|
if(new_val >= 0 && new_val < ANDROID_CAMERA_FOCUS_MODES_NUM){ |
|
|
|
|
const char* mode_name = focusModesNames[new_val]; |
|
|
|
|
if(is_supported(CameraParameters::KEY_SUPPORTED_FOCUS_MODES, mode_name)) |
|
|
|
|
params.set(CameraParameters::KEY_FOCUS_MODE, mode_name); |
|
|
|
|
else |
|
|
|
|
LOGE("Focus mode %s is not supported.", mode_name); |
|
|
|
|
} else { |
|
|
|
|
LOGE("Focus mode value not in valid range."); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case ANDROID_CAMERA_PROPERTY_WHITE_BALANCE: |
|
|
|
|
{ |
|
|
|
|
int new_val = (int)value; |
|
|
|
|
if(new_val >= 0 && new_val < ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM){ |
|
|
|
|
const char* mode_name = whiteBalanceModesNames[new_val]; |
|
|
|
|
if(is_supported(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE, mode_name)) |
|
|
|
|
params.set(CameraParameters::KEY_WHITE_BALANCE, mode_name); |
|
|
|
|
else |
|
|
|
|
LOGE("White balance mode %s is not supported.", mode_name); |
|
|
|
|
} else { |
|
|
|
|
LOGE("White balance mode value not in valid range."); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case ANDROID_CAMERA_PROPERTY_ANTIBANDING: |
|
|
|
|
{ |
|
|
|
|
int new_val = (int)value; |
|
|
|
|
if(new_val >= 0 && new_val < ANDROID_CAMERA_ANTIBANDING_MODES_NUM){ |
|
|
|
|
const char* mode_name = antibandingModesNames[new_val]; |
|
|
|
|
if(is_supported(CameraParameters::KEY_SUPPORTED_ANTIBANDING, mode_name)) |
|
|
|
|
params.set(CameraParameters::KEY_ANTIBANDING, mode_name); |
|
|
|
|
else |
|
|
|
|
LOGE("Antibanding mode %s is not supported.", mode_name); |
|
|
|
|
} else { |
|
|
|
|
LOGE("Antibanding mode value not in valid range."); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
LOGW("CameraHandler::setProperty - Unsupported property."); |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|