Home | History | Annotate | Download | only in xcore
      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