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()82PollThread::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()92PollThread::~PollThread () 93 { 94 stop(); 95 96 XCAM_LOG_DEBUG ("~PollThread destructed"); 97 } 98 99 bool set_capture_device(SmartPtr<V4l2Device> & dev)100PollThread::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)108PollThread::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)116PollThread::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)124PollThread::set_stats_callback (StatsCallback *callback) 125 { 126 XCAM_ASSERT (!_stats_callback); 127 _stats_callback = callback; 128 return true; 129 } 130 start()131XCamReturn 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()143XCamReturn 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()152PollThread::init_3a_stats_pool () 153 { 154 return XCAM_RETURN_NO_ERROR; 155 } 156 157 XCamReturn capture_3a_stats(SmartPtr<X3aStats> & stats)158PollThread::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)166PollThread::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)174PollThread::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()193PollThread::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()225PollThread::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