• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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