void V4L2VideoNode::destroyBufferPool()
{

    LOG1("@%s: device = %s", __FUNCTION__, mName.string());

    mBufferPool.clear();

    requestBuffers(0);
}
void V4L2VideoNode::destroyBufferPool()
{

    LOG1("@%s: device = %s", __FUNCTION__, mName.string());

    mBufferPool.clear();
    mBufferPool.setCapacity(MAX_V4L2_BUFFERS);

    requestBuffers(0);
}
/**
 * setBufferPool
 * Presents the pool of buffers to the device.
 *
 * The device has to be  in CONFIGURED state.
 *
 * In this stage we request the buffer slots to the device and present
 * them to the driver assigning one index to each buffer.
 *
 * After this method the device is PREPARED and ready to Q
 * buffers
 * The structures in the pool are empty.
 * After this call the buffers have been presented to the device an index is assigned.
 * The structure is updated with this index and other details  (this is the output)
 *
 * \param pool: [IN/OUT]Vector of v4l2_buffers structures
 * \param cached: [IN]boolean to detect whether the buffers are cached or not
 *                A cached buffer in this context means that the buffer
 *                memory may be accessed through some system caches, and
 *                the V4L2 driver must do cache invalidation in case
 *                the image data source is not updating system caches
 *                in hardware.
 *                When false (not cached), V4L2 driver can assume no cache
 *                invalidation/flushes are needed for this buffer.
 *\return  INVALID_OPERATION if the device was not configured
 *\return  UNKNOWN_ERROR if any of the v4l2 commands fails
 *\return  NO_ERROR if everything went AOK
 */
status_t V4L2VideoNode::setBufferPool(Vector<struct v4l2_buffer> &pool,
                                      bool cached, int memType)
{
    LOG1("@%s: device = %s", __FUNCTION__, mName.string());
    struct v4l2_buffer_info vinfo;
    CLEAR(vinfo);
    int ret;
    uint32_t cacheflags = V4L2_BUF_FLAG_NO_CACHE_INVALIDATE |
                         V4L2_BUF_FLAG_NO_CACHE_CLEAN;

    if ((mState != DEVICE_CONFIGURED)) {
        LOGE("%s:Invalid operation, device %s not configured (state = %d)",
                __FUNCTION__, mName.string(), mState);
        return INVALID_OPERATION;
    }

    mBufferPool.clear();
    int num_buffers = requestBuffers(pool.size(), memType);
    if (num_buffers <= 0) {
        LOGE("%s: Could not complete buffer request",__FUNCTION__);
        return UNKNOWN_ERROR;
    }

    vinfo.width = mConfig.stride;
    vinfo.height = mConfig.height;
    vinfo.format = mConfig.format;
    vinfo.length = mConfig.size;

    for (unsigned int i = 0; i < pool.size(); i++) {
        if (cached)
            vinfo.cache_flags = 0;
        else
            vinfo.cache_flags = cacheflags;

        //vinfo.data = (void *) pool.editItemAt(i).m.userptr;
        ret = newBuffer(i, vinfo, memType);
        if (ret < 0) {
            LOGE("Error querying buffers status");
            mBufferPool.clear();
            mState = DEVICE_ERROR;
            return UNKNOWN_ERROR;
        }
        pool.replaceAt(vinfo.vbuffer, i);
        mBufferPool.push(vinfo);
    }

    mState = DEVICE_PREPARED;
    return NO_ERROR;
}
/**
 * creates an active buffer pool from the set-buffer-pool that is provided
 * to the device by the call setBufferPool.
 *
 * We request to the V4L2 driver certain amount of buffer slots with the
 * buffer configuration.
 *
 * Then copy the required number from the set-buffer-pool to the active-buffer-pool
 *
 * \param buffer_count: number of buffers that the active pool contains
 * This number is at maximum the number of buffers in the set-buffer-pool
 * \return 0  success
 *        -1  failure
 */
int V4L2VideoNode::createBufferPool(unsigned int buffer_count)
{
    LOG1("@%s: device = %s buf count %d", __FUNCTION__, mName.string(), buffer_count);
    int i(0);
    int ret(0);

    if (mState != DEVICE_PREPARED) {
        ALOGE("%s: Incorrect device state  %d", __FUNCTION__, mState);
        return -1;
    }

    if (buffer_count > mSetBufferPool.size()) {
        ALOGE("%s: Incorrect parameter requested %d, but only %d provided",
                __FUNCTION__, buffer_count, mSetBufferPool.size());
        return -1;
    }

    int num_buffers = requestBuffers(buffer_count);
    if (num_buffers <= 0) {
        ALOGE("%s: Could not complete buffer request",__FUNCTION__);
        return -1;
    }

    mBufferPool.clear();
    mBufferPool.setCapacity(MAX_V4L2_BUFFERS);

    for (i = 0; i < num_buffers; i++) {
        ret = newBuffer(i, mSetBufferPool.editItemAt(i));
        if (ret < 0)
            goto error;
        mBufferPool.push(mSetBufferPool[i]);
    }

    mState = DEVICE_POPULATED;
    return 0;

error:
    ALOGE("Failed to VIDIOC_QUERYBUF some of the buffers, clearing the active buffer pool");
    mBufferPool.clear();
    mBufferPool.setCapacity(MAX_V4L2_BUFFERS);
    return ret;
}
Example #5
0
 void SslConnection::send()
 {
     asio::async_write(_socket, requestBuffers(), boost::bind(
             &SslConnection::handleWrite, this, pl::error));
 }
bool V4Linux2Camera::initCamera() {

    struct dirent **v4l2_devices;
    int dev_count = scandir ("/dev/", &v4l2_devices, v4lfilter, alphasort);
    if ((dev_count == 0) || (cfg->device<0) || (cfg->device>=dev_count)) return false;

    char v4l2_device[128];
    sprintf(v4l2_device,"/dev/video%d",cfg->device);

    dev_handle = open(v4l2_device, O_RDWR);
    if (dev_handle < 0) return false;

    memset(&v4l2_caps, 0, sizeof(v4l2_capability));
    if (ioctl(dev_handle, VIDIOC_QUERYCAP, &v4l2_caps) < 0) {
        close(dev_handle);
        return false;
    }

    if ((v4l2_caps.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) {
        close(dev_handle);
        return false;
    }

    if ((v4l2_caps.capabilities & V4L2_CAP_STREAMING) == 0) {
        close(dev_handle);
        return false;
    }

    sprintf(cfg->name, "%s (%s)", v4l2_caps.card, v4l2_caps.driver);

    std::vector<CameraConfig> cfg_list = V4Linux2Camera::getCameraConfigs(cfg->device);
    if (cfg->cam_format==FORMAT_UNKNOWN) cfg->cam_format = cfg_list[0].cam_format;
    setMinMaxConfig(cfg,cfg_list);

    pixelformat=0;
    for (int i=0;;i++) {
        struct v4l2_fmtdesc fmtdesc;
        memset(&fmtdesc, 0, sizeof(v4l2_fmtdesc));
        fmtdesc.index = i;
        fmtdesc.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        if (-1 == ioctl(dev_handle,VIDIOC_ENUM_FMT,&fmtdesc)) break;

        for (int i=FORMAT_MAX;i>0;i--) {
            if (fmtdesc.pixelformat == codec_table[i]) {
                if (cfg->cam_format==i) {
					pixelformat = fmtdesc.pixelformat;
					break;
				}
            }
        }

        if(pixelformat) break;
    }

    if (!pixelformat) {
        printf("%s does not support any valid pixel format\n",v4l2_device);
        close(dev_handle);
        return false;
    }

    cfg->cam_format = FORMAT_UNKNOWN;
    for (int i=FORMAT_MAX;i>0;i--) {
        if (pixelformat == codec_table[i]) {
            cfg->cam_format = i;
            break;
        }
    }

    // try to set the desired format
    memset(&v4l2_form, 0, sizeof(v4l2_format));
    v4l2_form.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    v4l2_form.fmt.pix.pixelformat = pixelformat;
    v4l2_form.fmt.pix.width  = cfg->cam_width;
    v4l2_form.fmt.pix.height = cfg->cam_height;

    if (-1 == ioctl (dev_handle, VIDIOC_S_FMT, &v4l2_form)) {
        printf("error setting pixel format: %s\n" , strerror(errno));
        return false;
    }

    // try to set the desired fps
    v4l2_parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    v4l2_parm.parm.capture.timeperframe.numerator = 1;
    v4l2_parm.parm.capture.timeperframe.denominator = int(cfg->cam_fps);

    if(-1 == ioctl (dev_handle, VIDIOC_S_PARM, &v4l2_parm)) {
        printf("error setting fps: %s\n", strerror(errno));
        //return false;
    }

    // use the settings we got from the driver
    pixelformat = v4l2_form.fmt.pix.pixelformat;
    cfg->cam_width = v4l2_form.fmt.pix.width;
    cfg->cam_height = v4l2_form.fmt.pix.height;
    cfg->cam_fps = roundf((v4l2_parm.parm.capture.timeperframe.denominator/(float)v4l2_parm.parm.capture.timeperframe.numerator)*10)/10.0f;

    if ((pixelformat == V4L2_PIX_FMT_MJPEG) || (pixelformat == V4L2_PIX_FMT_JPEG)) _jpegDecompressor = tjInitDecompress();

    if (!requestBuffers()) {
        printf("Error requesting buffers.\n");
        return false;
    }

    if (!mapBuffers()) {
        printf("Unable to mmap buffers.\n");
        return false;
    }

    setupFrame();
    if (cfg->frame) frm_buffer = new unsigned char[cfg->frame_width*cfg->frame_height*cfg->buf_format];
    cam_buffer = new unsigned char[cfg->cam_width*cfg->cam_height*cfg->buf_format];
    buffers_initialized = true;
    return true;
}