1 /*
2 * x3a_image_process_center.cpp - 3a process center
3 *
4 * Copyright (c) 2014-2015 Intel Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Author: Wind Yuan <feng.yuan@intel.com>
19 */
20 #include "x3a_image_process_center.h"
21
22 namespace XCam {
23
X3aImageProcessCenter()24 X3aImageProcessCenter::X3aImageProcessCenter()
25 : _callback (NULL)
26 {
27 XCAM_LOG_DEBUG ("X3aImageProcessCenter construction");
28 }
29
~X3aImageProcessCenter()30 X3aImageProcessCenter::~X3aImageProcessCenter()
31 {
32 stop ();
33 XCAM_LOG_DEBUG ("~X3aImageProcessCenter destruction");
34 }
35
36 bool
set_image_callback(ImageProcessCallback * callback)37 X3aImageProcessCenter::set_image_callback (ImageProcessCallback *callback)
38 {
39 XCAM_ASSERT (!_callback);
40 _callback = callback;
41 return true;
42 }
43
44 bool
insert_processor(SmartPtr<ImageProcessor> & processor)45 X3aImageProcessCenter::insert_processor (SmartPtr<ImageProcessor> &processor)
46 {
47 _image_processors.push_back (processor);
48 XCAM_LOG_INFO ("Add processor(%s) into image processor center", XCAM_STR (processor->get_name()));
49 return true;
50 }
51
52 bool
has_processors()53 X3aImageProcessCenter::has_processors ()
54 {
55 return !_image_processors.empty();
56 }
57
58 XCamReturn
start()59 X3aImageProcessCenter::start ()
60 {
61 XCamReturn ret = XCAM_RETURN_NO_ERROR;
62
63 if (_image_processors.empty()) {
64 XCAM_LOG_ERROR ("process center start failed, no processor found");
65 return XCAM_RETURN_ERROR_PARAM;
66 }
67
68 for (ImageProcessorList::iterator i_pro = _image_processors.begin ();
69 i_pro != _image_processors.end(); ++i_pro)
70 {
71 SmartPtr<ImageProcessor> &processor = *i_pro;
72 XCAM_ASSERT (processor.ptr());
73 processor->set_callback (this);
74 ret = processor->start ();
75 if (ret != XCAM_RETURN_NO_ERROR) {
76 XCAM_LOG_ERROR ("processor(%s) start failed", XCAM_STR(processor->get_name()));
77 break;
78 }
79 }
80
81 if (ret != XCAM_RETURN_NO_ERROR)
82 stop();
83 else {
84 XCAM_LOG_INFO ("3a process center started");
85 }
86
87 return ret;
88 }
89
90 XCamReturn
stop()91 X3aImageProcessCenter::stop ()
92 {
93 for (ImageProcessorList::iterator i_pro = _image_processors.begin ();
94 i_pro != _image_processors.end(); ++i_pro)
95 {
96 SmartPtr<ImageProcessor> &processor = *i_pro;
97 XCAM_ASSERT (processor.ptr());
98 processor->stop ();
99 }
100
101 XCAM_LOG_INFO ("3a process center stopped");
102
103 _image_processors.clear();
104 return XCAM_RETURN_NO_ERROR;
105 }
106
107 bool
put_buffer(SmartPtr<VideoBuffer> & buf)108 X3aImageProcessCenter::put_buffer (SmartPtr<VideoBuffer> &buf)
109 {
110 XCAM_ASSERT (!_image_processors.empty());
111 if (_image_processors.empty())
112 return false;
113
114 ImageProcessorList::iterator i_pro = _image_processors.begin ();
115 SmartPtr<ImageProcessor> &processor = *i_pro;
116 if (processor->push_buffer (buf) != XCAM_RETURN_NO_ERROR)
117 return false;
118 return true;
119 }
120
121
122 XCamReturn
put_3a_results(X3aResultList & results)123 X3aImageProcessCenter::put_3a_results (X3aResultList &results)
124 {
125 XCamReturn ret = XCAM_RETURN_NO_ERROR;
126
127 XCAM_FAIL_RETURN (ERROR, !results.empty(), XCAM_RETURN_ERROR_PARAM, "results empty");
128
129 for (ImageProcessorIter i_pro = _image_processors.begin();
130 i_pro != _image_processors.end(); i_pro++) {
131 SmartPtr<ImageProcessor> &processor = *i_pro;
132 XCAM_ASSERT (processor.ptr());
133 ret = processor->push_3a_results (results);
134 if (ret != XCAM_RETURN_NO_ERROR && ret != XCAM_RETURN_BYPASS) {
135 XCAM_LOG_WARNING ("processor(%s) gailed on results", XCAM_STR(processor->get_name()));
136 break;
137 }
138 if (results.empty ()) {
139 XCAM_LOG_DEBUG ("results done");
140 return XCAM_RETURN_NO_ERROR;
141 }
142 }
143
144 if (!results.empty()) {
145 XCAM_LOG_DEBUG ("process center: results left without being processed");
146 return XCAM_RETURN_BYPASS;
147 }
148
149 return XCAM_RETURN_NO_ERROR;
150 }
151
152 XCamReturn
put_3a_result(SmartPtr<X3aResult> & result)153 X3aImageProcessCenter::put_3a_result (SmartPtr<X3aResult> &result)
154 {
155 XCamReturn ret = XCAM_RETURN_NO_ERROR;
156
157 XCAM_FAIL_RETURN (ERROR, !result.ptr(), XCAM_RETURN_ERROR_PARAM, "result empty");
158
159 for (ImageProcessorIter i_pro = _image_processors.begin();
160 i_pro != _image_processors.end(); i_pro++)
161 {
162 SmartPtr<ImageProcessor> &processor = *i_pro;
163 XCAM_ASSERT (processor.ptr());
164 ret = processor->push_3a_result (result);
165
166 if (ret == XCAM_RETURN_BYPASS)
167 continue;
168
169 if (ret == XCAM_RETURN_NO_ERROR)
170 return XCAM_RETURN_NO_ERROR;
171
172 XCAM_LOG_WARNING ("processor(%s) failed on result", XCAM_STR(processor->get_name()));
173 return ret;
174 }
175
176 if (ret == XCAM_RETURN_BYPASS) {
177 XCAM_LOG_WARNING ("processor center: no processor can handle result()");
178 }
179
180 return ret;
181 }
182
183 void
process_buffer_done(ImageProcessor * processor,const SmartPtr<VideoBuffer> & buf)184 X3aImageProcessCenter::process_buffer_done (ImageProcessor *processor, const SmartPtr<VideoBuffer> &buf)
185 {
186 ImageProcessorIter i_pro = _image_processors.begin();
187 for (; i_pro != _image_processors.end(); ++i_pro)
188 {
189 SmartPtr<ImageProcessor> &cur_pro = *i_pro;
190 XCAM_ASSERT (cur_pro.ptr());
191 if (cur_pro.ptr() == processor)
192 break;
193 }
194
195 XCAM_ASSERT (i_pro != _image_processors.end());
196 if (i_pro == _image_processors.end()) {
197 XCAM_LOG_ERROR ("processor doesn't found from list of image center");
198 return;
199 }
200
201 if (++i_pro != _image_processors.end()) {
202 SmartPtr<ImageProcessor> &next_processor = *i_pro;
203 SmartPtr<VideoBuffer> cur_buf = buf;
204 XCAM_ASSERT (next_processor.ptr());
205 XCamReturn ret = next_processor->push_buffer (cur_buf);
206 if (ret != XCAM_RETURN_NO_ERROR) {
207 XCAM_LOG_ERROR ("processor(%s) failed in push_buffer", next_processor->get_name());
208 }
209 return;
210 }
211
212 //all processor done
213 if (_callback)
214 _callback->process_buffer_done (processor, buf);
215 else
216 ImageProcessCallback::process_buffer_done (processor, buf);
217 }
218
219 void
process_buffer_failed(ImageProcessor * processor,const SmartPtr<VideoBuffer> & buf)220 X3aImageProcessCenter::process_buffer_failed (ImageProcessor *processor, const SmartPtr<VideoBuffer> &buf)
221 {
222 if (_callback)
223 _callback->process_buffer_failed(processor, buf);
224 else
225 ImageProcessCallback::process_buffer_failed (processor, buf);
226 }
227
228 void
process_image_result_done(ImageProcessor * processor,const SmartPtr<X3aResult> & result)229 X3aImageProcessCenter::process_image_result_done (ImageProcessor *processor, const SmartPtr<X3aResult> &result)
230 {
231 if (_callback)
232 _callback->process_image_result_done(processor, result);
233 else
234 ImageProcessCallback::process_image_result_done (processor, result);
235 }
236
237 };
238