1 /*
2 * Copyright (c) 2019 Rockchip Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 #include <stdlib.h>
19 #include <fcntl.h>
20 #include "Stream.h"
21
22 namespace RkRawStream {
23
24 const int RkPollThread::default_poll_timeout = 300; // ms
25
26 const char*
27 RKStream::poll_type_to_str[ISP_POLL_POST_MAX] =
28 {
29 "luma_poll",
30 "isp_3a_stats_poll",
31 "isp_param_poll",
32 "ispp_fec_param_poll",
33 "ispp_tnr_param_poll",
34 "ispp_nr_param_poll",
35 "ispp_tnr_stats_poll",
36 "ispp_nr_stats_poll",
37 "isp_sof_poll",
38 "isp_tx_poll",
39 "isp_rx_poll",
40 "isp_sp_poll",
41 "isp_pdaf_poll",
42 "isp_stream_sync_poll",
43 };
44
RkPollThread(const char * thName,int type,SmartPtr<V4l2Device> dev,RKStream * stream)45 RkPollThread::RkPollThread (const char* thName, int type, SmartPtr<V4l2Device> dev, RKStream *stream)
46 :Thread(thName)
47 ,_poll_callback (NULL)
48 ,frameid (0)
49 ,_dev(dev)
50 ,_stream(stream)
51 ,_dev_type(type)
52 {
53 _poll_stop_fd[0] = -1;
54 _poll_stop_fd[1] = -1;
55
56 LOGD_RKSTREAM ("RkPollThread constructed");
57 }
58
RkPollThread(const char * thName,int type,SmartPtr<V4l2SubDevice> dev,RKStream * stream)59 RkPollThread::RkPollThread (const char* thName, int type, SmartPtr<V4l2SubDevice> dev, RKStream *stream)
60 :Thread(thName)
61 ,_poll_callback (NULL)
62 ,frameid (0)
63 ,_subdev(dev)
64 ,_dev(dev)
65 ,_stream(stream)
66 ,_dev_type(type)
67 {
68 _poll_stop_fd[0] = -1;
69 _poll_stop_fd[1] = -1;
70
71 LOGD_RKSTREAM ("RkPollThread constructed");
72 }
73
~RkPollThread()74 RkPollThread::~RkPollThread ()
75 {
76 stop();
77 LOGD_RKSTREAM ("~RkPollThread destructed");
78 }
79
destroy_stop_fds()80 void RkPollThread::destroy_stop_fds () {
81 if (_poll_stop_fd[1] != -1 || _poll_stop_fd[0] != -1) {
82 close(_poll_stop_fd[0]);
83 close(_poll_stop_fd[1]);
84 _poll_stop_fd[0] = -1;
85 _poll_stop_fd[1] = -1;
86 }
87 }
88
create_stop_fds()89 XCamReturn RkPollThread::create_stop_fds () {
90 int status = 0;
91 XCamReturn ret = XCAM_RETURN_NO_ERROR;
92
93 destroy_stop_fds ();
94
95 status = pipe(_poll_stop_fd);
96 if (status < 0) {
97 LOGE_RKSTREAM ("Failed to create ispp poll stop pipe: %s", strerror(errno));
98 ret = XCAM_RETURN_ERROR_UNKNOWN;
99 goto exit_error;
100 }
101
102 /**
103 * make the reading end of the pipe non blocking.
104 * This helps during flush to read any information left there without
105 * blocking
106 */
107 status = fcntl(_poll_stop_fd[0], F_SETFL, O_NONBLOCK);
108 if (status < 0) {
109 LOGE_RKSTREAM ("Fail to set event ispp stop pipe flag: %s", strerror(errno));
110 ret = XCAM_RETURN_ERROR_UNKNOWN;
111 goto exit_error;
112 }
113
114 return XCAM_RETURN_NO_ERROR;
115 exit_error:
116 destroy_stop_fds ();
117 return ret;
118 }
119
start()120 XCamReturn RkPollThread::start ()
121 {
122 if (create_stop_fds ()) {
123 LOGE_RKSTREAM("create stop fds failed !");
124 return XCAM_RETURN_ERROR_UNKNOWN;
125 }
126
127 Thread::start();
128
129 return XCAM_RETURN_NO_ERROR;
130 }
131
stop()132 XCamReturn RkPollThread::stop ()
133 {
134 LOGD_RKSTREAM ("RkPollThread %s:%s stop", get_name(),
135 _dev.ptr() ? _dev->get_device_name() : _subdev->get_device_name());
136 if (_poll_stop_fd[1] != -1) {
137 char buf = 0xf; // random value to write to flush fd.
138 unsigned int size = write(_poll_stop_fd[1], &buf, sizeof(char));
139 if (size != sizeof(char))
140 LOGW_RKSTREAM("Flush write not completed");
141 }
142 Thread::stop();
143 destroy_stop_fds ();
144 LOGD_RKSTREAM ("stop done");
145 return XCAM_RETURN_NO_ERROR;
146 }
147
148 bool
setPollCallback(PollCallback * callback)149 RkPollThread::setPollCallback (PollCallback *callback)
150 {
151 //XCAM_ASSERT (!_poll_callback);
152 _poll_callback = callback;
153 return true;
154 }
155
156 XCamReturn
poll_buffer_loop()157 RkPollThread::poll_buffer_loop ()
158 {
159 XCamReturn ret = XCAM_RETURN_NO_ERROR;
160 int poll_ret = 0;
161 SmartPtr<V4l2Buffer> buf;
162 int stop_fd = -1;
163
164 stop_fd = _poll_stop_fd[0];
165 poll_ret = _dev->poll_event (RkPollThread::default_poll_timeout, stop_fd);
166
167 if (poll_ret == POLL_STOP_RET) {
168 LOGD_RKSTREAM ("poll buffer stop success !");
169 // stop success, return error to stop the poll thread
170 return XCAM_RETURN_ERROR_UNKNOWN;
171 }
172
173 if (poll_ret < 0 && (errno == EAGAIN || errno == EINTR)) {
174 LOGD_RKSTREAM("poll buffer event got interrupt(0x%x), continue\n",
175 poll_ret);
176 return XCAM_RETURN_ERROR_TIMEOUT;
177 } else if (poll_ret < 0) {
178 LOGD_RKSTREAM("poll buffer event got error(0x%x) exit\n", poll_ret);
179 return XCAM_RETURN_ERROR_UNKNOWN;
180 } else if (poll_ret == 0) {
181 LOGD_RKSTREAM("poll buffer event timeout(0x%x), continue\n",
182 poll_ret);
183 return XCAM_RETURN_ERROR_TIMEOUT;
184 }
185
186 ret = _dev->dequeue_buffer (buf);
187 if (ret != XCAM_RETURN_NO_ERROR) {
188 LOGW_RKSTREAM ("dequeue buffer failed");
189 return ret;
190 }
191 if (_dev_type == ISP_POLL_TX){
192 LOGI_RKSTREAM ("dequeue buffer ok, seq %d", buf->get_buf().sequence);
193 }
194 XCAM_ASSERT (buf.ptr());
195
196 if (_dev_type == ISP_POLL_TX || _dev_type == ISP_POLL_RX) {
197 SmartPtr<V4l2BufferProxy> buf_proxy = _stream->new_v4l2proxy_buffer(buf, _dev);
198 if (_poll_callback && buf_proxy.ptr())
199 _poll_callback->poll_buffer_ready (buf_proxy, ((RKRawStream*)_stream)->_dev_index);
200 } else {
201 LOGW_RKSTREAM ("type not support failed");
202 }
203
204 return ret;
205 }
206
RkEventPollThread(const char * thName,int type,SmartPtr<V4l2Device> dev,RKStream * stream)207 RkEventPollThread::RkEventPollThread (const char* thName, int type, SmartPtr<V4l2Device> dev, RKStream *stream)
208 :RkPollThread(thName, type, dev, stream)
209 {
210 LOGD_RKSTREAM ("RkEventPollThread constructed");
211 }
212
RkEventPollThread(const char * thName,int type,SmartPtr<V4l2SubDevice> subdev,RKStream * stream)213 RkEventPollThread::RkEventPollThread (const char* thName, int type, SmartPtr<V4l2SubDevice> subdev, RKStream *stream)
214 :RkPollThread(thName, type, subdev, stream)
215 {
216 LOGD_RKSTREAM ("RkEventPollThread constructed");
217 }
218
~RkEventPollThread()219 RkEventPollThread::~RkEventPollThread ()
220 {
221 stop();
222 LOGD_RKSTREAM ("~RkEventPollThread destructed");
223 }
224
225 XCamReturn
poll_event_loop()226 RkEventPollThread::poll_event_loop ()
227 {
228 XCamReturn ret = XCAM_RETURN_NO_ERROR;
229 int poll_ret = 0;
230 int stop_fd = -1;
231
232 stop_fd = _poll_stop_fd[0];
233 poll_ret = _dev->poll_event (RkPollThread::default_poll_timeout, stop_fd);
234
235 if (poll_ret == POLL_STOP_RET) {
236 XCAM_LOG_INFO ("%s: poll event stop success !", get_name());
237 // stop success, return error to stop the poll thread
238 return XCAM_RETURN_ERROR_UNKNOWN;
239 }
240
241 if (poll_ret < 0 && (errno == EAGAIN || errno == EINTR)) {
242 LOGD_RKSTREAM("poll buffer event got interrupt(0x%x), continue\n",
243 poll_ret);
244 return XCAM_RETURN_ERROR_TIMEOUT;
245 } else if (poll_ret < 0) {
246 LOGD_RKSTREAM("poll buffer event got error(0x%x) exit\n", poll_ret);
247 return XCAM_RETURN_ERROR_UNKNOWN;
248 } else if (poll_ret == 0) {
249 LOGW_RKSTREAM ("poll event timeout and continue");
250 return XCAM_RETURN_ERROR_TIMEOUT;
251 }
252 xcam_mem_clear (_event);
253
254 ret = _dev->dequeue_event (_event);
255 if (ret != XCAM_RETURN_NO_ERROR) {
256 LOGW_RKSTREAM ("dequeue event failed on dev:%s", XCAM_STR(_dev->get_device_name()));
257 return XCAM_RETURN_ERROR_IOCTL;
258 }
259
260 if (_poll_callback && _stream) {
261 SmartPtr<VideoBuffer> video_buf = _stream->new_video_buffer(_event, _subdev);
262 _poll_callback->poll_buffer_ready (video_buf);
263 }
264
265
266 return ret;
267 }
268
RKStream(SmartPtr<V4l2Device> dev,int type)269 RKStream::RKStream (SmartPtr<V4l2Device> dev, int type)
270 :_dev(dev)
271 ,_dev_type(type)
272 ,_dev_prepared(false)
273 {
274 _poll_thread = new RkPollThread(RKStream::poll_type_to_str[type], type, dev, this);
275 LOGD_RKSTREAM ("RKStream constructed");
276 }
277
RKStream(SmartPtr<V4l2SubDevice> dev,int type)278 RKStream::RKStream (SmartPtr<V4l2SubDevice> dev, int type)
279 :_subdev(dev)
280 ,_dev_type(type)
281 ,_dev_prepared(false)
282 {
283 _poll_thread = new RkEventPollThread(RKStream::poll_type_to_str[type], type, dev, this);
284 LOGD_RKSTREAM ("RKStream constructed");
285 }
286
RKStream(const char * path,int type)287 RKStream::RKStream (const char *path, int type)
288 :_dev_type(type)
289 ,_dev_prepared(false)
290 {
291 _dev = new V4l2Device(path);
292 _poll_thread = new RkPollThread(RKStream::poll_type_to_str[type], type, _dev, this);
293 LOGD_RKSTREAM ("RKStream constructed");
294 }
295
~RKStream()296 RKStream::~RKStream()
297 {
298 LOGD_RKSTREAM ("~RKStream destructed");
299 }
300
301 void
start()302 RKStream::start()
303 {
304 if (!_dev->is_activated())
305 _dev->start(_dev_prepared);
306 _poll_thread->start();
307 }
308
309 void
startThreadOnly()310 RKStream::startThreadOnly()
311 {
312 _poll_thread->start();
313 }
314
315 void
startDeviceOnly()316 RKStream::startDeviceOnly()
317 {
318 if (!_dev->is_activated())
319 _dev->start(_dev_prepared);
320 }
321
322 void
stop()323 RKStream::stop()
324 {
325 _poll_thread->stop();
326 _dev->stop();
327 _dev_prepared = false;
328 }
329
330 void
stopThreadOnly()331 RKStream::stopThreadOnly()
332 {
333 _poll_thread->stop();
334 }
335
336 void
stopDeviceOnly()337 RKStream::stopDeviceOnly()
338 {
339 _dev->stop();
340 _dev_prepared = false;
341 }
342
343 void
stopDeviceStreamoff()344 RKStream::stopDeviceStreamoff()
345 {
346 _dev->stop_streamoff();
347 _dev_prepared = false;
348 }
349
350 void
stopDeviceFreebuffer()351 RKStream::stopDeviceFreebuffer()
352 {
353 _dev->stop_freebuffer();
354 _dev_prepared = false;
355 }
356
357 void
pause()358 RKStream::pause()
359 {
360 }
361
362 void
resume()363 RKStream::resume()
364 {
365 }
366
367 void
set_device_prepared(bool prepare)368 RKStream::set_device_prepared(bool prepare)
369 {
370 _dev_prepared = prepare;
371 }
372
new_video_buffer(SmartPtr<V4l2Buffer> buf,SmartPtr<V4l2Device> dev)373 SmartPtr<VideoBuffer> RKStream::new_video_buffer(SmartPtr<V4l2Buffer> buf,
374 SmartPtr<V4l2Device> dev)
375 {
376 SmartPtr<VideoBuffer> video_buf = new V4l2BufferProxy (buf, dev);
377 video_buf->_buf_type = _dev_type;
378 return video_buf;
379 }
380
381 bool
setPollCallback(PollCallback * callback)382 RKStream::setPollCallback (PollCallback *callback)
383 {
384 return _poll_thread->setPollCallback(callback);
385 }
386
getFormat(struct v4l2_format & format)387 XCamReturn RKStream::getFormat(struct v4l2_format &format)
388 {
389 return _dev->get_format (format);
390 }
391
getFormat(struct v4l2_subdev_format & format)392 XCamReturn RKStream::getFormat(struct v4l2_subdev_format &format)
393 {
394 return _subdev->getFormat (format);
395 }
396
397 /*--------------------Output stream---------------------------*/
398
RKRawStream(SmartPtr<V4l2Device> dev,int index,int type)399 RKRawStream::RKRawStream (SmartPtr<V4l2Device> dev, int index, int type)
400 :RKStream(dev, type)
401 ,_dev_index(index)
402 {
403 LOGD_RKSTREAM ("RKRawStream constructed");
404 }
405
~RKRawStream()406 RKRawStream::~RKRawStream()
407 {
408 LOGD_RKSTREAM ("~RKRawStream destructed");
409 }
410
411 SmartPtr<V4l2BufferProxy>
new_v4l2proxy_buffer(SmartPtr<V4l2Buffer> buf,SmartPtr<V4l2Device> dev)412 RKRawStream::new_v4l2proxy_buffer(SmartPtr<V4l2Buffer> buf,
413 SmartPtr<V4l2Device> dev)
414 {
415 ENTER_CAMHW_FUNCTION();
416 SmartPtr<V4l2BufferProxy> buf_proxy = new V4l2BufferProxy(buf, dev);
417 buf_proxy->_buf_type = _dev_type;
418 EXIT_CAMHW_FUNCTION();
419
420 return buf_proxy;
421 }
422
423 }; //namspace RkCam
424