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 ¶ms) {
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 ¶ms) {
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 ¤tWidth, ¤tHeight, 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 ¶ms) {
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 ¶ms, 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 ¤tWidth, ¤tHeight, ¤tFormat, ¤tDataSpace);
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 ¶ms) {
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 ¤tWidth, ¤tHeight,
361 ¤tFormat, ¤tDataSpace);
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