• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 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#include <vector>
18#include <inttypes.h>
19#include "ACameraDevice.h"
20#include "ACameraMetadata.h"
21#include "ACaptureRequest.h"
22#include "ACameraCaptureSession.h"
23
24namespace android {
25namespace acam {
26
27template<class T>
28camera_status_t
29CameraDevice::captureLocked(
30        sp<ACameraCaptureSession> session,
31        /*optional*/T* cbs,
32        int numRequests, ACaptureRequest** requests,
33        /*optional*/int* captureSequenceId) {
34    return submitRequestsLocked(
35            session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/false);
36}
37
38template<class T>
39camera_status_t
40CameraDevice::setRepeatingRequestsLocked(
41        sp<ACameraCaptureSession> session,
42        /*optional*/T* cbs,
43        int numRequests, ACaptureRequest** requests,
44        /*optional*/int* captureSequenceId) {
45    return submitRequestsLocked(
46            session, cbs, numRequests, requests, captureSequenceId, /*isRepeating*/true);
47}
48
49template<class T>
50camera_status_t CameraDevice::submitRequestsLocked(
51        sp<ACameraCaptureSession> session,
52        /*optional*/T* cbs,
53        int numRequests, ACaptureRequest** requests,
54        /*optional*/int* captureSequenceId,
55        bool isRepeating) {
56    camera_status_t ret = checkCameraClosedOrErrorLocked();
57    if (ret != ACAMERA_OK) {
58        ALOGE("Camera %s submit capture request failed! ret %d", getId(), ret);
59        return ret;
60    }
61
62    // Form two vectors of capture request, one for internal tracking
63    std::vector<hardware::camera2::CaptureRequest> requestList;
64    Vector<sp<CaptureRequest> > requestsV;
65    requestsV.setCapacity(numRequests);
66    for (int i = 0; i < numRequests; i++) {
67        sp<CaptureRequest> req;
68        ret = allocateCaptureRequest(requests[i], req);
69        if (ret != ACAMERA_OK) {
70            ALOGE("Convert capture request to internal format failure! ret %d", ret);
71            return ret;
72        }
73        if (req->mSurfaceList.empty()) {
74            ALOGE("Capture request without output target cannot be submitted!");
75            return ACAMERA_ERROR_INVALID_PARAMETER;
76        }
77        requestList.push_back(*(req.get()));
78        requestsV.push_back(req);
79    }
80
81    if (isRepeating) {
82        ret = stopRepeatingLocked();
83        if (ret != ACAMERA_OK) {
84            ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
85            return ret;
86        }
87    }
88
89    binder::Status remoteRet;
90    hardware::camera2::utils::SubmitInfo info;
91    remoteRet = mRemote->submitRequestList(requestList, isRepeating, &info);
92    int sequenceId = info.mRequestId;
93    int64_t lastFrameNumber = info.mLastFrameNumber;
94    if (sequenceId < 0) {
95        ALOGE("Camera %s submit request remote failure: ret %d", getId(), sequenceId);
96        return ACAMERA_ERROR_UNKNOWN;
97    }
98
99    CallbackHolder cbHolder(session, requestsV, isRepeating, cbs);
100    mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder));
101
102    if (isRepeating) {
103        // stopRepeating above should have cleanup repeating sequence id
104        if (mRepeatingSequenceId != REQUEST_ID_NONE) {
105            setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
106            return ACAMERA_ERROR_CAMERA_DEVICE;
107        }
108        mRepeatingSequenceId = sequenceId;
109    } else {
110        mSequenceLastFrameNumberMap.insert(std::make_pair(sequenceId, lastFrameNumber));
111    }
112
113    if (mIdle) {
114        sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
115        msg->setPointer(kContextKey, session->mUserSessionCallback.context);
116        msg->setObject(kSessionSpKey, session);
117        msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
118        postSessionMsgAndCleanup(msg);
119    }
120    mIdle = false;
121    mBusySession = session;
122
123    if (captureSequenceId) {
124        *captureSequenceId = sequenceId;
125    }
126    return ACAMERA_OK;
127}
128
129template<class T>
130camera_status_t CameraDevice::startStreamingLocked(ACameraCaptureSession* session,
131        /*optional*/T* callbacks, int numOutputWindows,
132        ANativeWindow** windows, /*optional*/int* captureSequenceId) {
133    camera_status_t ret = checkCameraClosedOrErrorLocked();
134    if (ret != ACAMERA_OK) {
135        ALOGE("%s: camera is in closed or error state %d", __FUNCTION__, ret);
136        return ret;
137    }
138    CameraMetadata rawPreviewRequest;
139    binder::Status remoteRet = mRemote->createDefaultRequest(TEMPLATE_PREVIEW, &rawPreviewRequest);
140    if (!remoteRet.isOk()) {
141        ALOGE("%s: Create capture request failed: %s", __FUNCTION__, remoteRet.toString8().c_str());
142        return ACAMERA_ERROR_UNKNOWN;
143    }
144    // ToDo: Check if the memory allocation can be freed automatically using either default_delete
145    // or ScopedAResource.
146    mPreviewRequest = new ACaptureRequest();
147    mPreviewRequest->settings = new ACameraMetadata(rawPreviewRequest.release(),
148            ACameraMetadata::ACM_REQUEST);
149    mPreviewRequest->targets  = new ACameraOutputTargets();
150    for (int i = 0; i < numOutputWindows ; i++) {
151        ACameraOutputTarget* outputTarget = nullptr;
152        ret = ACameraOutputTarget_create(windows[i], &outputTarget);
153        if (ret != ACAMERA_OK) {
154            ALOGE("%s: error while ACameraOutputTarget_create %d", __FUNCTION__, ret);
155            return ret;
156        }
157        ret = ACaptureRequest_addTarget(mPreviewRequest, outputTarget);
158        if (ret != ACAMERA_OK) {
159            ALOGE("%s: error while ACaptureRequest_addTarget %d", __FUNCTION__, ret);
160            return ret;
161        }
162        mPreviewRequestOutputs.push_back(outputTarget);
163    }
164
165    sp<CaptureRequest> req;
166    ret = allocateCaptureRequest(mPreviewRequest, req);
167    if (ret != ACAMERA_OK) {
168        ALOGE("Convert capture request to internal format failure! ret %d", ret);
169        return ret;
170    }
171    if (req->mSurfaceList.empty()) {
172        ALOGE("Capture request without output target cannot be submitted!");
173        return ACAMERA_ERROR_INVALID_PARAMETER;
174    }
175
176    // In shared session mode, if there are other active clients streaming then
177    // stoprepeating does not actually send request to HAL to cancel the request.
178    // Cameraservice will use this call to remove this client surfaces provided in its
179    // previous streaming request. If this is the only client for the shared camera device
180    // then camerservice will ask HAL to cancel the previous repeating request.
181    ret = stopRepeatingLocked();
182    if (ret != ACAMERA_OK) {
183        ALOGE("Camera %s stop repeating failed! ret %d", getId(), ret);
184        return ret;
185    }
186
187    hardware::camera2::utils::SubmitInfo info;
188    std::vector<int> streamIds(req->mStreamIdxList.begin(), req->mStreamIdxList.end());
189    std::vector<int> surfaceIds(req->mSurfaceIdxList.begin(), req->mSurfaceIdxList.end());
190    remoteRet = mRemote->startStreaming(streamIds, surfaceIds, &info);
191    int sequenceId = info.mRequestId;
192    int64_t lastFrameNumber = info.mLastFrameNumber;
193    if (sequenceId < 0) {
194        ALOGE("Camera %s start streaming remote failure: ret %d", getId(), sequenceId);
195        return ACAMERA_ERROR_UNKNOWN;
196    }
197
198    Vector<sp<CaptureRequest> > requestsV;
199    requestsV.push_back(req);
200    CallbackHolder cbHolder(session, requestsV, true, callbacks);
201    mSequenceCallbackMap.insert(std::make_pair(sequenceId, cbHolder));
202
203    // stopRepeating above should have cleanup repeating sequence id
204    if (mRepeatingSequenceId != REQUEST_ID_NONE) {
205        setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
206        return ACAMERA_ERROR_CAMERA_DEVICE;
207    }
208    mRepeatingSequenceId = sequenceId;
209
210    if (mIdle) {
211        sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
212        msg->setPointer(kContextKey, session->mUserSessionCallback.context);
213        msg->setObject(kSessionSpKey, session);
214        msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
215        postSessionMsgAndCleanup(msg);
216    }
217    mIdle = false;
218    mBusySession = session;
219
220    if (captureSequenceId) {
221        *captureSequenceId = sequenceId;
222    }
223    return ACAMERA_OK;
224}
225
226} // namespace acam
227} // namespace android
228