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