xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rk_stream/stream_cfg/Stream.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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