• 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 
21 #include <utils/Log.h>
22 #include <utils/Trace.h>
23 #include <gui/Surface.h>
24 #include <media/hardware/MetadataBufferType.h>
25 
26 #include "StreamingProcessor.h"
27 #include "Camera2Heap.h"
28 #include "../Camera2Client.h"
29 #include "../CameraDeviceBase.h"
30 
31 namespace android {
32 namespace camera2 {
33 
StreamingProcessor(sp<Camera2Client> client)34 StreamingProcessor::StreamingProcessor(sp<Camera2Client> client):
35         mClient(client),
36         mDevice(client->getCameraDevice()),
37         mId(client->getCameraId()),
38         mActiveRequest(NONE),
39         mPaused(false),
40         mPreviewRequestId(Camera2Client::kPreviewRequestIdStart),
41         mPreviewStreamId(NO_STREAM),
42         mRecordingRequestId(Camera2Client::kRecordingRequestIdStart),
43         mRecordingStreamId(NO_STREAM),
44         mRecordingFrameAvailable(false),
45         mRecordingHeapCount(kDefaultRecordingHeapCount)
46 {
47 }
48 
~StreamingProcessor()49 StreamingProcessor::~StreamingProcessor() {
50     deletePreviewStream();
51     deleteRecordingStream();
52 }
53 
setPreviewWindow(sp<ANativeWindow> window)54 status_t StreamingProcessor::setPreviewWindow(sp<ANativeWindow> window) {
55     ATRACE_CALL();
56     status_t res;
57 
58     res = deletePreviewStream();
59     if (res != OK) return res;
60 
61     Mutex::Autolock m(mMutex);
62 
63     mPreviewWindow = window;
64 
65     return OK;
66 }
67 
haveValidPreviewWindow() const68 bool StreamingProcessor::haveValidPreviewWindow() const {
69     Mutex::Autolock m(mMutex);
70     return mPreviewWindow != 0;
71 }
72 
updatePreviewRequest(const Parameters & params)73 status_t StreamingProcessor::updatePreviewRequest(const Parameters &params) {
74     ATRACE_CALL();
75     status_t res;
76     sp<CameraDeviceBase> device = mDevice.promote();
77     if (device == 0) {
78         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
79         return INVALID_OPERATION;
80     }
81 
82     Mutex::Autolock m(mMutex);
83     if (mPreviewRequest.entryCount() == 0) {
84         res = device->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
85                 &mPreviewRequest);
86         if (res != OK) {
87             ALOGE("%s: Camera %d: Unable to create default preview request: "
88                     "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
89             return res;
90         }
91     }
92 
93     res = params.updateRequest(&mPreviewRequest);
94     if (res != OK) {
95         ALOGE("%s: Camera %d: Unable to update common entries of preview "
96                 "request: %s (%d)", __FUNCTION__, mId,
97                 strerror(-res), res);
98         return res;
99     }
100 
101     res = mPreviewRequest.update(ANDROID_REQUEST_ID,
102             &mPreviewRequestId, 1);
103     if (res != OK) {
104         ALOGE("%s: Camera %d: Unable to update request id for preview: %s (%d)",
105                 __FUNCTION__, mId, strerror(-res), res);
106         return res;
107     }
108 
109     return OK;
110 }
111 
updatePreviewStream(const Parameters & params)112 status_t StreamingProcessor::updatePreviewStream(const Parameters &params) {
113     ATRACE_CALL();
114     Mutex::Autolock m(mMutex);
115 
116     status_t res;
117     sp<CameraDeviceBase> device = mDevice.promote();
118     if (device == 0) {
119         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
120         return INVALID_OPERATION;
121     }
122 
123     if (mPreviewStreamId != NO_STREAM) {
124         // Check if stream parameters have to change
125         uint32_t currentWidth, currentHeight;
126         res = device->getStreamInfo(mPreviewStreamId,
127                 &currentWidth, &currentHeight, 0);
128         if (res != OK) {
129             ALOGE("%s: Camera %d: Error querying preview stream info: "
130                     "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
131             return res;
132         }
133         if (currentWidth != (uint32_t)params.previewWidth ||
134                 currentHeight != (uint32_t)params.previewHeight) {
135             ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
136                     __FUNCTION__, mId, currentWidth, currentHeight,
137                     params.previewWidth, params.previewHeight);
138             res = device->waitUntilDrained();
139             if (res != OK) {
140                 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
141                         "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
142                 return res;
143             }
144             res = device->deleteStream(mPreviewStreamId);
145             if (res != OK) {
146                 ALOGE("%s: Camera %d: Unable to delete old output stream "
147                         "for preview: %s (%d)", __FUNCTION__, mId,
148                         strerror(-res), res);
149                 return res;
150             }
151             mPreviewStreamId = NO_STREAM;
152         }
153     }
154 
155     if (mPreviewStreamId == NO_STREAM) {
156         res = device->createStream(mPreviewWindow,
157                 params.previewWidth, params.previewHeight,
158                 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
159                 &mPreviewStreamId);
160         if (res != OK) {
161             ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
162                     __FUNCTION__, mId, strerror(-res), res);
163             return res;
164         }
165     }
166 
167     res = device->setStreamTransform(mPreviewStreamId,
168             params.previewTransform);
169     if (res != OK) {
170         ALOGE("%s: Camera %d: Unable to set preview stream transform: "
171                 "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
172         return res;
173     }
174 
175     return OK;
176 }
177 
deletePreviewStream()178 status_t StreamingProcessor::deletePreviewStream() {
179     ATRACE_CALL();
180     status_t res;
181 
182     Mutex::Autolock m(mMutex);
183 
184     if (mPreviewStreamId != NO_STREAM) {
185         sp<CameraDeviceBase> device = mDevice.promote();
186         if (device == 0) {
187             ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
188             return INVALID_OPERATION;
189         }
190 
191         ALOGV("%s: for cameraId %d on streamId %d",
192             __FUNCTION__, mId, mPreviewStreamId);
193 
194         res = device->waitUntilDrained();
195         if (res != OK) {
196             ALOGE("%s: Error waiting for preview to drain: %s (%d)",
197                     __FUNCTION__, strerror(-res), res);
198             return res;
199         }
200         res = device->deleteStream(mPreviewStreamId);
201         if (res != OK) {
202             ALOGE("%s: Unable to delete old preview stream: %s (%d)",
203                     __FUNCTION__, strerror(-res), res);
204             return res;
205         }
206         mPreviewStreamId = NO_STREAM;
207     }
208     return OK;
209 }
210 
getPreviewStreamId() const211 int StreamingProcessor::getPreviewStreamId() const {
212     Mutex::Autolock m(mMutex);
213     return mPreviewStreamId;
214 }
215 
setRecordingBufferCount(size_t count)216 status_t StreamingProcessor::setRecordingBufferCount(size_t count) {
217     ATRACE_CALL();
218     // 32 is the current upper limit on the video buffer count for BufferQueue
219     if (count > 32) {
220         ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
221                 __FUNCTION__, mId, count);
222         return BAD_VALUE;
223     }
224 
225     Mutex::Autolock m(mMutex);
226 
227     // Need to reallocate memory for heap
228     if (mRecordingHeapCount != count) {
229         if  (mRecordingHeap != 0) {
230             mRecordingHeap.clear();
231             mRecordingHeap = NULL;
232         }
233         mRecordingHeapCount = count;
234     }
235 
236     return OK;
237 }
238 
updateRecordingRequest(const Parameters & params)239 status_t StreamingProcessor::updateRecordingRequest(const Parameters &params) {
240     ATRACE_CALL();
241     status_t res;
242     Mutex::Autolock m(mMutex);
243 
244     sp<CameraDeviceBase> device = mDevice.promote();
245     if (device == 0) {
246         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
247         return INVALID_OPERATION;
248     }
249 
250     if (mRecordingRequest.entryCount() == 0) {
251         res = device->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
252                 &mRecordingRequest);
253         if (res != OK) {
254             ALOGE("%s: Camera %d: Unable to create default recording request:"
255                     " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
256             return res;
257         }
258     }
259 
260     res = params.updateRequest(&mRecordingRequest);
261     if (res != OK) {
262         ALOGE("%s: Camera %d: Unable to update common entries of recording "
263                 "request: %s (%d)", __FUNCTION__, mId,
264                 strerror(-res), res);
265         return res;
266     }
267 
268     res = mRecordingRequest.update(ANDROID_REQUEST_ID,
269             &mRecordingRequestId, 1);
270     if (res != OK) {
271         ALOGE("%s: Camera %d: Unable to update request id for request: %s (%d)",
272                 __FUNCTION__, mId, strerror(-res), res);
273         return res;
274     }
275 
276     return OK;
277 }
278 
updateRecordingStream(const Parameters & params)279 status_t StreamingProcessor::updateRecordingStream(const Parameters &params) {
280     ATRACE_CALL();
281     status_t res;
282     Mutex::Autolock m(mMutex);
283 
284     sp<CameraDeviceBase> device = mDevice.promote();
285     if (device == 0) {
286         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
287         return INVALID_OPERATION;
288     }
289 
290     if (mRecordingConsumer == 0) {
291         // Create CPU buffer queue endpoint. We need one more buffer here so that we can
292         // always acquire and free a buffer when the heap is full; otherwise the consumer
293         // will have buffers in flight we'll never clear out.
294         mRecordingConsumer = new BufferItemConsumer(
295                 GRALLOC_USAGE_HW_VIDEO_ENCODER,
296                 mRecordingHeapCount + 1,
297                 true);
298         mRecordingConsumer->setFrameAvailableListener(this);
299         mRecordingConsumer->setName(String8("Camera2-RecordingConsumer"));
300         mRecordingWindow = new Surface(
301             mRecordingConsumer->getProducerInterface());
302         // Allocate memory later, since we don't know buffer size until receipt
303     }
304 
305     if (mRecordingStreamId != NO_STREAM) {
306         // Check if stream parameters have to change
307         uint32_t currentWidth, currentHeight;
308         res = device->getStreamInfo(mRecordingStreamId,
309                 &currentWidth, &currentHeight, 0);
310         if (res != OK) {
311             ALOGE("%s: Camera %d: Error querying recording output stream info: "
312                     "%s (%d)", __FUNCTION__, mId,
313                     strerror(-res), res);
314             return res;
315         }
316         if (currentWidth != (uint32_t)params.videoWidth ||
317                 currentHeight != (uint32_t)params.videoHeight) {
318             // TODO: Should wait to be sure previous recording has finished
319             res = device->deleteStream(mRecordingStreamId);
320 
321             if (res == -EBUSY) {
322                 ALOGV("%s: Camera %d: Device is busy, call "
323                       "updateRecordingStream after it becomes idle",
324                       __FUNCTION__, mId);
325                 return res;
326             } else if (res != OK) {
327                 ALOGE("%s: Camera %d: Unable to delete old output stream "
328                         "for recording: %s (%d)", __FUNCTION__,
329                         mId, strerror(-res), res);
330                 return res;
331             }
332             mRecordingStreamId = NO_STREAM;
333         }
334     }
335 
336     if (mRecordingStreamId == NO_STREAM) {
337         mRecordingFrameCount = 0;
338         res = device->createStream(mRecordingWindow,
339                 params.videoWidth, params.videoHeight,
340                 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
341         if (res != OK) {
342             ALOGE("%s: Camera %d: Can't create output stream for recording: "
343                     "%s (%d)", __FUNCTION__, mId,
344                     strerror(-res), res);
345             return res;
346         }
347     }
348 
349     return OK;
350 }
351 
deleteRecordingStream()352 status_t StreamingProcessor::deleteRecordingStream() {
353     ATRACE_CALL();
354     status_t res;
355 
356     Mutex::Autolock m(mMutex);
357 
358     if (mRecordingStreamId != NO_STREAM) {
359         sp<CameraDeviceBase> device = mDevice.promote();
360         if (device == 0) {
361             ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
362             return INVALID_OPERATION;
363         }
364 
365         res = device->waitUntilDrained();
366         if (res != OK) {
367             ALOGE("%s: Error waiting for HAL to drain: %s (%d)",
368                     __FUNCTION__, strerror(-res), res);
369             return res;
370         }
371         res = device->deleteStream(mRecordingStreamId);
372         if (res != OK) {
373             ALOGE("%s: Unable to delete recording stream: %s (%d)",
374                     __FUNCTION__, strerror(-res), res);
375             return res;
376         }
377         mRecordingStreamId = NO_STREAM;
378     }
379     return OK;
380 }
381 
getRecordingStreamId() const382 int StreamingProcessor::getRecordingStreamId() const {
383     return mRecordingStreamId;
384 }
385 
startStream(StreamType type,const Vector<uint8_t> & outputStreams)386 status_t StreamingProcessor::startStream(StreamType type,
387         const Vector<uint8_t> &outputStreams) {
388     ATRACE_CALL();
389     status_t res;
390 
391     if (type == NONE) return INVALID_OPERATION;
392 
393     sp<CameraDeviceBase> device = mDevice.promote();
394     if (device == 0) {
395         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
396         return INVALID_OPERATION;
397     }
398 
399     ALOGV("%s: Camera %d: type = %d", __FUNCTION__, mId, type);
400 
401     Mutex::Autolock m(mMutex);
402 
403     CameraMetadata &request = (type == PREVIEW) ?
404             mPreviewRequest : mRecordingRequest;
405 
406     res = request.update(
407         ANDROID_REQUEST_OUTPUT_STREAMS,
408         outputStreams);
409     if (res != OK) {
410         ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
411                 __FUNCTION__, mId, strerror(-res), res);
412         return res;
413     }
414 
415     res = request.sort();
416     if (res != OK) {
417         ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
418                 __FUNCTION__, mId, strerror(-res), res);
419         return res;
420     }
421 
422     res = device->setStreamingRequest(request);
423     if (res != OK) {
424         ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
425                 "%s (%d)",
426                 __FUNCTION__, mId, strerror(-res), res);
427         return res;
428     }
429     mActiveRequest = type;
430     mPaused = false;
431 
432     return OK;
433 }
434 
togglePauseStream(bool pause)435 status_t StreamingProcessor::togglePauseStream(bool pause) {
436     ATRACE_CALL();
437     status_t res;
438 
439     sp<CameraDeviceBase> device = mDevice.promote();
440     if (device == 0) {
441         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
442         return INVALID_OPERATION;
443     }
444 
445     ALOGV("%s: Camera %d: toggling pause to %d", __FUNCTION__, mId, pause);
446 
447     Mutex::Autolock m(mMutex);
448 
449     if (mActiveRequest == NONE) {
450         ALOGE("%s: Camera %d: Can't toggle pause, streaming was not started",
451               __FUNCTION__, mId);
452         return INVALID_OPERATION;
453     }
454 
455     if (mPaused == pause) {
456         return OK;
457     }
458 
459     if (pause) {
460         res = device->clearStreamingRequest();
461         if (res != OK) {
462             ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)",
463                     __FUNCTION__, mId, strerror(-res), res);
464             return res;
465         }
466     } else {
467         CameraMetadata &request =
468                 (mActiveRequest == PREVIEW) ? mPreviewRequest
469                                             : mRecordingRequest;
470         res = device->setStreamingRequest(request);
471         if (res != OK) {
472             ALOGE("%s: Camera %d: Unable to set preview request to resume: "
473                     "%s (%d)",
474                     __FUNCTION__, mId, strerror(-res), res);
475             return res;
476         }
477     }
478 
479     mPaused = pause;
480     return OK;
481 }
482 
stopStream()483 status_t StreamingProcessor::stopStream() {
484     ATRACE_CALL();
485     status_t res;
486 
487     Mutex::Autolock m(mMutex);
488 
489     sp<CameraDeviceBase> device = mDevice.promote();
490     if (device == 0) {
491         ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId);
492         return INVALID_OPERATION;
493     }
494 
495     res = device->clearStreamingRequest();
496     if (res != OK) {
497         ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)",
498                 __FUNCTION__, mId, strerror(-res), res);
499         return res;
500     }
501 
502     mActiveRequest = NONE;
503     mPaused = false;
504 
505     return OK;
506 }
507 
getActiveRequestId() const508 int32_t StreamingProcessor::getActiveRequestId() const {
509     Mutex::Autolock m(mMutex);
510     switch (mActiveRequest) {
511         case NONE:
512             return 0;
513         case PREVIEW:
514             return mPreviewRequestId;
515         case RECORD:
516             return mRecordingRequestId;
517         default:
518             ALOGE("%s: Unexpected mode %d", __FUNCTION__, mActiveRequest);
519             return 0;
520     }
521 }
522 
incrementStreamingIds()523 status_t StreamingProcessor::incrementStreamingIds() {
524     ATRACE_CALL();
525     Mutex::Autolock m(mMutex);
526 
527     mPreviewRequestId++;
528     if (mPreviewRequestId >= Camera2Client::kPreviewRequestIdEnd) {
529         mPreviewRequestId = Camera2Client::kPreviewRequestIdStart;
530     }
531     mRecordingRequestId++;
532     if (mRecordingRequestId >= Camera2Client::kRecordingRequestIdEnd) {
533         mRecordingRequestId = Camera2Client::kRecordingRequestIdStart;
534     }
535     return OK;
536 }
537 
onFrameAvailable()538 void StreamingProcessor::onFrameAvailable() {
539     ATRACE_CALL();
540     Mutex::Autolock l(mMutex);
541     if (!mRecordingFrameAvailable) {
542         mRecordingFrameAvailable = true;
543         mRecordingFrameAvailableSignal.signal();
544     }
545 
546 }
547 
threadLoop()548 bool StreamingProcessor::threadLoop() {
549     status_t res;
550 
551     {
552         Mutex::Autolock l(mMutex);
553         while (!mRecordingFrameAvailable) {
554             res = mRecordingFrameAvailableSignal.waitRelative(
555                 mMutex, kWaitDuration);
556             if (res == TIMED_OUT) return true;
557         }
558         mRecordingFrameAvailable = false;
559     }
560 
561     do {
562         res = processRecordingFrame();
563     } while (res == OK);
564 
565     return true;
566 }
567 
processRecordingFrame()568 status_t StreamingProcessor::processRecordingFrame() {
569     ATRACE_CALL();
570     status_t res;
571     sp<Camera2Heap> recordingHeap;
572     size_t heapIdx = 0;
573     nsecs_t timestamp;
574 
575     sp<Camera2Client> client = mClient.promote();
576     if (client == 0) {
577         // Discard frames during shutdown
578         BufferItemConsumer::BufferItem imgBuffer;
579         res = mRecordingConsumer->acquireBuffer(&imgBuffer);
580         if (res != OK) {
581             if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
582                 ALOGE("%s: Camera %d: Can't acquire recording buffer: %s (%d)",
583                         __FUNCTION__, mId, strerror(-res), res);
584             }
585             return res;
586         }
587         mRecordingConsumer->releaseBuffer(imgBuffer);
588         return OK;
589     }
590 
591     {
592         /* acquire SharedParameters before mMutex so we don't dead lock
593             with Camera2Client code calling into StreamingProcessor */
594         SharedParameters::Lock l(client->getParameters());
595         Mutex::Autolock m(mMutex);
596         BufferItemConsumer::BufferItem imgBuffer;
597         res = mRecordingConsumer->acquireBuffer(&imgBuffer);
598         if (res != OK) {
599             if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) {
600                 ALOGE("%s: Camera %d: Can't acquire recording buffer: %s (%d)",
601                         __FUNCTION__, mId, strerror(-res), res);
602             }
603             return res;
604         }
605         timestamp = imgBuffer.mTimestamp;
606 
607         mRecordingFrameCount++;
608         ALOGV("OnRecordingFrame: Frame %d", mRecordingFrameCount);
609 
610         if (l.mParameters.state != Parameters::RECORD &&
611                 l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
612             ALOGV("%s: Camera %d: Discarding recording image buffers "
613                     "received after recording done", __FUNCTION__,
614                     mId);
615             mRecordingConsumer->releaseBuffer(imgBuffer);
616             return INVALID_OPERATION;
617         }
618 
619         if (mRecordingHeap == 0) {
620             const size_t bufferSize = 4 + sizeof(buffer_handle_t);
621             ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
622                     "size %d bytes", __FUNCTION__, mId,
623                     mRecordingHeapCount, bufferSize);
624 
625             mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
626                     "Camera2Client::RecordingHeap");
627             if (mRecordingHeap->mHeap->getSize() == 0) {
628                 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
629                         __FUNCTION__, mId);
630                 mRecordingConsumer->releaseBuffer(imgBuffer);
631                 return NO_MEMORY;
632             }
633             for (size_t i = 0; i < mRecordingBuffers.size(); i++) {
634                 if (mRecordingBuffers[i].mBuf !=
635                         BufferItemConsumer::INVALID_BUFFER_SLOT) {
636                     ALOGE("%s: Camera %d: Non-empty recording buffers list!",
637                             __FUNCTION__, mId);
638                 }
639             }
640             mRecordingBuffers.clear();
641             mRecordingBuffers.setCapacity(mRecordingHeapCount);
642             mRecordingBuffers.insertAt(0, mRecordingHeapCount);
643 
644             mRecordingHeapHead = 0;
645             mRecordingHeapFree = mRecordingHeapCount;
646         }
647 
648         if ( mRecordingHeapFree == 0) {
649             ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
650                     __FUNCTION__, mId);
651             mRecordingConsumer->releaseBuffer(imgBuffer);
652             return NO_MEMORY;
653         }
654 
655         heapIdx = mRecordingHeapHead;
656         mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
657         mRecordingHeapFree--;
658 
659         ALOGV("%s: Camera %d: Timestamp %lld",
660                 __FUNCTION__, mId, timestamp);
661 
662         ssize_t offset;
663         size_t size;
664         sp<IMemoryHeap> heap =
665                 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
666                         &size);
667 
668         uint8_t *data = (uint8_t*)heap->getBase() + offset;
669         uint32_t type = kMetadataBufferTypeGrallocSource;
670         *((uint32_t*)data) = type;
671         *((buffer_handle_t*)(data + 4)) = imgBuffer.mGraphicBuffer->handle;
672         ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
673                 __FUNCTION__, mId,
674                 imgBuffer.mGraphicBuffer->handle);
675         mRecordingBuffers.replaceAt(imgBuffer, heapIdx);
676         recordingHeap = mRecordingHeap;
677     }
678 
679     // Call outside locked parameters to allow re-entrancy from notification
680     Camera2Client::SharedCameraCallbacks::Lock l(client->mSharedCameraCallbacks);
681     if (l.mRemoteCallback != 0) {
682         l.mRemoteCallback->dataCallbackTimestamp(timestamp,
683                 CAMERA_MSG_VIDEO_FRAME,
684                 recordingHeap->mBuffers[heapIdx]);
685     }
686     return OK;
687 }
688 
releaseRecordingFrame(const sp<IMemory> & mem)689 void StreamingProcessor::releaseRecordingFrame(const sp<IMemory>& mem) {
690     ATRACE_CALL();
691     status_t res;
692 
693     Mutex::Autolock m(mMutex);
694     // Make sure this is for the current heap
695     ssize_t offset;
696     size_t size;
697     sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
698     if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
699         ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
700                 "(got %x, expected %x)", __FUNCTION__, mId,
701                 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
702         return;
703     }
704     uint8_t *data = (uint8_t*)heap->getBase() + offset;
705     uint32_t type = *(uint32_t*)data;
706     if (type != kMetadataBufferTypeGrallocSource) {
707         ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
708                 __FUNCTION__, mId, type,
709                 kMetadataBufferTypeGrallocSource);
710         return;
711     }
712 
713     // Release the buffer back to the recording queue
714 
715     buffer_handle_t imgHandle = *(buffer_handle_t*)(data + 4);
716 
717     size_t itemIndex;
718     for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) {
719         const BufferItemConsumer::BufferItem item =
720                 mRecordingBuffers[itemIndex];
721         if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT &&
722                 item.mGraphicBuffer->handle == imgHandle) {
723             break;
724         }
725     }
726     if (itemIndex == mRecordingBuffers.size()) {
727         ALOGE("%s: Camera %d: Can't find buffer_handle_t %p in list of "
728                 "outstanding buffers", __FUNCTION__, mId,
729                 imgHandle);
730         return;
731     }
732 
733     ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__,
734             mId, imgHandle);
735 
736     res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]);
737     if (res != OK) {
738         ALOGE("%s: Camera %d: Unable to free recording frame "
739                 "(buffer_handle_t: %p): %s (%d)", __FUNCTION__,
740                 mId, imgHandle, strerror(-res), res);
741         return;
742     }
743     mRecordingBuffers.replaceAt(itemIndex);
744 
745     mRecordingHeapFree++;
746 }
747 
748 
dump(int fd,const Vector<String16> &)749 status_t StreamingProcessor::dump(int fd, const Vector<String16>& /*args*/) {
750     String8 result;
751 
752     result.append("  Current requests:\n");
753     if (mPreviewRequest.entryCount() != 0) {
754         result.append("    Preview request:\n");
755         write(fd, result.string(), result.size());
756         mPreviewRequest.dump(fd, 2, 6);
757         result.clear();
758     } else {
759         result.append("    Preview request: undefined\n");
760     }
761 
762     if (mRecordingRequest.entryCount() != 0) {
763         result = "    Recording request:\n";
764         write(fd, result.string(), result.size());
765         mRecordingRequest.dump(fd, 2, 6);
766         result.clear();
767     } else {
768         result = "    Recording request: undefined\n";
769     }
770 
771     const char* streamTypeString[] = {
772         "none", "preview", "record"
773     };
774     result.append(String8::format("   Active request: %s (paused: %s)\n",
775                                   streamTypeString[mActiveRequest],
776                                   mPaused ? "yes" : "no"));
777 
778     write(fd, result.string(), result.size());
779 
780     return OK;
781 }
782 
783 }; // namespace camera2
784 }; // namespace android
785