• 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-Device"
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 <utils/Log.h>
29 #include <utils/Trace.h>
30 #include <utils/Timers.h>
31 #include "Camera2Device.h"
32 
33 namespace android {
34 
Camera2Device(int id)35 Camera2Device::Camera2Device(int id):
36         mId(id),
37         mDevice(NULL)
38 {
39     ATRACE_CALL();
40     ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
41 }
42 
~Camera2Device()43 Camera2Device::~Camera2Device()
44 {
45     ATRACE_CALL();
46     ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId);
47     disconnect();
48 }
49 
initialize(camera_module_t * module)50 status_t Camera2Device::initialize(camera_module_t *module)
51 {
52     ATRACE_CALL();
53     ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
54     if (mDevice != NULL) {
55         ALOGE("%s: Already initialized!", __FUNCTION__);
56         return INVALID_OPERATION;
57     }
58 
59     status_t res;
60     char name[10];
61     snprintf(name, sizeof(name), "%d", mId);
62 
63     camera2_device_t *device;
64 
65     res = module->common.methods->open(&module->common, name,
66             reinterpret_cast<hw_device_t**>(&device));
67 
68     if (res != OK) {
69         ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
70                 mId, strerror(-res), res);
71         return res;
72     }
73 
74     if (device->common.version != CAMERA_DEVICE_API_VERSION_2_0) {
75         ALOGE("%s: Could not open camera %d: "
76                 "Camera device is not version %x, reports %x instead",
77                 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_2_0,
78                 device->common.version);
79         device->common.close(&device->common);
80         return BAD_VALUE;
81     }
82 
83     camera_info info;
84     res = module->get_camera_info(mId, &info);
85     if (res != OK ) return res;
86 
87     if (info.device_version != device->common.version) {
88         ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
89                 " and device version (%x).", __FUNCTION__,
90                 device->common.version, info.device_version);
91         device->common.close(&device->common);
92         return BAD_VALUE;
93     }
94 
95     res = mRequestQueue.setConsumerDevice(device);
96     if (res != OK) {
97         ALOGE("%s: Camera %d: Unable to connect request queue to device: %s (%d)",
98                 __FUNCTION__, mId, strerror(-res), res);
99         device->common.close(&device->common);
100         return res;
101     }
102     res = mFrameQueue.setProducerDevice(device);
103     if (res != OK) {
104         ALOGE("%s: Camera %d: Unable to connect frame queue to device: %s (%d)",
105                 __FUNCTION__, mId, strerror(-res), res);
106         device->common.close(&device->common);
107         return res;
108     }
109 
110     res = device->ops->get_metadata_vendor_tag_ops(device, &mVendorTagOps);
111     if (res != OK ) {
112         ALOGE("%s: Camera %d: Unable to retrieve tag ops from device: %s (%d)",
113                 __FUNCTION__, mId, strerror(-res), res);
114         device->common.close(&device->common);
115         return res;
116     }
117     res = set_camera_metadata_vendor_tag_ops(mVendorTagOps);
118     if (res != OK) {
119         ALOGE("%s: Camera %d: Unable to set tag ops: %s (%d)",
120             __FUNCTION__, mId, strerror(-res), res);
121         device->common.close(&device->common);
122         return res;
123     }
124     res = device->ops->set_notify_callback(device, notificationCallback,
125             NULL);
126     if (res != OK) {
127         ALOGE("%s: Camera %d: Unable to initialize notification callback!",
128                 __FUNCTION__, mId);
129         device->common.close(&device->common);
130         return res;
131     }
132 
133     mDeviceInfo = info.static_camera_characteristics;
134     mDevice = device;
135 
136     return OK;
137 }
138 
disconnect()139 status_t Camera2Device::disconnect() {
140     ATRACE_CALL();
141     status_t res = OK;
142     if (mDevice) {
143         ALOGV("%s: Closing device for camera %d", __FUNCTION__, mId);
144 
145         int inProgressCount = mDevice->ops->get_in_progress_count(mDevice);
146         if (inProgressCount > 0) {
147             ALOGW("%s: Closing camera device %d with %d requests in flight!",
148                     __FUNCTION__, mId, inProgressCount);
149         }
150         mReprocessStreams.clear();
151         mStreams.clear();
152         res = mDevice->common.close(&mDevice->common);
153         if (res != OK) {
154             ALOGE("%s: Could not close camera %d: %s (%d)",
155                     __FUNCTION__,
156                     mId, strerror(-res), res);
157         }
158         mDevice = NULL;
159         ALOGV("%s: Shutdown complete", __FUNCTION__);
160     }
161     return res;
162 }
163 
dump(int fd,const Vector<String16> & args)164 status_t Camera2Device::dump(int fd, const Vector<String16>& args) {
165     ATRACE_CALL();
166     String8 result;
167     int detailLevel = 0;
168     int n = args.size();
169     String16 detailOption("-d");
170     for (int i = 0; i + 1 < n; i++) {
171         if (args[i] == detailOption) {
172             String8 levelStr(args[i+1]);
173             detailLevel = atoi(levelStr.string());
174         }
175     }
176 
177     result.appendFormat("  Camera2Device[%d] dump (detail level %d):\n",
178             mId, detailLevel);
179 
180     if (detailLevel > 0) {
181         result = "    Request queue contents:\n";
182         write(fd, result.string(), result.size());
183         mRequestQueue.dump(fd, args);
184 
185         result = "    Frame queue contents:\n";
186         write(fd, result.string(), result.size());
187         mFrameQueue.dump(fd, args);
188     }
189 
190     result = "    Active streams:\n";
191     write(fd, result.string(), result.size());
192     for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) {
193         (*s)->dump(fd, args);
194     }
195 
196     result = "    HAL device dump:\n";
197     write(fd, result.string(), result.size());
198 
199     status_t res;
200     res = mDevice->ops->dump(mDevice, fd);
201 
202     return res;
203 }
204 
info() const205 const camera2::CameraMetadata& Camera2Device::info() const {
206     ALOGVV("%s: E", __FUNCTION__);
207 
208     return mDeviceInfo;
209 }
210 
capture(CameraMetadata & request)211 status_t Camera2Device::capture(CameraMetadata &request) {
212     ATRACE_CALL();
213     ALOGV("%s: E", __FUNCTION__);
214 
215     mRequestQueue.enqueue(request.release());
216     return OK;
217 }
218 
219 
setStreamingRequest(const CameraMetadata & request)220 status_t Camera2Device::setStreamingRequest(const CameraMetadata &request) {
221     ATRACE_CALL();
222     ALOGV("%s: E", __FUNCTION__);
223     CameraMetadata streamRequest(request);
224     return mRequestQueue.setStreamSlot(streamRequest.release());
225 }
226 
clearStreamingRequest()227 status_t Camera2Device::clearStreamingRequest() {
228     ATRACE_CALL();
229     return mRequestQueue.setStreamSlot(NULL);
230 }
231 
waitUntilRequestReceived(int32_t requestId,nsecs_t timeout)232 status_t Camera2Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
233     ATRACE_CALL();
234     return mRequestQueue.waitForDequeue(requestId, timeout);
235 }
236 
createStream(sp<ANativeWindow> consumer,uint32_t width,uint32_t height,int format,size_t size,int * id)237 status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
238         uint32_t width, uint32_t height, int format, size_t size, int *id) {
239     ATRACE_CALL();
240     status_t res;
241     ALOGV("%s: E", __FUNCTION__);
242 
243     sp<StreamAdapter> stream = new StreamAdapter(mDevice);
244 
245     res = stream->connectToDevice(consumer, width, height, format, size);
246     if (res != OK) {
247         ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
248                 "%s (%d)",
249                 __FUNCTION__, mId, width, height, format, strerror(-res), res);
250         return res;
251     }
252 
253     *id = stream->getId();
254 
255     mStreams.push_back(stream);
256     return OK;
257 }
258 
createReprocessStreamFromStream(int outputId,int * id)259 status_t Camera2Device::createReprocessStreamFromStream(int outputId, int *id) {
260     ATRACE_CALL();
261     status_t res;
262     ALOGV("%s: E", __FUNCTION__);
263 
264     bool found = false;
265     StreamList::iterator streamI;
266     for (streamI = mStreams.begin();
267          streamI != mStreams.end(); streamI++) {
268         if ((*streamI)->getId() == outputId) {
269             found = true;
270             break;
271         }
272     }
273     if (!found) {
274         ALOGE("%s: Camera %d: Output stream %d doesn't exist; can't create "
275                 "reprocess stream from it!", __FUNCTION__, mId, outputId);
276         return BAD_VALUE;
277     }
278 
279     sp<ReprocessStreamAdapter> stream = new ReprocessStreamAdapter(mDevice);
280 
281     res = stream->connectToDevice((*streamI));
282     if (res != OK) {
283         ALOGE("%s: Camera %d: Unable to create reprocessing stream from "\
284                 "stream %d: %s (%d)", __FUNCTION__, mId, outputId,
285                 strerror(-res), res);
286         return res;
287     }
288 
289     *id = stream->getId();
290 
291     mReprocessStreams.push_back(stream);
292     return OK;
293 }
294 
295 
getStreamInfo(int id,uint32_t * width,uint32_t * height,uint32_t * format)296 status_t Camera2Device::getStreamInfo(int id,
297         uint32_t *width, uint32_t *height, uint32_t *format) {
298     ATRACE_CALL();
299     ALOGV("%s: E", __FUNCTION__);
300     bool found = false;
301     StreamList::iterator streamI;
302     for (streamI = mStreams.begin();
303          streamI != mStreams.end(); streamI++) {
304         if ((*streamI)->getId() == id) {
305             found = true;
306             break;
307         }
308     }
309     if (!found) {
310         ALOGE("%s: Camera %d: Stream %d does not exist",
311                 __FUNCTION__, mId, id);
312         return BAD_VALUE;
313     }
314 
315     if (width) *width = (*streamI)->getWidth();
316     if (height) *height = (*streamI)->getHeight();
317     if (format) *format = (*streamI)->getFormat();
318 
319     return OK;
320 }
321 
setStreamTransform(int id,int transform)322 status_t Camera2Device::setStreamTransform(int id,
323         int transform) {
324     ATRACE_CALL();
325     ALOGV("%s: E", __FUNCTION__);
326     bool found = false;
327     StreamList::iterator streamI;
328     for (streamI = mStreams.begin();
329          streamI != mStreams.end(); streamI++) {
330         if ((*streamI)->getId() == id) {
331             found = true;
332             break;
333         }
334     }
335     if (!found) {
336         ALOGE("%s: Camera %d: Stream %d does not exist",
337                 __FUNCTION__, mId, id);
338         return BAD_VALUE;
339     }
340 
341     return (*streamI)->setTransform(transform);
342 }
343 
deleteStream(int id)344 status_t Camera2Device::deleteStream(int id) {
345     ATRACE_CALL();
346     ALOGV("%s: E", __FUNCTION__);
347     bool found = false;
348     for (StreamList::iterator streamI = mStreams.begin();
349          streamI != mStreams.end(); streamI++) {
350         if ((*streamI)->getId() == id) {
351             status_t res = (*streamI)->release();
352             if (res != OK) {
353                 ALOGE("%s: Unable to release stream %d from HAL device: "
354                         "%s (%d)", __FUNCTION__, id, strerror(-res), res);
355                 return res;
356             }
357             mStreams.erase(streamI);
358             found = true;
359             break;
360         }
361     }
362     if (!found) {
363         ALOGE("%s: Camera %d: Unable to find stream %d to delete",
364                 __FUNCTION__, mId, id);
365         return BAD_VALUE;
366     }
367     return OK;
368 }
369 
deleteReprocessStream(int id)370 status_t Camera2Device::deleteReprocessStream(int id) {
371     ATRACE_CALL();
372     ALOGV("%s: E", __FUNCTION__);
373     bool found = false;
374     for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
375          streamI != mReprocessStreams.end(); streamI++) {
376         if ((*streamI)->getId() == id) {
377             status_t res = (*streamI)->release();
378             if (res != OK) {
379                 ALOGE("%s: Unable to release reprocess stream %d from "
380                         "HAL device: %s (%d)", __FUNCTION__, id,
381                         strerror(-res), res);
382                 return res;
383             }
384             mReprocessStreams.erase(streamI);
385             found = true;
386             break;
387         }
388     }
389     if (!found) {
390         ALOGE("%s: Camera %d: Unable to find stream %d to delete",
391                 __FUNCTION__, mId, id);
392         return BAD_VALUE;
393     }
394     return OK;
395 }
396 
397 
createDefaultRequest(int templateId,CameraMetadata * request)398 status_t Camera2Device::createDefaultRequest(int templateId,
399         CameraMetadata *request) {
400     ATRACE_CALL();
401     status_t err;
402     ALOGV("%s: E", __FUNCTION__);
403     camera_metadata_t *rawRequest;
404     err = mDevice->ops->construct_default_request(
405         mDevice, templateId, &rawRequest);
406     request->acquire(rawRequest);
407     return err;
408 }
409 
waitUntilDrained()410 status_t Camera2Device::waitUntilDrained() {
411     ATRACE_CALL();
412     static const uint32_t kSleepTime = 50000; // 50 ms
413     static const uint32_t kMaxSleepTime = 10000000; // 10 s
414     ALOGV("%s: Camera %d: Starting wait", __FUNCTION__, mId);
415     if (mRequestQueue.getBufferCount() ==
416             CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
417 
418     // TODO: Set up notifications from HAL, instead of sleeping here
419     uint32_t totalTime = 0;
420     while (mDevice->ops->get_in_progress_count(mDevice) > 0) {
421         usleep(kSleepTime);
422         totalTime += kSleepTime;
423         if (totalTime > kMaxSleepTime) {
424             ALOGE("%s: Waited %d us, %d requests still in flight", __FUNCTION__,
425                     mDevice->ops->get_in_progress_count(mDevice), totalTime);
426             return TIMED_OUT;
427         }
428     }
429     ALOGV("%s: Camera %d: HAL is idle", __FUNCTION__, mId);
430     return OK;
431 }
432 
setNotifyCallback(NotificationListener * listener)433 status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
434     ATRACE_CALL();
435     status_t res;
436     res = mDevice->ops->set_notify_callback(mDevice, notificationCallback,
437             reinterpret_cast<void*>(listener) );
438     if (res != OK) {
439         ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
440     }
441     return res;
442 }
443 
notificationCallback(int32_t msg_type,int32_t ext1,int32_t ext2,int32_t ext3,void * user)444 void Camera2Device::notificationCallback(int32_t msg_type,
445         int32_t ext1,
446         int32_t ext2,
447         int32_t ext3,
448         void *user) {
449     ATRACE_CALL();
450     NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
451     ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
452             ext1, ext2, ext3);
453     if (listener != NULL) {
454         switch (msg_type) {
455             case CAMERA2_MSG_ERROR:
456                 listener->notifyError(ext1, ext2, ext3);
457                 break;
458             case CAMERA2_MSG_SHUTTER: {
459                 nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
460                 listener->notifyShutter(ext1, timestamp);
461                 break;
462             }
463             case CAMERA2_MSG_AUTOFOCUS:
464                 listener->notifyAutoFocus(ext1, ext2);
465                 break;
466             case CAMERA2_MSG_AUTOEXPOSURE:
467                 listener->notifyAutoExposure(ext1, ext2);
468                 break;
469             case CAMERA2_MSG_AUTOWB:
470                 listener->notifyAutoWhitebalance(ext1, ext2);
471                 break;
472             default:
473                 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
474                         __FUNCTION__, msg_type, ext1, ext2, ext3);
475         }
476     }
477 }
478 
waitForNextFrame(nsecs_t timeout)479 status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
480     return mFrameQueue.waitForBuffer(timeout);
481 }
482 
getNextFrame(CameraMetadata * frame)483 status_t Camera2Device::getNextFrame(CameraMetadata *frame) {
484     ATRACE_CALL();
485     status_t res;
486     camera_metadata_t *rawFrame;
487     res = mFrameQueue.dequeue(&rawFrame);
488     if (rawFrame  == NULL) {
489         return NOT_ENOUGH_DATA;
490     } else if (res == OK) {
491         frame->acquire(rawFrame);
492     }
493     return res;
494 }
495 
triggerAutofocus(uint32_t id)496 status_t Camera2Device::triggerAutofocus(uint32_t id) {
497     ATRACE_CALL();
498     status_t res;
499     ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
500     res = mDevice->ops->trigger_action(mDevice,
501             CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
502     if (res != OK) {
503         ALOGE("%s: Error triggering autofocus (id %d)",
504                 __FUNCTION__, id);
505     }
506     return res;
507 }
508 
triggerCancelAutofocus(uint32_t id)509 status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
510     ATRACE_CALL();
511     status_t res;
512     ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
513     res = mDevice->ops->trigger_action(mDevice,
514             CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
515     if (res != OK) {
516         ALOGE("%s: Error canceling autofocus (id %d)",
517                 __FUNCTION__, id);
518     }
519     return res;
520 }
521 
triggerPrecaptureMetering(uint32_t id)522 status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
523     ATRACE_CALL();
524     status_t res;
525     ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
526     res = mDevice->ops->trigger_action(mDevice,
527             CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
528     if (res != OK) {
529         ALOGE("%s: Error triggering precapture metering (id %d)",
530                 __FUNCTION__, id);
531     }
532     return res;
533 }
534 
pushReprocessBuffer(int reprocessStreamId,buffer_handle_t * buffer,wp<BufferReleasedListener> listener)535 status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId,
536         buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
537     ATRACE_CALL();
538     ALOGV("%s: E", __FUNCTION__);
539     bool found = false;
540     status_t res = OK;
541     for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
542          streamI != mReprocessStreams.end(); streamI++) {
543         if ((*streamI)->getId() == reprocessStreamId) {
544             res = (*streamI)->pushIntoStream(buffer, listener);
545             if (res != OK) {
546                 ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)",
547                         __FUNCTION__, reprocessStreamId, strerror(-res), res);
548                 return res;
549             }
550             found = true;
551             break;
552         }
553     }
554     if (!found) {
555         ALOGE("%s: Camera %d: Unable to find reprocess stream %d",
556                 __FUNCTION__, mId, reprocessStreamId);
557         res = BAD_VALUE;
558     }
559     return res;
560 }
561 
562 /**
563  * Camera2Device::NotificationListener
564  */
565 
~NotificationListener()566 Camera2Device::NotificationListener::~NotificationListener() {
567 }
568 
569 /**
570  * Camera2Device::MetadataQueue
571  */
572 
MetadataQueue()573 Camera2Device::MetadataQueue::MetadataQueue():
574             mDevice(NULL),
575             mFrameCount(0),
576             mLatestRequestId(0),
577             mCount(0),
578             mStreamSlotCount(0),
579             mSignalConsumer(true)
580 {
581     ATRACE_CALL();
582     camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
583     camera2_request_queue_src_ops::request_count = consumer_buffer_count;
584     camera2_request_queue_src_ops::free_request = consumer_free;
585 
586     camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
587     camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
588     camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
589 }
590 
~MetadataQueue()591 Camera2Device::MetadataQueue::~MetadataQueue() {
592     ATRACE_CALL();
593     Mutex::Autolock l(mMutex);
594     freeBuffers(mEntries.begin(), mEntries.end());
595     freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
596 }
597 
598 // Connect to camera2 HAL as consumer (input requests/reprocessing)
setConsumerDevice(camera2_device_t * d)599 status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
600     ATRACE_CALL();
601     status_t res;
602     res = d->ops->set_request_queue_src_ops(d,
603             this);
604     if (res != OK) return res;
605     mDevice = d;
606     return OK;
607 }
608 
setProducerDevice(camera2_device_t * d)609 status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
610     ATRACE_CALL();
611     status_t res;
612     res = d->ops->set_frame_queue_dst_ops(d,
613             this);
614     return res;
615 }
616 
617 // Real interfaces
enqueue(camera_metadata_t * buf)618 status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
619     ATRACE_CALL();
620     ALOGVV("%s: E", __FUNCTION__);
621     Mutex::Autolock l(mMutex);
622 
623     mCount++;
624     mEntries.push_back(buf);
625 
626     return signalConsumerLocked();
627 }
628 
getBufferCount()629 int Camera2Device::MetadataQueue::getBufferCount() {
630     ATRACE_CALL();
631     Mutex::Autolock l(mMutex);
632     if (mStreamSlotCount > 0) {
633         return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
634     }
635     return mCount;
636 }
637 
dequeue(camera_metadata_t ** buf,bool incrementCount)638 status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
639         bool incrementCount)
640 {
641     ATRACE_CALL();
642     ALOGVV("%s: E", __FUNCTION__);
643     status_t res;
644     Mutex::Autolock l(mMutex);
645 
646     if (mCount == 0) {
647         if (mStreamSlotCount == 0) {
648             ALOGVV("%s: Empty", __FUNCTION__);
649             *buf = NULL;
650             mSignalConsumer = true;
651             return OK;
652         }
653         ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
654               mStreamSlotCount);
655 
656         for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
657                 slotEntry != mStreamSlot.end();
658                 slotEntry++ ) {
659             size_t entries = get_camera_metadata_entry_count(*slotEntry);
660             size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
661 
662             camera_metadata_t *copy =
663                     allocate_camera_metadata(entries, dataBytes);
664             append_camera_metadata(copy, *slotEntry);
665             mEntries.push_back(copy);
666         }
667         mCount = mStreamSlotCount;
668     }
669     ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
670     camera_metadata_t *b = *(mEntries.begin());
671     mEntries.erase(mEntries.begin());
672 
673     if (incrementCount) {
674         ATRACE_INT("cam2_request", mFrameCount);
675         camera_metadata_entry_t frameCount;
676         res = find_camera_metadata_entry(b,
677                 ANDROID_REQUEST_FRAME_COUNT,
678                 &frameCount);
679         if (res != OK) {
680             ALOGE("%s: Unable to add frame count: %s (%d)",
681                     __FUNCTION__, strerror(-res), res);
682         } else {
683             *frameCount.data.i32 = mFrameCount;
684         }
685         mFrameCount++;
686     }
687 
688     // Check for request ID, and if present, signal waiters.
689     camera_metadata_entry_t requestId;
690     res = find_camera_metadata_entry(b,
691             ANDROID_REQUEST_ID,
692             &requestId);
693     if (res == OK) {
694         mLatestRequestId = requestId.data.i32[0];
695         mNewRequestId.signal();
696     }
697 
698     *buf = b;
699     mCount--;
700 
701     return OK;
702 }
703 
waitForBuffer(nsecs_t timeout)704 status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
705 {
706     Mutex::Autolock l(mMutex);
707     status_t res;
708     while (mCount == 0) {
709         res = notEmpty.waitRelative(mMutex,timeout);
710         if (res != OK) return res;
711     }
712     return OK;
713 }
714 
waitForDequeue(int32_t id,nsecs_t timeout)715 status_t Camera2Device::MetadataQueue::waitForDequeue(int32_t id,
716         nsecs_t timeout) {
717     Mutex::Autolock l(mMutex);
718     status_t res;
719     while (mLatestRequestId != id) {
720         nsecs_t startTime = systemTime();
721 
722         res = mNewRequestId.waitRelative(mMutex, timeout);
723         if (res != OK) return res;
724 
725         timeout -= (systemTime() - startTime);
726     }
727 
728     return OK;
729 }
730 
setStreamSlot(camera_metadata_t * buf)731 status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
732 {
733     ATRACE_CALL();
734     ALOGV("%s: E", __FUNCTION__);
735     Mutex::Autolock l(mMutex);
736     if (buf == NULL) {
737         freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
738         mStreamSlotCount = 0;
739         return OK;
740     }
741     camera_metadata_t *buf2 = clone_camera_metadata(buf);
742     if (!buf2) {
743         ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
744         return NO_MEMORY;
745     }
746 
747     if (mStreamSlotCount > 1) {
748         List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
749         freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
750         mStreamSlotCount = 1;
751     }
752     if (mStreamSlotCount == 1) {
753         free_camera_metadata( *(mStreamSlot.begin()) );
754         *(mStreamSlot.begin()) = buf2;
755     } else {
756         mStreamSlot.push_front(buf2);
757         mStreamSlotCount = 1;
758     }
759     return signalConsumerLocked();
760 }
761 
setStreamSlot(const List<camera_metadata_t * > & bufs)762 status_t Camera2Device::MetadataQueue::setStreamSlot(
763         const List<camera_metadata_t*> &bufs)
764 {
765     ATRACE_CALL();
766     ALOGV("%s: E", __FUNCTION__);
767     Mutex::Autolock l(mMutex);
768     status_t res;
769 
770     if (mStreamSlotCount > 0) {
771         freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
772     }
773     mStreamSlotCount = 0;
774     for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
775          r != bufs.end(); r++) {
776         camera_metadata_t *r2 = clone_camera_metadata(*r);
777         if (!r2) {
778             ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
779             return NO_MEMORY;
780         }
781         mStreamSlot.push_back(r2);
782         mStreamSlotCount++;
783     }
784     return signalConsumerLocked();
785 }
786 
dump(int fd,const Vector<String16> & args)787 status_t Camera2Device::MetadataQueue::dump(int fd,
788         const Vector<String16>& args) {
789     ATRACE_CALL();
790     String8 result;
791     status_t notLocked;
792     notLocked = mMutex.tryLock();
793     if (notLocked) {
794         result.append("    (Unable to lock queue mutex)\n");
795     }
796     result.appendFormat("      Current frame number: %d\n", mFrameCount);
797     if (mStreamSlotCount == 0) {
798         result.append("      Stream slot: Empty\n");
799         write(fd, result.string(), result.size());
800     } else {
801         result.appendFormat("      Stream slot: %d entries\n",
802                 mStreamSlot.size());
803         int i = 0;
804         for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
805              r != mStreamSlot.end(); r++) {
806             result = String8::format("       Stream slot buffer %d:\n", i);
807             write(fd, result.string(), result.size());
808             dump_indented_camera_metadata(*r, fd, 2, 10);
809             i++;
810         }
811     }
812     if (mEntries.size() == 0) {
813         result = "      Main queue is empty\n";
814         write(fd, result.string(), result.size());
815     } else {
816         result = String8::format("      Main queue has %d entries:\n",
817                 mEntries.size());
818         int i = 0;
819         for (List<camera_metadata_t*>::iterator r = mEntries.begin();
820              r != mEntries.end(); r++) {
821             result = String8::format("       Queue entry %d:\n", i);
822             write(fd, result.string(), result.size());
823             dump_indented_camera_metadata(*r, fd, 2, 10);
824             i++;
825         }
826     }
827 
828     if (notLocked == 0) {
829         mMutex.unlock();
830     }
831 
832     return OK;
833 }
834 
signalConsumerLocked()835 status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
836     ATRACE_CALL();
837     status_t res = OK;
838     notEmpty.signal();
839     if (mSignalConsumer && mDevice != NULL) {
840         mSignalConsumer = false;
841 
842         mMutex.unlock();
843         ALOGV("%s: Signaling consumer", __FUNCTION__);
844         res = mDevice->ops->notify_request_queue_not_empty(mDevice);
845         mMutex.lock();
846     }
847     return res;
848 }
849 
freeBuffers(List<camera_metadata_t * >::iterator start,List<camera_metadata_t * >::iterator end)850 status_t Camera2Device::MetadataQueue::freeBuffers(
851         List<camera_metadata_t*>::iterator start,
852         List<camera_metadata_t*>::iterator end)
853 {
854     ATRACE_CALL();
855     while (start != end) {
856         free_camera_metadata(*start);
857         start = mStreamSlot.erase(start);
858     }
859     return OK;
860 }
861 
getInstance(const camera2_request_queue_src_ops_t * q)862 Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
863         const camera2_request_queue_src_ops_t *q)
864 {
865     const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
866     return const_cast<MetadataQueue*>(cmq);
867 }
868 
getInstance(const camera2_frame_queue_dst_ops_t * q)869 Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
870         const camera2_frame_queue_dst_ops_t *q)
871 {
872     const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
873     return const_cast<MetadataQueue*>(cmq);
874 }
875 
consumer_buffer_count(const camera2_request_queue_src_ops_t * q)876 int Camera2Device::MetadataQueue::consumer_buffer_count(
877         const camera2_request_queue_src_ops_t *q)
878 {
879     MetadataQueue *queue = getInstance(q);
880     return queue->getBufferCount();
881 }
882 
consumer_dequeue(const camera2_request_queue_src_ops_t * q,camera_metadata_t ** buffer)883 int Camera2Device::MetadataQueue::consumer_dequeue(
884         const camera2_request_queue_src_ops_t *q,
885         camera_metadata_t **buffer)
886 {
887     MetadataQueue *queue = getInstance(q);
888     return queue->dequeue(buffer, true);
889 }
890 
consumer_free(const camera2_request_queue_src_ops_t * q,camera_metadata_t * old_buffer)891 int Camera2Device::MetadataQueue::consumer_free(
892         const camera2_request_queue_src_ops_t *q,
893         camera_metadata_t *old_buffer)
894 {
895     ATRACE_CALL();
896     MetadataQueue *queue = getInstance(q);
897     free_camera_metadata(old_buffer);
898     return OK;
899 }
900 
producer_dequeue(const camera2_frame_queue_dst_ops_t * q,size_t entries,size_t bytes,camera_metadata_t ** buffer)901 int Camera2Device::MetadataQueue::producer_dequeue(
902         const camera2_frame_queue_dst_ops_t *q,
903         size_t entries, size_t bytes,
904         camera_metadata_t **buffer)
905 {
906     ATRACE_CALL();
907     camera_metadata_t *new_buffer =
908             allocate_camera_metadata(entries, bytes);
909     if (new_buffer == NULL) return NO_MEMORY;
910     *buffer = new_buffer;
911         return OK;
912 }
913 
producer_cancel(const camera2_frame_queue_dst_ops_t * q,camera_metadata_t * old_buffer)914 int Camera2Device::MetadataQueue::producer_cancel(
915         const camera2_frame_queue_dst_ops_t *q,
916         camera_metadata_t *old_buffer)
917 {
918     ATRACE_CALL();
919     free_camera_metadata(old_buffer);
920     return OK;
921 }
922 
producer_enqueue(const camera2_frame_queue_dst_ops_t * q,camera_metadata_t * filled_buffer)923 int Camera2Device::MetadataQueue::producer_enqueue(
924         const camera2_frame_queue_dst_ops_t *q,
925         camera_metadata_t *filled_buffer)
926 {
927     MetadataQueue *queue = getInstance(q);
928     return queue->enqueue(filled_buffer);
929 }
930 
931 /**
932  * Camera2Device::StreamAdapter
933  */
934 
935 #ifndef container_of
936 #define container_of(ptr, type, member) \
937     (type *)((char*)(ptr) - offsetof(type, member))
938 #endif
939 
StreamAdapter(camera2_device_t * d)940 Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
941         mState(RELEASED),
942         mDevice(d),
943         mId(-1),
944         mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
945         mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
946         mTotalBuffers(0),
947         mFormatRequested(0),
948         mActiveBuffers(0),
949         mFrameCount(0),
950         mLastTimestamp(0)
951 {
952     camera2_stream_ops::dequeue_buffer = dequeue_buffer;
953     camera2_stream_ops::enqueue_buffer = enqueue_buffer;
954     camera2_stream_ops::cancel_buffer = cancel_buffer;
955     camera2_stream_ops::set_crop = set_crop;
956 }
957 
~StreamAdapter()958 Camera2Device::StreamAdapter::~StreamAdapter() {
959     ATRACE_CALL();
960     if (mState != RELEASED) {
961         release();
962     }
963 }
964 
connectToDevice(sp<ANativeWindow> consumer,uint32_t width,uint32_t height,int format,size_t size)965 status_t Camera2Device::StreamAdapter::connectToDevice(
966         sp<ANativeWindow> consumer,
967         uint32_t width, uint32_t height, int format, size_t size) {
968     ATRACE_CALL();
969     status_t res;
970     ALOGV("%s: E", __FUNCTION__);
971 
972     if (mState != RELEASED) return INVALID_OPERATION;
973     if (consumer == NULL) {
974         ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
975         return BAD_VALUE;
976     }
977 
978     ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d",
979             __FUNCTION__, width, height, format, size);
980 
981     mConsumerInterface = consumer;
982     mWidth = width;
983     mHeight = height;
984     mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
985     mFormatRequested = format;
986 
987     // Allocate device-side stream interface
988 
989     uint32_t id;
990     uint32_t formatActual;
991     uint32_t usage;
992     uint32_t maxBuffers = 2;
993     res = mDevice->ops->allocate_stream(mDevice,
994             mWidth, mHeight, mFormatRequested, getStreamOps(),
995             &id, &formatActual, &usage, &maxBuffers);
996     if (res != OK) {
997         ALOGE("%s: Device stream allocation failed: %s (%d)",
998                 __FUNCTION__, strerror(-res), res);
999         return res;
1000     }
1001 
1002     ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
1003             "usage 0x%x, producer wants %d buffers", __FUNCTION__,
1004             id, formatActual, usage, maxBuffers);
1005 
1006     mId = id;
1007     mFormat = formatActual;
1008     mUsage = usage;
1009     mMaxProducerBuffers = maxBuffers;
1010 
1011     mState = ALLOCATED;
1012 
1013     // Configure consumer-side ANativeWindow interface
1014     res = native_window_api_connect(mConsumerInterface.get(),
1015             NATIVE_WINDOW_API_CAMERA);
1016     if (res != OK) {
1017         ALOGE("%s: Unable to connect to native window for stream %d",
1018                 __FUNCTION__, mId);
1019 
1020         return res;
1021     }
1022 
1023     mState = CONNECTED;
1024 
1025     res = native_window_set_usage(mConsumerInterface.get(), mUsage);
1026     if (res != OK) {
1027         ALOGE("%s: Unable to configure usage %08x for stream %d",
1028                 __FUNCTION__, mUsage, mId);
1029         return res;
1030     }
1031 
1032     res = native_window_set_scaling_mode(mConsumerInterface.get(),
1033             NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
1034     if (res != OK) {
1035         ALOGE("%s: Unable to configure stream scaling: %s (%d)",
1036                 __FUNCTION__, strerror(-res), res);
1037         return res;
1038     }
1039 
1040     res = setTransform(0);
1041     if (res != OK) {
1042         return res;
1043     }
1044 
1045     if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
1046         res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1047                 mSize, 1, mFormat);
1048         if (res != OK) {
1049             ALOGE("%s: Unable to configure compressed stream buffer geometry"
1050                     " %d x %d, size %d for stream %d",
1051                     __FUNCTION__, mWidth, mHeight, mSize, mId);
1052             return res;
1053         }
1054     } else {
1055         res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1056                 mWidth, mHeight, mFormat);
1057         if (res != OK) {
1058             ALOGE("%s: Unable to configure stream buffer geometry"
1059                     " %d x %d, format 0x%x for stream %d",
1060                     __FUNCTION__, mWidth, mHeight, mFormat, mId);
1061             return res;
1062         }
1063     }
1064 
1065     int maxConsumerBuffers;
1066     res = mConsumerInterface->query(mConsumerInterface.get(),
1067             NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
1068     if (res != OK) {
1069         ALOGE("%s: Unable to query consumer undequeued"
1070                 " buffer count for stream %d", __FUNCTION__, mId);
1071         return res;
1072     }
1073     mMaxConsumerBuffers = maxConsumerBuffers;
1074 
1075     ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
1076             mMaxConsumerBuffers);
1077 
1078     mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
1079     mActiveBuffers = 0;
1080     mFrameCount = 0;
1081     mLastTimestamp = 0;
1082 
1083     res = native_window_set_buffer_count(mConsumerInterface.get(),
1084             mTotalBuffers);
1085     if (res != OK) {
1086         ALOGE("%s: Unable to set buffer count for stream %d",
1087                 __FUNCTION__, mId);
1088         return res;
1089     }
1090 
1091     // Register allocated buffers with HAL device
1092     buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
1093     ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
1094     uint32_t bufferIdx = 0;
1095     for (; bufferIdx < mTotalBuffers; bufferIdx++) {
1096         res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
1097                 &anwBuffers[bufferIdx]);
1098         if (res != OK) {
1099             ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
1100                     "stream %d", __FUNCTION__, bufferIdx, mId);
1101             goto cleanUpBuffers;
1102         }
1103 
1104         buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
1105         ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]);
1106     }
1107 
1108     ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
1109     res = mDevice->ops->register_stream_buffers(mDevice,
1110             mId,
1111             mTotalBuffers,
1112             buffers);
1113     if (res != OK) {
1114         ALOGE("%s: Unable to register buffers with HAL device for stream %d",
1115                 __FUNCTION__, mId);
1116     } else {
1117         mState = ACTIVE;
1118     }
1119 
1120 cleanUpBuffers:
1121     ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
1122     for (uint32_t i = 0; i < bufferIdx; i++) {
1123         res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
1124                 anwBuffers[i], -1);
1125         if (res != OK) {
1126             ALOGE("%s: Unable to cancel buffer %d after registration",
1127                     __FUNCTION__, i);
1128         }
1129     }
1130     delete[] anwBuffers;
1131     delete[] buffers;
1132 
1133     return res;
1134 }
1135 
release()1136 status_t Camera2Device::StreamAdapter::release() {
1137     ATRACE_CALL();
1138     status_t res;
1139     ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
1140     if (mState >= ALLOCATED) {
1141         res = mDevice->ops->release_stream(mDevice, mId);
1142         if (res != OK) {
1143             ALOGE("%s: Unable to release stream %d",
1144                     __FUNCTION__, mId);
1145             return res;
1146         }
1147     }
1148     if (mState >= CONNECTED) {
1149         res = native_window_api_disconnect(mConsumerInterface.get(),
1150                 NATIVE_WINDOW_API_CAMERA);
1151 
1152         /* this is not an error. if client calling process dies,
1153            the window will also die and all calls to it will return
1154            DEAD_OBJECT, thus it's already "disconnected" */
1155         if (res == DEAD_OBJECT) {
1156             ALOGW("%s: While disconnecting stream %d from native window, the"
1157                   " native window died from under us", __FUNCTION__, mId);
1158         }
1159         else if (res != OK) {
1160             ALOGE("%s: Unable to disconnect stream %d from native window (error %d %s)",
1161                     __FUNCTION__, mId, res, strerror(-res));
1162             return res;
1163         }
1164     }
1165     mId = -1;
1166     mState = RELEASED;
1167     return OK;
1168 }
1169 
setTransform(int transform)1170 status_t Camera2Device::StreamAdapter::setTransform(int transform) {
1171     ATRACE_CALL();
1172     status_t res;
1173     if (mState < CONNECTED) {
1174         ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
1175         return INVALID_OPERATION;
1176     }
1177     res = native_window_set_buffers_transform(mConsumerInterface.get(),
1178                                               transform);
1179     if (res != OK) {
1180         ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
1181                 __FUNCTION__, transform, strerror(-res), res);
1182     }
1183     return res;
1184 }
1185 
dump(int fd,const Vector<String16> & args)1186 status_t Camera2Device::StreamAdapter::dump(int fd,
1187         const Vector<String16>& args) {
1188     ATRACE_CALL();
1189     String8 result = String8::format("      Stream %d: %d x %d, format 0x%x\n",
1190             mId, mWidth, mHeight, mFormat);
1191     result.appendFormat("        size %d, usage 0x%x, requested format 0x%x\n",
1192             mSize, mUsage, mFormatRequested);
1193     result.appendFormat("        total buffers: %d, dequeued buffers: %d\n",
1194             mTotalBuffers, mActiveBuffers);
1195     result.appendFormat("        frame count: %d, last timestamp %lld\n",
1196             mFrameCount, mLastTimestamp);
1197     write(fd, result.string(), result.size());
1198     return OK;
1199 }
1200 
getStreamOps()1201 const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
1202     return static_cast<camera2_stream_ops *>(this);
1203 }
1204 
toANW(const camera2_stream_ops_t * w)1205 ANativeWindow* Camera2Device::StreamAdapter::toANW(
1206         const camera2_stream_ops_t *w) {
1207     return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
1208 }
1209 
dequeue_buffer(const camera2_stream_ops_t * w,buffer_handle_t ** buffer)1210 int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1211         buffer_handle_t** buffer) {
1212     ATRACE_CALL();
1213     int res;
1214     StreamAdapter* stream =
1215             const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1216     if (stream->mState != ACTIVE) {
1217         ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1218         return INVALID_OPERATION;
1219     }
1220 
1221     ANativeWindow *a = toANW(w);
1222     ANativeWindowBuffer* anb;
1223     res = native_window_dequeue_buffer_and_wait(a, &anb);
1224     if (res != OK) {
1225         ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1226                 strerror(-res), res);
1227         return res;
1228     }
1229 
1230     *buffer = &(anb->handle);
1231     stream->mActiveBuffers++;
1232 
1233     ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
1234     return res;
1235 }
1236 
enqueue_buffer(const camera2_stream_ops_t * w,int64_t timestamp,buffer_handle_t * buffer)1237 int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1238         int64_t timestamp,
1239         buffer_handle_t* buffer) {
1240     ATRACE_CALL();
1241     StreamAdapter *stream =
1242             const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1243     stream->mFrameCount++;
1244     ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
1245             stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp);
1246     int state = stream->mState;
1247     if (state != ACTIVE) {
1248         ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1249         return INVALID_OPERATION;
1250     }
1251     ANativeWindow *a = toANW(w);
1252     status_t err;
1253 
1254     err = native_window_set_buffers_timestamp(a, timestamp);
1255     if (err != OK) {
1256         ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1257                 __FUNCTION__, strerror(-err), err);
1258         return err;
1259     }
1260     err = a->queueBuffer(a,
1261             container_of(buffer, ANativeWindowBuffer, handle), -1);
1262     if (err != OK) {
1263         ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1264                 __FUNCTION__, strerror(-err), err);
1265         return err;
1266     }
1267 
1268     stream->mActiveBuffers--;
1269     stream->mLastTimestamp = timestamp;
1270     return OK;
1271 }
1272 
cancel_buffer(const camera2_stream_ops_t * w,buffer_handle_t * buffer)1273 int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1274         buffer_handle_t* buffer) {
1275     ATRACE_CALL();
1276     StreamAdapter *stream =
1277             const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1278     ALOGVV("Stream %d cancel: Buffer %p",
1279             stream->mId, (void*)(*buffer));
1280     if (stream->mState != ACTIVE) {
1281         ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1282         return INVALID_OPERATION;
1283     }
1284 
1285     ANativeWindow *a = toANW(w);
1286     int err = a->cancelBuffer(a,
1287             container_of(buffer, ANativeWindowBuffer, handle), -1);
1288     if (err != OK) {
1289         ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1290                 __FUNCTION__, strerror(-err), err);
1291         return err;
1292     }
1293 
1294     stream->mActiveBuffers--;
1295     return OK;
1296 }
1297 
set_crop(const camera2_stream_ops_t * w,int left,int top,int right,int bottom)1298 int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1299         int left, int top, int right, int bottom) {
1300     ATRACE_CALL();
1301     int state = static_cast<const StreamAdapter*>(w)->mState;
1302     if (state != ACTIVE) {
1303         ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1304         return INVALID_OPERATION;
1305     }
1306     ANativeWindow *a = toANW(w);
1307     android_native_rect_t crop = { left, top, right, bottom };
1308     return native_window_set_crop(a, &crop);
1309 }
1310 
1311 /**
1312  * Camera2Device::ReprocessStreamAdapter
1313  */
1314 
1315 #ifndef container_of
1316 #define container_of(ptr, type, member) \
1317     (type *)((char*)(ptr) - offsetof(type, member))
1318 #endif
1319 
ReprocessStreamAdapter(camera2_device_t * d)1320 Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d):
1321         mState(RELEASED),
1322         mDevice(d),
1323         mId(-1),
1324         mWidth(0), mHeight(0), mFormat(0),
1325         mActiveBuffers(0),
1326         mFrameCount(0)
1327 {
1328     ATRACE_CALL();
1329     camera2_stream_in_ops::acquire_buffer = acquire_buffer;
1330     camera2_stream_in_ops::release_buffer = release_buffer;
1331 }
1332 
~ReprocessStreamAdapter()1333 Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() {
1334     ATRACE_CALL();
1335     if (mState != RELEASED) {
1336         release();
1337     }
1338 }
1339 
connectToDevice(const sp<StreamAdapter> & outputStream)1340 status_t Camera2Device::ReprocessStreamAdapter::connectToDevice(
1341         const sp<StreamAdapter> &outputStream) {
1342     ATRACE_CALL();
1343     status_t res;
1344     ALOGV("%s: E", __FUNCTION__);
1345 
1346     if (mState != RELEASED) return INVALID_OPERATION;
1347     if (outputStream == NULL) {
1348         ALOGE("%s: Null base stream passed to reprocess stream adapter",
1349                 __FUNCTION__);
1350         return BAD_VALUE;
1351     }
1352 
1353     mBaseStream = outputStream;
1354     mWidth = outputStream->getWidth();
1355     mHeight = outputStream->getHeight();
1356     mFormat = outputStream->getFormat();
1357 
1358     ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x",
1359             __FUNCTION__, mWidth, mHeight, mFormat);
1360 
1361     // Allocate device-side stream interface
1362 
1363     uint32_t id;
1364     res = mDevice->ops->allocate_reprocess_stream_from_stream(mDevice,
1365             outputStream->getId(), getStreamOps(),
1366             &id);
1367     if (res != OK) {
1368         ALOGE("%s: Device reprocess stream allocation failed: %s (%d)",
1369                 __FUNCTION__, strerror(-res), res);
1370         return res;
1371     }
1372 
1373     ALOGV("%s: Allocated reprocess stream id %d based on stream %d",
1374             __FUNCTION__, id, outputStream->getId());
1375 
1376     mId = id;
1377 
1378     mState = ACTIVE;
1379 
1380     return OK;
1381 }
1382 
release()1383 status_t Camera2Device::ReprocessStreamAdapter::release() {
1384     ATRACE_CALL();
1385     status_t res;
1386     ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
1387     if (mState >= ACTIVE) {
1388         res = mDevice->ops->release_reprocess_stream(mDevice, mId);
1389         if (res != OK) {
1390             ALOGE("%s: Unable to release stream %d",
1391                     __FUNCTION__, mId);
1392             return res;
1393         }
1394     }
1395 
1396     List<QueueEntry>::iterator s;
1397     for (s = mQueue.begin(); s != mQueue.end(); s++) {
1398         sp<BufferReleasedListener> listener = s->releaseListener.promote();
1399         if (listener != 0) listener->onBufferReleased(s->handle);
1400     }
1401     for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) {
1402         sp<BufferReleasedListener> listener = s->releaseListener.promote();
1403         if (listener != 0) listener->onBufferReleased(s->handle);
1404     }
1405     mQueue.clear();
1406     mInFlightQueue.clear();
1407 
1408     mState = RELEASED;
1409     return OK;
1410 }
1411 
pushIntoStream(buffer_handle_t * handle,const wp<BufferReleasedListener> & releaseListener)1412 status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream(
1413     buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) {
1414     ATRACE_CALL();
1415     // TODO: Some error checking here would be nice
1416     ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle));
1417 
1418     QueueEntry entry;
1419     entry.handle = handle;
1420     entry.releaseListener = releaseListener;
1421     mQueue.push_back(entry);
1422     return OK;
1423 }
1424 
dump(int fd,const Vector<String16> & args)1425 status_t Camera2Device::ReprocessStreamAdapter::dump(int fd,
1426         const Vector<String16>& args) {
1427     ATRACE_CALL();
1428     String8 result =
1429             String8::format("      Reprocess stream %d: %d x %d, fmt 0x%x\n",
1430                     mId, mWidth, mHeight, mFormat);
1431     result.appendFormat("        acquired buffers: %d\n",
1432             mActiveBuffers);
1433     result.appendFormat("        frame count: %d\n",
1434             mFrameCount);
1435     write(fd, result.string(), result.size());
1436     return OK;
1437 }
1438 
getStreamOps()1439 const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() {
1440     return static_cast<camera2_stream_in_ops *>(this);
1441 }
1442 
acquire_buffer(const camera2_stream_in_ops_t * w,buffer_handle_t ** buffer)1443 int Camera2Device::ReprocessStreamAdapter::acquire_buffer(
1444     const camera2_stream_in_ops_t *w,
1445         buffer_handle_t** buffer) {
1446     ATRACE_CALL();
1447     int res;
1448     ReprocessStreamAdapter* stream =
1449             const_cast<ReprocessStreamAdapter*>(
1450                 static_cast<const ReprocessStreamAdapter*>(w));
1451     if (stream->mState != ACTIVE) {
1452         ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1453         return INVALID_OPERATION;
1454     }
1455 
1456     if (stream->mQueue.empty()) {
1457         *buffer = NULL;
1458         return OK;
1459     }
1460 
1461     QueueEntry &entry = *(stream->mQueue.begin());
1462 
1463     *buffer = entry.handle;
1464 
1465     stream->mInFlightQueue.push_back(entry);
1466     stream->mQueue.erase(stream->mQueue.begin());
1467 
1468     stream->mActiveBuffers++;
1469 
1470     ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId,
1471             (void*)(**buffer));
1472     return OK;
1473 }
1474 
release_buffer(const camera2_stream_in_ops_t * w,buffer_handle_t * buffer)1475 int Camera2Device::ReprocessStreamAdapter::release_buffer(
1476     const camera2_stream_in_ops_t* w,
1477     buffer_handle_t* buffer) {
1478     ATRACE_CALL();
1479     ReprocessStreamAdapter *stream =
1480             const_cast<ReprocessStreamAdapter*>(
1481                 static_cast<const ReprocessStreamAdapter*>(w) );
1482     stream->mFrameCount++;
1483     ALOGV("Reprocess stream %d release: Frame %d (%p)",
1484             stream->mId, stream->mFrameCount, (void*)*buffer);
1485     int state = stream->mState;
1486     if (state != ACTIVE) {
1487         ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1488         return INVALID_OPERATION;
1489     }
1490     stream->mActiveBuffers--;
1491 
1492     List<QueueEntry>::iterator s;
1493     for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) {
1494         if ( s->handle == buffer ) break;
1495     }
1496     if (s == stream->mInFlightQueue.end()) {
1497         ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__,
1498                 buffer);
1499         return INVALID_OPERATION;
1500     }
1501 
1502     sp<BufferReleasedListener> listener = s->releaseListener.promote();
1503     if (listener != 0) {
1504         listener->onBufferReleased(s->handle);
1505     } else {
1506         ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__);
1507     }
1508     stream->mInFlightQueue.erase(s);
1509 
1510     return OK;
1511 }
1512 
1513 }; // namespace android
1514