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 #include "hal_types.h"
19 #define LOG_TAG "GCH_RealtimeZslResultProcessor"
20 #define ATRACE_TAG ATRACE_TAG_CAMERA
21 
22 #include <inttypes.h>
23 #include <log/log.h>
24 #include <utils/Trace.h>
25 
26 #include "hal_utils.h"
27 #include "realtime_zsl_result_processor.h"
28 
29 namespace android {
30 namespace google_camera_hal {
31 
Create(InternalStreamManager * internal_stream_manager,int32_t stream_id,android_pixel_format_t pixel_format,uint32_t partial_result_count)32 std::unique_ptr<RealtimeZslResultProcessor> RealtimeZslResultProcessor::Create(
33     InternalStreamManager* internal_stream_manager, int32_t stream_id,
34     android_pixel_format_t pixel_format, uint32_t partial_result_count) {
35   ATRACE_CALL();
36   if (internal_stream_manager == nullptr) {
37     ALOGE("%s: internal_stream_manager is nullptr.", __FUNCTION__);
38     return nullptr;
39   }
40   if (pixel_format != android_pixel_format_t::HAL_PIXEL_FORMAT_YCBCR_420_888) {
41     ALOGE("%s: only YCBCR_420_888 is supported for YUV ZSL", __FUNCTION__);
42     return nullptr;
43   }
44 
45   auto result_processor =
46       std::unique_ptr<RealtimeZslResultProcessor>(new RealtimeZslResultProcessor(
47           internal_stream_manager, stream_id, partial_result_count));
48   if (result_processor == nullptr) {
49     ALOGE("%s: Creating RealtimeZslResultProcessor failed.", __FUNCTION__);
50     return nullptr;
51   }
52 
53   return result_processor;
54 }
55 
RealtimeZslResultProcessor(InternalStreamManager * internal_stream_manager,int32_t stream_id,uint32_t partial_result_count)56 RealtimeZslResultProcessor::RealtimeZslResultProcessor(
57     InternalStreamManager* internal_stream_manager, int32_t stream_id,
58     uint32_t partial_result_count) {
59   internal_stream_manager_ = internal_stream_manager;
60   stream_id_ = stream_id;
61   partial_result_count_ = partial_result_count;
62 }
63 
SetResultCallback(ProcessCaptureResultFunc process_capture_result,NotifyFunc notify,ProcessBatchCaptureResultFunc)64 void RealtimeZslResultProcessor::SetResultCallback(
65     ProcessCaptureResultFunc process_capture_result, NotifyFunc notify,
66     ProcessBatchCaptureResultFunc /*process_batch_capture_result*/) {
67   std::lock_guard<std::mutex> lock(callback_lock_);
68   process_capture_result_ = process_capture_result;
69   notify_ = notify;
70 }
71 
AddPendingRequests(const std::vector<ProcessBlockRequest> & process_block_requests,const CaptureRequest & remaining_session_request)72 status_t RealtimeZslResultProcessor::AddPendingRequests(
73     const std::vector<ProcessBlockRequest>& process_block_requests,
74     const CaptureRequest& remaining_session_request) {
75   ATRACE_CALL();
76   // This is the last result processor. Sanity check if requests contains
77   // all remaining output buffers.
78   if (!hal_utils::AreAllRemainingBuffersRequested(process_block_requests,
79                                                   remaining_session_request)) {
80     ALOGE("%s: Some output buffers will not be completed.", __FUNCTION__);
81     return BAD_VALUE;
82   }
83 
84   return OK;
85 }
86 
ProcessResult(ProcessBlockResult block_result)87 void RealtimeZslResultProcessor::ProcessResult(ProcessBlockResult block_result) {
88   ATRACE_CALL();
89   std::lock_guard<std::mutex> lock(callback_lock_);
90   std::unique_ptr<CaptureResult> result = std::move(block_result.result);
91   if (result == nullptr) {
92     ALOGW("%s: Received a nullptr result.", __FUNCTION__);
93     return;
94   }
95 
96   if (process_capture_result_ == nullptr) {
97     ALOGE("%s: process_capture_result_ is nullptr. Dropping a result.",
98           __FUNCTION__);
99     return;
100   }
101 
102   // Return filled buffer to internal stream manager
103   // And remove buffer from result
104   bool returned_output = false;
105   status_t res;
106   std::vector<StreamBuffer> modified_output_buffers;
107   for (uint32_t i = 0; i < result->output_buffers.size(); i++) {
108     if (stream_id_ == result->output_buffers[i].stream_id) {
109       returned_output = true;
110       res = internal_stream_manager_->ReturnFilledBuffer(
111           result->frame_number, result->output_buffers[i]);
112       if (res != OK) {
113         ALOGW("%s: (%d)ReturnStreamBuffer fail", __FUNCTION__,
114               result->frame_number);
115       }
116     } else {
117       modified_output_buffers.push_back(result->output_buffers[i]);
118     }
119   }
120 
121   if (result->output_buffers.size() > 0) {
122     result->output_buffers.clear();
123     result->output_buffers = modified_output_buffers;
124   }
125 
126   if (result->result_metadata) {
127     result->result_metadata->Erase(ANDROID_CONTROL_ENABLE_ZSL);
128 
129     res = internal_stream_manager_->ReturnMetadata(
130         stream_id_, result->frame_number, result->result_metadata.get(),
131         result->partial_result);
132     if (res != OK) {
133       ALOGW("%s: (%d)ReturnMetadata fail", __FUNCTION__, result->frame_number);
134     }
135 
136     if (result->partial_result == partial_result_count_) {
137       res =
138           hal_utils::SetEnableZslMetadata(result->result_metadata.get(), false);
139       if (res != OK) {
140         ALOGW("%s: SetEnableZslMetadata (%d) fail", __FUNCTION__,
141               result->frame_number);
142       }
143     }
144   }
145 
146   // Don't send result to framework if only internal callback
147   if (returned_output && result->result_metadata == nullptr &&
148       result->output_buffers.size() == 0) {
149     return;
150   }
151 
152   process_capture_result_(std::move(result));
153 }
154 
Notify(const ProcessBlockNotifyMessage & block_message)155 void RealtimeZslResultProcessor::Notify(
156     const ProcessBlockNotifyMessage& block_message) {
157   ATRACE_CALL();
158   std::lock_guard<std::mutex> lock(callback_lock_);
159   const NotifyMessage& message = block_message.message;
160   if (notify_ == nullptr) {
161     ALOGE("%s: notify_ is nullptr. Dropping a message.", __FUNCTION__);
162     return;
163   }
164 
165   // Do not notify errors for internal streams
166   if (message.type == MessageType::kError &&
167       message.message.error.error_stream_id == stream_id_) {
168     return;
169   }
170 
171   notify_(message);
172 }
173 
FlushPendingRequests()174 status_t RealtimeZslResultProcessor::FlushPendingRequests() {
175   ATRACE_CALL();
176   return INVALID_OPERATION;
177 }
178 
179 }  // namespace google_camera_hal
180 }  // namespace android
181