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