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 (at) 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: 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 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 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 70 XCamMessage::~XCamMessage () 71 { 72 if (msg) 73 xcam_free (msg); 74 } 75 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 84 DeviceManager::~DeviceManager() 85 { 86 XCAM_LOG_DEBUG ("~DeviceManager destruction"); 87 } 88 89 bool 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 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 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 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 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 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 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 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 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 289 DeviceManager::dvs_stats_ready () 290 { 291 XCAM_ASSERT (false); 292 // TODO 293 return XCAM_RETURN_NO_ERROR; 294 } 295 296 XCamReturn 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 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 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 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 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 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 355 DeviceManager::process_buffer_failed (ImageProcessor *processor, const SmartPtr<VideoBuffer> &buf) 356 { 357 ImageProcessCallback::process_buffer_failed (processor, buf); 358 } 359 360 void 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 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 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