1. 程式人生 > >android native開發-native實現對camera的操作

android native開發-native實現對camera的操作

通過native實現camera的操作

原始碼路徑:frameworks/av/camera/ndk/ 參考的test原始碼路徑:cts/tests/tests/graphics/jni/CameraTestHelpers.cpp

1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18#ifndef ANDROID_CAMERATESTHELPERS_H
19#define ANDROID_CAMERATESTHELPERS_H
20
21// Must come before NdkCameraCaptureSession.h
22#include <camera/NdkCaptureRequest.h>
23
24#include <camera/NdkCameraCaptureSession.h>
25#include <camera/NdkCameraDevice.h>
26#include <camera/NdkCameraError.h>
27#include <camera/NdkCameraManager.h>
28#include <cstdlib>
29#include <cstring>
30#include <jni.h>
31#include <media/NdkImage.h>
32#include <media/NdkImageReader.h>
33
34// A helper class which can be used to initialize/control the camera.
35class CameraHelper {
36public:
37  ~CameraHelper();
38
39  int initCamera(ANativeWindow *imgReaderAnw);
40  bool isCapabilitySupported(
41      acamera_metadata_enum_android_request_available_capabilities_t cap);
42  bool isCameraReady() { return mIsCameraReady; }
43  void closeCamera();
44  int takePicture();
45
46  static void onDeviceDisconnected(void * /*obj*/, ACameraDevice * /*device*/) {
47  }
48  static void onDeviceError(void * /*obj*/, ACameraDevice * /*device*/,
49                            int /*errorCode*/) {}
50  static void onSessionClosed(void * /*obj*/,
51                              ACameraCaptureSession * /*session*/) {}
52  static void onSessionReady(void * /*obj*/,
53                             ACameraCaptureSession * /*session*/) {}
54  static void onSessionActive(void * /*obj*/,
55                              ACameraCaptureSession * /*session*/) {}
56
57private:
58  ACameraDevice_StateCallbacks mDeviceCb{this, onDeviceDisconnected,
59                                         onDeviceError};
60  ACameraCaptureSession_stateCallbacks mSessionCb{
61      this, onSessionClosed, onSessionReady, onSessionActive};
62
63  ANativeWindow *mImgReaderAnw{nullptr}; // not owned by us.
64
65  // Camera manager
66  ACameraManager *mCameraManager{nullptr};
67  ACameraIdList *mCameraIdList{nullptr};
68  // Camera device
69  ACameraMetadata *mCameraMetadata{nullptr};
70  ACameraDevice *mDevice{nullptr};
71  // Capture session
72  ACaptureSessionOutputContainer *mOutputs{nullptr};
73  ACaptureSessionOutput *mImgReaderOutput{nullptr};
74  ACameraCaptureSession *mSession{nullptr};
75  // Capture request
76  ACaptureRequest *mCaptureRequest{nullptr};
77  ACameraOutputTarget *mReqImgReaderOutput{nullptr};
78
79  bool mIsCameraReady{false};
80  const char *mCameraId{nullptr};
81};
82
83#endif // ANDROID_CAMERATHELPERS_H
84
/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18#define LOG_TAG "CameraTestHelpers"
19
20#include "CameraTestHelpers.h"
21
22#include <android/log.h>
23
24#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
25#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
26#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
27
28CameraHelper::~CameraHelper() { closeCamera(); }
29
30int CameraHelper::initCamera(ANativeWindow *imgReaderAnw) {
31  if (imgReaderAnw == nullptr) {
32    ALOGE("Cannot initialize camera before image reader get initialized.");
33    return -1;
34  }
35
36  mImgReaderAnw = imgReaderAnw;
37  mCameraManager = ACameraManager_create();
38  if (mCameraManager == nullptr) {
39    ALOGE("Failed to create ACameraManager.");
40    return -1;
41  }
42
43  int ret = ACameraManager_getCameraIdList(mCameraManager, &mCameraIdList);
44  if (ret != AMEDIA_OK) {
45    ALOGE("Failed to get cameraIdList: ret=%d", ret);
46    return ret;
47  }
48  if (mCameraIdList->numCameras < 1) {
49    ALOGW("Device has no NDK compatible camera.");
50    return 0;
51  }
52  ALOGI("Found %d camera(s).", mCameraIdList->numCameras);
53
54  // We always use the first camera.
55  mCameraId = mCameraIdList->cameraIds[0];
56  if (mCameraId == nullptr) {
57    ALOGE("Failed to get cameraId.");
58    return -1;
59  }
60
61  ret = ACameraManager_openCamera(mCameraManager, mCameraId, &mDeviceCb,
62                                  &mDevice);
63  if (ret != AMEDIA_OK || mDevice == nullptr) {
64    ALOGE("Failed to open camera, ret=%d, mDevice=%p.", ret, mDevice);
65    return -1;
66  }
67
68  ret = ACameraManager_getCameraCharacteristics(mCameraManager, mCameraId,
69                                                &mCameraMetadata);
70  if (ret != ACAMERA_OK || mCameraMetadata == nullptr) {
71    ALOGE("Get camera %s characteristics failure. ret %d, metadata %p",
72          mCameraId, ret, mCameraMetadata);
73    return -1;
74  }
75
76  if (!isCapabilitySupported(
77          ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE)) {
78    ALOGW("Camera does not support BACKWARD_COMPATIBLE.");
79    return 0;
80  }
81
82  // Create capture session
83  ret = ACaptureSessionOutputContainer_create(&mOutputs);
84  if (ret != AMEDIA_OK) {
85    ALOGE("ACaptureSessionOutputContainer_create failed, ret=%d", ret);
86    return ret;
87  }
88  ret = ACaptureSessionOutput_create(mImgReaderAnw, &mImgReaderOutput);
89  if (ret != AMEDIA_OK) {
90    ALOGE("ACaptureSessionOutput_create failed, ret=%d", ret);
91    return ret;
92  }
93  ret = ACaptureSessionOutputContainer_add(mOutputs, mImgReaderOutput);
94  if (ret != AMEDIA_OK) {
95    ALOGE("ACaptureSessionOutputContainer_add failed, ret=%d", ret);
96    return ret;
97  }
98  ret = ACameraDevice_createCaptureSession(mDevice, mOutputs, &mSessionCb,
99                                           &mSession);
100  if (ret != AMEDIA_OK) {
101    ALOGE("ACameraDevice_createCaptureSession failed, ret=%d", ret);
102    return ret;
103  }
104
105  // Create capture request
106  ret = ACameraDevice_createCaptureRequest(mDevice, TEMPLATE_RECORD,
107                                           &mCaptureRequest);
108  if (ret != AMEDIA_OK) {
109    ALOGE("ACameraDevice_createCaptureRequest failed, ret=%d", ret);
110    return ret;
111  }
112  ret = ACameraOutputTarget_create(mImgReaderAnw, &mReqImgReaderOutput);
113  if (ret != AMEDIA_OK) {
114    ALOGE("ACameraOutputTarget_create failed, ret=%d", ret);
115    return ret;
116  }
117  ret = ACaptureRequest_addTarget(mCaptureRequest, mReqImgReaderOutput);
118  if (ret != AMEDIA_OK) {
119    ALOGE("ACaptureRequest_addTarget failed, ret=%d", ret);
120    return ret;
121  }
122
123  mIsCameraReady = true;
124  return 0;
125}
126
127bool CameraHelper::isCapabilitySupported(
128    acamera_metadata_enum_android_request_available_capabilities_t cap) {
129  ACameraMetadata_const_entry entry;
130  ACameraMetadata_getConstEntry(mCameraMetadata,
131                                ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
132  for (uint32_t i = 0; i < entry.count; i++) {
133    if (entry.data.u8[i] == cap) {
134      return true;
135    }
136  }
137  return false;
138}
139
140void CameraHelper::closeCamera() {
141  // Destroy capture request
142  if (mReqImgReaderOutput) {
143    ACameraOutputTarget_free(mReqImgReaderOutput);
144    mReqImgReaderOutput = nullptr;
145  }
146  if (mCaptureRequest) {
147    ACaptureRequest_free(mCaptureRequest);
148    mCaptureRequest = nullptr;
149  }
150  // Destroy capture session
151  if (mSession != nullptr) {
152    ACameraCaptureSession_close(mSession);
153    mSession = nullptr;
154  }
155  if (mImgReaderOutput) {
156    ACaptureSessionOutput_free(mImgReaderOutput);
157    mImgReaderOutput = nullptr;
158  }
159  if (mOutputs) {
160    ACaptureSessionOutputContainer_free(mOutputs);
161    mOutputs = nullptr;
162  }
163  // Destroy camera device
164  if (mDevice) {
165    ACameraDevice_close(mDevice);
166    mDevice = nullptr;
167  }
168  if (mCameraMetadata) {
169    ACameraMetadata_free(mCameraMetadata);
170    mCameraMetadata = nullptr;
171  }
172  // Destroy camera manager
173  if (mCameraIdList) {
174    ACameraManager_deleteCameraIdList(mCameraIdList);
175    mCameraIdList = nullptr;
176  }
177  if (mCameraManager) {
178    ACameraManager_delete(mCameraManager);
179    mCameraManager = nullptr;
180  }
181  mIsCameraReady = false;
182}
183
184int CameraHelper::takePicture() {
185  return ACameraCaptureSession_capture(mSession, nullptr, 1, &mCaptureRequest,
186                                       nullptr);
187}
188