diff options
author | Eino-Ville Talvala <etalvala@google.com> | 2012-05-30 13:39:00 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-05-30 13:39:00 -0700 |
commit | 9d1e267c831b21dcfd380ce36de0e5837f94aab3 (patch) | |
tree | 3ce090a7d0151b76e1b82214617cea58b56d5efc | |
parent | da4cb00ea329ac6d15d33ec67e85d76fed3154fa (diff) | |
parent | f69c70ded4316ea3ee504ac779bd024433ed4ef7 (diff) | |
download | frameworks_av-9d1e267c831b21dcfd380ce36de0e5837f94aab3.zip frameworks_av-9d1e267c831b21dcfd380ce36de0e5837f94aab3.tar.gz frameworks_av-9d1e267c831b21dcfd380ce36de0e5837f94aab3.tar.bz2 |
Merge "Camera service: Initialization for camera2 clients and devices"
-rw-r--r-- | services/camera/libcameraservice/Android.mk | 3 | ||||
-rw-r--r-- | services/camera/libcameraservice/Camera2Client.cpp | 706 | ||||
-rw-r--r-- | services/camera/libcameraservice/Camera2Client.h | 11 | ||||
-rw-r--r-- | services/camera/libcameraservice/Camera2Device.cpp | 295 | ||||
-rw-r--r-- | services/camera/libcameraservice/Camera2Device.h | 98 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraClient.cpp | 42 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraClient.h | 5 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraService.cpp | 34 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraService.h | 2 |
9 files changed, 1135 insertions, 61 deletions
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk index a2a7e57..9f713fa 100644 --- a/services/camera/libcameraservice/Android.mk +++ b/services/camera/libcameraservice/Android.mk @@ -21,7 +21,8 @@ LOCAL_SHARED_LIBRARIES:= \ libmedia_native \ libcamera_client \ libgui \ - libhardware + libhardware \ + libcamera_metadata LOCAL_C_INCLUDES += \ system/media/camera/include diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp index f0725ed..e138cd1 100644 --- a/services/camera/libcameraservice/Camera2Client.cpp +++ b/services/camera/libcameraservice/Camera2Client.cpp @@ -16,11 +16,14 @@ #define LOG_TAG "Camera2Client" //#define LOG_NDEBUG 0 +#include <utils/Log.h> #include <cutils/properties.h> #include <gui/SurfaceTextureClient.h> #include <gui/Surface.h> +#include <math.h> + #include "Camera2Client.h" namespace android { @@ -28,11 +31,14 @@ namespace android { #define ALOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__); #define ALOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__); -#define ALOG1_ENTRY { \ +#define ALOG1_ENTRY \ int callingPid = getCallingPid(); \ ALOG1("%s: E (pid %d, id %d) ", __FUNCTION__, \ - callingPid, mCameraId); \ -} + callingPid, mCameraId) + +#define ALOG1_EXIT \ + ALOG1("%s: X (pid %d, id %d) ", __FUNCTION__, \ + callingPid, mCameraId) static int getCallingPid() { return IPCThreadState::self()->getCallingPid(); @@ -46,19 +52,54 @@ static int getCallingUid() { Camera2Client::Camera2Client(const sp<CameraService>& cameraService, const sp<ICameraClient>& cameraClient, - const sp<Camera2Device>& device, int cameraId, int cameraFacing, int clientPid): Client(cameraService, cameraClient, - cameraId, cameraFacing, clientPid) { - int callingPid = getCallingPid(); - ALOG1("%s: E (pid %d, id %d)", __FUNCTION__, callingPid, cameraId); + cameraId, cameraFacing, clientPid), + mParams(NULL) +{ ALOG1_ENTRY; + mDevice = new Camera2Device(cameraId); + + ALOG1_EXIT; +} + +status_t Camera2Client::initialize(camera_module_t *module) +{ + ALOG1_ENTRY; + status_t res; + + res = mDevice->initialize(module); + if (res != OK) { + ALOGE("%s: Camera %d: unable to initialize device: %s (%d)", + __FUNCTION__, mCameraId, strerror(-res), res); + return NO_INIT; + } + + res = buildDefaultParameters(); + if (res != OK) { + ALOGE("%s: Camera %d: unable to build defaults: %s (%d)", + __FUNCTION__, mCameraId, strerror(-res), res); + return NO_INIT; + } + if (gLogLevel >= 1) { + ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__, + mCameraId); + mParams->dump(); + } + + ALOG1_EXIT; + return OK; } Camera2Client::~Camera2Client() { + mDestructionStarted = true; + + if (mParams) delete mParams; + + disconnect(); } status_t Camera2Client::dump(int fd, const Vector<String16>& args) { @@ -68,6 +109,11 @@ status_t Camera2Client::dump(int fd, const Vector<String16>& args) { // ICamera interface void Camera2Client::disconnect() { + + if (mDevice == 0) return; + + mDevice->setStreamingRequest(NULL); + CameraService::Client::disconnect(); } @@ -141,13 +187,657 @@ status_t Camera2Client::takePicture(int msgType) { status_t Camera2Client::setParameters(const String8& params) { return BAD_VALUE; } + String8 Camera2Client::getParameters() const { - return String8(); + return mParams->flatten(); } status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) { return BAD_VALUE; } +// private methods + +status_t Camera2Client::buildDefaultParameters() { + status_t res; + if (mParams) { + delete mParams; + } + mParams = new CameraParameters; + + camera_metadata_entry_t availableProcessedSizes; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, + &availableProcessedSizes); + if (res != OK) return res; + if (availableProcessedSizes.count < 2) { + ALOGE("%s: Camera %d: " + "Malformed %s entry", + __FUNCTION__, mCameraId, + get_camera_metadata_tag_name( + ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES)); + return NO_INIT; + } + + // TODO: Pick more intelligently + int previewWidth = availableProcessedSizes.data.i32[0]; + int previewHeight = availableProcessedSizes.data.i32[1]; + + mParams->setPreviewSize(previewWidth, previewHeight); + mParams->setVideoSize(previewWidth, previewHeight); + mParams->set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO, + String8::format("%dx%d",previewWidth,previewHeight)); + { + String8 supportedPreviewSizes; + for (size_t i=0; i < availableProcessedSizes.count; i += 2) { + if (i != 0) supportedPreviewSizes += ","; + supportedPreviewSizes += String8::format("%dx%d", + availableProcessedSizes.data.i32[i], + availableProcessedSizes.data.i32[i+1]); + } + mParams->set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, + supportedPreviewSizes); + mParams->set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES, + supportedPreviewSizes); + } + + camera_metadata_entry_t availableFpsRanges; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, + &availableFpsRanges); + if (res != OK) return res; + if (availableFpsRanges.count < 2) { + ALOGE("%s: Camera %d: " + "Malformed %s entry", + __FUNCTION__, mCameraId, + get_camera_metadata_tag_name( + ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES)); + return NO_INIT; + } + + int previewFpsRangeMin = availableFpsRanges.data.i32[0]; + int previewFpsRangeMax = availableFpsRanges.data.i32[1]; + + mParams->set(CameraParameters::KEY_PREVIEW_FPS_RANGE, + String8::format("%d,%d", previewFpsRangeMin, previewFpsRangeMax)); + + { + String8 supportedPreviewFpsRange; + for (size_t i=0; i < availableFpsRanges.count; i += 2) { + if (i != 0) supportedPreviewFpsRange += ","; + supportedPreviewFpsRange += String8::format("(%d,%d)", + availableFpsRanges.data.i32[i], + availableFpsRanges.data.i32[i+1]); + } + mParams->set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, + supportedPreviewFpsRange); + } + + mParams->set(CameraParameters::KEY_PREVIEW_FORMAT, + "yuv420sp"); // NV21 + + camera_metadata_entry_t availableFormats; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_SCALER_AVAILABLE_FORMATS, + &availableFormats); + { + String8 supportedPreviewFormats; + bool addComma = false; + for (size_t i=0; i < availableFormats.count; i++) { + if (addComma) supportedPreviewFormats += ","; + addComma = true; + switch (availableFormats.data.i32[i]) { + case HAL_PIXEL_FORMAT_YCbCr_422_SP: + supportedPreviewFormats += "yuv422sp"; + break; + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + supportedPreviewFormats += "yuv420sp"; + break; + case HAL_PIXEL_FORMAT_YCbCr_422_I: + supportedPreviewFormats += "yuv422i-yuyv"; + break; + case HAL_PIXEL_FORMAT_YV12: + supportedPreviewFormats += "yuv420p"; + break; + case HAL_PIXEL_FORMAT_RGB_565: + supportedPreviewFormats += "rgb565"; + break; + // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats + case HAL_PIXEL_FORMAT_RAW_SENSOR: + addComma = false; + break; + default: + ALOGW("%s: Camera %d: Unknown preview format: %x", + __FUNCTION__, mCameraId, availableFormats.data.i32[i]); + addComma = false; + break; + } + } + mParams->set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, + supportedPreviewFormats); + } + + // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but + // still have to do something sane for them + + mParams->set(CameraParameters::KEY_PREVIEW_FRAME_RATE, + previewFpsRangeMin); + + { + String8 supportedPreviewFrameRates; + for (size_t i=0; i < availableFpsRanges.count; i += 2) { + if (i != 0) supportedPreviewFrameRates += ","; + supportedPreviewFrameRates += String8::format("%d", + availableFpsRanges.data.i32[i]); + } + mParams->set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, + supportedPreviewFrameRates); + } + + camera_metadata_entry_t availableJpegSizes; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_SCALER_AVAILABLE_JPEG_SIZES, + &availableJpegSizes); + if (res != OK) return res; + if (availableJpegSizes.count < 2) { + ALOGE("%s: Camera %d: " + "Malformed %s entry", + __FUNCTION__, mCameraId, + get_camera_metadata_tag_name( + ANDROID_SCALER_AVAILABLE_JPEG_SIZES)); + return NO_INIT; + } + + // TODO: Pick maximum + int32_t pictureWidth = availableJpegSizes.data.i32[0]; + int32_t pictureHeight = availableJpegSizes.data.i32[1]; + + mParams->setPictureSize(pictureWidth, pictureHeight); + + { + String8 supportedPictureSizes; + for (size_t i=0; i < availableJpegSizes.count; i += 2) { + if (i != 0) supportedPictureSizes += ","; + supportedPictureSizes += String8::format("%dx%d", + availableJpegSizes.data.i32[i], + availableJpegSizes.data.i32[i+1]); + } + mParams->set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, + supportedPictureSizes); + } + + mParams->setPictureFormat("jpeg"); + + mParams->set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS, + "jpeg"); + + camera_metadata_entry_t availableJpegThumbnailSizes; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, + &availableJpegThumbnailSizes); + if (res != OK) return res; + if (availableJpegThumbnailSizes.count < 2) { + ALOGE("%s: Camera %d: " + "Malformed %s entry", + __FUNCTION__, mCameraId, + get_camera_metadata_tag_name( + ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES)); + return NO_INIT; + } + + // TODO: Pick default thumbnail size sensibly + int32_t jpegThumbWidth = availableJpegThumbnailSizes.data.i32[0]; + int32_t jpegThumbHeight = availableJpegThumbnailSizes.data.i32[1]; + + mParams->set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, + jpegThumbWidth); + mParams->set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, + jpegThumbHeight); + + { + String8 supportedJpegThumbSizes; + for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) { + if (i != 0) supportedJpegThumbSizes += ","; + supportedJpegThumbSizes += String8::format("%dx%d", + availableJpegThumbnailSizes.data.i32[i], + availableJpegThumbnailSizes.data.i32[i+1]); + } + mParams->set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, + supportedJpegThumbSizes); + } + + mParams->set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, + "90"); + mParams->set(CameraParameters::KEY_JPEG_QUALITY, + "90"); + mParams->set(CameraParameters::KEY_ROTATION, + "0"); + // Not settting GPS fields + + mParams->set(CameraParameters::KEY_WHITE_BALANCE, + "auto"); + + camera_metadata_entry_t availableWhiteBalanceModes; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_CONTROL_AWB_AVAILABLE_MODES, + &availableWhiteBalanceModes); + { + String8 supportedWhiteBalance; + bool addComma = false; + for (size_t i=0; i < availableWhiteBalanceModes.count; i++) { + if (addComma) supportedWhiteBalance += ","; + addComma = true; + switch (availableWhiteBalanceModes.data.u8[i]) { + case ANDROID_CONTROL_AWB_AUTO: + supportedWhiteBalance += "auto"; + break; + case ANDROID_CONTROL_AWB_INCANDESCENT: + supportedWhiteBalance += "incandescent"; + break; + case ANDROID_CONTROL_AWB_FLUORESCENT: + supportedWhiteBalance += "fluorescent"; + break; + case ANDROID_CONTROL_AWB_WARM_FLUORESCENT: + supportedWhiteBalance += "warm-fluorescent"; + break; + case ANDROID_CONTROL_AWB_DAYLIGHT: + supportedWhiteBalance += "daylight"; + break; + case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT: + supportedWhiteBalance += "cloudy-daylight"; + break; + case ANDROID_CONTROL_AWB_TWILIGHT: + supportedWhiteBalance += "twilight"; + break; + case ANDROID_CONTROL_AWB_SHADE: + supportedWhiteBalance += "shade"; + break; + // Skipping values not mappable to v1 API + case ANDROID_CONTROL_AWB_OFF: + addComma = false; + break; + default: + ALOGW("%s: Camera %d: Unknown white balance value: %d", + __FUNCTION__, mCameraId, + availableWhiteBalanceModes.data.u8[i]); + addComma = false; + break; + } + } + mParams->set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE, + supportedWhiteBalance); + } + + mParams->set(CameraParameters::KEY_EFFECT, "none"); + camera_metadata_entry_t availableEffects; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_CONTROL_AVAILABLE_EFFECTS, + &availableEffects); + if (res != OK) return res; + { + String8 supportedEffects; + bool addComma = false; + for (size_t i=0; i < availableEffects.count; i++) { + if (addComma) supportedEffects += ","; + addComma = true; + switch (availableEffects.data.u8[i]) { + case ANDROID_CONTROL_EFFECT_OFF: + supportedEffects += "none"; + break; + case ANDROID_CONTROL_EFFECT_MONO: + supportedEffects += "mono"; + case ANDROID_CONTROL_EFFECT_NEGATIVE: + supportedEffects += "negative"; + break; + case ANDROID_CONTROL_EFFECT_SOLARIZE: + supportedEffects += "solarize"; + break; + case ANDROID_CONTROL_EFFECT_SEPIA: + supportedEffects += "sepia"; + break; + case ANDROID_CONTROL_EFFECT_POSTERIZE: + supportedEffects += "posterize"; + break; + case ANDROID_CONTROL_EFFECT_WHITEBOARD: + supportedEffects += "whiteboard"; + break; + case ANDROID_CONTROL_EFFECT_BLACKBOARD: + supportedEffects += "blackboard"; + break; + case ANDROID_CONTROL_EFFECT_AQUA: + supportedEffects += "aqua"; + break; + default: + ALOGW("%s: Camera %d: Unknown effect value: %d", + __FUNCTION__, mCameraId, availableEffects.data.u8[i]); + addComma = false; + break; + } + } + mParams->set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects); + } + + mParams->set(CameraParameters::KEY_ANTIBANDING, "auto"); + camera_metadata_entry_t availableAntibandingModes; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, + &availableAntibandingModes); + if (res != OK) return res; + { + String8 supportedAntibanding; + bool addComma = false; + for (size_t i=0; i < availableAntibandingModes.count; i++) { + if (addComma) supportedAntibanding += ","; + addComma = true; + switch (availableAntibandingModes.data.u8[i]) { + case ANDROID_CONTROL_AE_ANTIBANDING_OFF: + supportedAntibanding += "off"; + break; + case ANDROID_CONTROL_AE_ANTIBANDING_50HZ: + supportedAntibanding += "50hz"; + break; + case ANDROID_CONTROL_AE_ANTIBANDING_60HZ: + supportedAntibanding += "60hz"; + break; + case ANDROID_CONTROL_AE_ANTIBANDING_AUTO: + supportedAntibanding += "auto"; + break; + default: + ALOGW("%s: Camera %d: Unknown antibanding value: %d", + __FUNCTION__, mCameraId, + availableAntibandingModes.data.u8[i]); + addComma = false; + break; + } + } + mParams->set(CameraParameters::KEY_SUPPORTED_ANTIBANDING, + supportedAntibanding); + } + + mParams->set(CameraParameters::KEY_SCENE_MODE, "auto"); + camera_metadata_entry_t availableSceneModes; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_CONTROL_AVAILABLE_SCENE_MODES, + &availableSceneModes); + if (res != OK) return res; + { + String8 supportedSceneModes("auto"); + bool addComma = true; + bool noSceneModes = false; + for (size_t i=0; i < availableSceneModes.count; i++) { + if (addComma) supportedSceneModes += ","; + addComma = true; + switch (availableSceneModes.data.u8[i]) { + case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED: + noSceneModes = true; + break; + case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY: + // Not in old API + addComma = false; + break; + case ANDROID_CONTROL_SCENE_MODE_ACTION: + supportedSceneModes += "action"; + break; + case ANDROID_CONTROL_SCENE_MODE_PORTRAIT: + supportedSceneModes += "portrait"; + break; + case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE: + supportedSceneModes += "landscape"; + break; + case ANDROID_CONTROL_SCENE_MODE_NIGHT: + supportedSceneModes += "night"; + break; + case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT: + supportedSceneModes += "night-portrait"; + break; + case ANDROID_CONTROL_SCENE_MODE_THEATRE: + supportedSceneModes += "theatre"; + break; + case ANDROID_CONTROL_SCENE_MODE_BEACH: + supportedSceneModes += "beach"; + break; + case ANDROID_CONTROL_SCENE_MODE_SNOW: + supportedSceneModes += "snow"; + break; + case ANDROID_CONTROL_SCENE_MODE_SUNSET: + supportedSceneModes += "sunset"; + break; + case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO: + supportedSceneModes += "steadyphoto"; + break; + case ANDROID_CONTROL_SCENE_MODE_FIREWORKS: + supportedSceneModes += "fireworks"; + break; + case ANDROID_CONTROL_SCENE_MODE_SPORTS: + supportedSceneModes += "sports"; + break; + case ANDROID_CONTROL_SCENE_MODE_PARTY: + supportedSceneModes += "party"; + break; + case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT: + supportedSceneModes += "candlelight"; + break; + case ANDROID_CONTROL_SCENE_MODE_BARCODE: + supportedSceneModes += "barcode"; + break; + default: + ALOGW("%s: Camera %d: Unknown scene mode value: %d", + __FUNCTION__, mCameraId, availableSceneModes.data.u8[i]); + addComma = false; + break; + } + } + if (!noSceneModes) { + mParams->set(CameraParameters::KEY_SUPPORTED_SCENE_MODES, + supportedSceneModes); + } + } + + camera_metadata_entry_t flashAvailable; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_FLASH_AVAILABLE, &flashAvailable); + if (res != OK) return res; + + camera_metadata_entry_t availableAeModes; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_CONTROL_AE_AVAILABLE_MODES, + &availableAeModes); + if (res != OK) return res; + + if (flashAvailable.data.u8[0]) { + mParams->set(CameraParameters::KEY_FLASH_MODE, "auto"); + String8 supportedFlashModes("off,auto,on,torch"); + for (size_t i=0; i < availableAeModes.count; i++) { + if (availableAeModes.data.u8[i] == + ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) { + supportedFlashModes += ",red-eye"; + break; + } + } + mParams->set(CameraParameters::KEY_SUPPORTED_FLASH_MODES, + supportedFlashModes); + } + + camera_metadata_entry_t minFocusDistance; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, + &minFocusDistance); + if (res != OK) return res; + camera_metadata_entry_t availableAfModes; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_CONTROL_AF_AVAILABLE_MODES, + &availableAfModes); + if (res != OK) return res; + if (minFocusDistance.data.f[0] == 0) { + // Fixed-focus lens + mParams->set(CameraParameters::KEY_FOCUS_MODE, "fixed"); + mParams->set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES, "fixed"); + } else { + mParams->set(CameraParameters::KEY_FOCUS_MODE, "auto"); + String8 supportedFocusModes("fixed,infinity"); + bool addComma = true; + for (size_t i=0; i < availableAfModes.count; i++) { + if (addComma) supportedFocusModes += ","; + addComma = true; + switch (availableAfModes.data.u8[i]) { + case ANDROID_CONTROL_AF_AUTO: + supportedFocusModes += "auto"; + break; + case ANDROID_CONTROL_AF_MACRO: + supportedFocusModes += "macro"; + break; + case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO: + supportedFocusModes += "continuous-video"; + break; + case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE: + supportedFocusModes += "continuous-picture"; + break; + case ANDROID_CONTROL_AF_EDOF: + supportedFocusModes += "edof"; + break; + // Not supported in v1 API + case ANDROID_CONTROL_AF_OFF: + addComma = false; + break; + default: + ALOGW("%s: Camera %d: Unknown AF mode value: %d", + __FUNCTION__, mCameraId, availableAfModes.data.u8[i]); + addComma = false; + break; + } + } + mParams->set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES, + supportedFocusModes); + } + + camera_metadata_entry_t max3aRegions; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_CONTROL_MAX_REGIONS, &max3aRegions); + if (res != OK) return res; + + mParams->set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS, + max3aRegions.data.i32[0]); + mParams->set(CameraParameters::KEY_FOCUS_AREAS, + "(0,0,0,0,0)"); + + camera_metadata_entry_t availableFocalLengths; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS, + &availableFocalLengths); + if (res != OK) return res; + float minFocalLength = availableFocalLengths.data.f[0]; + mParams->setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength); + + camera_metadata_entry_t sensorSize; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_SENSOR_PHYSICAL_SIZE, + &sensorSize); + if (res != OK) return res; + + // The fields of view here assume infinity focus, maximum wide angle + float horizFov = 180 / M_PI * + 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength)); + float vertFov = 180 / M_PI * + 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength)); + mParams->setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov); + mParams->setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov); + + mParams->set(CameraParameters::KEY_EXPOSURE_COMPENSATION, 0); + + camera_metadata_entry_t exposureCompensationRange; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, + &exposureCompensationRange); + if (res != OK) return res; + mParams->set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, + exposureCompensationRange.data.i32[1]); + mParams->set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, + exposureCompensationRange.data.i32[0]); + + camera_metadata_entry_t exposureCompensationStep; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, + &exposureCompensationStep); + if (res != OK) return res; + mParams->setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, + exposureCompensationStep.data.r[0].numerator / + exposureCompensationStep.data.r[0].denominator); + + mParams->set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK, "false"); + mParams->set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED, "true"); + + mParams->set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, "false"); + mParams->set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED, "true"); + + mParams->set(CameraParameters::KEY_MAX_NUM_METERING_AREAS, + max3aRegions.data.i32[0]); + mParams->set(CameraParameters::KEY_METERING_AREAS, + "(0,0,0,0,0)"); + + mParams->set(CameraParameters::KEY_ZOOM, 0); + mParams->set(CameraParameters::KEY_MAX_ZOOM, kNumZoomSteps - 1); + + camera_metadata_entry_t maxDigitalZoom; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_SCALER_AVAILABLE_MAX_ZOOM, &maxDigitalZoom); + if (res != OK) return res; + + { + String8 zoomRatios; + float zoom = 1.f; + float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) / + (kNumZoomSteps-1); + bool addComma = false; + for (size_t i=0; i < kNumZoomSteps; i++) { + if (addComma) zoomRatios += ","; + addComma = true; + zoomRatios += String8::format("%d", static_cast<int>(zoom * 100)); + zoom += zoomIncrement; + } + mParams->set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios); + } + + mParams->set(CameraParameters::KEY_ZOOM_SUPPORTED, "true"); + mParams->set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED, "true"); + + mParams->set(CameraParameters::KEY_FOCUS_DISTANCES, + "Infinity,Infinity,Infinity"); + + camera_metadata_entry_t maxFacesDetected; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_STATS_MAX_FACE_COUNT, + &maxFacesDetected); + mParams->set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW, + maxFacesDetected.data.i32[0]); + mParams->set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW, + 0); + + mParams->set(CameraParameters::KEY_VIDEO_FRAME_FORMAT, + "yuv420sp"); + + mParams->set(CameraParameters::KEY_RECORDING_HINT, + "false"); + + mParams->set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED, + "true"); + + mParams->set(CameraParameters::KEY_VIDEO_STABILIZATION, + "false"); + + camera_metadata_entry_t availableVideoStabilizationModes; + res = find_camera_metadata_entry(mDevice->info(), + ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, + &availableVideoStabilizationModes); + if (res != OK) return res; + if (availableVideoStabilizationModes.count > 1) { + mParams->set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED, + "true"); + } else { + mParams->set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED, + "false"); + } + + return OK; +} } // namespace android diff --git a/services/camera/libcameraservice/Camera2Client.h b/services/camera/libcameraservice/Camera2Client.h index 709de0b..4f0fcf0 100644 --- a/services/camera/libcameraservice/Camera2Client.h +++ b/services/camera/libcameraservice/Camera2Client.h @@ -19,6 +19,7 @@ #include "Camera2Device.h" #include "CameraService.h" +#include "camera/CameraParameters.h" namespace android { @@ -55,17 +56,25 @@ public: // Interface used by CameraService Camera2Client(const sp<CameraService>& cameraService, const sp<ICameraClient>& cameraClient, - const sp<Camera2Device>& device, int cameraId, int cameraFacing, int clientPid); ~Camera2Client(); + status_t initialize(camera_module_t *module); + virtual status_t dump(int fd, const Vector<String16>& args); private: + CameraParameters *mParams; + sp<Camera2Device> mDevice; + // Convert static camera info from a camera2 device to the + // old API parameter map. + status_t buildDefaultParameters(); + // Free parameters for mapping from new to old HAL + static const unsigned int kNumZoomSteps = 10; }; }; // namespace android diff --git a/services/camera/libcameraservice/Camera2Device.cpp b/services/camera/libcameraservice/Camera2Device.cpp index ff5b057..4b0cfc4 100644 --- a/services/camera/libcameraservice/Camera2Device.cpp +++ b/services/camera/libcameraservice/Camera2Device.cpp @@ -22,8 +22,8 @@ namespace android { -Camera2Device::Camera2Device(const char *name): - mName(name), +Camera2Device::Camera2Device(int id): + mId(id), mDevice(NULL) { @@ -35,32 +35,307 @@ Camera2Device::~Camera2Device() status_t res; res = mDevice->common.close(&mDevice->common); if (res != OK) { - ALOGE("Could not close camera2 %s: %s (%d)", - mName, strerror(-res), res); + ALOGE("%s: Could not close camera %d: %s (%d)", + __FUNCTION__, + mId, strerror(-res), res); } + mDevice = NULL; } } -status_t Camera2Device::initialize(hw_module_t *module) +status_t Camera2Device::initialize(camera_module_t *module) { status_t res; - res = module->methods->open(module, mName, + char name[10]; + snprintf(name, sizeof(name), "%d", mId); + + res = module->common.methods->open(&module->common, name, reinterpret_cast<hw_device_t**>(&mDevice)); if (res != OK) { - ALOGE("Could not open camera %s: %s (%d)", mName, strerror(-res), res); + ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__, + mId, strerror(-res), res); return res; } if (mDevice->common.version != CAMERA_DEVICE_API_VERSION_2_0) { - ALOGE("Could not open camera %s: " - "Camera device is not version 2.0, reports %x instead", - mName, mDevice->common.version); + ALOGE("%s: Could not open camera %d: " + "Camera device is not version %x, reports %x instead", + __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_2_0, + mDevice->common.version); return BAD_VALUE; } + camera_info info; + res = module->get_camera_info(mId, &info); + if (res != OK ) return res; + + if (info.device_version != mDevice->common.version) { + ALOGE("%s: HAL reporting mismatched camera_info version (%x)" + " and device version (%x).", __FUNCTION__, + mDevice->common.version, info.device_version); + return BAD_VALUE; + } + + mDeviceInfo = info.static_camera_characteristics; + + res = mDevice->ops->set_request_queue_src_ops(mDevice, + mRequestQueue.getToConsumerInterface()); + if (res != OK) return res; + + res = mDevice->ops->set_frame_queue_dst_ops(mDevice, + mFrameQueue.getToProducerInterface()); + if (res != OK) return res; + + res = mDevice->ops->get_metadata_vendor_tag_ops(mDevice, &mVendorTagOps); + if (res != OK ) return res; + + return OK; +} + +status_t Camera2Device::setStreamingRequest(camera_metadata_t* request) +{ + mRequestQueue.setStreamSlot(request); + return OK; +} + +/** + * Camera2Device::MetadataQueue + */ + +Camera2Device::MetadataQueue::MetadataQueue(): + mDevice(NULL), + mFrameCount(0), + mCount(0), + mStreamSlotCount(0), + mSignalConsumer(true) +{ + camera2_request_queue_src_ops::dequeue_request = consumer_dequeue; + camera2_request_queue_src_ops::request_count = consumer_buffer_count; + camera2_request_queue_src_ops::free_request = consumer_free; + + camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue; + camera2_frame_queue_dst_ops::cancel_frame = producer_cancel; + camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue; +} + +Camera2Device::MetadataQueue::~MetadataQueue() { + Mutex::Autolock l(mMutex); + freeBuffers(mEntries.begin(), mEntries.end()); + freeBuffers(mStreamSlot.begin(), mStreamSlot.end()); +} + +// Interface to camera2 HAL as consumer (input requests/reprocessing) +const camera2_request_queue_src_ops_t* +Camera2Device::MetadataQueue::getToConsumerInterface() { + return static_cast<camera2_request_queue_src_ops_t*>(this); +} + +void Camera2Device::MetadataQueue::setFromConsumerInterface(camera2_device_t *d) { + Mutex::Autolock l(mMutex); + mDevice = d; +} + +const camera2_frame_queue_dst_ops_t* +Camera2Device::MetadataQueue::getToProducerInterface() { + return static_cast<camera2_frame_queue_dst_ops_t*>(this); +} + +// Real interfaces +status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) { + Mutex::Autolock l(mMutex); + + mCount++; + mEntries.push_back(buf); + notEmpty.signal(); + + if (mSignalConsumer && mDevice != NULL) { + mSignalConsumer = false; + + mMutex.unlock(); + ALOGV("%s: Signaling consumer", __FUNCTION__); + mDevice->ops->notify_request_queue_not_empty(mDevice); + mMutex.lock(); + } + return OK; +} + +int Camera2Device::MetadataQueue::getBufferCount() { + Mutex::Autolock l(mMutex); + if (mStreamSlotCount > 0) { + return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS; + } + return mCount; +} + +status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf, + bool incrementCount) +{ + Mutex::Autolock l(mMutex); + + if (mCount == 0) { + if (mStreamSlotCount == 0) { + ALOGV("%s: Empty", __FUNCTION__); + *buf = NULL; + mSignalConsumer = true; + return OK; + } + ALOGV("%s: Streaming %d frames to queue", __FUNCTION__, + mStreamSlotCount); + + for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin(); + slotEntry != mStreamSlot.end(); + slotEntry++ ) { + size_t entries = get_camera_metadata_entry_count(*slotEntry); + size_t dataBytes = get_camera_metadata_data_count(*slotEntry); + + camera_metadata_t *copy = + allocate_camera_metadata(entries, dataBytes); + append_camera_metadata(copy, *slotEntry); + mEntries.push_back(copy); + } + mCount = mStreamSlotCount; + } + ALOGV("MetadataQueue: deque (%d buffers)", mCount); + camera_metadata_t *b = *(mEntries.begin()); + mEntries.erase(mEntries.begin()); + + if (incrementCount) { + add_camera_metadata_entry(b, + ANDROID_REQUEST_FRAME_COUNT, + (void**)&mFrameCount, 1); + mFrameCount++; + } + + *buf = b; + mCount--; + return OK; } +status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout) +{ + Mutex::Autolock l(mMutex); + status_t res; + while (mCount == 0) { + res = notEmpty.waitRelative(mMutex,timeout); + if (res != OK) return res; + } + return OK; +} + +status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf) +{ + Mutex::Autolock l(mMutex); + if (buf == NULL) { + freeBuffers(mStreamSlot.begin(), mStreamSlot.end()); + mStreamSlotCount = 0; + return OK; + } + if (mStreamSlotCount > 1) { + List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin(); + freeBuffers(++mStreamSlot.begin(), mStreamSlot.end()); + mStreamSlotCount = 1; + } + if (mStreamSlotCount == 1) { + free_camera_metadata( *(mStreamSlot.begin()) ); + *(mStreamSlot.begin()) = buf; + } else { + mStreamSlot.push_front(buf); + mStreamSlotCount = 1; + } + return OK; +} + +status_t Camera2Device::MetadataQueue::setStreamSlot( + const List<camera_metadata_t*> &bufs) +{ + Mutex::Autolock l(mMutex); + if (mStreamSlotCount > 0) { + freeBuffers(mStreamSlot.begin(), mStreamSlot.end()); + } + mStreamSlot = bufs; + mStreamSlotCount = mStreamSlot.size(); + + return OK; +} + +status_t Camera2Device::MetadataQueue::freeBuffers( + List<camera_metadata_t*>::iterator start, + List<camera_metadata_t*>::iterator end) +{ + while (start != end) { + free_camera_metadata(*start); + start = mStreamSlot.erase(start); + } + return OK; +} + +Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance( + const camera2_request_queue_src_ops_t *q) +{ + const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q); + return const_cast<MetadataQueue*>(cmq); +} + +Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance( + const camera2_frame_queue_dst_ops_t *q) +{ + const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q); + return const_cast<MetadataQueue*>(cmq); +} + +int Camera2Device::MetadataQueue::consumer_buffer_count( + const camera2_request_queue_src_ops_t *q) +{ + MetadataQueue *queue = getInstance(q); + return queue->getBufferCount(); +} + +int Camera2Device::MetadataQueue::consumer_dequeue( + const camera2_request_queue_src_ops_t *q, + camera_metadata_t **buffer) +{ + MetadataQueue *queue = getInstance(q); + return queue->dequeue(buffer, true); +} + +int Camera2Device::MetadataQueue::consumer_free( + const camera2_request_queue_src_ops_t *q, + camera_metadata_t *old_buffer) +{ + MetadataQueue *queue = getInstance(q); + free_camera_metadata(old_buffer); + return OK; +} + +int Camera2Device::MetadataQueue::producer_dequeue( + const camera2_frame_queue_dst_ops_t *q, + size_t entries, size_t bytes, + camera_metadata_t **buffer) +{ + camera_metadata_t *new_buffer = + allocate_camera_metadata(entries, bytes); + if (new_buffer == NULL) return NO_MEMORY; + *buffer = new_buffer; + return OK; +} + +int Camera2Device::MetadataQueue::producer_cancel( + const camera2_frame_queue_dst_ops_t *q, + camera_metadata_t *old_buffer) +{ + free_camera_metadata(old_buffer); + return OK; +} + +int Camera2Device::MetadataQueue::producer_enqueue( + const camera2_frame_queue_dst_ops_t *q, + camera_metadata_t *filled_buffer) +{ + MetadataQueue *queue = getInstance(q); + return queue->enqueue(filled_buffer); +} + }; // namespace android diff --git a/services/camera/libcameraservice/Camera2Device.h b/services/camera/libcameraservice/Camera2Device.h index 0ce5421..07c5ff7 100644 --- a/services/camera/libcameraservice/Camera2Device.h +++ b/services/camera/libcameraservice/Camera2Device.h @@ -18,6 +18,9 @@ #define ANDROID_SERVERS_CAMERA_CAMERA2DEVICE_H #include <utils/RefBase.h> +#include <utils/List.h> +#include <utils/Mutex.h> +#include <utils/Condition.h> #include <utils/Errors.h> #include "hardware/camera2.h" @@ -25,17 +28,104 @@ namespace android { class Camera2Device : public virtual RefBase { public: - Camera2Device(const char *name); + Camera2Device(int id); ~Camera2Device(); - status_t initialize(hw_module_t *module); + status_t initialize(camera_module_t *module); + + status_t setStreamingRequest(camera_metadata_t* request); + + camera_metadata_t* info() { + return mDeviceInfo; + } + private: - const char *mName; + const int mId; camera2_device_t *mDevice; -}; + camera_metadata_t *mDeviceInfo; + vendor_tag_query_ops_t *mVendorTagOps; + + /** + * Queue class for both sending requests to a camera2 device, and for + * receiving frames from a camera2 device. + */ + class MetadataQueue: public camera2_request_queue_src_ops_t, + public camera2_frame_queue_dst_ops_t { + public: + MetadataQueue(); + ~MetadataQueue(); + + // Interface to camera2 HAL device, either for requests (device is + // consumer) or for frames (device is producer) + const camera2_request_queue_src_ops_t* getToConsumerInterface(); + void setFromConsumerInterface(camera2_device_t *d); + + const camera2_frame_queue_dst_ops_t* getToProducerInterface(); + + // Real interfaces. On enqueue, queue takes ownership of buffer pointer + // On dequeue, user takes ownership of buffer pointer. + status_t enqueue(camera_metadata_t *buf); + status_t dequeue(camera_metadata_t **buf, bool incrementCount = true); + int getBufferCount(); + status_t waitForBuffer(nsecs_t timeout); + + // Set repeating buffer(s); if the queue is empty on a dequeue call, the + // queue copies the contents of the stream slot into the queue, and then + // dequeues the first new entry. + status_t setStreamSlot(camera_metadata_t *buf); + status_t setStreamSlot(const List<camera_metadata_t*> &bufs); + + private: + status_t freeBuffers(List<camera_metadata_t*>::iterator start, + List<camera_metadata_t*>::iterator end); + + camera2_device_t *mDevice; + + Mutex mMutex; + Condition notEmpty; + + int mFrameCount; + + int mCount; + List<camera_metadata_t*> mEntries; + int mStreamSlotCount; + List<camera_metadata_t*> mStreamSlot; + + bool mSignalConsumer; + + static MetadataQueue* getInstance( + const camera2_frame_queue_dst_ops_t *q); + static MetadataQueue* getInstance( + const camera2_request_queue_src_ops_t *q); + + static int consumer_buffer_count( + const camera2_request_queue_src_ops_t *q); + + static int consumer_dequeue(const camera2_request_queue_src_ops_t *q, + camera_metadata_t **buffer); + + static int consumer_free(const camera2_request_queue_src_ops_t *q, + camera_metadata_t *old_buffer); + + static int producer_dequeue(const camera2_frame_queue_dst_ops_t *q, + size_t entries, size_t bytes, + camera_metadata_t **buffer); + + static int producer_cancel(const camera2_frame_queue_dst_ops_t *q, + camera_metadata_t *old_buffer); + + static int producer_enqueue(const camera2_frame_queue_dst_ops_t *q, + camera_metadata_t *filled_buffer); + + }; // class MetadataQueue + + MetadataQueue mRequestQueue; + MetadataQueue mFrameQueue; + +}; // class Camera2Device }; // namespace android diff --git a/services/camera/libcameraservice/CameraClient.cpp b/services/camera/libcameraservice/CameraClient.cpp index ce9ee1e..80ccb43 100644 --- a/services/camera/libcameraservice/CameraClient.cpp +++ b/services/camera/libcameraservice/CameraClient.cpp @@ -40,7 +40,6 @@ static int getCallingUid() { CameraClient::CameraClient(const sp<CameraService>& cameraService, const sp<ICameraClient>& cameraClient, - const sp<CameraHardwareInterface>& hardware, int cameraId, int cameraFacing, int clientPid): Client(cameraService, cameraClient, cameraId, cameraFacing, clientPid) @@ -48,19 +47,11 @@ CameraClient::CameraClient(const sp<CameraService>& cameraService, int callingPid = getCallingPid(); LOG1("CameraClient::CameraClient E (pid %d, id %d)", callingPid, cameraId); - mHardware = hardware; + mHardware = NULL; mMsgEnabled = 0; mSurface = 0; mPreviewWindow = 0; mDestructionStarted = false; - mHardware->setCallbacks(notifyCallback, - dataCallback, - dataCallbackTimestamp, - (void *)cameraId); - - // Enable zoom, error, focus, and metadata messages by default - enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS | - CAMERA_MSG_PREVIEW_METADATA | CAMERA_MSG_FOCUS_MOVE); // Callback is disabled by default mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP; @@ -69,6 +60,36 @@ CameraClient::CameraClient(const sp<CameraService>& cameraService, LOG1("CameraClient::CameraClient X (pid %d, id %d)", callingPid, cameraId); } +status_t CameraClient::initialize(camera_module_t *module) { + int callingPid = getCallingPid(); + LOG1("CameraClient::initialize E (pid %d, id %d)", callingPid, mCameraId); + + char camera_device_name[10]; + status_t res; + snprintf(camera_device_name, sizeof(camera_device_name), "%d", mCameraId); + + mHardware = new CameraHardwareInterface(camera_device_name); + res = mHardware->initialize(&module->common); + if (res != OK) { + ALOGE("%s: Camera %d: unable to initialize device: %s (%d)", + __FUNCTION__, mCameraId, strerror(-res), res); + return NO_INIT; + } + + mHardware->setCallbacks(notifyCallback, + dataCallback, + dataCallbackTimestamp, + (void *)mCameraId); + + // Enable zoom, error, focus, and metadata messages by default + enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS | + CAMERA_MSG_PREVIEW_METADATA | CAMERA_MSG_FOCUS_MOVE); + + LOG1("CameraClient::initialize X (pid %d, id %d)", callingPid, mCameraId); + return OK; +} + + // tear down the client CameraClient::~CameraClient() { // this lock should never be NULL @@ -83,7 +104,6 @@ CameraClient::~CameraClient() { // set mClientPid to let disconnet() tear down the hardware mClientPid = callingPid; disconnect(); - mCameraService->releaseSound(); LOG1("CameraClient::~CameraClient X (pid %d, this %p)", callingPid, this); } diff --git a/services/camera/libcameraservice/CameraClient.h b/services/camera/libcameraservice/CameraClient.h index d3ff9cf..256298d 100644 --- a/services/camera/libcameraservice/CameraClient.h +++ b/services/camera/libcameraservice/CameraClient.h @@ -53,13 +53,14 @@ public: // Interface used by CameraService CameraClient(const sp<CameraService>& cameraService, const sp<ICameraClient>& cameraClient, - const sp<CameraHardwareInterface>& hardware, int cameraId, int cameraFacing, int clientPid); ~CameraClient(); - virtual status_t dump(int fd, const Vector<String16>& args); + status_t initialize(camera_module_t *module); + + status_t dump(int fd, const Vector<String16>& args); private: diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index b273f6f..d01fcf9 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -39,9 +39,7 @@ #include "CameraService.h" #include "CameraClient.h" -#include "CameraHardwareInterface.h" #include "Camera2Client.h" -#include "Camera2Device.h" namespace android { @@ -188,9 +186,6 @@ sp<ICamera> CameraService::connect( return NULL; } - char camera_device_name[10]; - snprintf(camera_device_name, sizeof(camera_device_name), "%d", cameraId); - int deviceVersion; if (mModule->common.module_api_version == CAMERA_MODULE_API_VERSION_2_0) { deviceVersion = info.device_version; @@ -199,33 +194,23 @@ sp<ICamera> CameraService::connect( } switch(deviceVersion) { - case CAMERA_DEVICE_API_VERSION_1_0: { - sp<CameraHardwareInterface> hardware = - new CameraHardwareInterface(camera_device_name); - if (hardware->initialize(&mModule->common) != OK) { - return NULL; - } - - client = new CameraClient(this, cameraClient, hardware, cameraId, + case CAMERA_DEVICE_API_VERSION_1_0: + client = new CameraClient(this, cameraClient, cameraId, info.facing, callingPid); break; - } - case CAMERA_DEVICE_API_VERSION_2_0: { - sp<Camera2Device> hardware = - new Camera2Device(camera_device_name); - if (hardware->initialize(&mModule->common) != OK) { - return NULL; - } - - client = new Camera2Client(this, cameraClient, hardware, cameraId, + case CAMERA_DEVICE_API_VERSION_2_0: + client = new Camera2Client(this, cameraClient, cameraId, info.facing, callingPid); break; - } - default: + default: ALOGE("Unknown camera device HAL version: %d", deviceVersion); return NULL; } + if (client->initialize(mModule) != OK) { + return NULL; + } + mClient[cameraId] = client; LOG1("CameraService::connect X (id %d)", cameraId); return client; @@ -383,6 +368,7 @@ CameraService::Client::Client(const sp<CameraService>& cameraService, // tear down the client CameraService::Client::~Client() { + mCameraService->releaseSound(); } // ---------------------------------------------------------------------------- diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index 7f8ef6c..630fca7 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -108,6 +108,8 @@ public: return mCameraClient; } + virtual status_t initialize(camera_module_t *module) = 0; + virtual status_t dump(int fd, const Vector<String16>& args) = 0; protected: |