• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &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 (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 &params) {
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                 &currentWidth, &currentHeight, 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 &params) {
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 &params, 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             &currentWidth, &currentHeight, &currentFormat, &currentDataSpace);
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 &params) {
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                 &currentWidth, &currentHeight,
356                 &currentFormat, &currentDataSpace);
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