1 /*
2 * Copyright (C) 2019 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_NDEBUG 0
18 #define LOG_TAG "GCH_InternalStreamManager"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include <log/log.h>
21 #include <utils/Trace.h>
22
23 #include "hal_utils.h"
24 #include "internal_stream_manager.h"
25
26 namespace android {
27 namespace google_camera_hal {
28
Create(IHalBufferAllocator * buffer_allocator)29 std::unique_ptr<InternalStreamManager> InternalStreamManager::Create(
30 IHalBufferAllocator* buffer_allocator) {
31 ATRACE_CALL();
32 auto stream_manager =
33 std::unique_ptr<InternalStreamManager>(new InternalStreamManager());
34 if (stream_manager == nullptr) {
35 ALOGE("%s: Creating InternalStreamManager failed.", __FUNCTION__);
36 return nullptr;
37 }
38
39 stream_manager->Initialize(buffer_allocator);
40
41 return stream_manager;
42 }
43
Initialize(IHalBufferAllocator * buffer_allocator)44 void InternalStreamManager::Initialize(IHalBufferAllocator* buffer_allocator) {
45 hwl_buffer_allocator_ = buffer_allocator;
46 }
47
IsStreamRegisteredLocked(int32_t stream_id) const48 status_t InternalStreamManager::IsStreamRegisteredLocked(int32_t stream_id) const {
49 return registered_streams_.find(stream_id) != registered_streams_.end();
50 }
51
IsStreamAllocatedLocked(int32_t stream_id) const52 status_t InternalStreamManager::IsStreamAllocatedLocked(int32_t stream_id) const {
53 // Check if this stream is sharing buffers with another stream or owns a
54 // a buffer manager.
55 return shared_stream_owner_ids_.find(stream_id) !=
56 shared_stream_owner_ids_.end() ||
57 buffer_managers_.find(stream_id) != buffer_managers_.end();
58 }
59
GetBufferManagerOwnerIdLocked(int32_t stream_id)60 int32_t InternalStreamManager::GetBufferManagerOwnerIdLocked(int32_t stream_id) {
61 int32_t owner_stream_id = stream_id;
62 auto owner_id_it = shared_stream_owner_ids_.find(stream_id);
63 if (owner_id_it != shared_stream_owner_ids_.end()) {
64 owner_stream_id = owner_id_it->second;
65 }
66
67 if (buffer_managers_.find(owner_stream_id) == buffer_managers_.end()) {
68 return kInvalidStreamId;
69 }
70
71 return owner_stream_id;
72 }
73
RegisterNewInternalStream(const Stream & stream,int32_t * stream_id)74 status_t InternalStreamManager::RegisterNewInternalStream(const Stream& stream,
75 int32_t* stream_id) {
76 ATRACE_CALL();
77 std::lock_guard<std::mutex> lock(stream_mutex_);
78 if (stream_id == nullptr) {
79 ALOGE("%s: stream_id is nullptr.", __FUNCTION__);
80 return BAD_VALUE;
81 }
82
83 Stream internal_stream = stream;
84 int32_t id = stream.id;
85 // if stream.id is one of reserved ids in camera_buffer_allocator_hwl.h, we
86 // will use the given id so that HWL can use its predefined id to setup
87 // implementation defined internal stream format. other wise will use the next
88 // available unique id.
89 if (stream.id < kStreamIdReserve) {
90 id = next_available_stream_id_++;
91 internal_stream.id = id;
92 }
93 registered_streams_[id] = std::move(internal_stream);
94
95 *stream_id = id;
96 return OK;
97 }
98
GetBufferDescriptor(const Stream & stream,const HalStream & hal_stream,uint32_t additional_num_buffers,HalBufferDescriptor * buffer_descriptor)99 status_t InternalStreamManager::GetBufferDescriptor(
100 const Stream& stream, const HalStream& hal_stream,
101 uint32_t additional_num_buffers, HalBufferDescriptor* buffer_descriptor) {
102 ATRACE_CALL();
103 if (buffer_descriptor == nullptr) {
104 ALOGE("%s: buffer_descriptor is nullptr", __FUNCTION__);
105 return BAD_VALUE;
106 }
107
108 if (stream.id != hal_stream.id) {
109 ALOGE("%s: IDs don't match: stream %d hal stream %d", __FUNCTION__,
110 stream.id, hal_stream.id);
111 return BAD_VALUE;
112 }
113
114 buffer_descriptor->stream_id = stream.id;
115 buffer_descriptor->width = stream.width;
116 buffer_descriptor->height = stream.height;
117 buffer_descriptor->format = hal_stream.override_format;
118 buffer_descriptor->producer_flags = hal_stream.producer_usage;
119 buffer_descriptor->consumer_flags = hal_stream.consumer_usage;
120 buffer_descriptor->immediate_num_buffers = hal_stream.max_buffers;
121 buffer_descriptor->max_num_buffers =
122 hal_stream.max_buffers + additional_num_buffers;
123
124 return OK;
125 }
126
AllocateBuffers(const HalStream & hal_stream,uint32_t additional_num_buffers,bool need_vendor_buffer)127 status_t InternalStreamManager::AllocateBuffers(const HalStream& hal_stream,
128 uint32_t additional_num_buffers,
129 bool need_vendor_buffer) {
130 ATRACE_CALL();
131 std::lock_guard<std::mutex> lock(stream_mutex_);
132 return AllocateBuffersLocked(hal_stream, additional_num_buffers,
133 need_vendor_buffer);
134 }
135
AllocateBuffersLocked(const HalStream & hal_stream,uint32_t additional_num_buffers,bool need_vendor_buffer)136 status_t InternalStreamManager::AllocateBuffersLocked(
137 const HalStream& hal_stream, uint32_t additional_num_buffers,
138 bool need_vendor_buffer) {
139 ATRACE_CALL();
140 int32_t stream_id = hal_stream.id;
141
142 if (!IsStreamRegisteredLocked(stream_id)) {
143 ALOGE("%s: Stream %d was not registered.", __FUNCTION__, stream_id);
144 return NAME_NOT_FOUND;
145 }
146
147 if (IsStreamAllocatedLocked(stream_id)) {
148 ALOGE("%s: Stream %d is already allocated.", __FUNCTION__, stream_id);
149 return ALREADY_EXISTS;
150 }
151
152 HalBufferDescriptor buffer_descriptor;
153 status_t res = GetBufferDescriptor(registered_streams_[stream_id], hal_stream,
154 additional_num_buffers, &buffer_descriptor);
155 if (res != OK) {
156 ALOGE("%s: Getting buffer descriptor failed: %s(%d)", __FUNCTION__,
157 strerror(-res), res);
158 return res;
159 }
160
161 auto buffer_manager = std::make_unique<ZslBufferManager>(
162 need_vendor_buffer ? hwl_buffer_allocator_ : nullptr);
163 if (buffer_manager == nullptr) {
164 ALOGE("%s: Failed to create a buffer manager for stream %d", __FUNCTION__,
165 stream_id);
166 return UNKNOWN_ERROR;
167 }
168
169 res = buffer_manager->AllocateBuffers(buffer_descriptor);
170 if (res != OK) {
171 ALOGE(
172 "%s: Failed to allocate %u immediate buffers (max: %u) for stream %d: "
173 "%s(%d)",
174 __FUNCTION__, buffer_descriptor.immediate_num_buffers,
175 buffer_descriptor.max_num_buffers, stream_id, strerror(-res), res);
176 return res;
177 }
178
179 buffer_managers_[stream_id] = std::move(buffer_manager);
180 return OK;
181 }
182
AreStreamsCompatible(const Stream & stream_0,const HalStream & hal_stream_0,const Stream & stream_1,const HalStream & hal_stream_1) const183 bool InternalStreamManager::AreStreamsCompatible(
184 const Stream& stream_0, const HalStream& hal_stream_0,
185 const Stream& stream_1, const HalStream& hal_stream_1) const {
186 return stream_0.width == stream_1.width &&
187 stream_0.height == stream_1.height &&
188 stream_0.rotation == stream_1.rotation &&
189 hal_stream_0.override_format == hal_stream_1.override_format &&
190 hal_stream_0.producer_usage == hal_stream_1.producer_usage &&
191 hal_stream_0.consumer_usage == hal_stream_1.consumer_usage &&
192 hal_stream_0.override_data_space == hal_stream_1.override_data_space;
193 }
194
CanHalStreamsShareBuffersLocked(const std::vector<HalStream> & hal_streams) const195 bool InternalStreamManager::CanHalStreamsShareBuffersLocked(
196 const std::vector<HalStream>& hal_streams) const {
197 if (hal_streams.size() < 2) {
198 ALOGV("%s: Cannot sharing buffers for %zu stream.", __FUNCTION__,
199 hal_streams.size());
200 return BAD_VALUE;
201 }
202
203 int32_t first_stream_id = hal_streams[0].id;
204 for (uint32_t i = 0; i < hal_streams.size(); i++) {
205 int32_t stream_id = hal_streams[i].id;
206 if (!IsStreamRegisteredLocked(stream_id)) {
207 ALOGE("%s: stream id %d was not registered.", __FUNCTION__, stream_id);
208 return false;
209 }
210
211 if (i == 0) {
212 // Skip the first one.
213 continue;
214 }
215
216 if (!AreStreamsCompatible(registered_streams_.at(first_stream_id),
217 hal_streams[0], registered_streams_.at(stream_id),
218 hal_streams[i])) {
219 ALOGV("%s: Stream %d and %d are not compatible", __FUNCTION__,
220 first_stream_id, stream_id);
221 IF_ALOGV() {
222 hal_utils::DumpStream(registered_streams_.at(first_stream_id),
223 "stream_0");
224 hal_utils::DumpStream(registered_streams_.at(stream_id), "stream_1");
225 hal_utils::DumpHalStream(hal_streams[0], "hal_stream_0");
226 hal_utils::DumpHalStream(hal_streams[i], "hal_stream_1");
227 }
228
229 return false;
230 }
231 }
232
233 return true;
234 }
235
AllocateSharedBuffers(const std::vector<HalStream> & hal_streams,uint32_t additional_num_buffers,bool need_vendor_buffer)236 status_t InternalStreamManager::AllocateSharedBuffers(
237 const std::vector<HalStream>& hal_streams, uint32_t additional_num_buffers,
238 bool need_vendor_buffer) {
239 std::lock_guard<std::mutex> lock(stream_mutex_);
240 if (hal_streams.size() < 2) {
241 ALOGE("%s: Cannot sharing buffers for %zu stream.", __FUNCTION__,
242 hal_streams.size());
243 return BAD_VALUE;
244 }
245
246 uint32_t max_buffers = 0;
247 uint32_t total_max_buffers = 0;
248
249 // Find the maximum and total of all hal_streams' max_buffers.
250 for (auto& hal_stream : hal_streams) {
251 if (!IsStreamRegisteredLocked(hal_stream.id)) {
252 ALOGE("%s: Stream %d was not registered.", __FUNCTION__, hal_stream.id);
253 return BAD_VALUE;
254 }
255
256 if (IsStreamAllocatedLocked(hal_stream.id)) {
257 ALOGE("%s: Stream %d has been allocated.", __FUNCTION__, hal_stream.id);
258 return BAD_VALUE;
259 }
260
261 total_max_buffers += hal_stream.max_buffers;
262 max_buffers = std::max(max_buffers, hal_stream.max_buffers);
263 }
264
265 if (!CanHalStreamsShareBuffersLocked(hal_streams)) {
266 ALOGE("%s: Streams cannot share buffers.", __FUNCTION__);
267 return BAD_VALUE;
268 }
269
270 // Allocate the maximum of all hal_streams' max_buffers immediately and
271 // additional (total_max_buffers + additional_num_buffers - max_buffers)
272 // buffers.
273 HalStream hal_stream = hal_streams[0];
274 hal_stream.max_buffers = max_buffers;
275 uint32_t total_additional_num_buffers =
276 total_max_buffers + additional_num_buffers - max_buffers;
277
278 status_t res = AllocateBuffersLocked(hal_stream, total_additional_num_buffers,
279 need_vendor_buffer);
280 if (res != OK) {
281 ALOGE("%s: Allocating buffers for stream %d failed: %s(%d)", __FUNCTION__,
282 hal_stream.id, strerror(-res), res);
283 return res;
284 }
285
286 for (uint32_t i = 1; i < hal_streams.size(); i++) {
287 shared_stream_owner_ids_[hal_streams[i].id] = hal_streams[0].id;
288 }
289
290 return OK;
291 }
292
RemoveOwnerStreamIdLocked(int32_t old_owner_stream_id)293 status_t InternalStreamManager::RemoveOwnerStreamIdLocked(
294 int32_t old_owner_stream_id) {
295 int32_t new_owner_stream_id = kInvalidStreamId;
296
297 if (buffer_managers_.find(old_owner_stream_id) == buffer_managers_.end()) {
298 ALOGE("%s: Stream %d does not own any buffer manager.", __FUNCTION__,
299 old_owner_stream_id);
300 return BAD_VALUE;
301 }
302
303 // Find the first stream that shares the buffer manager that
304 // old_owner_stream_id owns, and update the rest of the streams to point to
305 // the new owner.
306 auto owner_stream_id_it = shared_stream_owner_ids_.begin();
307 while (owner_stream_id_it != shared_stream_owner_ids_.end()) {
308 if (owner_stream_id_it->second == old_owner_stream_id) {
309 if (new_owner_stream_id == kInvalidStreamId) {
310 // Found the first stream sharing the old owner's buffer manager.
311 // Make this the new buffer manager owner.
312 new_owner_stream_id = owner_stream_id_it->first;
313 owner_stream_id_it = shared_stream_owner_ids_.erase(owner_stream_id_it);
314 continue;
315 } else {
316 // Update the rest of the stream to point to the new owner.
317 owner_stream_id_it->second = new_owner_stream_id;
318 }
319 }
320 owner_stream_id_it++;
321 }
322
323 if (new_owner_stream_id != kInvalidStreamId) {
324 // Update buffer manager owner.
325 buffer_managers_[new_owner_stream_id] =
326 std::move(buffer_managers_[old_owner_stream_id]);
327 }
328
329 buffer_managers_.erase(old_owner_stream_id);
330 return OK;
331 }
332
FreeStream(int32_t stream_id)333 void InternalStreamManager::FreeStream(int32_t stream_id) {
334 ATRACE_CALL();
335 std::lock_guard<std::mutex> lock(stream_mutex_);
336 registered_streams_.erase(stream_id);
337
338 int32_t owner_stream_id = GetBufferManagerOwnerIdLocked(stream_id);
339 if (owner_stream_id == kInvalidStreamId) {
340 ALOGE("%s: Cannot find a owner stream ID for stream %d", __FUNCTION__,
341 stream_id);
342 return;
343 }
344
345 if (stream_id == owner_stream_id) {
346 // Find a new owner if the owner is being freed.
347 status_t res = RemoveOwnerStreamIdLocked(owner_stream_id);
348 if (res != OK) {
349 ALOGE("%s: Removing owner stream failed: %s(%d)", __FUNCTION__,
350 strerror(-res), res);
351 return;
352 }
353 } else {
354 // If this stream is not the owner, just remove it from
355 // shared_stream_owner_ids_.
356 shared_stream_owner_ids_.erase(stream_id);
357 }
358 }
359
GetStreamBuffer(int32_t stream_id,StreamBuffer * buffer)360 status_t InternalStreamManager::GetStreamBuffer(int32_t stream_id,
361 StreamBuffer* buffer) {
362 ATRACE_CALL();
363 std::lock_guard<std::mutex> lock(stream_mutex_);
364
365 if (!IsStreamAllocatedLocked(stream_id)) {
366 ALOGE("%s: Stream %d was not allocated.", __FUNCTION__, stream_id);
367 return ALREADY_EXISTS;
368 }
369
370 if (buffer == nullptr) {
371 ALOGE("%s: buffer is nullptr", __FUNCTION__);
372 return BAD_VALUE;
373 }
374
375 int32_t owner_stream_id = GetBufferManagerOwnerIdLocked(stream_id);
376 if (owner_stream_id == kInvalidStreamId) {
377 ALOGE("%s: Cannot find a owner stream ID for stream %d", __FUNCTION__,
378 stream_id);
379 return BAD_VALUE;
380 }
381
382 buffer->buffer = buffer_managers_[owner_stream_id]->GetEmptyBuffer();
383 if (buffer->buffer == kInvalidBufferHandle) {
384 ALOGE("%s: Failed to get an empty buffer for stream %d (owner %d)",
385 __FUNCTION__, stream_id, owner_stream_id);
386 return UNKNOWN_ERROR;
387 }
388
389 buffer->stream_id = stream_id;
390 buffer->buffer_id = 0; // Buffer ID should be irrelevant internally in HAL.
391 buffer->status = BufferStatus::kOk;
392 buffer->acquire_fence = nullptr;
393 buffer->release_fence = nullptr;
394 return OK;
395 }
396
IsPendingBufferEmpty(int32_t stream_id)397 bool InternalStreamManager::IsPendingBufferEmpty(int32_t stream_id) {
398 ATRACE_CALL();
399 std::lock_guard<std::mutex> lock(stream_mutex_);
400 if (!IsStreamAllocatedLocked(stream_id)) {
401 ALOGE("%s: Stream %d was not allocated.", __FUNCTION__, stream_id);
402 return false;
403 }
404
405 int32_t owner_stream_id = GetBufferManagerOwnerIdLocked(stream_id);
406 if (owner_stream_id == kInvalidStreamId) {
407 ALOGE("%s: Cannot find a owner stream ID for stream %d", __FUNCTION__,
408 stream_id);
409 return false;
410 }
411
412 return buffer_managers_[owner_stream_id]->IsPendingBufferEmpty();
413 }
414
GetMostRecentStreamBuffer(int32_t stream_id,std::vector<StreamBuffer> * input_buffers,std::vector<std::unique_ptr<HalCameraMetadata>> * input_buffer_metadata,uint32_t payload_frames)415 status_t InternalStreamManager::GetMostRecentStreamBuffer(
416 int32_t stream_id, std::vector<StreamBuffer>* input_buffers,
417 std::vector<std::unique_ptr<HalCameraMetadata>>* input_buffer_metadata,
418 uint32_t payload_frames) {
419 ATRACE_CALL();
420 std::lock_guard<std::mutex> lock(stream_mutex_);
421
422 if (!IsStreamAllocatedLocked(stream_id)) {
423 ALOGE("%s: Stream %d was not allocated.", __FUNCTION__, stream_id);
424 return BAD_VALUE;
425 }
426
427 int32_t owner_stream_id = GetBufferManagerOwnerIdLocked(stream_id);
428 if (owner_stream_id == kInvalidStreamId) {
429 ALOGE("%s: Cannot find a owner stream ID for stream %d", __FUNCTION__,
430 stream_id);
431 return BAD_VALUE;
432 }
433
434 if (input_buffers == nullptr || input_buffer_metadata == nullptr) {
435 ALOGE("%s: input_buffers (%p) or input_buffer_metadata (%p) is nullptr",
436 __FUNCTION__, input_buffers, input_buffer_metadata);
437 return BAD_VALUE;
438 }
439
440 std::vector<ZslBufferManager::ZslBuffer> filled_buffers;
441 buffer_managers_[owner_stream_id]->GetMostRecentZslBuffers(
442 &filled_buffers, payload_frames, kMinFilledBuffers);
443
444 if (filled_buffers.size() == 0) {
445 ALOGE("%s: There is no input buffers.", __FUNCTION__);
446 return INVALID_OPERATION;
447 }
448
449 // TODO(b/138592133): Remove AddPendingBuffers because internal stream manager
450 // should not be responsible for saving the pending buffers' metadata.
451 buffer_managers_[owner_stream_id]->AddPendingBuffers(filled_buffers);
452
453 for (uint32_t i = 0; i < filled_buffers.size(); i++) {
454 StreamBuffer buffer = {};
455 buffer.stream_id = stream_id;
456 buffer.buffer_id = 0; // Buffer ID should be irrelevant internally in HAL.
457 buffer.status = BufferStatus::kOk;
458 buffer.acquire_fence = nullptr;
459 buffer.release_fence = nullptr;
460 buffer.buffer = filled_buffers[i].buffer.buffer;
461 input_buffers->push_back(buffer);
462 if (filled_buffers[i].metadata == nullptr) {
463 std::vector<ZslBufferManager::ZslBuffer> buffers;
464 buffer_managers_[owner_stream_id]->CleanPendingBuffers(&buffers);
465 buffer_managers_[owner_stream_id]->ReturnZslBuffers(std::move(buffers));
466 return INVALID_OPERATION;
467 }
468 input_buffer_metadata->push_back(std::move(filled_buffers[i].metadata));
469 }
470
471 return OK;
472 }
473
ReturnZslStreamBuffers(uint32_t frame_number,int32_t stream_id)474 status_t InternalStreamManager::ReturnZslStreamBuffers(uint32_t frame_number,
475 int32_t stream_id) {
476 ATRACE_CALL();
477 std::lock_guard<std::mutex> lock(stream_mutex_);
478
479 if (!IsStreamAllocatedLocked(stream_id)) {
480 ALOGE("%s: Unknown stream ID %d.", __FUNCTION__, stream_id);
481 return BAD_VALUE;
482 }
483
484 int32_t owner_stream_id = GetBufferManagerOwnerIdLocked(stream_id);
485 if (owner_stream_id == kInvalidStreamId) {
486 ALOGE("%s: Cannot find a owner stream ID for stream %d", __FUNCTION__,
487 stream_id);
488 return BAD_VALUE;
489 }
490
491 std::vector<ZslBufferManager::ZslBuffer> zsl_buffers;
492 status_t res =
493 buffer_managers_[owner_stream_id]->CleanPendingBuffers(&zsl_buffers);
494 if (res != OK) {
495 ALOGE("%s: frame (%d)fail to return zsl stream buffers", __FUNCTION__,
496 frame_number);
497 return res;
498 }
499 buffer_managers_[owner_stream_id]->ReturnZslBuffers(std::move(zsl_buffers));
500
501 return OK;
502 }
503
ReturnStreamBuffer(const StreamBuffer & buffer)504 status_t InternalStreamManager::ReturnStreamBuffer(const StreamBuffer& buffer) {
505 ATRACE_CALL();
506 std::lock_guard<std::mutex> lock(stream_mutex_);
507 int32_t stream_id = buffer.stream_id;
508
509 if (!IsStreamAllocatedLocked(stream_id)) {
510 ALOGE("%s: Unknown stream ID %d.", __FUNCTION__, stream_id);
511 return BAD_VALUE;
512 }
513
514 int32_t owner_stream_id = GetBufferManagerOwnerIdLocked(stream_id);
515 if (owner_stream_id == kInvalidStreamId) {
516 ALOGE("%s: Cannot find a owner stream ID for stream %d", __FUNCTION__,
517 stream_id);
518 return BAD_VALUE;
519 }
520
521 return buffer_managers_[owner_stream_id]->ReturnEmptyBuffer(buffer.buffer);
522 }
523
ReturnFilledBuffer(uint32_t frame_number,const StreamBuffer & buffer)524 status_t InternalStreamManager::ReturnFilledBuffer(uint32_t frame_number,
525 const StreamBuffer& buffer) {
526 ATRACE_CALL();
527 std::lock_guard<std::mutex> lock(stream_mutex_);
528 int32_t stream_id = buffer.stream_id;
529
530 if (!IsStreamAllocatedLocked(stream_id)) {
531 ALOGE("%s: Unknown stream ID %d.", __FUNCTION__, stream_id);
532 return BAD_VALUE;
533 }
534
535 int32_t owner_stream_id = GetBufferManagerOwnerIdLocked(stream_id);
536 if (owner_stream_id == kInvalidStreamId) {
537 ALOGE("%s: Cannot find a owner stream ID for stream %d", __FUNCTION__,
538 stream_id);
539 return BAD_VALUE;
540 }
541
542 return buffer_managers_[owner_stream_id]->ReturnFilledBuffer(frame_number,
543 buffer);
544 }
545
ReturnMetadata(int32_t stream_id,uint32_t frame_number,const HalCameraMetadata * metadata)546 status_t InternalStreamManager::ReturnMetadata(
547 int32_t stream_id, uint32_t frame_number,
548 const HalCameraMetadata* metadata) {
549 ATRACE_CALL();
550 std::lock_guard<std::mutex> lock(stream_mutex_);
551
552 if (!IsStreamAllocatedLocked(stream_id)) {
553 ALOGE("%s: Unknown stream ID %d.", __FUNCTION__, stream_id);
554 return BAD_VALUE;
555 }
556
557 int32_t owner_stream_id = GetBufferManagerOwnerIdLocked(stream_id);
558 if (owner_stream_id == kInvalidStreamId) {
559 ALOGE("%s: Cannot find a owner stream ID for stream %d", __FUNCTION__,
560 stream_id);
561 return BAD_VALUE;
562 }
563
564 return buffer_managers_[owner_stream_id]->ReturnMetadata(frame_number,
565 metadata);
566 }
567
568 } // namespace google_camera_hal
569 } // namespace android