xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkaiq/xcore/poll_thread.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 <linux/rkisp.h>
24 #include <unistd.h>
25 #include <fcntl.h>
26 
27 namespace XCam {
28 
29 class PollThread;
30 
31 const char*
32 PollThread::isp_poll_type_to_str[ISP_POLL_POST_MAX] =
33 {
34     "luma_poll",
35     "ispp_poll",
36     "stats_poll",
37     "params_poll",
38     "pparams_poll",
39 };
40 
41 class IspPollThread
42     : public Thread
43 {
44 public:
IspPollThread(PollThread * poll,int type)45     IspPollThread (PollThread *poll, int type)
46         : Thread (PollThread::isp_poll_type_to_str[type])
47         , _poll (poll)
48         , _type (type)
49     {}
50 
51 protected:
loop()52     virtual bool loop () {
53         XCamReturn ret = _poll->poll_buffer_loop (_type);
54 
55         if (ret == XCAM_RETURN_NO_ERROR || ret == XCAM_RETURN_ERROR_TIMEOUT ||
56                 XCAM_RETURN_BYPASS)
57             return true;
58         return false;
59     }
60 
61 private:
62     PollThread   *_poll;
63     int _type;
64 };
65 
66 class EventPollThread
67     : public Thread
68 {
69 public:
EventPollThread(PollThread * poll)70     EventPollThread (PollThread *poll)
71         : Thread ("event_poll")
72         , _poll (poll)
73     {}
74 
75 protected:
loop()76     virtual bool loop () {
77         XCamReturn ret = _poll->poll_subdev_event_loop ();
78 
79         if (ret == XCAM_RETURN_NO_ERROR || ret == XCAM_RETURN_ERROR_TIMEOUT)
80             return true;
81         return false;
82     }
83 
84 private:
85     PollThread   *_poll;
86 };
87 
88 const int PollThread::default_poll_timeout = 300; // ms
89 
PollThread()90 PollThread::PollThread ()
91     : _poll_callback (NULL)
92     , frameid (0)
93 {
94 #if 0
95     SmartPtr<EventPollThread> event_loop = new EventPollThread(this);
96     XCAM_ASSERT (event_loop.ptr ());
97     _event_loop = event_loop;
98 
99     SmartPtr<IspPollThread> isp_stats_loop = new IspPollThread(this, ISP_POLL_3A_STATS);
100     XCAM_ASSERT (isp_stats_loop.ptr ());
101     _isp_stats_loop = isp_stats_loop;
102 
103     SmartPtr<IspPollThread> isp_luma_loop = new IspPollThread(this, ISP_POLL_LUMA);
104     XCAM_ASSERT (isp_luma_loop.ptr ());
105     _isp_luma_loop = isp_luma_loop;
106 
107     SmartPtr<IspPollThread> isp_params_loop = new IspPollThread(this, ISP_POLL_PARAMS);
108     XCAM_ASSERT (isp_params_loop.ptr ());
109     _isp_params_loop = isp_params_loop;
110 
111     SmartPtr<IspPollThread> isp_pparams_loop = new IspPollThread(this, ISP_POLL_POST_PARAMS);
112     XCAM_ASSERT (isp_pparams_loop.ptr ());
113     _isp_pparams_loop = isp_pparams_loop;
114 
115     SmartPtr<IspPollThread> ispp_stats_loop = new IspPollThread(this, ISPP_POLL_STATS);
116     XCAM_ASSERT (ispp_stats_loop.ptr ());
117     _ispp_stats_loop = ispp_stats_loop;
118 
119     _ispp_poll_stop_fd[0] =  -1;
120     _ispp_poll_stop_fd[1] =  -1;
121     _luma_poll_stop_fd[0] =  -1;
122     _luma_poll_stop_fd[1] =  -1;
123     _3a_stats_poll_stop_fd[0] =  -1;
124     _3a_stats_poll_stop_fd[1] =  -1;
125     _event_poll_stop_fd[0] = -1;
126     _event_poll_stop_fd[1] = -1;
127     _isp_params_poll_stop_fd[0] = -1;
128     _isp_params_poll_stop_fd[1] = -1;
129     _isp_pparams_poll_stop_fd[0] = -1;
130     _isp_pparams_poll_stop_fd[1] = -1;
131 #endif
132     XCAM_LOG_DEBUG ("PollThread constructed");
133 }
134 
~PollThread()135 PollThread::~PollThread ()
136 {
137     stop();
138 
139     XCAM_LOG_DEBUG ("~PollThread destructed");
140 }
141 
142 bool
set_event_device(SmartPtr<V4l2SubDevice> & dev)143 PollThread::set_event_device (SmartPtr<V4l2SubDevice> &dev)
144 {
145     XCAM_ASSERT (!_event_dev.ptr());
146     _event_dev = dev;
147     return true;
148 }
149 
150 bool
set_isp_stats_device(SmartPtr<V4l2Device> & dev)151 PollThread::set_isp_stats_device (SmartPtr<V4l2Device> &dev)
152 {
153     XCAM_ASSERT (!_isp_stats_dev.ptr());
154     _isp_stats_dev = dev;
155     return true;
156 }
157 
158 bool
set_isp_luma_device(SmartPtr<V4l2Device> & dev)159 PollThread::set_isp_luma_device (SmartPtr<V4l2Device> &dev)
160 {
161     XCAM_ASSERT (!_isp_luma_dev.ptr());
162     _isp_luma_dev = dev;
163     return true;
164 }
165 
166 bool
set_ispp_stats_device(SmartPtr<V4l2Device> & dev)167 PollThread::set_ispp_stats_device (SmartPtr<V4l2Device> &dev)
168 {
169     XCAM_ASSERT (!_ispp_stats_dev.ptr());
170     _ispp_stats_dev = dev;
171     return true;
172 }
173 
174 bool
set_isp_params_devices(SmartPtr<V4l2Device> & params_dev,SmartPtr<V4l2Device> & post_params_dev)175 PollThread::set_isp_params_devices (SmartPtr<V4l2Device> &params_dev,
176                                     SmartPtr<V4l2Device> &post_params_dev)
177 {
178     XCAM_ASSERT (!_isp_params_dev.ptr());
179     XCAM_ASSERT (!_isp_pparams_dev.ptr());
180     _isp_params_dev = params_dev;
181     _isp_pparams_dev = post_params_dev;
182     return true;
183 }
184 
185 bool
set_poll_callback(PollCallback * callback)186 PollThread::set_poll_callback (PollCallback *callback)
187 {
188     XCAM_ASSERT (!_poll_callback);
189     _poll_callback = callback;
190     return true;
191 }
192 
destroy_stop_fds()193 void PollThread::destroy_stop_fds () {
194     if (_ispp_poll_stop_fd[1] != -1 || _ispp_poll_stop_fd[0] != -1) {
195         close(_ispp_poll_stop_fd[0]);
196         close(_ispp_poll_stop_fd[1]);
197         _ispp_poll_stop_fd[0] = -1;
198         _ispp_poll_stop_fd[1] = -1;
199     }
200 
201     if (_luma_poll_stop_fd[1] != -1 || _luma_poll_stop_fd[0] != -1) {
202         close(_luma_poll_stop_fd[0]);
203         close(_luma_poll_stop_fd[1]);
204         _luma_poll_stop_fd[0] = -1;
205         _luma_poll_stop_fd[1] = -1;
206     }
207 
208     if (_3a_stats_poll_stop_fd[1] != -1 || _3a_stats_poll_stop_fd[0] != -1) {
209         close(_3a_stats_poll_stop_fd[0]);
210         close(_3a_stats_poll_stop_fd[1]);
211         _3a_stats_poll_stop_fd[0] = -1;
212         _3a_stats_poll_stop_fd[1] = -1;
213     }
214 
215     if (_event_poll_stop_fd[1] != -1 || _event_poll_stop_fd[0] != -1) {
216         close(_event_poll_stop_fd[0]);
217         close(_event_poll_stop_fd[1]);
218         _event_poll_stop_fd[0] = -1;
219         _event_poll_stop_fd[1] = -1;
220     }
221 
222     if (_isp_params_poll_stop_fd[1] != -1 || _isp_params_poll_stop_fd[0] != -1) {
223         close(_isp_params_poll_stop_fd[0]);
224         close(_isp_params_poll_stop_fd[1]);
225         _isp_params_poll_stop_fd[0] = -1;
226         _isp_params_poll_stop_fd[1] = -1;
227     }
228 
229     if (_isp_pparams_poll_stop_fd[1] != -1 || _isp_pparams_poll_stop_fd[0] != -1) {
230         close(_isp_pparams_poll_stop_fd[0]);
231         close(_isp_pparams_poll_stop_fd[1]);
232         _isp_pparams_poll_stop_fd[0] = -1;
233         _isp_pparams_poll_stop_fd[1] = -1;
234     }
235 }
236 
create_stop_fds()237 XCamReturn PollThread::create_stop_fds () {
238     int status = 0;
239     XCamReturn ret = XCAM_RETURN_NO_ERROR;
240 
241     destroy_stop_fds ();
242 
243     status = pipe(_ispp_poll_stop_fd);
244     if (status < 0) {
245         XCAM_LOG_ERROR ("Failed to create ispp poll stop pipe: %s", strerror(errno));
246         ret = XCAM_RETURN_ERROR_UNKNOWN;
247         goto exit_error;
248     }
249 
250     /**
251      * make the reading end of the pipe non blocking.
252      * This helps during flush to read any information left there without
253      * blocking
254      */
255     status = fcntl(_ispp_poll_stop_fd[0], F_SETFL, O_NONBLOCK);
256     if (status < 0) {
257         XCAM_LOG_ERROR ("Fail to set event ispp stop pipe flag: %s", strerror(errno));
258         ret = XCAM_RETURN_ERROR_UNKNOWN;
259         goto exit_error;
260     }
261 
262     status = pipe(_luma_poll_stop_fd);
263     if (status < 0) {
264         XCAM_LOG_ERROR ("Failed to create luma poll stop pipe: %s", strerror(errno));
265         ret = XCAM_RETURN_ERROR_UNKNOWN;
266         goto exit_error;
267     }
268 
269     /**
270      * make the reading end of the pipe non blocking.
271      * This helps during flush to read any information left there without
272      * blocking
273      */
274     status = fcntl(_luma_poll_stop_fd[0], F_SETFL, O_NONBLOCK);
275     if (status < 0) {
276         XCAM_LOG_ERROR ("Fail to set event luma stop pipe flag: %s", strerror(errno));
277         ret = XCAM_RETURN_ERROR_UNKNOWN;
278         goto exit_error;
279     }
280 
281     status = pipe(_3a_stats_poll_stop_fd);
282     if (status < 0) {
283         XCAM_LOG_ERROR ("Failed to create stats poll stop pipe: %s", strerror(errno));
284         ret = XCAM_RETURN_ERROR_UNKNOWN;
285         goto exit_error;
286     }
287 
288     /**
289      * make the reading end of the pipe non blocking.
290      * This helps during flush to read any information left there without
291      * blocking
292      */
293     status = fcntl(_3a_stats_poll_stop_fd[0], F_SETFL, O_NONBLOCK);
294     if (status < 0) {
295         XCAM_LOG_ERROR ("Fail to set stats poll stop pipe flag: %s", strerror(errno));
296         ret = XCAM_RETURN_ERROR_UNKNOWN;
297         goto exit_error;
298     }
299 
300     status = pipe(_event_poll_stop_fd);
301     if (status < 0) {
302         XCAM_LOG_ERROR ("Failed to create event poll stop pipe: %s", strerror(errno));
303         ret = XCAM_RETURN_ERROR_UNKNOWN;
304         goto exit_error;
305     }
306 
307     /**
308      * make the reading end of the pipe non blocking.
309      * This helps during flush to read any information left there without
310      * blocking
311      */
312     status = fcntl(_event_poll_stop_fd[0], F_SETFL, O_NONBLOCK);
313     if (status < 0) {
314         XCAM_LOG_ERROR ("Fail to set stats poll stop pipe flag: %s", strerror(errno));
315         ret = XCAM_RETURN_ERROR_UNKNOWN;
316         goto exit_error;
317     }
318 
319     status = pipe(_isp_params_poll_stop_fd);
320     if (status < 0) {
321         XCAM_LOG_ERROR ("Failed to create params poll stop pipe: %s", strerror(errno));
322         ret = XCAM_RETURN_ERROR_UNKNOWN;
323         goto exit_error;
324     }
325 
326     /**
327      * make the reading end of the pipe non blocking.
328      * This helps during flush to read any information left there without
329      * blocking
330      */
331     status = fcntl(_isp_params_poll_stop_fd[0], F_SETFL, O_NONBLOCK);
332     if (status < 0) {
333         XCAM_LOG_ERROR ("Fail to set params poll stop pipe flag: %s", strerror(errno));
334         ret = XCAM_RETURN_ERROR_UNKNOWN;
335         goto exit_error;
336     }
337 
338     status = pipe(_isp_pparams_poll_stop_fd);
339     if (status < 0) {
340         XCAM_LOG_ERROR ("Failed to create pparams poll stop pipe: %s", strerror(errno));
341         ret = XCAM_RETURN_ERROR_UNKNOWN;
342         goto exit_error;
343     }
344 
345     /**
346      * make the reading end of the pipe non blocking.
347      * This helps during flush to read any information left there without
348      * blocking
349      */
350     status = fcntl(_isp_pparams_poll_stop_fd[0], F_SETFL, O_NONBLOCK);
351     if (status < 0) {
352         XCAM_LOG_ERROR ("Fail to set pparams poll stop pipe flag: %s", strerror(errno));
353         ret = XCAM_RETURN_ERROR_UNKNOWN;
354         goto exit_error;
355     }
356     return XCAM_RETURN_NO_ERROR;
357 exit_error:
358     destroy_stop_fds ();
359     return ret;
360 }
361 
start()362 XCamReturn PollThread::start ()
363 {
364     if (create_stop_fds ()) {
365         XCAM_LOG_ERROR("create stop fds failed !");
366         return XCAM_RETURN_ERROR_UNKNOWN;
367     }
368 
369     if (_event_dev.ptr () && !_event_loop->start ()) {
370         return XCAM_RETURN_ERROR_THREAD;
371     }
372 
373     if (_isp_stats_dev.ptr () && !_isp_stats_loop->start ()) {
374         return XCAM_RETURN_ERROR_THREAD;
375     }
376 
377     if (_isp_luma_dev.ptr () && !_isp_luma_loop->start ()) {
378         return XCAM_RETURN_ERROR_THREAD;
379     }
380 
381     if (_isp_params_dev.ptr () && !_isp_params_loop->start ()) {
382         return XCAM_RETURN_ERROR_THREAD;
383     }
384 
385     if (_ispp_stats_dev.ptr () && !_ispp_stats_loop->start ()) {
386         return XCAM_RETURN_ERROR_THREAD;
387     }
388 
389     if (_isp_pparams_dev.ptr () && !_isp_pparams_loop->start ()) {
390         return XCAM_RETURN_ERROR_THREAD;
391     }
392 
393     return XCAM_RETURN_NO_ERROR;
394 }
395 
stop()396 XCamReturn PollThread::stop ()
397 {
398     XCAM_LOG_DEBUG ("PollThread stop");
399 
400     if (_event_dev.ptr ()) {
401         if (_event_poll_stop_fd[1] != -1) {
402             char buf = 0xf;  // random value to write to flush fd.
403             unsigned int size = write(_event_poll_stop_fd[1], &buf, sizeof(char));
404             if (size != sizeof(char)) {
405                 XCAM_LOG_WARNING("Flush write not completed");
406             }
407         }
408         _event_loop->stop ();
409     }
410 
411     if (_ispp_stats_dev.ptr ()) {
412         if (_ispp_poll_stop_fd[1] != -1) {
413             char buf = 0xf;  // random value to write to flush fd.
414             unsigned int size = write(_ispp_poll_stop_fd[1], &buf, sizeof(char));
415             if (size != sizeof(char)) {
416                 XCAM_LOG_WARNING("Flush write not completed");
417             }
418         }
419         _ispp_stats_loop->stop ();
420     }
421 
422     if (_isp_stats_dev.ptr ()) {
423         if (_3a_stats_poll_stop_fd[1] != -1) {
424             char buf = 0xf;  // random value to write to flush fd.
425             unsigned int size = write(_3a_stats_poll_stop_fd[1], &buf, sizeof(char));
426             if (size != sizeof(char)) {
427                 XCAM_LOG_WARNING("Flush write not completed");
428             }
429         }
430         _isp_stats_loop->stop ();
431     }
432 
433     if (_isp_luma_dev.ptr ()) {
434         if (_luma_poll_stop_fd[1] != -1) {
435             char buf = 0xf;  // random value to write to flush fd.
436             unsigned int size = write(_luma_poll_stop_fd[1], &buf, sizeof(char));
437             if (size != sizeof(char)) {
438                 XCAM_LOG_WARNING("Flush write not completed");
439             }
440         }
441         _isp_luma_loop->stop ();
442     }
443 
444     if (_isp_params_dev.ptr ()) {
445         if (_isp_params_poll_stop_fd[1] != -1) {
446             char buf = 0xf;  // random value to write to flush fd.
447             unsigned int size = write(_isp_params_poll_stop_fd[1], &buf, sizeof(char));
448             if (size != sizeof(char)) {
449                 XCAM_LOG_WARNING("Flush write not completed");
450             }
451         }
452         _isp_params_loop->stop ();
453     }
454 
455     if (_isp_pparams_dev.ptr ()) {
456         if (_isp_pparams_poll_stop_fd[1] != -1) {
457             char buf = 0xf;  // random value to write to flush fd.
458             unsigned int size = write(_isp_pparams_poll_stop_fd[1], &buf, sizeof(char));
459             if (size != sizeof(char)) {
460                 XCAM_LOG_WARNING("Flush write not completed");
461             }
462         }
463         _isp_pparams_loop->stop ();
464     }
465 
466     destroy_stop_fds ();
467 
468     return XCAM_RETURN_NO_ERROR;
469 }
470 
471 XCamReturn
notify_sof(uint64_t time,uint32_t frameid)472 PollThread::notify_sof (uint64_t time, uint32_t frameid)
473 {
474     XCAM_UNUSED (time);
475     XCAM_UNUSED (frameid);
476 
477     return XCAM_RETURN_NO_ERROR;
478 }
479 
480 XCamReturn
handle_events(struct v4l2_event & event)481 PollThread::handle_events (struct v4l2_event &event)
482 {
483     XCamReturn ret = XCAM_RETURN_NO_ERROR;
484     switch (event.type) {
485     case V4L2_EVENT_FRAME_SYNC:
486         ret = handle_frame_sync_event (event);
487         break;
488     default:
489         ret = XCAM_RETURN_ERROR_UNKNOWN;
490         break;
491     }
492 
493     return ret;
494 }
495 
496 XCamReturn
handle_frame_sync_event(struct v4l2_event & event)497 PollThread::handle_frame_sync_event (struct v4l2_event &event)
498 {
499     int64_t tv_sec = event.timestamp.tv_sec;
500     int64_t tv_nsec = event.timestamp.tv_nsec;
501     int exp_id = event.u.frame_sync.frame_sequence;
502 
503     notify_sof(tv_sec * 1000 * 1000 * 1000 + tv_nsec, exp_id);
504 
505     return XCAM_RETURN_NO_ERROR;
506 }
507 
508 XCamReturn
poll_subdev_event_loop()509 PollThread::poll_subdev_event_loop ()
510 {
511     XCamReturn ret = XCAM_RETURN_NO_ERROR;
512     struct v4l2_event event;
513     int poll_ret = 0;
514 
515     poll_ret = _event_dev->poll_event (PollThread::default_poll_timeout,
516                                        _event_poll_stop_fd[0]);
517 
518     if (poll_ret == POLL_STOP_RET) {
519         XCAM_LOG_DEBUG ("poll event stop success !");
520         // stop success, return error to stop the poll thread
521         return XCAM_RETURN_ERROR_UNKNOWN;
522     }
523 
524     if (poll_ret < 0) {
525         XCAM_LOG_WARNING ("poll event failed but continue");
526         ::usleep (1000); // 1ms
527         return XCAM_RETURN_ERROR_TIMEOUT;
528     }
529 
530     /* timeout */
531     if (poll_ret == 0) {
532         XCAM_LOG_WARNING ("poll event timeout and continue");
533         return XCAM_RETURN_ERROR_TIMEOUT;
534     }
535 
536     xcam_mem_clear (event);
537     ret = _event_dev->dequeue_event (event);
538     if (ret != XCAM_RETURN_NO_ERROR) {
539         XCAM_LOG_WARNING ("dequeue event failed on dev:%s", XCAM_STR(_event_dev->get_device_name()));
540         return XCAM_RETURN_ERROR_IOCTL;
541     }
542 
543     ret = handle_events (event);
544 
545     XCAM_ASSERT (_poll_callback);
546 
547     if (_poll_callback && event.type == V4L2_EVENT_FRAME_SYNC)
548         return _poll_callback->poll_event_ready (event.u.frame_sync.frame_sequence,
549                                                  event.type);
550 
551     return ret;
552 }
553 
554 SmartPtr<VideoBuffer>
new_video_buffer(SmartPtr<V4l2Buffer> buf,SmartPtr<V4l2Device> dev,int type)555 PollThread::new_video_buffer(SmartPtr<V4l2Buffer> buf,
556                              SmartPtr<V4l2Device> dev,
557                              int type)
558 {
559     SmartPtr<VideoBuffer> video_buf = new V4l2BufferProxy (buf, dev);
560 
561     return video_buf;
562 }
563 
564 XCamReturn
poll_buffer_loop(int type)565 PollThread::poll_buffer_loop (int type)
566 {
567     XCamReturn ret = XCAM_RETURN_NO_ERROR;
568     int poll_ret = 0;
569     SmartPtr<V4l2Buffer> buf;
570     SmartPtr<V4l2Device> dev;
571     int stop_fd = -1;
572 #if 0
573     if (type == ISP_POLL_LUMA) {
574         dev = _isp_luma_dev;
575         stop_fd = _luma_poll_stop_fd[0];
576     } else if (type == ISPP_POLL_STATS) {
577         dev = _ispp_stats_dev;
578         stop_fd = _ispp_poll_stop_fd[0];
579     } else if (type == ISP_POLL_3A_STATS) {
580         dev = _isp_stats_dev;
581         stop_fd = _3a_stats_poll_stop_fd[0];
582     } else if (type == ISP_POLL_PARAMS) {
583         dev = _isp_params_dev;
584         stop_fd = _isp_params_poll_stop_fd[0];
585     } else if (type == ISP_POLL_POST_PARAMS) {
586         dev = _isp_pparams_dev;
587         stop_fd = _isp_pparams_poll_stop_fd[0];
588     } else
589         return XCAM_RETURN_ERROR_UNKNOWN;
590 
591     poll_ret = dev->poll_event (PollThread::default_poll_timeout,
592                                 stop_fd);
593 
594     if (poll_ret == POLL_STOP_RET) {
595         XCAM_LOG_DEBUG ("poll %s buffer stop success !", isp_poll_type_to_str[type]);
596         // stop success, return error to stop the poll thread
597         return XCAM_RETURN_ERROR_UNKNOWN;
598     }
599 
600     if (poll_ret <= 0) {
601         XCAM_LOG_DEBUG ("poll %s buffer event got error(0x%x) but continue\n", isp_poll_type_to_str[type], poll_ret);
602         ::usleep (100000); // 100ms
603         return XCAM_RETURN_ERROR_TIMEOUT;
604     }
605 
606     ret = dev->dequeue_buffer (buf);
607     if (ret != XCAM_RETURN_NO_ERROR) {
608         XCAM_LOG_WARNING ("dequeue %s buffer failed", isp_poll_type_to_str[type]);
609         return ret;
610     }
611 
612     XCAM_ASSERT (buf.ptr());
613     XCAM_ASSERT (_poll_callback);
614 
615     if (_poll_callback &&
616             (type == ISP_POLL_3A_STATS || type == ISP_POLL_LUMA || type == ISPP_POLL_STATS)) {
617         SmartPtr<VideoBuffer> video_buf = new_video_buffer(buf, dev, type);
618 
619         return _poll_callback->poll_buffer_ready (video_buf, type);
620     }
621 #endif
622     return ret;
623 }
624 
625 }
626