/* 
 | 
 * poll_thread.cpp - poll thread for event and buffer 
 | 
 * 
 | 
 *  Copyright (c) 2014-2015 Intel Corporation 
 | 
 * 
 | 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 | 
 * you may not use this file except in compliance with the License. 
 | 
 * You may obtain a copy of the License at 
 | 
 * 
 | 
 *      http://www.apache.org/licenses/LICENSE-2.0 
 | 
 * 
 | 
 * Unless required by applicable law or agreed to in writing, software 
 | 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 | 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 | 
 * See the License for the specific language governing permissions and 
 | 
 * limitations under the License. 
 | 
 * 
 | 
 * Author: Wind Yuan <feng.yuan@intel.com> 
 | 
 */ 
 | 
  
 | 
#include "poll_thread.h" 
 | 
#include "xcam_thread.h" 
 | 
//#include <linux/rkisp.h> 
 | 
#include <unistd.h> 
 | 
#include <fcntl.h> 
 | 
  
 | 
namespace XCam { 
 | 
  
 | 
class PollThread; 
 | 
  
 | 
const char* 
 | 
PollThread::isp_poll_type_to_str[ISP_POLL_POST_MAX] = 
 | 
{ 
 | 
    "luma_poll", 
 | 
    "ispp_poll", 
 | 
    "stats_poll", 
 | 
    "params_poll", 
 | 
    "pparams_poll", 
 | 
}; 
 | 
  
 | 
class IspPollThread 
 | 
    : public Thread 
 | 
{ 
 | 
public: 
 | 
    IspPollThread (PollThread *poll, int type) 
 | 
        : Thread (PollThread::isp_poll_type_to_str[type]) 
 | 
        , _poll (poll) 
 | 
        , _type (type) 
 | 
    {} 
 | 
  
 | 
protected: 
 | 
    virtual bool loop () { 
 | 
        XCamReturn ret = _poll->poll_buffer_loop (_type); 
 | 
  
 | 
        if (ret == XCAM_RETURN_NO_ERROR || ret == XCAM_RETURN_ERROR_TIMEOUT || 
 | 
                XCAM_RETURN_BYPASS) 
 | 
            return true; 
 | 
        return false; 
 | 
    } 
 | 
  
 | 
private: 
 | 
    PollThread   *_poll; 
 | 
    int _type; 
 | 
}; 
 | 
  
 | 
class EventPollThread 
 | 
    : public Thread 
 | 
{ 
 | 
public: 
 | 
    EventPollThread (PollThread *poll) 
 | 
        : Thread ("event_poll") 
 | 
        , _poll (poll) 
 | 
    {} 
 | 
  
 | 
protected: 
 | 
    virtual bool loop () { 
 | 
        XCamReturn ret = _poll->poll_subdev_event_loop (); 
 | 
  
 | 
        if (ret == XCAM_RETURN_NO_ERROR || ret == XCAM_RETURN_ERROR_TIMEOUT) 
 | 
            return true; 
 | 
        return false; 
 | 
    } 
 | 
  
 | 
private: 
 | 
    PollThread   *_poll; 
 | 
}; 
 | 
  
 | 
const int PollThread::default_poll_timeout = 300; // ms 
 | 
  
 | 
PollThread::PollThread () 
 | 
    : _poll_callback (NULL) 
 | 
    , frameid (0) 
 | 
{ 
 | 
#if 0 
 | 
    SmartPtr<EventPollThread> event_loop = new EventPollThread(this); 
 | 
    XCAM_ASSERT (event_loop.ptr ()); 
 | 
    _event_loop = event_loop; 
 | 
  
 | 
    SmartPtr<IspPollThread> isp_stats_loop = new IspPollThread(this, ISP_POLL_3A_STATS); 
 | 
    XCAM_ASSERT (isp_stats_loop.ptr ()); 
 | 
    _isp_stats_loop = isp_stats_loop; 
 | 
  
 | 
    SmartPtr<IspPollThread> isp_luma_loop = new IspPollThread(this, ISP_POLL_LUMA); 
 | 
    XCAM_ASSERT (isp_luma_loop.ptr ()); 
 | 
    _isp_luma_loop = isp_luma_loop; 
 | 
  
 | 
    SmartPtr<IspPollThread> isp_params_loop = new IspPollThread(this, ISP_POLL_PARAMS); 
 | 
    XCAM_ASSERT (isp_params_loop.ptr ()); 
 | 
    _isp_params_loop = isp_params_loop; 
 | 
  
 | 
    SmartPtr<IspPollThread> isp_pparams_loop = new IspPollThread(this, ISP_POLL_POST_PARAMS); 
 | 
    XCAM_ASSERT (isp_pparams_loop.ptr ()); 
 | 
    _isp_pparams_loop = isp_pparams_loop; 
 | 
  
 | 
    SmartPtr<IspPollThread> ispp_stats_loop = new IspPollThread(this, ISPP_POLL_STATS); 
 | 
    XCAM_ASSERT (ispp_stats_loop.ptr ()); 
 | 
    _ispp_stats_loop = ispp_stats_loop; 
 | 
  
 | 
    _ispp_poll_stop_fd[0] =  -1; 
 | 
    _ispp_poll_stop_fd[1] =  -1; 
 | 
    _luma_poll_stop_fd[0] =  -1; 
 | 
    _luma_poll_stop_fd[1] =  -1; 
 | 
    _3a_stats_poll_stop_fd[0] =  -1; 
 | 
    _3a_stats_poll_stop_fd[1] =  -1; 
 | 
    _event_poll_stop_fd[0] = -1; 
 | 
    _event_poll_stop_fd[1] = -1; 
 | 
    _isp_params_poll_stop_fd[0] = -1; 
 | 
    _isp_params_poll_stop_fd[1] = -1; 
 | 
    _isp_pparams_poll_stop_fd[0] = -1; 
 | 
    _isp_pparams_poll_stop_fd[1] = -1; 
 | 
#endif 
 | 
    XCAM_LOG_DEBUG ("PollThread constructed"); 
 | 
} 
 | 
  
 | 
PollThread::~PollThread () 
 | 
{ 
 | 
    stop(); 
 | 
  
 | 
    XCAM_LOG_DEBUG ("~PollThread destructed"); 
 | 
} 
 | 
  
 | 
bool 
 | 
PollThread::set_event_device (SmartPtr<V4l2SubDevice> &dev) 
 | 
{ 
 | 
    XCAM_ASSERT (!_event_dev.ptr()); 
 | 
    _event_dev = dev; 
 | 
    return true; 
 | 
} 
 | 
  
 | 
bool 
 | 
PollThread::set_isp_stats_device (SmartPtr<V4l2Device> &dev) 
 | 
{ 
 | 
    XCAM_ASSERT (!_isp_stats_dev.ptr()); 
 | 
    _isp_stats_dev = dev; 
 | 
    return true; 
 | 
} 
 | 
  
 | 
bool 
 | 
PollThread::set_isp_luma_device (SmartPtr<V4l2Device> &dev) 
 | 
{ 
 | 
    XCAM_ASSERT (!_isp_luma_dev.ptr()); 
 | 
    _isp_luma_dev = dev; 
 | 
    return true; 
 | 
} 
 | 
  
 | 
bool 
 | 
PollThread::set_ispp_stats_device (SmartPtr<V4l2Device> &dev) 
 | 
{ 
 | 
    XCAM_ASSERT (!_ispp_stats_dev.ptr()); 
 | 
    _ispp_stats_dev = dev; 
 | 
    return true; 
 | 
} 
 | 
  
 | 
bool 
 | 
PollThread::set_isp_params_devices (SmartPtr<V4l2Device> ¶ms_dev, 
 | 
                                    SmartPtr<V4l2Device> &post_params_dev) 
 | 
{ 
 | 
    XCAM_ASSERT (!_isp_params_dev.ptr()); 
 | 
    XCAM_ASSERT (!_isp_pparams_dev.ptr()); 
 | 
    _isp_params_dev = params_dev; 
 | 
    _isp_pparams_dev = post_params_dev; 
 | 
    return true; 
 | 
} 
 | 
  
 | 
bool 
 | 
PollThread::set_poll_callback (PollCallback *callback) 
 | 
{ 
 | 
    XCAM_ASSERT (!_poll_callback); 
 | 
    _poll_callback = callback; 
 | 
    return true; 
 | 
} 
 | 
  
 | 
void PollThread::destroy_stop_fds () { 
 | 
    if (_ispp_poll_stop_fd[1] != -1 || _ispp_poll_stop_fd[0] != -1) { 
 | 
        close(_ispp_poll_stop_fd[0]); 
 | 
        close(_ispp_poll_stop_fd[1]); 
 | 
        _ispp_poll_stop_fd[0] = -1; 
 | 
        _ispp_poll_stop_fd[1] = -1; 
 | 
    } 
 | 
  
 | 
    if (_luma_poll_stop_fd[1] != -1 || _luma_poll_stop_fd[0] != -1) { 
 | 
        close(_luma_poll_stop_fd[0]); 
 | 
        close(_luma_poll_stop_fd[1]); 
 | 
        _luma_poll_stop_fd[0] = -1; 
 | 
        _luma_poll_stop_fd[1] = -1; 
 | 
    } 
 | 
  
 | 
    if (_3a_stats_poll_stop_fd[1] != -1 || _3a_stats_poll_stop_fd[0] != -1) { 
 | 
        close(_3a_stats_poll_stop_fd[0]); 
 | 
        close(_3a_stats_poll_stop_fd[1]); 
 | 
        _3a_stats_poll_stop_fd[0] = -1; 
 | 
        _3a_stats_poll_stop_fd[1] = -1; 
 | 
    } 
 | 
  
 | 
    if (_event_poll_stop_fd[1] != -1 || _event_poll_stop_fd[0] != -1) { 
 | 
        close(_event_poll_stop_fd[0]); 
 | 
        close(_event_poll_stop_fd[1]); 
 | 
        _event_poll_stop_fd[0] = -1; 
 | 
        _event_poll_stop_fd[1] = -1; 
 | 
    } 
 | 
  
 | 
    if (_isp_params_poll_stop_fd[1] != -1 || _isp_params_poll_stop_fd[0] != -1) { 
 | 
        close(_isp_params_poll_stop_fd[0]); 
 | 
        close(_isp_params_poll_stop_fd[1]); 
 | 
        _isp_params_poll_stop_fd[0] = -1; 
 | 
        _isp_params_poll_stop_fd[1] = -1; 
 | 
    } 
 | 
  
 | 
    if (_isp_pparams_poll_stop_fd[1] != -1 || _isp_pparams_poll_stop_fd[0] != -1) { 
 | 
        close(_isp_pparams_poll_stop_fd[0]); 
 | 
        close(_isp_pparams_poll_stop_fd[1]); 
 | 
        _isp_pparams_poll_stop_fd[0] = -1; 
 | 
        _isp_pparams_poll_stop_fd[1] = -1; 
 | 
    } 
 | 
} 
 | 
  
 | 
XCamReturn PollThread::create_stop_fds () { 
 | 
    int status = 0; 
 | 
    XCamReturn ret = XCAM_RETURN_NO_ERROR; 
 | 
  
 | 
    destroy_stop_fds (); 
 | 
  
 | 
    status = pipe(_ispp_poll_stop_fd); 
 | 
    if (status < 0) { 
 | 
        XCAM_LOG_ERROR ("Failed to create ispp poll stop pipe: %s", strerror(errno)); 
 | 
        ret = XCAM_RETURN_ERROR_UNKNOWN; 
 | 
        goto exit_error; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * make the reading end of the pipe non blocking. 
 | 
     * This helps during flush to read any information left there without 
 | 
     * blocking 
 | 
     */ 
 | 
    status = fcntl(_ispp_poll_stop_fd[0], F_SETFL, O_NONBLOCK); 
 | 
    if (status < 0) { 
 | 
        XCAM_LOG_ERROR ("Fail to set event ispp stop pipe flag: %s", strerror(errno)); 
 | 
        ret = XCAM_RETURN_ERROR_UNKNOWN; 
 | 
        goto exit_error; 
 | 
    } 
 | 
  
 | 
    status = pipe(_luma_poll_stop_fd); 
 | 
    if (status < 0) { 
 | 
        XCAM_LOG_ERROR ("Failed to create luma poll stop pipe: %s", strerror(errno)); 
 | 
        ret = XCAM_RETURN_ERROR_UNKNOWN; 
 | 
        goto exit_error; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * make the reading end of the pipe non blocking. 
 | 
     * This helps during flush to read any information left there without 
 | 
     * blocking 
 | 
     */ 
 | 
    status = fcntl(_luma_poll_stop_fd[0], F_SETFL, O_NONBLOCK); 
 | 
    if (status < 0) { 
 | 
        XCAM_LOG_ERROR ("Fail to set event luma stop pipe flag: %s", strerror(errno)); 
 | 
        ret = XCAM_RETURN_ERROR_UNKNOWN; 
 | 
        goto exit_error; 
 | 
    } 
 | 
  
 | 
    status = pipe(_3a_stats_poll_stop_fd); 
 | 
    if (status < 0) { 
 | 
        XCAM_LOG_ERROR ("Failed to create stats poll stop pipe: %s", strerror(errno)); 
 | 
        ret = XCAM_RETURN_ERROR_UNKNOWN; 
 | 
        goto exit_error; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * make the reading end of the pipe non blocking. 
 | 
     * This helps during flush to read any information left there without 
 | 
     * blocking 
 | 
     */ 
 | 
    status = fcntl(_3a_stats_poll_stop_fd[0], F_SETFL, O_NONBLOCK); 
 | 
    if (status < 0) { 
 | 
        XCAM_LOG_ERROR ("Fail to set stats poll stop pipe flag: %s", strerror(errno)); 
 | 
        ret = XCAM_RETURN_ERROR_UNKNOWN; 
 | 
        goto exit_error; 
 | 
    } 
 | 
  
 | 
    status = pipe(_event_poll_stop_fd); 
 | 
    if (status < 0) { 
 | 
        XCAM_LOG_ERROR ("Failed to create event poll stop pipe: %s", strerror(errno)); 
 | 
        ret = XCAM_RETURN_ERROR_UNKNOWN; 
 | 
        goto exit_error; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * make the reading end of the pipe non blocking. 
 | 
     * This helps during flush to read any information left there without 
 | 
     * blocking 
 | 
     */ 
 | 
    status = fcntl(_event_poll_stop_fd[0], F_SETFL, O_NONBLOCK); 
 | 
    if (status < 0) { 
 | 
        XCAM_LOG_ERROR ("Fail to set stats poll stop pipe flag: %s", strerror(errno)); 
 | 
        ret = XCAM_RETURN_ERROR_UNKNOWN; 
 | 
        goto exit_error; 
 | 
    } 
 | 
  
 | 
    status = pipe(_isp_params_poll_stop_fd); 
 | 
    if (status < 0) { 
 | 
        XCAM_LOG_ERROR ("Failed to create params poll stop pipe: %s", strerror(errno)); 
 | 
        ret = XCAM_RETURN_ERROR_UNKNOWN; 
 | 
        goto exit_error; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * make the reading end of the pipe non blocking. 
 | 
     * This helps during flush to read any information left there without 
 | 
     * blocking 
 | 
     */ 
 | 
    status = fcntl(_isp_params_poll_stop_fd[0], F_SETFL, O_NONBLOCK); 
 | 
    if (status < 0) { 
 | 
        XCAM_LOG_ERROR ("Fail to set params poll stop pipe flag: %s", strerror(errno)); 
 | 
        ret = XCAM_RETURN_ERROR_UNKNOWN; 
 | 
        goto exit_error; 
 | 
    } 
 | 
  
 | 
    status = pipe(_isp_pparams_poll_stop_fd); 
 | 
    if (status < 0) { 
 | 
        XCAM_LOG_ERROR ("Failed to create pparams poll stop pipe: %s", strerror(errno)); 
 | 
        ret = XCAM_RETURN_ERROR_UNKNOWN; 
 | 
        goto exit_error; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * make the reading end of the pipe non blocking. 
 | 
     * This helps during flush to read any information left there without 
 | 
     * blocking 
 | 
     */ 
 | 
    status = fcntl(_isp_pparams_poll_stop_fd[0], F_SETFL, O_NONBLOCK); 
 | 
    if (status < 0) { 
 | 
        XCAM_LOG_ERROR ("Fail to set pparams poll stop pipe flag: %s", strerror(errno)); 
 | 
        ret = XCAM_RETURN_ERROR_UNKNOWN; 
 | 
        goto exit_error; 
 | 
    } 
 | 
    return XCAM_RETURN_NO_ERROR; 
 | 
exit_error: 
 | 
    destroy_stop_fds (); 
 | 
    return ret; 
 | 
} 
 | 
  
 | 
XCamReturn PollThread::start () 
 | 
{ 
 | 
    if (create_stop_fds ()) { 
 | 
        XCAM_LOG_ERROR("create stop fds failed !"); 
 | 
        return XCAM_RETURN_ERROR_UNKNOWN; 
 | 
    } 
 | 
  
 | 
    if (_event_dev.ptr () && !_event_loop->start ()) { 
 | 
        return XCAM_RETURN_ERROR_THREAD; 
 | 
    } 
 | 
  
 | 
    if (_isp_stats_dev.ptr () && !_isp_stats_loop->start ()) { 
 | 
        return XCAM_RETURN_ERROR_THREAD; 
 | 
    } 
 | 
  
 | 
    if (_isp_luma_dev.ptr () && !_isp_luma_loop->start ()) { 
 | 
        return XCAM_RETURN_ERROR_THREAD; 
 | 
    } 
 | 
  
 | 
    if (_isp_params_dev.ptr () && !_isp_params_loop->start ()) { 
 | 
        return XCAM_RETURN_ERROR_THREAD; 
 | 
    } 
 | 
  
 | 
    if (_ispp_stats_dev.ptr () && !_ispp_stats_loop->start ()) { 
 | 
        return XCAM_RETURN_ERROR_THREAD; 
 | 
    } 
 | 
  
 | 
    if (_isp_pparams_dev.ptr () && !_isp_pparams_loop->start ()) { 
 | 
        return XCAM_RETURN_ERROR_THREAD; 
 | 
    } 
 | 
  
 | 
    return XCAM_RETURN_NO_ERROR; 
 | 
} 
 | 
  
 | 
XCamReturn PollThread::stop () 
 | 
{ 
 | 
    XCAM_LOG_DEBUG ("PollThread stop"); 
 | 
  
 | 
    if (_event_dev.ptr ()) { 
 | 
        if (_event_poll_stop_fd[1] != -1) { 
 | 
            char buf = 0xf;  // random value to write to flush fd. 
 | 
            unsigned int size = write(_event_poll_stop_fd[1], &buf, sizeof(char)); 
 | 
            if (size != sizeof(char)) 
 | 
                XCAM_LOG_WARNING("Flush write not completed"); 
 | 
        } 
 | 
        _event_loop->stop (); 
 | 
    } 
 | 
  
 | 
    if (_ispp_stats_dev.ptr ()) { 
 | 
        if (_ispp_poll_stop_fd[1] != -1) { 
 | 
            char buf = 0xf;  // random value to write to flush fd. 
 | 
            unsigned int size = write(_ispp_poll_stop_fd[1], &buf, sizeof(char)); 
 | 
            if (size != sizeof(char)) 
 | 
                XCAM_LOG_WARNING("Flush write not completed"); 
 | 
        } 
 | 
        _ispp_stats_loop->stop (); 
 | 
    } 
 | 
  
 | 
    if (_isp_stats_dev.ptr ()) { 
 | 
        if (_3a_stats_poll_stop_fd[1] != -1) { 
 | 
            char buf = 0xf;  // random value to write to flush fd. 
 | 
            unsigned int size = write(_3a_stats_poll_stop_fd[1], &buf, sizeof(char)); 
 | 
            if (size != sizeof(char)) 
 | 
                XCAM_LOG_WARNING("Flush write not completed"); 
 | 
        } 
 | 
        _isp_stats_loop->stop (); 
 | 
    } 
 | 
  
 | 
    if (_isp_luma_dev.ptr ()) { 
 | 
        if (_luma_poll_stop_fd[1] != -1) { 
 | 
            char buf = 0xf;  // random value to write to flush fd. 
 | 
            unsigned int size = write(_luma_poll_stop_fd[1], &buf, sizeof(char)); 
 | 
            if (size != sizeof(char)) 
 | 
                XCAM_LOG_WARNING("Flush write not completed"); 
 | 
        } 
 | 
        _isp_luma_loop->stop (); 
 | 
    } 
 | 
  
 | 
    if (_isp_params_dev.ptr ()) { 
 | 
        if (_isp_params_poll_stop_fd[1] != -1) { 
 | 
            char buf = 0xf;  // random value to write to flush fd. 
 | 
            unsigned int size = write(_isp_params_poll_stop_fd[1], &buf, sizeof(char)); 
 | 
            if (size != sizeof(char)) 
 | 
                XCAM_LOG_WARNING("Flush write not completed"); 
 | 
        } 
 | 
        _isp_params_loop->stop (); 
 | 
    } 
 | 
  
 | 
    if (_isp_pparams_dev.ptr ()) { 
 | 
        if (_isp_pparams_poll_stop_fd[1] != -1) { 
 | 
            char buf = 0xf;  // random value to write to flush fd. 
 | 
            unsigned int size = write(_isp_pparams_poll_stop_fd[1], &buf, sizeof(char)); 
 | 
            if (size != sizeof(char)) 
 | 
                XCAM_LOG_WARNING("Flush write not completed"); 
 | 
        } 
 | 
        _isp_pparams_loop->stop (); 
 | 
    } 
 | 
  
 | 
    destroy_stop_fds (); 
 | 
  
 | 
    return XCAM_RETURN_NO_ERROR; 
 | 
} 
 | 
  
 | 
XCamReturn 
 | 
PollThread::notify_sof (uint64_t time, int frameid) 
 | 
{ 
 | 
    XCAM_UNUSED (time); 
 | 
    XCAM_UNUSED (frameid); 
 | 
  
 | 
    return XCAM_RETURN_NO_ERROR; 
 | 
} 
 | 
  
 | 
XCamReturn 
 | 
PollThread::handle_events (struct v4l2_event &event) 
 | 
{ 
 | 
    XCamReturn ret = XCAM_RETURN_NO_ERROR; 
 | 
    switch (event.type) { 
 | 
    case V4L2_EVENT_FRAME_SYNC: 
 | 
        ret = handle_frame_sync_event (event); 
 | 
        break; 
 | 
    default: 
 | 
        ret = XCAM_RETURN_ERROR_UNKNOWN; 
 | 
        break; 
 | 
    } 
 | 
  
 | 
    return ret; 
 | 
} 
 | 
  
 | 
XCamReturn 
 | 
PollThread::handle_frame_sync_event (struct v4l2_event &event) 
 | 
{ 
 | 
    int64_t tv_sec = event.timestamp.tv_sec; 
 | 
    int64_t tv_nsec = event.timestamp.tv_nsec; 
 | 
    int exp_id = event.u.frame_sync.frame_sequence; 
 | 
  
 | 
    notify_sof(tv_sec * 1000 * 1000 * 1000 + tv_nsec, exp_id); 
 | 
  
 | 
    return XCAM_RETURN_NO_ERROR; 
 | 
} 
 | 
  
 | 
XCamReturn 
 | 
PollThread::poll_subdev_event_loop () 
 | 
{ 
 | 
    XCamReturn ret = XCAM_RETURN_NO_ERROR; 
 | 
    struct v4l2_event event; 
 | 
    int poll_ret = 0; 
 | 
  
 | 
    poll_ret = _event_dev->poll_event (PollThread::default_poll_timeout, 
 | 
                                       _event_poll_stop_fd[0]); 
 | 
  
 | 
    if (poll_ret == POLL_STOP_RET) { 
 | 
        XCAM_LOG_DEBUG ("poll event stop success !"); 
 | 
        // stop success, return error to stop the poll thread 
 | 
        return XCAM_RETURN_ERROR_UNKNOWN; 
 | 
    } 
 | 
  
 | 
    if (poll_ret < 0) { 
 | 
        XCAM_LOG_WARNING ("poll event failed but continue"); 
 | 
        ::usleep (1000); // 1ms 
 | 
        return XCAM_RETURN_ERROR_TIMEOUT; 
 | 
    } 
 | 
  
 | 
    /* timeout */ 
 | 
    if (poll_ret == 0) { 
 | 
        XCAM_LOG_WARNING ("poll event timeout and continue"); 
 | 
        return XCAM_RETURN_ERROR_TIMEOUT; 
 | 
    } 
 | 
  
 | 
    xcam_mem_clear (event); 
 | 
    ret = _event_dev->dequeue_event (event); 
 | 
    if (ret != XCAM_RETURN_NO_ERROR) { 
 | 
        XCAM_LOG_WARNING ("dequeue event failed on dev:%s", XCAM_STR(_event_dev->get_device_name())); 
 | 
        return XCAM_RETURN_ERROR_IOCTL; 
 | 
    } 
 | 
  
 | 
    ret = handle_events (event); 
 | 
  
 | 
    XCAM_ASSERT (_poll_callback); 
 | 
  
 | 
    if (_poll_callback && event.type == V4L2_EVENT_FRAME_SYNC) 
 | 
        return _poll_callback->poll_event_ready (event.u.frame_sync.frame_sequence, 
 | 
                                                 event.type); 
 | 
  
 | 
    return ret; 
 | 
} 
 | 
  
 | 
SmartPtr<VideoBuffer> 
 | 
PollThread::new_video_buffer(SmartPtr<V4l2Buffer> buf, 
 | 
                             SmartPtr<V4l2Device> dev, 
 | 
                             int type) 
 | 
{ 
 | 
    SmartPtr<VideoBuffer> video_buf = new V4l2BufferProxy (buf, dev); 
 | 
  
 | 
    return video_buf; 
 | 
} 
 | 
  
 | 
XCamReturn 
 | 
PollThread::poll_buffer_loop (int type) 
 | 
{ 
 | 
    XCamReturn ret = XCAM_RETURN_NO_ERROR; 
 | 
    int poll_ret = 0; 
 | 
    SmartPtr<V4l2Buffer> buf; 
 | 
    SmartPtr<V4l2Device> dev; 
 | 
    int stop_fd = -1; 
 | 
#if 0 
 | 
    if (type == ISP_POLL_LUMA) { 
 | 
        dev = _isp_luma_dev; 
 | 
        stop_fd = _luma_poll_stop_fd[0]; 
 | 
    } else if (type == ISPP_POLL_STATS) { 
 | 
        dev = _ispp_stats_dev; 
 | 
        stop_fd = _ispp_poll_stop_fd[0]; 
 | 
    } else if (type == ISP_POLL_3A_STATS) { 
 | 
        dev = _isp_stats_dev; 
 | 
        stop_fd = _3a_stats_poll_stop_fd[0]; 
 | 
    } else if (type == ISP_POLL_PARAMS) { 
 | 
        dev = _isp_params_dev; 
 | 
        stop_fd = _isp_params_poll_stop_fd[0]; 
 | 
    } else if (type == ISP_POLL_POST_PARAMS) { 
 | 
        dev = _isp_pparams_dev; 
 | 
        stop_fd = _isp_pparams_poll_stop_fd[0]; 
 | 
    } else 
 | 
        return XCAM_RETURN_ERROR_UNKNOWN; 
 | 
  
 | 
    poll_ret = dev->poll_event (PollThread::default_poll_timeout, 
 | 
                                stop_fd); 
 | 
  
 | 
    if (poll_ret == POLL_STOP_RET) { 
 | 
        XCAM_LOG_DEBUG ("poll %s buffer stop success !", isp_poll_type_to_str[type]); 
 | 
        // stop success, return error to stop the poll thread 
 | 
        return XCAM_RETURN_ERROR_UNKNOWN; 
 | 
    } 
 | 
  
 | 
    if (poll_ret <= 0) { 
 | 
        XCAM_LOG_DEBUG ("poll %s buffer event got error(0x%x) but continue\n", isp_poll_type_to_str[type], poll_ret); 
 | 
        ::usleep (100000); // 100ms 
 | 
        return XCAM_RETURN_ERROR_TIMEOUT; 
 | 
    } 
 | 
  
 | 
    ret = dev->dequeue_buffer (buf); 
 | 
    if (ret != XCAM_RETURN_NO_ERROR) { 
 | 
        XCAM_LOG_WARNING ("dequeue %s buffer failed", isp_poll_type_to_str[type]); 
 | 
        return ret; 
 | 
    } 
 | 
  
 | 
    XCAM_ASSERT (buf.ptr()); 
 | 
    XCAM_ASSERT (_poll_callback); 
 | 
  
 | 
    if (_poll_callback && 
 | 
            (type == ISP_POLL_3A_STATS || type == ISP_POLL_LUMA || type == ISPP_POLL_STATS)) { 
 | 
        SmartPtr<VideoBuffer> video_buf = new_video_buffer(buf, dev, type); 
 | 
  
 | 
        return _poll_callback->poll_buffer_ready (video_buf, type); 
 | 
    } 
 | 
#endif 
 | 
    return ret; 
 | 
} 
 | 
  
 | 
}; 
 |