• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_ResultDispatcher"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include "result_dispatcher.h"
21 
22 #include <inttypes.h>
23 #include <log/log.h>
24 #include <sys/resource.h>
25 #include <utils/Trace.h>
26 
27 #include <string>
28 #include <string_view>
29 
30 #include "utils.h"
31 
32 namespace android {
33 namespace google_camera_hal {
34 
Create(uint32_t partial_result_count,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,const StreamConfiguration & stream_config,std::string_view name)35 std::unique_ptr<ResultDispatcher> ResultDispatcher::Create(
36     uint32_t partial_result_count,
37     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
38     const StreamConfiguration& stream_config, std::string_view name) {
39   ATRACE_CALL();
40   auto dispatcher = std::unique_ptr<ResultDispatcher>(
41       new ResultDispatcher(partial_result_count, process_capture_result, notify,
42                            stream_config, name));
43   if (dispatcher == nullptr) {
44     ALOGE("[%s] %s: Creating ResultDispatcher failed.",
45           std::string(name).c_str(), __FUNCTION__);
46     return nullptr;
47   }
48 
49   return dispatcher;
50 }
51 
ResultDispatcher(uint32_t partial_result_count,ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,const StreamConfiguration & stream_config,std::string_view name)52 ResultDispatcher::ResultDispatcher(
53     uint32_t partial_result_count,
54     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
55     const StreamConfiguration& stream_config, std::string_view name)
56     : kPartialResultCount(partial_result_count),
57       name_(name),
58       process_capture_result_(process_capture_result),
59       notify_(notify) {
60   ATRACE_CALL();
61   notify_callback_thread_ =
62       std::thread([this] { this->NotifyCallbackThreadLoop(); });
63 
64   // Assign higher priority to reduce the preemption when CPU usage is high
65   //
66   // As from b/295977499, we need to make it realtime for priority inheritance
67   // to avoid CameraServer thread being the bottleneck
68   status_t res =
69       utils::SetRealtimeThread(notify_callback_thread_.native_handle());
70   if (res != OK) {
71     ALOGE("[%s] %s: SetRealtimeThread fail", name_.c_str(), __FUNCTION__);
72   } else {
73     ALOGI("[%s] %s: SetRealtimeThread OK", name_.c_str(), __FUNCTION__);
74   }
75   InitializeGroupStreamIdsMap(stream_config);
76 }
77 
~ResultDispatcher()78 ResultDispatcher::~ResultDispatcher() {
79   ATRACE_CALL();
80   {
81     std::unique_lock<std::mutex> lock(notify_callback_lock_);
82     notify_callback_thread_exiting_ = true;
83   }
84 
85   notify_callback_condition_.notify_one();
86   notify_callback_thread_.join();
87 }
88 
RemovePendingRequest(uint32_t frame_number)89 void ResultDispatcher::RemovePendingRequest(uint32_t frame_number) {
90   ATRACE_CALL();
91   std::lock_guard<std::mutex> lock(result_lock_);
92   RemovePendingRequestLocked(frame_number);
93 }
94 
AddPendingRequest(const CaptureRequest & pending_request)95 status_t ResultDispatcher::AddPendingRequest(
96     const CaptureRequest& pending_request) {
97   ATRACE_CALL();
98   std::lock_guard<std::mutex> lock(result_lock_);
99 
100   status_t res = AddPendingRequestLocked(pending_request);
101   if (res != OK) {
102     ALOGE("[%s] %s: Adding a pending request failed: %s(%d).", name_.c_str(),
103           __FUNCTION__, strerror(-res), res);
104     RemovePendingRequestLocked(pending_request.frame_number);
105     return res;
106   }
107 
108   return OK;
109 }
110 
AddPendingRequestLocked(const CaptureRequest & pending_request)111 status_t ResultDispatcher::AddPendingRequestLocked(
112     const CaptureRequest& pending_request) {
113   ATRACE_CALL();
114   uint32_t frame_number = pending_request.frame_number;
115 
116   status_t res = AddPendingShutterLocked(frame_number);
117   if (res != OK) {
118     ALOGE("[%s] %s: Adding pending shutter for frame %u failed: %s(%d)",
119           name_.c_str(), __FUNCTION__, frame_number, strerror(-res), res);
120     return res;
121   }
122 
123   res = AddPendingFinalResultMetadataLocked(frame_number);
124   if (res != OK) {
125     ALOGE("[%s] %s: Adding pending result metadata for frame %u failed: %s(%d)",
126           name_.c_str(), __FUNCTION__, frame_number, strerror(-res), res);
127     return res;
128   }
129 
130   for (auto& buffer : pending_request.input_buffers) {
131     res = AddPendingBufferLocked(frame_number, buffer, /*is_input=*/true);
132     if (res != OK) {
133       ALOGE("[%s] %s: Adding pending input buffer for frame %u failed: %s(%d)",
134             name_.c_str(), __FUNCTION__, frame_number, strerror(-res), res);
135       return res;
136     }
137   }
138 
139   for (auto& buffer : pending_request.output_buffers) {
140     res = AddPendingBufferLocked(frame_number, buffer, /*is_input=*/false);
141     if (res != OK) {
142       ALOGE("[%s] %s: Adding pending output buffer for frame %u failed: %s(%d)",
143             name_.c_str(), __FUNCTION__, frame_number, strerror(-res), res);
144       return res;
145     }
146   }
147 
148   return OK;
149 }
150 
AddPendingShutterLocked(uint32_t frame_number)151 status_t ResultDispatcher::AddPendingShutterLocked(uint32_t frame_number) {
152   ATRACE_CALL();
153   if (pending_shutters_.find(frame_number) != pending_shutters_.end()) {
154     ALOGE("[%s] %s: Pending shutter for frame %u already exists.",
155           name_.c_str(), __FUNCTION__, frame_number);
156     return ALREADY_EXISTS;
157   }
158 
159   pending_shutters_[frame_number] = PendingShutter();
160   return OK;
161 }
162 
AddPendingFinalResultMetadataLocked(uint32_t frame_number)163 status_t ResultDispatcher::AddPendingFinalResultMetadataLocked(
164     uint32_t frame_number) {
165   ATRACE_CALL();
166   if (pending_final_metadata_.find(frame_number) !=
167       pending_final_metadata_.end()) {
168     ALOGE("[%s] %s: Pending final result metadata for frame %u already exists.",
169           name_.c_str(), __FUNCTION__, frame_number);
170     return ALREADY_EXISTS;
171   }
172 
173   pending_final_metadata_[frame_number] = PendingFinalResultMetadata();
174   return OK;
175 }
176 
AddPendingBufferLocked(uint32_t frame_number,const StreamBuffer & buffer,bool is_input)177 status_t ResultDispatcher::AddPendingBufferLocked(uint32_t frame_number,
178                                                   const StreamBuffer& buffer,
179                                                   bool is_input) {
180   ATRACE_CALL();
181   StreamKey stream_key = CreateStreamKey(buffer.stream_id);
182   if (stream_pending_buffers_map_.find(stream_key) ==
183       stream_pending_buffers_map_.end()) {
184     stream_pending_buffers_map_[stream_key] =
185         std::map<uint32_t, PendingBuffer>();
186   }
187 
188   if (stream_pending_buffers_map_[stream_key].find(frame_number) !=
189       stream_pending_buffers_map_[stream_key].end()) {
190     ALOGE("[%s] %s: Pending buffer of stream %s for frame %u already exists.",
191           name_.c_str(), __FUNCTION__, DumpStreamKey(stream_key).c_str(),
192           frame_number);
193     return ALREADY_EXISTS;
194   }
195 
196   PendingBuffer pending_buffer = {.is_input = is_input};
197   stream_pending_buffers_map_[stream_key][frame_number] = pending_buffer;
198   return OK;
199 }
200 
RemovePendingRequestLocked(uint32_t frame_number)201 void ResultDispatcher::RemovePendingRequestLocked(uint32_t frame_number) {
202   ATRACE_CALL();
203   pending_shutters_.erase(frame_number);
204   pending_final_metadata_.erase(frame_number);
205 
206   for (auto& pending_buffers : stream_pending_buffers_map_) {
207     pending_buffers.second.erase(frame_number);
208   }
209 }
210 
AddResult(std::unique_ptr<CaptureResult> result)211 status_t ResultDispatcher::AddResult(std::unique_ptr<CaptureResult> result) {
212   ATRACE_CALL();
213   status_t res;
214   bool failed = false;
215   uint32_t frame_number = result->frame_number;
216 
217   if (result->result_metadata != nullptr) {
218     res = AddResultMetadata(frame_number, std::move(result->result_metadata),
219                             std::move(result->physical_metadata),
220                             result->partial_result);
221     if (res != OK) {
222       ALOGE("[%s] %s: Adding result metadata failed: %s (%d)", name_.c_str(),
223             __FUNCTION__, strerror(-res), res);
224       failed = true;
225     }
226   }
227 
228   for (auto& buffer : result->output_buffers) {
229     res = AddBuffer(frame_number, buffer);
230     if (res != OK) {
231       ALOGE("[%s] %s: Adding an output buffer failed: %s (%d)", name_.c_str(),
232             __FUNCTION__, strerror(-res), res);
233       failed = true;
234     }
235   }
236 
237   for (auto& buffer : result->input_buffers) {
238     res = AddBuffer(frame_number, buffer);
239     if (res != OK) {
240       ALOGE("[%s] %s: Adding an input buffer failed: %s (%d)", name_.c_str(),
241             __FUNCTION__, strerror(-res), res);
242       failed = true;
243     }
244   }
245   {
246     std::unique_lock<std::mutex> lock(notify_callback_lock_);
247     is_result_shutter_updated_ = true;
248     notify_callback_condition_.notify_one();
249   }
250   return failed ? UNKNOWN_ERROR : OK;
251 }
252 
AddShutter(uint32_t frame_number,int64_t timestamp_ns,int64_t readout_timestamp_ns)253 status_t ResultDispatcher::AddShutter(uint32_t frame_number,
254                                       int64_t timestamp_ns,
255                                       int64_t readout_timestamp_ns) {
256   ATRACE_CALL();
257   {
258     std::lock_guard<std::mutex> lock(result_lock_);
259 
260     auto shutter_it = pending_shutters_.find(frame_number);
261     if (shutter_it == pending_shutters_.end()) {
262       ALOGE("[%s] %s: Cannot find the pending shutter for frame %u",
263             name_.c_str(), __FUNCTION__, frame_number);
264       return NAME_NOT_FOUND;
265     }
266 
267     if (shutter_it->second.ready) {
268       ALOGE("[%s] %s: Already received shutter (%" PRId64
269             ") for frame %u. New timestamp %" PRId64,
270             name_.c_str(), __FUNCTION__, shutter_it->second.timestamp_ns,
271             frame_number, timestamp_ns);
272       return ALREADY_EXISTS;
273     }
274 
275     shutter_it->second.timestamp_ns = timestamp_ns;
276     shutter_it->second.readout_timestamp_ns = readout_timestamp_ns;
277     shutter_it->second.ready = true;
278   }
279   {
280     std::unique_lock<std::mutex> lock(notify_callback_lock_);
281     is_result_shutter_updated_ = true;
282     notify_callback_condition_.notify_one();
283   }
284   return OK;
285 }
286 
AddError(const ErrorMessage & error)287 status_t ResultDispatcher::AddError(const ErrorMessage& error) {
288   ATRACE_CALL();
289   std::lock_guard<std::mutex> lock(result_lock_);
290   uint32_t frame_number = error.frame_number;
291   // No need to deliver the shutter message on an error
292   if (error.error_code == ErrorCode::kErrorDevice ||
293       error.error_code == ErrorCode::kErrorResult ||
294       error.error_code == ErrorCode::kErrorRequest) {
295     pending_shutters_.erase(frame_number);
296   }
297   // No need to deliver the result metadata on a result metadata error
298   if (error.error_code == ErrorCode::kErrorResult ||
299       error.error_code == ErrorCode::kErrorRequest) {
300     pending_final_metadata_.erase(frame_number);
301   }
302 
303   NotifyMessage message = {.type = MessageType::kError, .message.error = error};
304   ALOGV("[%s] %s: Notify error %u for frame %u stream %d", name_.c_str(),
305         __FUNCTION__, error.error_code, frame_number, error.error_stream_id);
306   notify_(message);
307 
308   return OK;
309 }
310 
NotifyResultMetadata(uint32_t frame_number,std::unique_ptr<HalCameraMetadata> metadata,std::vector<PhysicalCameraMetadata> physical_metadata,uint32_t partial_result)311 void ResultDispatcher::NotifyResultMetadata(
312     uint32_t frame_number, std::unique_ptr<HalCameraMetadata> metadata,
313     std::vector<PhysicalCameraMetadata> physical_metadata,
314     uint32_t partial_result) {
315   ATRACE_CALL();
316   auto result = std::make_unique<CaptureResult>(CaptureResult({}));
317   result->frame_number = frame_number;
318   result->result_metadata = std::move(metadata);
319   result->physical_metadata = std::move(physical_metadata);
320   result->partial_result = partial_result;
321 
322   std::lock_guard<std::mutex> lock(process_capture_result_lock_);
323   process_capture_result_(std::move(result));
324 }
325 
AddFinalResultMetadata(uint32_t frame_number,std::unique_ptr<HalCameraMetadata> final_metadata,std::vector<PhysicalCameraMetadata> physical_metadata)326 status_t ResultDispatcher::AddFinalResultMetadata(
327     uint32_t frame_number, std::unique_ptr<HalCameraMetadata> final_metadata,
328     std::vector<PhysicalCameraMetadata> physical_metadata) {
329   ATRACE_CALL();
330   std::lock_guard<std::mutex> lock(result_lock_);
331 
332   auto metadata_it = pending_final_metadata_.find(frame_number);
333   if (metadata_it == pending_final_metadata_.end()) {
334     ALOGE("[%s] %s: Cannot find the pending result metadata for frame %u",
335           name_.c_str(), __FUNCTION__, frame_number);
336     return NAME_NOT_FOUND;
337   }
338 
339   if (metadata_it->second.ready) {
340     ALOGE("[%s] %s: Already received final result metadata for frame %u.",
341           name_.c_str(), __FUNCTION__, frame_number);
342     return ALREADY_EXISTS;
343   }
344 
345   metadata_it->second.metadata = std::move(final_metadata);
346   metadata_it->second.physical_metadata = std::move(physical_metadata);
347   metadata_it->second.ready = true;
348   return OK;
349 }
350 
AddResultMetadata(uint32_t frame_number,std::unique_ptr<HalCameraMetadata> metadata,std::vector<PhysicalCameraMetadata> physical_metadata,uint32_t partial_result)351 status_t ResultDispatcher::AddResultMetadata(
352     uint32_t frame_number, std::unique_ptr<HalCameraMetadata> metadata,
353     std::vector<PhysicalCameraMetadata> physical_metadata,
354     uint32_t partial_result) {
355   ATRACE_CALL();
356   if (metadata == nullptr) {
357     ALOGE("[%s] %s: metadata is nullptr.", name_.c_str(), __FUNCTION__);
358     return BAD_VALUE;
359   }
360 
361   if (partial_result > kPartialResultCount) {
362     ALOGE(
363         "[%s] %s: partial_result %u cannot be larger than partial result count "
364         "%u",
365         name_.c_str(), __FUNCTION__, partial_result, kPartialResultCount);
366     return BAD_VALUE;
367   }
368 
369   if (partial_result < kPartialResultCount) {
370     // Send out partial results immediately.
371     NotifyResultMetadata(frame_number, std::move(metadata),
372                          std::move(physical_metadata), partial_result);
373     return OK;
374   }
375 
376   return AddFinalResultMetadata(frame_number, std::move(metadata),
377                                 std::move(physical_metadata));
378 }
379 
AddBuffer(uint32_t frame_number,StreamBuffer buffer)380 status_t ResultDispatcher::AddBuffer(uint32_t frame_number,
381                                      StreamBuffer buffer) {
382   ATRACE_CALL();
383   std::lock_guard<std::mutex> lock(result_lock_);
384 
385   StreamKey stream_key = CreateStreamKey(buffer.stream_id);
386   auto pending_buffers_it = stream_pending_buffers_map_.find(stream_key);
387   if (pending_buffers_it == stream_pending_buffers_map_.end()) {
388     ALOGE("[%s] %s: Cannot find the pending buffer for stream %s",
389           name_.c_str(), __FUNCTION__, DumpStreamKey(stream_key).c_str());
390     return NAME_NOT_FOUND;
391   }
392 
393   auto pending_buffer_it = pending_buffers_it->second.find(frame_number);
394   if (pending_buffer_it == pending_buffers_it->second.end()) {
395     ALOGE("[%s] %s: Cannot find the pending buffer for stream %s for frame %u",
396           name_.c_str(), __FUNCTION__, DumpStreamKey(stream_key).c_str(),
397           frame_number);
398     return NAME_NOT_FOUND;
399   }
400 
401   if (pending_buffer_it->second.ready) {
402     ALOGE("[%s] %s: Already received a buffer for stream %s for frame %u",
403           name_.c_str(), __FUNCTION__, DumpStreamKey(stream_key).c_str(),
404           frame_number);
405     return ALREADY_EXISTS;
406   }
407 
408   pending_buffer_it->second.buffer = std::move(buffer);
409   pending_buffer_it->second.ready = true;
410 
411   return OK;
412 }
413 
NotifyCallbackThreadLoop()414 void ResultDispatcher::NotifyCallbackThreadLoop() {
415   // '\0' counts toward the 16-character restriction.
416   constexpr int kPthreadNameLenMinusOne = 16 - 1;
417   pthread_setname_np(
418       pthread_self(),
419       name_.substr(/*pos=*/0, /*count=*/kPthreadNameLenMinusOne).c_str());
420 
421   while (1) {
422     NotifyShutters();
423     NotifyFinalResultMetadata();
424     NotifyBuffers();
425 
426     std::unique_lock<std::mutex> lock(notify_callback_lock_);
427     if (notify_callback_thread_exiting_) {
428       ALOGV("[%s] %s: NotifyCallbackThreadLoop exits.", name_.c_str(),
429             __FUNCTION__);
430       return;
431     }
432     if (!is_result_shutter_updated_) {
433       if (notify_callback_condition_.wait_for(
434               lock, std::chrono::milliseconds(kCallbackThreadTimeoutMs)) ==
435           std::cv_status::timeout) {
436         PrintTimeoutMessages();
437       }
438     }
439     is_result_shutter_updated_ = false;
440   }
441 }
442 
PrintTimeoutMessages()443 void ResultDispatcher::PrintTimeoutMessages() {
444   std::lock_guard<std::mutex> lock(result_lock_);
445   for (auto& [frame_number, shutter] : pending_shutters_) {
446     ALOGW("[%s] %s: pending shutter for frame %u ready %d", name_.c_str(),
447           __FUNCTION__, frame_number, shutter.ready);
448   }
449 
450   for (auto& [frame_number, final_metadata] : pending_final_metadata_) {
451     ALOGW("[%s] %s: pending final result metadaata for frame %u ready %d",
452           name_.c_str(), __FUNCTION__, frame_number, final_metadata.ready);
453   }
454 
455   for (auto& [stream_key, pending_buffers] : stream_pending_buffers_map_) {
456     for (auto& [frame_number, pending_buffer] : pending_buffers) {
457       ALOGW("[%s] %s: pending buffer of stream %s for frame %u ready %d",
458             name_.c_str(), __FUNCTION__, DumpStreamKey(stream_key).c_str(),
459             frame_number, pending_buffer.ready);
460     }
461   }
462 }
463 
InitializeGroupStreamIdsMap(const StreamConfiguration & stream_config)464 void ResultDispatcher::InitializeGroupStreamIdsMap(
465     const StreamConfiguration& stream_config) {
466   std::lock_guard<std::mutex> lock(result_lock_);
467   for (const auto& stream : stream_config.streams) {
468     if (stream.group_id != -1) {
469       group_stream_map_[stream.id] = stream.group_id;
470     }
471   }
472 }
473 
CreateStreamKey(int32_t stream_id) const474 ResultDispatcher::StreamKey ResultDispatcher::CreateStreamKey(
475     int32_t stream_id) const {
476   if (group_stream_map_.count(stream_id) == 0) {
477     return StreamKey(stream_id, StreamKeyType::kSingleStream);
478   } else {
479     return StreamKey(group_stream_map_.at(stream_id),
480                      StreamKeyType::kGroupStream);
481   }
482 }
483 
DumpStreamKey(const StreamKey & stream_key) const484 std::string ResultDispatcher::DumpStreamKey(const StreamKey& stream_key) const {
485   switch (stream_key.second) {
486     case StreamKeyType::kSingleStream:
487       return std::to_string(stream_key.first);
488     case StreamKeyType::kGroupStream:
489       return "group " + std::to_string(stream_key.first);
490     default:
491       return "Invalid stream key type";
492   }
493 }
494 
GetReadyShutterMessage(NotifyMessage * message)495 status_t ResultDispatcher::GetReadyShutterMessage(NotifyMessage* message) {
496   ATRACE_CALL();
497   if (message == nullptr) {
498     ALOGE("[%s] %s: message is nullptr", name_.c_str(), __FUNCTION__);
499     return BAD_VALUE;
500   }
501 
502   auto shutter_it = pending_shutters_.begin();
503   if (shutter_it == pending_shutters_.end() || !shutter_it->second.ready) {
504     // The first pending shutter is not ready.
505     return NAME_NOT_FOUND;
506   }
507 
508   message->type = MessageType::kShutter;
509   message->message.shutter.frame_number = shutter_it->first;
510   message->message.shutter.timestamp_ns = shutter_it->second.timestamp_ns;
511   message->message.shutter.readout_timestamp_ns =
512       shutter_it->second.readout_timestamp_ns;
513   pending_shutters_.erase(shutter_it);
514 
515   return OK;
516 }
517 
NotifyShutters()518 void ResultDispatcher::NotifyShutters() {
519   ATRACE_CALL();
520   NotifyMessage message = {};
521   while (true) {
522     std::lock_guard<std::mutex> lock(result_lock_);
523     if (GetReadyShutterMessage(&message) != OK) {
524       break;
525     }
526     ALOGV("[%s] %s: Notify shutter for frame %u timestamp %" PRIu64
527           " readout_timestamp %" PRIu64,
528           name_.c_str(), __FUNCTION__, message.message.shutter.frame_number,
529           message.message.shutter.timestamp_ns,
530           message.message.shutter.readout_timestamp_ns);
531     notify_(message);
532   }
533 }
534 
GetReadyFinalMetadata(uint32_t * frame_number,std::unique_ptr<HalCameraMetadata> * final_metadata,std::vector<PhysicalCameraMetadata> * physical_metadata)535 status_t ResultDispatcher::GetReadyFinalMetadata(
536     uint32_t* frame_number, std::unique_ptr<HalCameraMetadata>* final_metadata,
537     std::vector<PhysicalCameraMetadata>* physical_metadata) {
538   ATRACE_CALL();
539   if (final_metadata == nullptr || frame_number == nullptr) {
540     ALOGE("[%s] %s: final_metadata (%p) or frame_number (%p) is nullptr",
541           name_.c_str(), __FUNCTION__, final_metadata, frame_number);
542     return BAD_VALUE;
543   }
544 
545   std::lock_guard<std::mutex> lock(result_lock_);
546 
547   auto final_metadata_it = pending_final_metadata_.begin();
548   if (final_metadata_it == pending_final_metadata_.end() ||
549       !final_metadata_it->second.ready) {
550     // The first pending final metadata is not ready.
551     return NAME_NOT_FOUND;
552   }
553 
554   *frame_number = final_metadata_it->first;
555   *final_metadata = std::move(final_metadata_it->second.metadata);
556   *physical_metadata = std::move(final_metadata_it->second.physical_metadata);
557   pending_final_metadata_.erase(final_metadata_it);
558 
559   return OK;
560 }
561 
NotifyFinalResultMetadata()562 void ResultDispatcher::NotifyFinalResultMetadata() {
563   ATRACE_CALL();
564   uint32_t frame_number;
565   std::unique_ptr<HalCameraMetadata> final_metadata;
566   std::vector<PhysicalCameraMetadata> physical_metadata;
567 
568   while (GetReadyFinalMetadata(&frame_number, &final_metadata,
569                                &physical_metadata) == OK) {
570     ALOGV("[%s] %s: Notify final metadata for frame %u", name_.c_str(),
571           __FUNCTION__, frame_number);
572     NotifyResultMetadata(frame_number, std::move(final_metadata),
573                          std::move(physical_metadata), kPartialResultCount);
574   }
575 }
576 
GetReadyBufferResult(std::unique_ptr<CaptureResult> * result)577 status_t ResultDispatcher::GetReadyBufferResult(
578     std::unique_ptr<CaptureResult>* result) {
579   ATRACE_CALL();
580   std::lock_guard<std::mutex> lock(result_lock_);
581   if (result == nullptr) {
582     ALOGE("[%s] %s: result is nullptr.", name_.c_str(), __FUNCTION__);
583     return BAD_VALUE;
584   }
585 
586   *result = nullptr;
587 
588   for (auto& pending_buffers : stream_pending_buffers_map_) {
589     auto buffer_it = pending_buffers.second.begin();
590     while (buffer_it != pending_buffers.second.end()) {
591       if (!buffer_it->second.ready) {
592         // No more buffer ready.
593         break;
594       }
595 
596       auto buffer_result = std::make_unique<CaptureResult>(CaptureResult({}));
597 
598       buffer_result->frame_number = buffer_it->first;
599       if (buffer_it->second.is_input) {
600         buffer_result->input_buffers.push_back(buffer_it->second.buffer);
601       } else {
602         buffer_result->output_buffers.push_back(buffer_it->second.buffer);
603       }
604 
605       pending_buffers.second.erase(buffer_it);
606       *result = std::move(buffer_result);
607       return OK;
608     }
609   }
610 
611   return NAME_NOT_FOUND;
612 }
613 
NotifyBuffers()614 void ResultDispatcher::NotifyBuffers() {
615   ATRACE_CALL();
616   std::unique_ptr<CaptureResult> result;
617 
618   while (GetReadyBufferResult(&result) == OK) {
619     if (result == nullptr) {
620       ALOGE("[%s] %s: result is nullptr", name_.c_str(), __FUNCTION__);
621       return;
622     }
623     std::lock_guard<std::mutex> lock(process_capture_result_lock_);
624     process_capture_result_(std::move(result));
625   }
626 }
627 
628 }  // namespace google_camera_hal
629 }  // namespace android
630