1 /*
2  * Copyright (C) 2012 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 #define LOG_TAG "Camera2-StreamingProcessor"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19 //#define LOG_NDEBUG 0
20 //#define LOG_NNDEBUG 0 // Per-frame verbose logging
21 
22 #ifdef LOG_NNDEBUG
23 #define ALOGVV(...) ALOGV(__VA_ARGS__)
24 #else
25 #define ALOGVV(...) ((void)0)
26 #endif
27 
28 #include <cutils/properties.h>
29 #include <utils/Log.h>
30 #include <utils/Trace.h>
31 #include <gui/BufferItem.h>
32 #include <gui/Surface.h>
33 #include <media/hardware/HardwareAPI.h>
34 
35 #include "common/CameraDeviceBase.h"
36 #include "api1/Camera2Client.h"
37 #include "api1/client2/StreamingProcessor.h"
38 #include "api1/client2/Camera2Heap.h"
39 
40 namespace android {
41 namespace camera2 {
42 
StreamingProcessor(sp<Camera2Client> client)43 StreamingProcessor::StreamingProcessor(sp<Camera2Client> client):
44         mClient(client),
45         mDevice(client->getCameraDevice()),
46         mId(client->getCameraId()),
47         mActiveRequest(NONE),
48         mPaused(false),
49         mPreviewRequestId(Camera2Client::kPreviewRequestIdStart),
50         mPreviewStreamId(NO_STREAM),
51         mRecordingRequestId(Camera2Client::kRecordingRequestIdStart),
52         mRecordingStreamId(NO_STREAM)
53 {
54 }
55 
~StreamingProcessor()56 StreamingProcessor::~StreamingProcessor() {
57     deletePreviewStream();
58     deleteRecordingStream();
59 }
60 
setPreviewWindow(sp<Surface> window)61 status_t StreamingProcessor::setPreviewWindow(sp<Surface> window) {
62     ATRACE_CALL();
63     status_t res;
64 
65     res = deletePreviewStream();
66     if (res != OK) return res;
67 
68     Mutex::Autolock m(mMutex);
69 
70     mPreviewWindow = window;
71 
72     return OK;
73 }
74 
setRecordingWindow(sp<Surface> window)75 status_t StreamingProcessor::setRecordingWindow(sp<Surface> window) {
76     ATRACE_CALL();
77     status_t res;
78 
79     res = deleteRecordingStream();
80     if (res != OK) return res;
81 
82     Mutex::Autolock m(mMutex);
83 
84     mRecordingWindow = window;
85 
86     return OK;
87 }
88 
haveValidPreviewWindow() const89 bool StreamingProcessor::haveValidPreviewWindow() const {
90     Mutex::Autolock m(mMutex);
91     return mPreviewWindow != 0;
92 }
93 
haveValidRecordingWindow() const94 bool StreamingProcessor::haveValidRecordingWindow() const {
95     Mutex::Autolock m(mMutex);
96     return mRecordingWindow != nullptr;
97 }
98 
updatePreviewRequest(const Parameters & params)99 status_t StreamingProcessor::updatePreviewRequest(const Parameters &params) {
100     ATRACE_CALL();
101     status_t res;
102     sp<CameraDeviceBase> device = mDevice.promote();
103     if (device == 0) {
104         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
105         return INVALID_OPERATION;
106     }
107 
108     Mutex::Autolock m(mMutex);
109     if (mPreviewRequest.entryCount() == 0) {
110         sp<Camera2Client> client = mClient.promote();
111         if (client == 0) {
112             ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
113             return INVALID_OPERATION;
114         }
115 
116         // Use CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG for ZSL streaming case.
117         if (client->getCameraDeviceVersion() >= CAMERA_DEVICE_API_VERSION_3_0) {
118             if (params.zslMode && !params.recordingHint) {
119                 res = device->createDefaultRequest(CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG,
120                         &mPreviewRequest);
121             } else {
122                 res = device->createDefaultRequest(CAMERA3_TEMPLATE_PREVIEW,
123                         &mPreviewRequest);
124             }
125         } else {
126             res = device->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
127                     &mPreviewRequest);
128         }
129 
130         if (res != OK) {
131             ALOGE("%s: Camera %d: Unable to create default preview request: "
132                     "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
133             return res;
134         }
135     }
136 
137     res = params.updateRequest(&mPreviewRequest);
138     if (res != OK) {
139         ALOGE("%s: Camera %d: Unable to update common entries of preview "
140                 "request: %s (%d)", __FUNCTION__, mId,
141                 strerror(-res), res);
142         return res;
143     }
144 
145     res = mPreviewRequest.update(ANDROID_REQUEST_ID,
146             &mPreviewRequestId, 1);
147     if (res != OK) {
148         ALOGE("%s: Camera %d: Unable to update request id for preview: %s (%d)",
149                 __FUNCTION__, mId, strerror(-res), res);
150         return res;
151     }
152 
153     return OK;
154 }
155 
updatePreviewStream(const Parameters & params)156 status_t StreamingProcessor::updatePreviewStream(const Parameters &params) {
157     ATRACE_CALL();
158     Mutex::Autolock m(mMutex);
159 
160     status_t res;
161     sp<CameraDeviceBase> device = mDevice.promote();
162     if (device == 0) {
163         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
164         return INVALID_OPERATION;
165     }
166 
167     if (mPreviewStreamId != NO_STREAM) {
168         // Check if stream parameters have to change
169         uint32_t currentWidth, currentHeight;
170         res = device->getStreamInfo(mPreviewStreamId,
171                 &currentWidth, &currentHeight, 0, 0);
172         if (res != OK) {
173             ALOGE("%s: Camera %d: Error querying preview stream info: "
174                     "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
175             return res;
176         }
177         if (currentWidth != (uint32_t)params.previewWidth ||
178                 currentHeight != (uint32_t)params.previewHeight) {
179             ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
180                     __FUNCTION__, mId, currentWidth, currentHeight,
181                     params.previewWidth, params.previewHeight);
182             res = device->waitUntilDrained();
183             if (res != OK) {
184                 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
185                         "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
186                 return res;
187             }
188             res = device->deleteStream(mPreviewStreamId);
189             if (res != OK) {
190                 ALOGE("%s: Camera %d: Unable to delete old output stream "
191                         "for preview: %s (%d)", __FUNCTION__, mId,
192                         strerror(-res), res);
193                 return res;
194             }
195             mPreviewStreamId = NO_STREAM;
196         }
197     }
198 
199     if (mPreviewStreamId == NO_STREAM) {
200         res = device->createStream(mPreviewWindow,
201                 params.previewWidth, params.previewHeight,
202                 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, HAL_DATASPACE_UNKNOWN,
203                 CAMERA3_STREAM_ROTATION_0, &mPreviewStreamId);
204         if (res != OK) {
205             ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
206                     __FUNCTION__, mId, strerror(-res), res);
207             return res;
208         }
209     }
210 
211     res = device->setStreamTransform(mPreviewStreamId,
212             params.previewTransform);
213     if (res != OK) {
214         ALOGE("%s: Camera %d: Unable to set preview stream transform: "
215                 "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
216         return res;
217     }
218 
219     return OK;
220 }
221 
deletePreviewStream()222 status_t StreamingProcessor::deletePreviewStream() {
223     ATRACE_CALL();
224     status_t res;
225 
226     Mutex::Autolock m(mMutex);
227 
228     if (mPreviewStreamId != NO_STREAM) {
229         sp<CameraDeviceBase> device = mDevice.promote();
230         if (device == 0) {
231             ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
232             return INVALID_OPERATION;
233         }
234 
235         ALOGV("%s: for cameraId %d on streamId %d",
236             __FUNCTION__, mId, mPreviewStreamId);
237 
238         res = device->waitUntilDrained();
239         if (res != OK) {
240             ALOGE("%s: Error waiting for preview to drain: %s (%d)",
241                     __FUNCTION__, strerror(-res), res);
242             return res;
243         }
244         res = device->deleteStream(mPreviewStreamId);
245         if (res != OK) {
246             ALOGE("%s: Unable to delete old preview stream: %s (%d)",
247                     __FUNCTION__, strerror(-res), res);
248             return res;
249         }
250         mPreviewStreamId = NO_STREAM;
251     }
252     return OK;
253 }
254 
getPreviewStreamId() const255 int StreamingProcessor::getPreviewStreamId() const {
256     Mutex::Autolock m(mMutex);
257     return mPreviewStreamId;
258 }
259 
updateRecordingRequest(const Parameters & params)260 status_t StreamingProcessor::updateRecordingRequest(const Parameters &params) {
261     ATRACE_CALL();
262     status_t res;
263     Mutex::Autolock m(mMutex);
264 
265     sp<CameraDeviceBase> device = mDevice.promote();
266     if (device == 0) {
267         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
268         return INVALID_OPERATION;
269     }
270 
271     if (mRecordingRequest.entryCount() == 0) {
272         res = device->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
273                 &mRecordingRequest);
274         if (res != OK) {
275             ALOGE("%s: Camera %d: Unable to create default recording request:"
276                     " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
277             return res;
278         }
279     }
280 
281     res = params.updateRequest(&mRecordingRequest);
282     if (res != OK) {
283         ALOGE("%s: Camera %d: Unable to update common entries of recording "
284                 "request: %s (%d)", __FUNCTION__, mId,
285                 strerror(-res), res);
286         return res;
287     }
288 
289     res = mRecordingRequest.update(ANDROID_REQUEST_ID,
290             &mRecordingRequestId, 1);
291     if (res != OK) {
292         ALOGE("%s: Camera %d: Unable to update request id for request: %s (%d)",
293                 __FUNCTION__, mId, strerror(-res), res);
294         return res;
295     }
296 
297     return OK;
298 }
299 
recordingStreamNeedsUpdate(const Parameters & params,bool * needsUpdate)300 status_t StreamingProcessor::recordingStreamNeedsUpdate(
301         const Parameters &params, bool *needsUpdate) {
302     status_t res;
303 
304     if (needsUpdate == 0) {
305         ALOGE("%s: Camera %d: invalid argument", __FUNCTION__, mId);
306         return INVALID_OPERATION;
307     }
308 
309     if (mRecordingStreamId == NO_STREAM) {
310         *needsUpdate = true;
311         return OK;
312     }
313 
314     sp<CameraDeviceBase> device = mDevice.promote();
315     if (device == 0) {
316         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
317         return INVALID_OPERATION;
318     }
319 
320     uint32_t currentWidth, currentHeight, currentFormat;
321     android_dataspace currentDataSpace;
322     res = device->getStreamInfo(mRecordingStreamId,
323             &currentWidth, &currentHeight, &currentFormat, &currentDataSpace);
324     if (res != OK) {
325         ALOGE("%s: Camera %d: Error querying recording output stream info: "
326                 "%s (%d)", __FUNCTION__, mId,
327                 strerror(-res), res);
328         return res;
329     }
330 
331     if (mRecordingWindow == nullptr ||
332             currentWidth != (uint32_t)params.videoWidth ||
333             currentHeight != (uint32_t)params.videoHeight ||
334             currentFormat != (uint32_t)params.videoFormat ||
335             currentDataSpace != params.videoDataSpace) {
336         *needsUpdate = true;
337         return res;
338     }
339     *needsUpdate = false;
340     return res;
341 }
342 
updateRecordingStream(const Parameters & params)343 status_t StreamingProcessor::updateRecordingStream(const Parameters &params) {
344     ATRACE_CALL();
345     status_t res;
346     Mutex::Autolock m(mMutex);
347 
348     sp<CameraDeviceBase> device = mDevice.promote();
349     if (device == 0) {
350         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
351         return INVALID_OPERATION;
352     }
353 
354     if (mRecordingStreamId != NO_STREAM) {
355         // Check if stream parameters have to change
356         uint32_t currentWidth, currentHeight;
357         uint32_t currentFormat;
358         android_dataspace currentDataSpace;
359         res = device->getStreamInfo(mRecordingStreamId,
360                 &currentWidth, &currentHeight,
361                 &currentFormat, &currentDataSpace);
362         if (res != OK) {
363             ALOGE("%s: Camera %d: Error querying recording output stream info: "
364                     "%s (%d)", __FUNCTION__, mId,
365                     strerror(-res), res);
366             return res;
367         }
368         if (currentWidth != (uint32_t)params.videoWidth ||
369                 currentHeight != (uint32_t)params.videoHeight ||
370                 currentFormat != (uint32_t)params.videoFormat ||
371                 currentDataSpace != params.videoDataSpace) {
372             // TODO: Should wait to be sure previous recording has finished
373             res = device->deleteStream(mRecordingStreamId);
374 
375             if (res == -EBUSY) {
376                 ALOGV("%s: Camera %d: Device is busy, call "
377                       "updateRecordingStream after it becomes idle",
378                       __FUNCTION__, mId);
379                 return res;
380             } else if (res != OK) {
381                 ALOGE("%s: Camera %d: Unable to delete old output stream "
382                         "for recording: %s (%d)", __FUNCTION__,
383                         mId, strerror(-res), res);
384                 return res;
385             }
386             mRecordingStreamId = NO_STREAM;
387         }
388     }
389 
390     if (mRecordingStreamId == NO_STREAM) {
391         res = device->createStream(mRecordingWindow,
392                 params.videoWidth, params.videoHeight,
393                 params.videoFormat, params.videoDataSpace,
394                 CAMERA3_STREAM_ROTATION_0, &mRecordingStreamId);
395         if (res != OK) {
396             ALOGE("%s: Camera %d: Can't create output stream for recording: "
397                     "%s (%d)", __FUNCTION__, mId,
398                     strerror(-res), res);
399             return res;
400         }
401     }
402 
403     return OK;
404 }
405 
deleteRecordingStream()406 status_t StreamingProcessor::deleteRecordingStream() {
407     ATRACE_CALL();
408     status_t res;
409 
410     Mutex::Autolock m(mMutex);
411 
412     if (mRecordingStreamId != NO_STREAM) {
413         sp<CameraDeviceBase> device = mDevice.promote();
414         if (device == 0) {
415             ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
416             return INVALID_OPERATION;
417         }
418 
419         res = device->waitUntilDrained();
420         if (res != OK) {
421             ALOGE("%s: Error waiting for HAL to drain: %s (%d)",
422                     __FUNCTION__, strerror(-res), res);
423             return res;
424         }
425         res = device->deleteStream(mRecordingStreamId);
426         if (res != OK) {
427             ALOGE("%s: Unable to delete recording stream: %s (%d)",
428                     __FUNCTION__, strerror(-res), res);
429             return res;
430         }
431         mRecordingStreamId = NO_STREAM;
432     }
433     return OK;
434 }
435 
getRecordingStreamId() const436 int StreamingProcessor::getRecordingStreamId() const {
437     return mRecordingStreamId;
438 }
439 
startStream(StreamType type,const Vector<int32_t> & outputStreams)440 status_t StreamingProcessor::startStream(StreamType type,
441         const Vector<int32_t> &outputStreams) {
442     ATRACE_CALL();
443     status_t res;
444 
445     if (type == NONE) return INVALID_OPERATION;
446 
447     sp<CameraDeviceBase> device = mDevice.promote();
448     if (device == 0) {
449         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
450         return INVALID_OPERATION;
451     }
452 
453     ALOGV("%s: Camera %d: type = %d", __FUNCTION__, mId, type);
454 
455     Mutex::Autolock m(mMutex);
456 
457     CameraMetadata &request = (type == PREVIEW) ?
458             mPreviewRequest : mRecordingRequest;
459 
460     res = request.update(
461         ANDROID_REQUEST_OUTPUT_STREAMS,
462         outputStreams);
463     if (res != OK) {
464         ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
465                 __FUNCTION__, mId, strerror(-res), res);
466         return res;
467     }
468 
469     res = request.sort();
470     if (res != OK) {
471         ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
472                 __FUNCTION__, mId, strerror(-res), res);
473         return res;
474     }
475 
476     res = device->setStreamingRequest(request);
477     if (res != OK) {
478         ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
479                 "%s (%d)",
480                 __FUNCTION__, mId, strerror(-res), res);
481         return res;
482     }
483     mActiveRequest = type;
484     mPaused = false;
485     mActiveStreamIds = outputStreams;
486     return OK;
487 }
488 
togglePauseStream(bool pause)489 status_t StreamingProcessor::togglePauseStream(bool pause) {
490     ATRACE_CALL();
491     status_t res;
492 
493     sp<CameraDeviceBase> device = mDevice.promote();
494     if (device == 0) {
495         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
496         return INVALID_OPERATION;
497     }
498 
499     ALOGV("%s: Camera %d: toggling pause to %d", __FUNCTION__, mId, pause);
500 
501     Mutex::Autolock m(mMutex);
502 
503     if (mActiveRequest == NONE) {
504         ALOGE("%s: Camera %d: Can't toggle pause, streaming was not started",
505               __FUNCTION__, mId);
506         return INVALID_OPERATION;
507     }
508 
509     if (mPaused == pause) {
510         return OK;
511     }
512 
513     if (pause) {
514         res = device->clearStreamingRequest();
515         if (res != OK) {
516             ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)",
517                     __FUNCTION__, mId, strerror(-res), res);
518             return res;
519         }
520     } else {
521         CameraMetadata &request =
522                 (mActiveRequest == PREVIEW) ? mPreviewRequest
523                                             : mRecordingRequest;
524         res = device->setStreamingRequest(request);
525         if (res != OK) {
526             ALOGE("%s: Camera %d: Unable to set preview request to resume: "
527                     "%s (%d)",
528                     __FUNCTION__, mId, strerror(-res), res);
529             return res;
530         }
531     }
532 
533     mPaused = pause;
534     return OK;
535 }
536 
stopStream()537 status_t StreamingProcessor::stopStream() {
538     ATRACE_CALL();
539     status_t res;
540 
541     Mutex::Autolock m(mMutex);
542 
543     sp<CameraDeviceBase> device = mDevice.promote();
544     if (device == 0) {
545         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
546         return INVALID_OPERATION;
547     }
548 
549     res = device->clearStreamingRequest();
550     if (res != OK) {
551         ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)",
552                 __FUNCTION__, mId, strerror(-res), res);
553         return res;
554     }
555 
556     mActiveRequest = NONE;
557     mActiveStreamIds.clear();
558     mPaused = false;
559 
560     return OK;
561 }
562 
getActiveRequestId() const563 int32_t StreamingProcessor::getActiveRequestId() const {
564     Mutex::Autolock m(mMutex);
565     switch (mActiveRequest) {
566         case NONE:
567             return 0;
568         case PREVIEW:
569             return mPreviewRequestId;
570         case RECORD:
571             return mRecordingRequestId;
572         default:
573             ALOGE("%s: Unexpected mode %d", __FUNCTION__, mActiveRequest);
574             return 0;
575     }
576 }
577 
incrementStreamingIds()578 status_t StreamingProcessor::incrementStreamingIds() {
579     ATRACE_CALL();
580     Mutex::Autolock m(mMutex);
581 
582     mPreviewRequestId++;
583     if (mPreviewRequestId >= Camera2Client::kPreviewRequestIdEnd) {
584         mPreviewRequestId = Camera2Client::kPreviewRequestIdStart;
585     }
586     mRecordingRequestId++;
587     if (mRecordingRequestId >= Camera2Client::kRecordingRequestIdEnd) {
588         mRecordingRequestId = Camera2Client::kRecordingRequestIdStart;
589     }
590     return OK;
591 }
592 
dump(int fd,const Vector<String16> &)593 status_t StreamingProcessor::dump(int fd, const Vector<String16>& /*args*/) {
594     String8 result;
595 
596     result.append("  Current requests:\n");
597     if (mPreviewRequest.entryCount() != 0) {
598         result.append("    Preview request:\n");
599         write(fd, result.string(), result.size());
600         mPreviewRequest.dump(fd, 2, 6);
601         result.clear();
602     } else {
603         result.append("    Preview request: undefined\n");
604     }
605 
606     if (mRecordingRequest.entryCount() != 0) {
607         result = "    Recording request:\n";
608         write(fd, result.string(), result.size());
609         mRecordingRequest.dump(fd, 2, 6);
610         result.clear();
611     } else {
612         result = "    Recording request: undefined\n";
613     }
614 
615     const char* streamTypeString[] = {
616         "none", "preview", "record"
617     };
618     result.append(String8::format("   Active request: %s (paused: %s)\n",
619                                   streamTypeString[mActiveRequest],
620                                   mPaused ? "yes" : "no"));
621 
622     write(fd, result.string(), result.size());
623 
624     return OK;
625 }
626 
627 }; // namespace camera2
628 }; // namespace android
629