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