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