summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--services/camera/libcameraservice/Android.mk3
-rw-r--r--services/camera/libcameraservice/Camera2Client.cpp706
-rw-r--r--services/camera/libcameraservice/Camera2Client.h11
-rw-r--r--services/camera/libcameraservice/Camera2Device.cpp295
-rw-r--r--services/camera/libcameraservice/Camera2Device.h98
-rw-r--r--services/camera/libcameraservice/CameraClient.cpp42
-rw-r--r--services/camera/libcameraservice/CameraClient.h5
-rw-r--r--services/camera/libcameraservice/CameraService.cpp34
-rw-r--r--services/camera/libcameraservice/CameraService.h2
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: