Commit 8ab16f66 authored by Andrey Kamaev's avatar Andrey Kamaev

Fixing native camera for Android

parent 2d3606a5
......@@ -1398,7 +1398,7 @@ if(ANDROID)
set(CMAKE_CAMERA_LIBS_CONFIGCMAKE "native_camera_r${ANDROID_VERSION}")
elseif(WITH_ANDROID_CAMERA)
SET(CMAKE_CAMERA_LIBS_CONFIGCMAKE "")
file(GLOB CMAKE_CAMERA_LIBS "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/lib/libnative_camera_r*.so")
file(GLOB CMAKE_CAMERA_LIBS "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/lib/${ARMEABI_NDK_NAME}/libnative_camera_r*.so")
foreach(cam_lib ${CMAKE_CAMERA_LIBS})
get_filename_component(cam_lib "${cam_lib}" NAME)
string(REGEX REPLACE "lib(native_camera_r[0-9]+\\.[0-9]+\\.[0-9]+)\\.so" "\\1" cam_lib "${cam_lib}")
......@@ -1653,11 +1653,7 @@ if(UNIX AND NOT APPLE)
if(ANDROID)
if(WITH_ANDROID_CAMERA)
if(BUILD_ANDROID_CAMERA_WRAPPER)
status(" AndroidNativeCamera:" "build for Android ${ANDROID_VERSION}")
else()
status(" AndroidNativeCamera:" ARMEABI_V7A THEN use prebuilt libraries ELSE NO)
endif()
status(" AndroidNativeCamera:" BUILD_ANDROID_CAMERA_WRAPPER THEN "build for Android ${ANDROID_VERSION}" ELSE "use prebuilt libraries")
else()
status(" AndroidNativeCamera:" "NO (native camera requires Android API level 8 or higher)")
endif()
......
......@@ -37,8 +37,8 @@ IF (NOT BUILD_SHARED_LIBS)
)
ENDIF()
if (ARMEABI_V7A AND NOT BUILD_ANDROID_CAMERA_WRAPPER)
file(GLOB camera_wrappers "${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/lib/libnative_camera_r*.so")
if (NOT BUILD_ANDROID_CAMERA_WRAPPER)
file(GLOB camera_wrappers "${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/lib/${ARMEABI_NDK_NAME}/libnative_camera_r*.so")
foreach(wrapper ${camera_wrappers})
ADD_CUSTOM_COMMAND(
......
......@@ -197,6 +197,7 @@ public:
static void applyProperties(CameraHandler** ppcameraHandler);
std::string cameraPropertySupportedPreviewSizesString;
std::string cameraPropertyPreviewFormatString;
};
......@@ -229,35 +230,74 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback,
{
LOGI("initCameraConnect: Setting paramers from previous camera handler");
camera->setParameters(prevCameraParameters->flatten());
handler->params.unflatten(prevCameraParameters->flatten());
}
else
{
android::String8 params_str = camera->getParameters();
LOGI("initCameraConnect: [%s]", params_str.string());
handler->params.unflatten(params_str);
LOGD("Supported Cameras: %s", handler->params.get("camera-indexes"));
LOGD("Supported Picture Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES));
LOGD("Supported Picture Formats: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS));
LOGD("Supported Preview Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES));
LOGD("Supported Preview Formats: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS));
LOGD("Supported Preview Frame Rates: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES));
LOGD("Supported Thumbnail Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES));
LOGD("Supported Whitebalance Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE));
LOGD("Supported Effects: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_EFFECTS));
LOGD("Supported Scene Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_SCENE_MODES));
LOGD("Supported Focus Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
LOGD("Supported Antibanding Options: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_ANTIBANDING));
LOGD("Supported Flash Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES));
//check if yuv420sp format available. Set this format as preview format.
const char* available_formats = handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
if (available_formats != 0)
{
const char* format_to_set = 0;
const char* pos = available_formats;
const char* ptr = pos;
while(true)
{
while(*ptr != 0 && *ptr != ',') ++ptr;
if (ptr != pos)
{
if (0 == strncmp(pos, "yuv420sp", ptr - pos))
{
format_to_set = "yuv420sp";
break;
}
if (0 == strncmp(pos, "yuv420i", ptr - pos))
format_to_set = "yuv420i";
}
if (*ptr == 0)
break;
pos = ++ptr;
}
android::String8 params_str = camera->getParameters();
LOGI("initCameraConnect: [%s]", params_str.string());
handler->params.unflatten(params_str);
LOGD("Supported Cameras: %s", handler->params.get("camera-indexes"));
LOGD("Supported Picture Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES));
LOGD("Supported Picture Formats: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS));
LOGD("Supported Preview Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES));
LOGD("Supported Preview Formats: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS));
LOGD("Supported Preview Frame Rates: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES));
LOGD("Supported Thumbnail Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES));
LOGD("Supported Whitebalance Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE));
LOGD("Supported Effects: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_EFFECTS));
LOGD("Supported Scene Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_SCENE_MODES));
LOGD("Supported Focus Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
LOGD("Supported Antibanding Options: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_ANTIBANDING));
LOGD("Supported Flash Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES));
if (0 != format_to_set)
{
handler->params.setPreviewFormat(format_to_set);
status_t resParams = handler->camera->setParameters(handler->params.flatten());
//TODO: check if yuv420i format available. Set this format as preview format.
if (resParams != 0)
LOGE("initCameraConnect: failed to set preview format to %s", format_to_set);
else
LOGD("initCameraConnect: preview format is set to %s", format_to_set);
}
}
}
#ifdef ANDROID_r2_2_2
status_t pdstatus = camera->setPreviewDisplay(sp<ISurface>(0 /*new DummySurface*/));
if (pdstatus != 0)
{
LOGE("initCameraConnect: failed setPreviewDisplay(0) call; camera migth not work correcttly on some devices");
}
#endif
////ATTENTION: switching between two versions: with and without copying memory inside Android OS
//// see the method CameraService::Client::copyFrameAndPostCopiedFrame and where it is used
......@@ -316,6 +356,8 @@ void CameraHandler::closeCameraConnect()
double CameraHandler::getProperty(int propIdx)
{
LOGD("CameraHandler::getProperty(%d)", propIdx);
switch (propIdx)
{
case ANDROID_CAMERA_PROPERTY_FRAMEWIDTH:
......@@ -332,12 +374,32 @@ double CameraHandler::getProperty(int propIdx)
}
case ANDROID_CAMERA_PROPERTY_SUPPORTED_PREVIEW_SIZES_STRING:
{
cameraPropertySupportedPreviewSizesString = params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES);
double res;
memset(&res, 0, sizeof(res));
(*( (void**)&res ))= (void*)( cameraPropertySupportedPreviewSizesString.c_str() );
return res;
cameraPropertySupportedPreviewSizesString = params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES);
union {const char* str;double res;} u;
memset(&u.res, 0, sizeof(u.res));
u.str = cameraPropertySupportedPreviewSizesString.c_str();
return u.res;
}
case ANDROID_CAMERA_PROPERTY_PREVIEW_FORMAT_STRING:
{
const char* fmt = params.get(CameraParameters::KEY_PREVIEW_FORMAT);
if (fmt == CameraParameters::PIXEL_FORMAT_YUV422SP)
fmt = "yuv422sp";
else if (fmt == CameraParameters::PIXEL_FORMAT_YUV420SP)
fmt = "yuv420sp";
else if (fmt == CameraParameters::PIXEL_FORMAT_YUV422I)
fmt = "yuv422i";
else if (fmt == CameraParameters::PIXEL_FORMAT_RGB565)
fmt = "rgb565";
else if (fmt == CameraParameters::PIXEL_FORMAT_JPEG)
fmt = "jpeg";
cameraPropertyPreviewFormatString = fmt;
union {const char* str;double res;} u;
memset(&u.res, 0, sizeof(u.res));
u.str = cameraPropertySupportedPreviewSizesString.c_str();
return u.res;
}
};
......@@ -346,6 +408,8 @@ double CameraHandler::getProperty(int propIdx)
void CameraHandler::setProperty(int propIdx, double value)
{
LOGD("CameraHandler::setProperty(%d, %f)", propIdx, value);
switch (propIdx)
{
case ANDROID_CAMERA_PROPERTY_FRAMEWIDTH:
......@@ -369,6 +433,20 @@ void CameraHandler::setProperty(int propIdx, double value)
void CameraHandler::applyProperties(CameraHandler** ppcameraHandler)
{
LOGD("CameraHandler::applyProperties()");
if (ppcameraHandler == 0)
{
LOGE("applyProperties: Passed NULL ppcameraHandler");
return;
}
if (*ppcameraHandler == 0)
{
LOGE("applyProperties: Passed null *ppcameraHandler");
return;
}
LOGD("CameraHandler::applyProperties()");
CameraHandler* previousCameraHandler=*ppcameraHandler;
CameraParameters curCameraParameters(previousCameraHandler->params.flatten());
......@@ -386,12 +464,12 @@ void CameraHandler::applyProperties(CameraHandler** ppcameraHandler)
CameraHandler* handler=initCameraConnect(cameraCallback, cameraId, userData, &curCameraParameters);
LOGD("CameraHandler::applyProperties(): after initCameraConnect, handler=0x%x", (int)handler);
if (handler == NULL) {
LOGE("ERROR in applyProperties --- cannot reinit camera");
handler=initCameraConnect(cameraCallback, cameraId, userData, NULL);
LOGD("CameraHandler::applyProperties(): repeate initCameraConnect after ERROR, handler=0x%x", (int)handler);
if (handler == NULL) {
LOGE("ERROR in applyProperties --- cannot reinit camera AGAIN --- cannot do anything else");
}
LOGE("ERROR in applyProperties --- cannot reinit camera");
handler=initCameraConnect(cameraCallback, cameraId, userData, NULL);
LOGD("CameraHandler::applyProperties(): repeate initCameraConnect after ERROR, handler=0x%x", (int)handler);
if (handler == NULL) {
LOGE("ERROR in applyProperties --- cannot reinit camera AGAIN --- cannot do anything else");
}
}
(*ppcameraHandler)=handler;
}
......@@ -423,7 +501,7 @@ void setCameraPropertyC(void* camera, int propIdx, double value)
void applyCameraPropertiesC(void** camera)
{
CameraHandler::applyProperties((CameraHandler**)camera);
CameraHandler::applyProperties((CameraHandler**)camera);
}
}
enum CameraWrapperErrorCode {
ERROR_NATIVE_CAMERA_WRAPPER_NOERROR = 0,
ERROR_NATIVE_CAMERA_WRAPPER_CANNOT_FIND_CLASS = 1,
ERROR_NATIVE_CAMERA_WRAPPER_CANNOT_FIND_FIELD = 2,
ERROR_NATIVE_CAMERA_WRAPPER_CANNOT_SET_PREVIEW_DISPLAY = 3
};
typedef bool (*CameraCallback)(void* buffer, size_t bufferSize, void* userData);
typedef void* (*InitCameraConnectC)(void* cameraCallback, int cameraId, void* userData);
......
......@@ -4,7 +4,8 @@
enum {
ANDROID_CAMERA_PROPERTY_FRAMEWIDTH = 0,
ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT = 1,
ANDROID_CAMERA_PROPERTY_SUPPORTED_PREVIEW_SIZES_STRING = 2
ANDROID_CAMERA_PROPERTY_SUPPORTED_PREVIEW_SIZES_STRING = 2,
ANDROID_CAMERA_PROPERTY_PREVIEW_FORMAT_STRING = 3
};
#endif // CAMERA_PROPERTIES_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment