1 /*
2 * device_manager.h - device manager
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
21 #include "device_manager.h"
22 #include "poll_thread.h"
23 #include "xcam_thread.h"
24 #include "x3a_image_process_center.h"
25 #include "x3a_analyzer_manager.h"
26
27 #define XCAM_FAILED_STOP(exp, msg, ...) \
28 if ((exp) != XCAM_RETURN_NO_ERROR) { \
29 XCAM_LOG_ERROR (msg, ## __VA_ARGS__); \
30 stop (); \
31 return ret; \
32 }
33
34 namespace XCam {
35
36 class MessageThread
37 : public Thread
38 {
39 public:
MessageThread(DeviceManager * dev_manager)40 explicit MessageThread (DeviceManager *dev_manager)
41 : Thread ("MessageThread")
42 , _manager (dev_manager)
43 {}
44
45 protected:
46 virtual bool loop ();
47
48 DeviceManager *_manager;
49 };
50
51 bool
loop()52 MessageThread::loop()
53 {
54 XCamReturn ret = _manager->message_loop();
55 if (ret == XCAM_RETURN_NO_ERROR || ret == XCAM_RETURN_ERROR_TIMEOUT)
56 return true;
57
58 return false;
59 }
60
XCamMessage(XCamMessageType type,int64_t timestamp,const char * message)61 XCamMessage::XCamMessage (XCamMessageType type, int64_t timestamp, const char *message)
62 : timestamp (timestamp)
63 , msg_id (type)
64 , msg (NULL)
65 {
66 if (message)
67 this->msg = strndup (message, XCAM_MAX_STR_SIZE);
68 }
69
~XCamMessage()70 XCamMessage::~XCamMessage ()
71 {
72 if (msg)
73 xcam_free (msg);
74 }
75
DeviceManager()76 DeviceManager::DeviceManager()
77 : _has_3a (true)
78 , _is_running (false)
79 {
80 _3a_process_center = new X3aImageProcessCenter;
81 XCAM_LOG_DEBUG ("~DeviceManager construction");
82 }
83
~DeviceManager()84 DeviceManager::~DeviceManager()
85 {
86 XCAM_LOG_DEBUG ("~DeviceManager destruction");
87 }
88
89 bool
set_capture_device(SmartPtr<V4l2Device> device)90 DeviceManager::set_capture_device (SmartPtr<V4l2Device> device)
91 {
92 if (is_running())
93 return false;
94
95 XCAM_ASSERT (device.ptr () && !_device.ptr ());
96 _device = device;
97 return true;
98 }
99
100 bool
set_event_device(SmartPtr<V4l2SubDevice> device)101 DeviceManager::set_event_device (SmartPtr<V4l2SubDevice> device)
102 {
103 if (is_running())
104 return false;
105
106 XCAM_ASSERT (device.ptr () && !_subdevice.ptr ());
107 _subdevice = device;
108 return true;
109 }
110
111 bool
set_3a_analyzer(SmartPtr<X3aAnalyzer> analyzer)112 DeviceManager::set_3a_analyzer (SmartPtr<X3aAnalyzer> analyzer)
113 {
114 if (is_running())
115 return false;
116
117 XCAM_ASSERT (analyzer.ptr () && !_3a_analyzer.ptr ());
118 _3a_analyzer = analyzer;
119
120 return true;
121 }
122
123 bool
set_smart_analyzer(SmartPtr<SmartAnalyzer> analyzer)124 DeviceManager::set_smart_analyzer (SmartPtr<SmartAnalyzer> analyzer)
125 {
126 if (is_running())
127 return false;
128
129 XCAM_ASSERT (analyzer.ptr () && !_smart_analyzer.ptr ());
130 _smart_analyzer = analyzer;
131
132 return true;
133 }
134
135 bool
add_image_processor(SmartPtr<ImageProcessor> processor)136 DeviceManager::add_image_processor (SmartPtr<ImageProcessor> processor)
137 {
138 if (is_running())
139 return false;
140
141 XCAM_ASSERT (processor.ptr ());
142 return _3a_process_center->insert_processor (processor);
143 }
144
145 bool
set_poll_thread(SmartPtr<PollThread> thread)146 DeviceManager::set_poll_thread (SmartPtr<PollThread> thread)
147 {
148 if (is_running ())
149 return false;
150
151 XCAM_ASSERT (thread.ptr () && !_poll_thread.ptr ());
152 _poll_thread = thread;
153 return true;
154 }
155
156 XCamReturn
start()157 DeviceManager::start ()
158 {
159 XCamReturn ret = XCAM_RETURN_NO_ERROR;
160
161 // start device
162 XCAM_ASSERT (_device->is_opened());
163 if (!_device.ptr() || !_device->is_opened()) {
164 XCAM_FAILED_STOP (ret = XCAM_RETURN_ERROR_FILE, "capture device not ready");
165 }
166 XCAM_FAILED_STOP (ret = _device->start(), "capture device start failed");
167
168 //start subdevice
169 //XCAM_ASSERT (_subdevice->is_opened());
170 if (_subdevice.ptr()) {
171 if (!_subdevice->is_opened())
172 XCAM_FAILED_STOP (ret = XCAM_RETURN_ERROR_FILE, "event device not ready");
173 XCAM_FAILED_STOP (ret = _subdevice->start(), "start event device failed");
174 }
175
176 if (_has_3a) {
177 // Initialize and start analyzer
178 uint32_t width = 0, height = 0;
179 uint32_t fps_n = 0, fps_d = 0;
180 double framerate = 30.0;
181
182 if (!_3a_analyzer.ptr()) {
183 _3a_analyzer = X3aAnalyzerManager::instance()->create_analyzer();
184 if (!_3a_analyzer.ptr()) {
185 XCAM_FAILED_STOP (ret = XCAM_RETURN_ERROR_PARAM, "create analyzer failed");
186 }
187 }
188 if (_3a_analyzer->prepare_handlers () != XCAM_RETURN_NO_ERROR) {
189 XCAM_FAILED_STOP (ret = XCAM_RETURN_ERROR_PARAM, "prepare analyzer handler failed");
190 }
191 _3a_analyzer->set_results_callback (this);
192
193 _device->get_size (width, height);
194 _device->get_framerate (fps_n, fps_d);
195 if (fps_d)
196 framerate = (double)fps_n / (double)fps_d;
197 XCAM_FAILED_STOP (
198 ret = _3a_analyzer->init (width, height, framerate),
199 "initialize analyzer failed");
200
201 XCAM_FAILED_STOP (ret = _3a_analyzer->start (), "start analyzer failed");
202
203 if (_smart_analyzer.ptr()) {
204 if (_smart_analyzer->prepare_handlers () != XCAM_RETURN_NO_ERROR) {
205 XCAM_LOG_INFO ("prepare smart analyzer handler failed");
206 }
207 _smart_analyzer->set_results_callback (this);
208 if (_smart_analyzer->init (width, height, framerate) != XCAM_RETURN_NO_ERROR) {
209 XCAM_LOG_INFO ("initialize smart analyzer failed");
210 }
211 if (_smart_analyzer->start () != XCAM_RETURN_NO_ERROR) {
212 XCAM_LOG_INFO ("start smart analyzer failed");
213 }
214 }
215
216 if (!_3a_process_center->has_processors ()) {
217 XCAM_LOG_ERROR ("image processors empty");
218 }
219
220 _3a_process_center->set_image_callback(this);
221 XCAM_FAILED_STOP (ret = _3a_process_center->start (), "3A process center start failed");
222
223 }
224
225 //Initialize and start poll thread
226 XCAM_ASSERT (_poll_thread.ptr ());
227 _poll_thread->set_capture_device (_device);
228 if (_subdevice.ptr ())
229 _poll_thread->set_event_device (_subdevice);
230 _poll_thread->set_poll_callback (this);
231 _poll_thread->set_stats_callback (this);
232
233 XCAM_FAILED_STOP (ret = _poll_thread->start(), "start poll failed");
234
235 _is_running = true;
236
237 XCAM_LOG_DEBUG ("Device manager started");
238 return XCAM_RETURN_NO_ERROR;
239 }
240
241 XCamReturn
stop()242 DeviceManager::stop ()
243 {
244 _is_running = false;
245
246 if (_poll_thread.ptr())
247 _poll_thread->stop ();
248
249 if (_3a_analyzer.ptr()) {
250 _3a_analyzer->stop ();
251 _3a_analyzer->deinit ();
252 }
253 if (_smart_analyzer.ptr()) {
254 _smart_analyzer->stop ();
255 _smart_analyzer->deinit ();
256 }
257
258 if (_3a_process_center.ptr())
259 _3a_process_center->stop ();
260
261 if (_subdevice.ptr ())
262 _subdevice->stop ();
263
264 _device->stop ();
265
266 _poll_thread.release ();
267
268 XCAM_LOG_DEBUG ("Device manager stopped");
269 return XCAM_RETURN_NO_ERROR;
270 }
271
272 XCamReturn
x3a_stats_ready(const SmartPtr<X3aStats> & stats)273 DeviceManager::x3a_stats_ready (const SmartPtr<X3aStats> &stats)
274 {
275 XCamReturn ret = XCAM_RETURN_NO_ERROR;
276 X3aResultList results;
277 XCAM_ASSERT (_3a_analyzer.ptr());
278
279 ret = _3a_analyzer->push_3a_stats (stats);
280 XCAM_FAIL_RETURN (ERROR,
281 ret == XCAM_RETURN_NO_ERROR,
282 ret,
283 "analyze 3a statistics failed");
284
285 return XCAM_RETURN_NO_ERROR;
286 }
287
288 XCamReturn
dvs_stats_ready()289 DeviceManager::dvs_stats_ready ()
290 {
291 XCAM_ASSERT (false);
292 // TODO
293 return XCAM_RETURN_NO_ERROR;
294 }
295
296 XCamReturn
scaled_image_ready(const SmartPtr<VideoBuffer> & buffer)297 DeviceManager::scaled_image_ready (const SmartPtr<VideoBuffer> &buffer)
298 {
299 XCamReturn ret = XCAM_RETURN_NO_ERROR;
300 if (!_smart_analyzer.ptr()) {
301 return XCAM_RETURN_NO_ERROR;
302 }
303
304 ret = _smart_analyzer->push_buffer (buffer);
305 XCAM_FAIL_RETURN (
306 ERROR, ret == XCAM_RETURN_NO_ERROR, ret,
307 "push frame buffer failed");
308
309 return XCAM_RETURN_NO_ERROR;
310 }
311
312
313 XCamReturn
poll_buffer_ready(SmartPtr<VideoBuffer> & buf)314 DeviceManager::poll_buffer_ready (SmartPtr<VideoBuffer> &buf)
315 {
316 if (_has_3a) {
317 if (_3a_process_center->put_buffer (buf) == false)
318 return XCAM_RETURN_ERROR_UNKNOWN;
319 }
320 return XCAM_RETURN_NO_ERROR;
321 }
322
323 XCamReturn
poll_buffer_failed(int64_t timestamp,const char * msg)324 DeviceManager::poll_buffer_failed (int64_t timestamp, const char *msg)
325 {
326 post_message (XCAM_MESSAGE_BUF_ERROR, timestamp, msg);
327 return XCAM_RETURN_NO_ERROR;
328 }
329
330 void
x3a_calculation_done(XAnalyzer * analyzer,X3aResultList & results)331 DeviceManager::x3a_calculation_done (XAnalyzer *analyzer, X3aResultList &results)
332 {
333 XCamReturn ret = _3a_process_center->put_3a_results (results);
334 if (ret != XCAM_RETURN_NO_ERROR && ret != XCAM_RETURN_BYPASS) {
335 XCAM_LOG_WARNING ("apply 3a results failed");
336 return;
337 }
338 AnalyzerCallback::x3a_calculation_done (analyzer, results);
339 }
340
341 void
x3a_calculation_failed(XAnalyzer * analyzer,int64_t timestamp,const char * msg)342 DeviceManager::x3a_calculation_failed (XAnalyzer *analyzer, int64_t timestamp, const char *msg)
343 {
344 AnalyzerCallback::x3a_calculation_failed (analyzer, timestamp, msg);
345 }
346
347 void
process_buffer_done(ImageProcessor * processor,const SmartPtr<VideoBuffer> & buf)348 DeviceManager::process_buffer_done (ImageProcessor *processor, const SmartPtr<VideoBuffer> &buf)
349 {
350 ImageProcessCallback::process_buffer_done (processor, buf);
351 handle_buffer (buf);
352 }
353
354 void
process_buffer_failed(ImageProcessor * processor,const SmartPtr<VideoBuffer> & buf)355 DeviceManager::process_buffer_failed (ImageProcessor *processor, const SmartPtr<VideoBuffer> &buf)
356 {
357 ImageProcessCallback::process_buffer_failed (processor, buf);
358 }
359
360 void
process_image_result_done(ImageProcessor * processor,const SmartPtr<X3aResult> & result)361 DeviceManager::process_image_result_done (ImageProcessor *processor, const SmartPtr<X3aResult> &result)
362 {
363 ImageProcessCallback::process_image_result_done (processor, result);
364 }
365
366 void
post_message(XCamMessageType type,int64_t timestamp,const char * msg)367 DeviceManager::post_message (XCamMessageType type, int64_t timestamp, const char *msg)
368 {
369 SmartPtr<XCamMessage> new_msg = new XCamMessage (type, timestamp, msg);
370 _msg_queue.push (new_msg);
371 }
372
373 XCamReturn
message_loop()374 DeviceManager::message_loop ()
375 {
376 const static int32_t msg_time_out = -1; //wait until wakeup
377 SmartPtr<XCamMessage> msg = _msg_queue.pop (msg_time_out);
378 if (!msg.ptr ())
379 return XCAM_RETURN_ERROR_THREAD;
380 handle_message (msg);
381 return XCAM_RETURN_NO_ERROR;
382 }
383
384 };
385