xref: /aosp_15_r20/hardware/interfaces/camera/device/3.5/default/ExternalCameraDeviceSession.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker  *
4*4d7e907cSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker  *
8*4d7e907cSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker  *
10*4d7e907cSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker  * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker  */
16*4d7e907cSAndroid Build Coastguard Worker 
17*4d7e907cSAndroid Build Coastguard Worker #define LOG_TAG "[email protected]"
18*4d7e907cSAndroid Build Coastguard Worker #include <android/log.h>
19*4d7e907cSAndroid Build Coastguard Worker 
20*4d7e907cSAndroid Build Coastguard Worker #include <utils/Trace.h>
21*4d7e907cSAndroid Build Coastguard Worker #include "ExternalCameraDeviceSession.h"
22*4d7e907cSAndroid Build Coastguard Worker 
23*4d7e907cSAndroid Build Coastguard Worker namespace android {
24*4d7e907cSAndroid Build Coastguard Worker namespace hardware {
25*4d7e907cSAndroid Build Coastguard Worker namespace camera {
26*4d7e907cSAndroid Build Coastguard Worker namespace device {
27*4d7e907cSAndroid Build Coastguard Worker namespace V3_5 {
28*4d7e907cSAndroid Build Coastguard Worker namespace implementation {
29*4d7e907cSAndroid Build Coastguard Worker 
ExternalCameraDeviceSession(const sp<V3_2::ICameraDeviceCallback> & callback,const ExternalCameraConfig & cfg,const std::vector<SupportedV4L2Format> & sortedFormats,const CroppingType & croppingType,const common::V1_0::helper::CameraMetadata & chars,const std::string & cameraId,unique_fd v4l2Fd)30*4d7e907cSAndroid Build Coastguard Worker ExternalCameraDeviceSession::ExternalCameraDeviceSession(
31*4d7e907cSAndroid Build Coastguard Worker         const sp<V3_2::ICameraDeviceCallback>& callback,
32*4d7e907cSAndroid Build Coastguard Worker         const ExternalCameraConfig& cfg,
33*4d7e907cSAndroid Build Coastguard Worker         const std::vector<SupportedV4L2Format>& sortedFormats,
34*4d7e907cSAndroid Build Coastguard Worker         const CroppingType& croppingType,
35*4d7e907cSAndroid Build Coastguard Worker         const common::V1_0::helper::CameraMetadata& chars,
36*4d7e907cSAndroid Build Coastguard Worker         const std::string& cameraId,
37*4d7e907cSAndroid Build Coastguard Worker         unique_fd v4l2Fd) :
38*4d7e907cSAndroid Build Coastguard Worker         V3_4::implementation::ExternalCameraDeviceSession(
39*4d7e907cSAndroid Build Coastguard Worker                 callback, cfg, sortedFormats, croppingType, chars, cameraId, std::move(v4l2Fd)) {
40*4d7e907cSAndroid Build Coastguard Worker 
41*4d7e907cSAndroid Build Coastguard Worker     mCallback_3_5 = nullptr;
42*4d7e907cSAndroid Build Coastguard Worker 
43*4d7e907cSAndroid Build Coastguard Worker     auto castResult = V3_5::ICameraDeviceCallback::castFrom(callback);
44*4d7e907cSAndroid Build Coastguard Worker     if (castResult.isOk()) {
45*4d7e907cSAndroid Build Coastguard Worker         sp<V3_5::ICameraDeviceCallback> callback3_5 = castResult;
46*4d7e907cSAndroid Build Coastguard Worker         if (callback3_5 != nullptr) {
47*4d7e907cSAndroid Build Coastguard Worker             mCallback_3_5 = callback3_5;
48*4d7e907cSAndroid Build Coastguard Worker         }
49*4d7e907cSAndroid Build Coastguard Worker     }
50*4d7e907cSAndroid Build Coastguard Worker 
51*4d7e907cSAndroid Build Coastguard Worker     if (mCallback_3_5 != nullptr) {
52*4d7e907cSAndroid Build Coastguard Worker         mSupportBufMgr = true;
53*4d7e907cSAndroid Build Coastguard Worker     }
54*4d7e907cSAndroid Build Coastguard Worker }
55*4d7e907cSAndroid Build Coastguard Worker 
~ExternalCameraDeviceSession()56*4d7e907cSAndroid Build Coastguard Worker ExternalCameraDeviceSession::~ExternalCameraDeviceSession() {
57*4d7e907cSAndroid Build Coastguard Worker     closeOutputThreadImpl();
58*4d7e907cSAndroid Build Coastguard Worker }
59*4d7e907cSAndroid Build Coastguard Worker 
configureStreams_3_5(const StreamConfiguration & requestedConfiguration,ICameraDeviceSession::configureStreams_3_5_cb _hidl_cb)60*4d7e907cSAndroid Build Coastguard Worker Return<void> ExternalCameraDeviceSession::configureStreams_3_5(
61*4d7e907cSAndroid Build Coastguard Worker         const StreamConfiguration& requestedConfiguration,
62*4d7e907cSAndroid Build Coastguard Worker         ICameraDeviceSession::configureStreams_3_5_cb _hidl_cb)  {
63*4d7e907cSAndroid Build Coastguard Worker     return configureStreams_3_4(requestedConfiguration.v3_4, _hidl_cb);
64*4d7e907cSAndroid Build Coastguard Worker }
65*4d7e907cSAndroid Build Coastguard Worker 
signalStreamFlush(const hidl_vec<int32_t> &,uint32_t)66*4d7e907cSAndroid Build Coastguard Worker Return<void> ExternalCameraDeviceSession::signalStreamFlush(
67*4d7e907cSAndroid Build Coastguard Worker         const hidl_vec<int32_t>& /*streamIds*/, uint32_t /*streamConfigCounter*/) {
68*4d7e907cSAndroid Build Coastguard Worker     return Void();
69*4d7e907cSAndroid Build Coastguard Worker }
70*4d7e907cSAndroid Build Coastguard Worker 
importRequestLocked(const CaptureRequest & request,hidl_vec<buffer_handle_t * > & allBufPtrs,hidl_vec<int> & allFences)71*4d7e907cSAndroid Build Coastguard Worker Status ExternalCameraDeviceSession::importRequestLocked(
72*4d7e907cSAndroid Build Coastguard Worker         const CaptureRequest& request,
73*4d7e907cSAndroid Build Coastguard Worker         hidl_vec<buffer_handle_t*>& allBufPtrs,
74*4d7e907cSAndroid Build Coastguard Worker         hidl_vec<int>& allFences) {
75*4d7e907cSAndroid Build Coastguard Worker     if (mSupportBufMgr) {
76*4d7e907cSAndroid Build Coastguard Worker         return importRequestLockedImpl(request, allBufPtrs, allFences, /*allowEmptyBuf*/ true);
77*4d7e907cSAndroid Build Coastguard Worker     }
78*4d7e907cSAndroid Build Coastguard Worker     return importRequestLockedImpl(request, allBufPtrs, allFences, /*allowEmptyBuf*/ false);
79*4d7e907cSAndroid Build Coastguard Worker }
80*4d7e907cSAndroid Build Coastguard Worker 
81*4d7e907cSAndroid Build Coastguard Worker 
BufferRequestThread(wp<OutputThreadInterface> parent,sp<V3_5::ICameraDeviceCallback> callbacks)82*4d7e907cSAndroid Build Coastguard Worker ExternalCameraDeviceSession::BufferRequestThread::BufferRequestThread(
83*4d7e907cSAndroid Build Coastguard Worker         wp<OutputThreadInterface> parent,
84*4d7e907cSAndroid Build Coastguard Worker         sp<V3_5::ICameraDeviceCallback> callbacks) :
85*4d7e907cSAndroid Build Coastguard Worker         mParent(parent),
86*4d7e907cSAndroid Build Coastguard Worker         mCallbacks(callbacks) {}
87*4d7e907cSAndroid Build Coastguard Worker 
requestBufferStart(const std::vector<HalStreamBuffer> & bufReqs)88*4d7e907cSAndroid Build Coastguard Worker int ExternalCameraDeviceSession::BufferRequestThread::requestBufferStart(
89*4d7e907cSAndroid Build Coastguard Worker         const std::vector<HalStreamBuffer>& bufReqs) {
90*4d7e907cSAndroid Build Coastguard Worker     if (bufReqs.empty()) {
91*4d7e907cSAndroid Build Coastguard Worker         ALOGE("%s: bufReqs is empty!", __FUNCTION__);
92*4d7e907cSAndroid Build Coastguard Worker         return -1;
93*4d7e907cSAndroid Build Coastguard Worker     }
94*4d7e907cSAndroid Build Coastguard Worker 
95*4d7e907cSAndroid Build Coastguard Worker     {
96*4d7e907cSAndroid Build Coastguard Worker         std::lock_guard<std::mutex> lk(mLock);
97*4d7e907cSAndroid Build Coastguard Worker         if (mRequestingBuffer) {
98*4d7e907cSAndroid Build Coastguard Worker             ALOGE("%s: BufferRequestThread does not support more than one concurrent request!",
99*4d7e907cSAndroid Build Coastguard Worker                     __FUNCTION__);
100*4d7e907cSAndroid Build Coastguard Worker             return -1;
101*4d7e907cSAndroid Build Coastguard Worker         }
102*4d7e907cSAndroid Build Coastguard Worker 
103*4d7e907cSAndroid Build Coastguard Worker         mBufferReqs = bufReqs;
104*4d7e907cSAndroid Build Coastguard Worker         mRequestingBuffer = true;
105*4d7e907cSAndroid Build Coastguard Worker     }
106*4d7e907cSAndroid Build Coastguard Worker     mRequestCond.notify_one();
107*4d7e907cSAndroid Build Coastguard Worker     return 0;
108*4d7e907cSAndroid Build Coastguard Worker }
109*4d7e907cSAndroid Build Coastguard Worker 
waitForBufferRequestDone(std::vector<HalStreamBuffer> * outBufReq)110*4d7e907cSAndroid Build Coastguard Worker int ExternalCameraDeviceSession::BufferRequestThread::waitForBufferRequestDone(
111*4d7e907cSAndroid Build Coastguard Worker         std::vector<HalStreamBuffer>* outBufReq) {
112*4d7e907cSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lk(mLock);
113*4d7e907cSAndroid Build Coastguard Worker     if (!mRequestingBuffer) {
114*4d7e907cSAndroid Build Coastguard Worker         ALOGE("%s: no pending buffer request!", __FUNCTION__);
115*4d7e907cSAndroid Build Coastguard Worker         return -1;
116*4d7e907cSAndroid Build Coastguard Worker     }
117*4d7e907cSAndroid Build Coastguard Worker 
118*4d7e907cSAndroid Build Coastguard Worker     if (mPendingReturnBufferReqs.empty()) {
119*4d7e907cSAndroid Build Coastguard Worker         std::chrono::milliseconds timeout = std::chrono::milliseconds(kReqProcTimeoutMs);
120*4d7e907cSAndroid Build Coastguard Worker         auto st = mRequestDoneCond.wait_for(lk, timeout);
121*4d7e907cSAndroid Build Coastguard Worker         if (st == std::cv_status::timeout) {
122*4d7e907cSAndroid Build Coastguard Worker             ALOGE("%s: wait for buffer request finish timeout!", __FUNCTION__);
123*4d7e907cSAndroid Build Coastguard Worker             return -1;
124*4d7e907cSAndroid Build Coastguard Worker         }
125*4d7e907cSAndroid Build Coastguard Worker     }
126*4d7e907cSAndroid Build Coastguard Worker     mRequestingBuffer = false;
127*4d7e907cSAndroid Build Coastguard Worker     *outBufReq = std::move(mPendingReturnBufferReqs);
128*4d7e907cSAndroid Build Coastguard Worker     mPendingReturnBufferReqs.clear();
129*4d7e907cSAndroid Build Coastguard Worker     return 0;
130*4d7e907cSAndroid Build Coastguard Worker }
131*4d7e907cSAndroid Build Coastguard Worker 
waitForNextRequest()132*4d7e907cSAndroid Build Coastguard Worker void ExternalCameraDeviceSession::BufferRequestThread::waitForNextRequest() {
133*4d7e907cSAndroid Build Coastguard Worker     ATRACE_CALL();
134*4d7e907cSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lk(mLock);
135*4d7e907cSAndroid Build Coastguard Worker     int waitTimes = 0;
136*4d7e907cSAndroid Build Coastguard Worker     while (mBufferReqs.empty()) {
137*4d7e907cSAndroid Build Coastguard Worker         if (exitPending()) {
138*4d7e907cSAndroid Build Coastguard Worker             return;
139*4d7e907cSAndroid Build Coastguard Worker         }
140*4d7e907cSAndroid Build Coastguard Worker         std::chrono::milliseconds timeout = std::chrono::milliseconds(kReqWaitTimeoutMs);
141*4d7e907cSAndroid Build Coastguard Worker         auto st = mRequestCond.wait_for(lk, timeout);
142*4d7e907cSAndroid Build Coastguard Worker         if (st == std::cv_status::timeout) {
143*4d7e907cSAndroid Build Coastguard Worker             waitTimes++;
144*4d7e907cSAndroid Build Coastguard Worker             if (waitTimes == kReqWaitTimesWarn) {
145*4d7e907cSAndroid Build Coastguard Worker                 // BufferRequestThread just wait forever for new buffer request
146*4d7e907cSAndroid Build Coastguard Worker                 // But it will print some periodic warning indicating it's waiting
147*4d7e907cSAndroid Build Coastguard Worker                 ALOGV("%s: still waiting for new buffer request", __FUNCTION__);
148*4d7e907cSAndroid Build Coastguard Worker                 waitTimes = 0;
149*4d7e907cSAndroid Build Coastguard Worker             }
150*4d7e907cSAndroid Build Coastguard Worker         }
151*4d7e907cSAndroid Build Coastguard Worker     }
152*4d7e907cSAndroid Build Coastguard Worker 
153*4d7e907cSAndroid Build Coastguard Worker     // Fill in hidl BufferRequest
154*4d7e907cSAndroid Build Coastguard Worker     mHalBufferReqs.resize(mBufferReqs.size());
155*4d7e907cSAndroid Build Coastguard Worker     for (size_t i = 0; i < mHalBufferReqs.size(); i++) {
156*4d7e907cSAndroid Build Coastguard Worker         mHalBufferReqs[i].streamId = mBufferReqs[i].streamId;
157*4d7e907cSAndroid Build Coastguard Worker         mHalBufferReqs[i].numBuffersRequested = 1;
158*4d7e907cSAndroid Build Coastguard Worker     }
159*4d7e907cSAndroid Build Coastguard Worker }
160*4d7e907cSAndroid Build Coastguard Worker 
threadLoop()161*4d7e907cSAndroid Build Coastguard Worker bool ExternalCameraDeviceSession::BufferRequestThread::threadLoop() {
162*4d7e907cSAndroid Build Coastguard Worker     waitForNextRequest();
163*4d7e907cSAndroid Build Coastguard Worker     if (exitPending()) {
164*4d7e907cSAndroid Build Coastguard Worker         return false;
165*4d7e907cSAndroid Build Coastguard Worker     }
166*4d7e907cSAndroid Build Coastguard Worker 
167*4d7e907cSAndroid Build Coastguard Worker     ATRACE_BEGIN("HIDL requestStreamBuffers");
168*4d7e907cSAndroid Build Coastguard Worker     BufferRequestStatus status;
169*4d7e907cSAndroid Build Coastguard Worker     hidl_vec<StreamBufferRet> bufRets;
170*4d7e907cSAndroid Build Coastguard Worker     auto err = mCallbacks->requestStreamBuffers(mHalBufferReqs,
171*4d7e907cSAndroid Build Coastguard Worker             [&status, &bufRets]
172*4d7e907cSAndroid Build Coastguard Worker             (BufferRequestStatus s, const hidl_vec<StreamBufferRet>& rets) {
173*4d7e907cSAndroid Build Coastguard Worker                 status = s;
174*4d7e907cSAndroid Build Coastguard Worker                 bufRets = std::move(rets);
175*4d7e907cSAndroid Build Coastguard Worker             });
176*4d7e907cSAndroid Build Coastguard Worker     ATRACE_END();
177*4d7e907cSAndroid Build Coastguard Worker     if (!err.isOk()) {
178*4d7e907cSAndroid Build Coastguard Worker         ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
179*4d7e907cSAndroid Build Coastguard Worker         return false;
180*4d7e907cSAndroid Build Coastguard Worker     }
181*4d7e907cSAndroid Build Coastguard Worker 
182*4d7e907cSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lk(mLock);
183*4d7e907cSAndroid Build Coastguard Worker     if (status == BufferRequestStatus::OK || status == BufferRequestStatus::FAILED_PARTIAL) {
184*4d7e907cSAndroid Build Coastguard Worker         if (bufRets.size() != mHalBufferReqs.size()) {
185*4d7e907cSAndroid Build Coastguard Worker             ALOGE("%s: expect %zu buffer requests returned, only got %zu",
186*4d7e907cSAndroid Build Coastguard Worker                     __FUNCTION__, mHalBufferReqs.size(), bufRets.size());
187*4d7e907cSAndroid Build Coastguard Worker             return false;
188*4d7e907cSAndroid Build Coastguard Worker         }
189*4d7e907cSAndroid Build Coastguard Worker 
190*4d7e907cSAndroid Build Coastguard Worker         auto parent = mParent.promote();
191*4d7e907cSAndroid Build Coastguard Worker         if (parent == nullptr) {
192*4d7e907cSAndroid Build Coastguard Worker             ALOGE("%s: session has been disconnected!", __FUNCTION__);
193*4d7e907cSAndroid Build Coastguard Worker             return false;
194*4d7e907cSAndroid Build Coastguard Worker         }
195*4d7e907cSAndroid Build Coastguard Worker 
196*4d7e907cSAndroid Build Coastguard Worker         hidl_vec<int> importedFences;
197*4d7e907cSAndroid Build Coastguard Worker         importedFences.resize(bufRets.size());
198*4d7e907cSAndroid Build Coastguard Worker         for (size_t i = 0; i < bufRets.size(); i++) {
199*4d7e907cSAndroid Build Coastguard Worker             int streamId = bufRets[i].streamId;
200*4d7e907cSAndroid Build Coastguard Worker             switch (bufRets[i].val.getDiscriminator()) {
201*4d7e907cSAndroid Build Coastguard Worker                 case StreamBuffersVal::hidl_discriminator::error:
202*4d7e907cSAndroid Build Coastguard Worker                     continue;
203*4d7e907cSAndroid Build Coastguard Worker                 case StreamBuffersVal::hidl_discriminator::buffers: {
204*4d7e907cSAndroid Build Coastguard Worker                     const hidl_vec<V3_2::StreamBuffer>& hBufs = bufRets[i].val.buffers();
205*4d7e907cSAndroid Build Coastguard Worker                     if (hBufs.size() != 1) {
206*4d7e907cSAndroid Build Coastguard Worker                         ALOGE("%s: expect 1 buffer returned, got %zu!", __FUNCTION__, hBufs.size());
207*4d7e907cSAndroid Build Coastguard Worker                         return false;
208*4d7e907cSAndroid Build Coastguard Worker                     }
209*4d7e907cSAndroid Build Coastguard Worker                     const V3_2::StreamBuffer& hBuf = hBufs[0];
210*4d7e907cSAndroid Build Coastguard Worker 
211*4d7e907cSAndroid Build Coastguard Worker                     mBufferReqs[i].bufferId = hBuf.bufferId;
212*4d7e907cSAndroid Build Coastguard Worker                     // TODO: create a batch import API so we don't need to lock/unlock mCbsLock
213*4d7e907cSAndroid Build Coastguard Worker                     // repeatedly?
214*4d7e907cSAndroid Build Coastguard Worker                     lk.unlock();
215*4d7e907cSAndroid Build Coastguard Worker                     Status s = parent->importBuffer(streamId,
216*4d7e907cSAndroid Build Coastguard Worker                             hBuf.bufferId, hBuf.buffer.getNativeHandle(),
217*4d7e907cSAndroid Build Coastguard Worker                             /*out*/&mBufferReqs[i].bufPtr,
218*4d7e907cSAndroid Build Coastguard Worker                             /*allowEmptyBuf*/false);
219*4d7e907cSAndroid Build Coastguard Worker                     lk.lock();
220*4d7e907cSAndroid Build Coastguard Worker 
221*4d7e907cSAndroid Build Coastguard Worker                     if (s != Status::OK) {
222*4d7e907cSAndroid Build Coastguard Worker                         ALOGE("%s: stream %d import buffer failed!", __FUNCTION__, streamId);
223*4d7e907cSAndroid Build Coastguard Worker                         cleanupInflightFences(importedFences, i - 1);
224*4d7e907cSAndroid Build Coastguard Worker                         return false;
225*4d7e907cSAndroid Build Coastguard Worker                     }
226*4d7e907cSAndroid Build Coastguard Worker                     if (!sHandleImporter.importFence(hBuf.acquireFence,
227*4d7e907cSAndroid Build Coastguard Worker                             mBufferReqs[i].acquireFence)) {
228*4d7e907cSAndroid Build Coastguard Worker                         ALOGE("%s: stream %d import fence failed!", __FUNCTION__, streamId);
229*4d7e907cSAndroid Build Coastguard Worker                         cleanupInflightFences(importedFences, i - 1);
230*4d7e907cSAndroid Build Coastguard Worker                         return false;
231*4d7e907cSAndroid Build Coastguard Worker                     }
232*4d7e907cSAndroid Build Coastguard Worker                     importedFences[i] = mBufferReqs[i].acquireFence;
233*4d7e907cSAndroid Build Coastguard Worker                 }
234*4d7e907cSAndroid Build Coastguard Worker                 break;
235*4d7e907cSAndroid Build Coastguard Worker                 default:
236*4d7e907cSAndroid Build Coastguard Worker                     ALOGE("%s: unkown StreamBuffersVal discrimator!", __FUNCTION__);
237*4d7e907cSAndroid Build Coastguard Worker                     return false;
238*4d7e907cSAndroid Build Coastguard Worker             }
239*4d7e907cSAndroid Build Coastguard Worker         }
240*4d7e907cSAndroid Build Coastguard Worker     } else {
241*4d7e907cSAndroid Build Coastguard Worker         ALOGE("%s: requestStreamBuffers call failed!", __FUNCTION__);
242*4d7e907cSAndroid Build Coastguard Worker     }
243*4d7e907cSAndroid Build Coastguard Worker 
244*4d7e907cSAndroid Build Coastguard Worker     mPendingReturnBufferReqs = std::move(mBufferReqs);
245*4d7e907cSAndroid Build Coastguard Worker     mBufferReqs.clear();
246*4d7e907cSAndroid Build Coastguard Worker 
247*4d7e907cSAndroid Build Coastguard Worker     lk.unlock();
248*4d7e907cSAndroid Build Coastguard Worker     mRequestDoneCond.notify_one();
249*4d7e907cSAndroid Build Coastguard Worker     return true;
250*4d7e907cSAndroid Build Coastguard Worker }
251*4d7e907cSAndroid Build Coastguard Worker 
initOutputThread()252*4d7e907cSAndroid Build Coastguard Worker void ExternalCameraDeviceSession::initOutputThread() {
253*4d7e907cSAndroid Build Coastguard Worker     if (mSupportBufMgr) {
254*4d7e907cSAndroid Build Coastguard Worker         mBufferRequestThread = new BufferRequestThread(this, mCallback_3_5);
255*4d7e907cSAndroid Build Coastguard Worker         mBufferRequestThread->run("ExtCamBufReq", PRIORITY_DISPLAY);
256*4d7e907cSAndroid Build Coastguard Worker     }
257*4d7e907cSAndroid Build Coastguard Worker     mOutputThread = new OutputThread(
258*4d7e907cSAndroid Build Coastguard Worker             this, mCroppingType, mCameraCharacteristics, mBufferRequestThread);
259*4d7e907cSAndroid Build Coastguard Worker }
260*4d7e907cSAndroid Build Coastguard Worker 
closeOutputThreadImpl()261*4d7e907cSAndroid Build Coastguard Worker void ExternalCameraDeviceSession::closeOutputThreadImpl() {
262*4d7e907cSAndroid Build Coastguard Worker     if (mBufferRequestThread) {
263*4d7e907cSAndroid Build Coastguard Worker         mBufferRequestThread->requestExit();
264*4d7e907cSAndroid Build Coastguard Worker         mBufferRequestThread->join();
265*4d7e907cSAndroid Build Coastguard Worker         mBufferRequestThread.clear();
266*4d7e907cSAndroid Build Coastguard Worker     }
267*4d7e907cSAndroid Build Coastguard Worker }
268*4d7e907cSAndroid Build Coastguard Worker 
closeOutputThread()269*4d7e907cSAndroid Build Coastguard Worker void ExternalCameraDeviceSession::closeOutputThread() {
270*4d7e907cSAndroid Build Coastguard Worker     closeOutputThreadImpl();
271*4d7e907cSAndroid Build Coastguard Worker     V3_4::implementation::ExternalCameraDeviceSession::closeOutputThread();
272*4d7e907cSAndroid Build Coastguard Worker }
273*4d7e907cSAndroid Build Coastguard Worker 
OutputThread(wp<OutputThreadInterface> parent,CroppingType ct,const common::V1_0::helper::CameraMetadata & chars,sp<BufferRequestThread> bufReqThread)274*4d7e907cSAndroid Build Coastguard Worker ExternalCameraDeviceSession::OutputThread::OutputThread(
275*4d7e907cSAndroid Build Coastguard Worker         wp<OutputThreadInterface> parent,
276*4d7e907cSAndroid Build Coastguard Worker         CroppingType ct,
277*4d7e907cSAndroid Build Coastguard Worker         const common::V1_0::helper::CameraMetadata& chars,
278*4d7e907cSAndroid Build Coastguard Worker         sp<BufferRequestThread> bufReqThread) :
279*4d7e907cSAndroid Build Coastguard Worker         V3_4::implementation::ExternalCameraDeviceSession::OutputThread(parent, ct, chars),
280*4d7e907cSAndroid Build Coastguard Worker         mBufferRequestThread(bufReqThread) {}
281*4d7e907cSAndroid Build Coastguard Worker 
~OutputThread()282*4d7e907cSAndroid Build Coastguard Worker ExternalCameraDeviceSession::OutputThread::~OutputThread() {}
283*4d7e907cSAndroid Build Coastguard Worker 
requestBufferStart(const std::vector<HalStreamBuffer> & bufs)284*4d7e907cSAndroid Build Coastguard Worker int ExternalCameraDeviceSession::OutputThread::requestBufferStart(
285*4d7e907cSAndroid Build Coastguard Worker         const std::vector<HalStreamBuffer>& bufs) {
286*4d7e907cSAndroid Build Coastguard Worker     if (mBufferRequestThread != nullptr) {
287*4d7e907cSAndroid Build Coastguard Worker         return mBufferRequestThread->requestBufferStart(bufs);
288*4d7e907cSAndroid Build Coastguard Worker     }
289*4d7e907cSAndroid Build Coastguard Worker     return 0;
290*4d7e907cSAndroid Build Coastguard Worker }
291*4d7e907cSAndroid Build Coastguard Worker 
waitForBufferRequestDone(std::vector<HalStreamBuffer> * outBufs)292*4d7e907cSAndroid Build Coastguard Worker int ExternalCameraDeviceSession::OutputThread::waitForBufferRequestDone(
293*4d7e907cSAndroid Build Coastguard Worker         /*out*/std::vector<HalStreamBuffer>* outBufs) {
294*4d7e907cSAndroid Build Coastguard Worker     if (mBufferRequestThread != nullptr) {
295*4d7e907cSAndroid Build Coastguard Worker         return mBufferRequestThread->waitForBufferRequestDone(outBufs);
296*4d7e907cSAndroid Build Coastguard Worker     }
297*4d7e907cSAndroid Build Coastguard Worker     return 0;
298*4d7e907cSAndroid Build Coastguard Worker }
299*4d7e907cSAndroid Build Coastguard Worker 
isReconfigurationRequired(const V3_2::CameraMetadata &,const V3_2::CameraMetadata &,ICameraDeviceSession::isReconfigurationRequired_cb _hidl_cb)300*4d7e907cSAndroid Build Coastguard Worker Return<void> ExternalCameraDeviceSession::isReconfigurationRequired(
301*4d7e907cSAndroid Build Coastguard Worker         const V3_2::CameraMetadata& /*oldSessionParams*/,
302*4d7e907cSAndroid Build Coastguard Worker         const V3_2::CameraMetadata& /*newSessionParams*/,
303*4d7e907cSAndroid Build Coastguard Worker         ICameraDeviceSession::isReconfigurationRequired_cb _hidl_cb) {
304*4d7e907cSAndroid Build Coastguard Worker     //Stub implementation
305*4d7e907cSAndroid Build Coastguard Worker     _hidl_cb(Status::OK, true);
306*4d7e907cSAndroid Build Coastguard Worker     return Void();
307*4d7e907cSAndroid Build Coastguard Worker }
308*4d7e907cSAndroid Build Coastguard Worker 
309*4d7e907cSAndroid Build Coastguard Worker } // namespace implementation
310*4d7e907cSAndroid Build Coastguard Worker }  // namespace V3_5
311*4d7e907cSAndroid Build Coastguard Worker }  // namespace device
312*4d7e907cSAndroid Build Coastguard Worker }  // namespace camera
313*4d7e907cSAndroid Build Coastguard Worker }  // namespace hardware
314*4d7e907cSAndroid Build Coastguard Worker }  // namespace android
315