• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * poll_thread.cpp - poll thread for event and buffer
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 "poll_thread.h"
22 #include "xcam_thread.h"
23 #include <unistd.h>
24 
25 namespace XCam {
26 
27 class PollThread;
28 
29 class EventPollThread
30     : public Thread
31 {
32 public:
EventPollThread(PollThread * poll)33     EventPollThread (PollThread *poll)
34         : Thread ("event_poll")
35         , _poll (poll)
36     {}
37 
38 protected:
started()39     virtual bool started () {
40         XCamReturn ret = _poll->init_3a_stats_pool ();
41         if (ret != XCAM_RETURN_NO_ERROR)
42             return false;
43         return true;
44     }
loop()45     virtual bool loop () {
46         XCamReturn ret = _poll->poll_subdev_event_loop ();
47 
48         if (ret == XCAM_RETURN_NO_ERROR || ret == XCAM_RETURN_ERROR_TIMEOUT)
49             return true;
50         return false;
51     }
52 
53 private:
54     PollThread   *_poll;
55 };
56 
57 class CapturePollThread
58     : public Thread
59 {
60 public:
CapturePollThread(PollThread * poll)61     CapturePollThread (PollThread *poll)
62         : Thread ("capture_poll")
63         , _poll (poll)
64     {}
65 
66 protected:
loop()67     virtual bool loop () {
68         XCamReturn ret = _poll->poll_buffer_loop ();
69 
70         if (ret == XCAM_RETURN_NO_ERROR || ret == XCAM_RETURN_ERROR_TIMEOUT)
71             return true;
72         return false;
73     }
74 
75 private:
76     PollThread   *_poll;
77 };
78 
79 const int PollThread::default_subdev_event_timeout = 100; // ms
80 const int PollThread::default_capture_event_timeout = 100; // ms
81 
PollThread()82 PollThread::PollThread ()
83     : _poll_callback (NULL)
84     , _stats_callback (NULL)
85 {
86     _event_loop = new EventPollThread(this);
87     _capture_loop = new CapturePollThread (this);
88 
89     XCAM_LOG_DEBUG ("PollThread constructed");
90 }
91 
~PollThread()92 PollThread::~PollThread ()
93 {
94     stop();
95 
96     XCAM_LOG_DEBUG ("~PollThread destructed");
97 }
98 
99 bool
set_capture_device(SmartPtr<V4l2Device> & dev)100 PollThread::set_capture_device (SmartPtr<V4l2Device> &dev)
101 {
102     XCAM_ASSERT (!_capture_dev.ptr());
103     _capture_dev = dev;
104     return true;
105 }
106 
107 bool
set_event_device(SmartPtr<V4l2SubDevice> & dev)108 PollThread::set_event_device (SmartPtr<V4l2SubDevice> &dev)
109 {
110     XCAM_ASSERT (!_event_dev.ptr());
111     _event_dev = dev;
112     return true;
113 }
114 
115 bool
set_poll_callback(PollCallback * callback)116 PollThread::set_poll_callback (PollCallback *callback)
117 {
118     XCAM_ASSERT (!_poll_callback);
119     _poll_callback = callback;
120     return true;
121 }
122 
123 bool
set_stats_callback(StatsCallback * callback)124 PollThread::set_stats_callback (StatsCallback *callback)
125 {
126     XCAM_ASSERT (!_stats_callback);
127     _stats_callback = callback;
128     return true;
129 }
130 
start()131 XCamReturn PollThread::start ()
132 {
133     if (_event_dev.ptr () && !_event_loop->start ()) {
134         return XCAM_RETURN_ERROR_THREAD;
135     }
136     if (!_capture_loop->start ()) {
137         return XCAM_RETURN_ERROR_THREAD;
138     }
139 
140     return XCAM_RETURN_NO_ERROR;
141 }
142 
stop()143 XCamReturn PollThread::stop ()
144 {
145     _event_loop->stop ();
146     _capture_loop->stop ();
147 
148     return XCAM_RETURN_NO_ERROR;
149 }
150 
151 XCamReturn
init_3a_stats_pool()152 PollThread::init_3a_stats_pool ()
153 {
154     return XCAM_RETURN_NO_ERROR;
155 }
156 
157 XCamReturn
capture_3a_stats(SmartPtr<X3aStats> & stats)158 PollThread::capture_3a_stats (SmartPtr<X3aStats> &stats)
159 {
160     XCAM_UNUSED (stats);
161 
162     return XCAM_RETURN_NO_ERROR;
163 }
164 
165 XCamReturn
handle_events(struct v4l2_event & event)166 PollThread::handle_events (struct v4l2_event &event)
167 {
168     XCAM_UNUSED (event);
169 
170     return XCAM_RETURN_NO_ERROR;
171 }
172 
173 XCamReturn
handle_3a_stats_event(struct v4l2_event & event)174 PollThread::handle_3a_stats_event (struct v4l2_event &event)
175 {
176     XCamReturn ret = XCAM_RETURN_NO_ERROR;
177     SmartPtr<X3aStats> stats;
178 
179     ret = capture_3a_stats (stats);
180     if (ret != XCAM_RETURN_NO_ERROR || !stats.ptr()) {
181         XCAM_LOG_WARNING ("capture 3a stats failed");
182         return ret;
183     }
184     stats->set_timestamp (XCAM_TIMESPEC_2_USEC (event.timestamp));
185 
186     if (_stats_callback)
187         return _stats_callback->x3a_stats_ready (stats);
188 
189     return ret;
190 }
191 
192 XCamReturn
poll_subdev_event_loop()193 PollThread::poll_subdev_event_loop ()
194 {
195     XCamReturn ret = XCAM_RETURN_NO_ERROR;
196     struct v4l2_event event;
197     int poll_ret = 0;
198 
199     poll_ret = _event_dev->poll_event (PollThread::default_subdev_event_timeout);
200 
201     if (poll_ret < 0) {
202         XCAM_LOG_WARNING ("poll event failed but continue");
203         ::usleep (100000); // 100ms
204         return XCAM_RETURN_ERROR_TIMEOUT;
205     }
206 
207     /* timeout */
208     if (poll_ret == 0) {
209         XCAM_LOG_DEBUG ("poll event timeout and continue");
210         return XCAM_RETURN_ERROR_TIMEOUT;
211     }
212 
213     xcam_mem_clear (event);
214     ret = _event_dev->dequeue_event (event);
215     if (ret != XCAM_RETURN_NO_ERROR) {
216         XCAM_LOG_WARNING ("dequeue event failed on dev:%s", XCAM_STR(_event_dev->get_device_name()));
217         return XCAM_RETURN_ERROR_IOCTL;
218     }
219 
220     ret = handle_events (event);
221     return ret;
222 }
223 
224 XCamReturn
poll_buffer_loop()225 PollThread::poll_buffer_loop ()
226 {
227     XCamReturn ret = XCAM_RETURN_NO_ERROR;
228     int poll_ret = 0;
229     SmartPtr<V4l2Buffer> buf;
230 
231     poll_ret = _capture_dev->poll_event (PollThread::default_capture_event_timeout);
232 
233     if (poll_ret < 0) {
234         XCAM_LOG_DEBUG ("poll buffer event got error but continue");
235         ::usleep (100000); // 100ms
236         return XCAM_RETURN_ERROR_TIMEOUT;
237     }
238 
239     /* timeout */
240     if (poll_ret == 0) {
241         XCAM_LOG_DEBUG ("poll buffer timeout and continue");
242         return XCAM_RETURN_ERROR_TIMEOUT;
243     }
244 
245     ret = _capture_dev->dequeue_buffer (buf);
246     if (ret != XCAM_RETURN_NO_ERROR) {
247         XCAM_LOG_WARNING ("capture buffer failed");
248         return ret;
249     }
250     XCAM_ASSERT (buf.ptr());
251     XCAM_ASSERT (_poll_callback);
252 
253     SmartPtr<VideoBuffer> video_buf = new V4l2BufferProxy (buf, _capture_dev);
254 
255     if (_poll_callback)
256         return _poll_callback->poll_buffer_ready (video_buf);
257 
258     return ret;
259 }
260 
261 };
262