int Private_Impl_Still::startCapture() {
    // If the parameters were changed and this function wasn't called, it will be called here
    // However if the parameters weren't changed, the function won't do anything - it will return right away
    commitParameters();

    if ( encoder_output_port->is_enabled ) {
        cout << API_NAME << ": Could not enable encoder output port. Try waiting longer before attempting to take another picture.\n";
        return -1;
    }
    if ( mmal_port_enable ( encoder_output_port, buffer_callback ) != MMAL_SUCCESS ) {
        cout << API_NAME << ": Could not enable encoder output port.\n";
        return -1;
    }
    int num = mmal_queue_length ( encoder_pool->queue );
    for ( int b = 0; b < num; b++ ) {
        MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get ( encoder_pool->queue );

        if ( !buffer )
            cout << API_NAME << ": Could not get buffer (#" << b << ") from pool queue.\n";

        if ( mmal_port_send_buffer ( encoder_output_port, buffer ) != MMAL_SUCCESS )
            cout << API_NAME << ": Could not send a buffer (#" << b << ") to encoder output port.\n";
    }
    if ( mmal_port_parameter_set_boolean ( camera_still_port, MMAL_PARAMETER_CAPTURE, 1 ) != MMAL_SUCCESS ) {
        cout << API_NAME << ": Failed to start capture.\n";
        return -1;
    }
    return 0;
}
        bool  Private_Impl::open ( bool StartCapture ) {
            if ( _isOpened ) return false; //already opened
// create camera
            if ( ! create_camera_component ( &State ) ) {
                cerr<<__func__<<" Failed to create camera component"<<__FILE__<<" "<<__LINE__<<endl;
                return false;
            }
            commitParameters();
            camera_video_port   = State.camera_component->output[MMAL_CAMERA_VIDEO_PORT];
            callback_data.pstate = &State;
            // assign data to use for callback
            camera_video_port->userdata = ( struct MMAL_PORT_USERDATA_T * ) &callback_data;

            _isOpened=true;
            if ( StartCapture ) return startCapture();
            else return true;
        }
int Private_Impl_Still::createCamera() {
    if ( mmal_component_create ( MMAL_COMPONENT_DEFAULT_CAMERA, &camera ) ) {
        cout << API_NAME << ": Failed to create camera component.\n";
        destroyCamera();
        return -1;
    }

    if ( !camera->output_num ) {
        cout << API_NAME << ": Camera does not have output ports!\n";
        destroyCamera();
        return -1;
    }

    camera_still_port = camera->output[MMAL_CAMERA_CAPTURE_PORT];

    // Enable the camera, and tell it its control callback function
    if ( mmal_port_enable ( camera->control, control_callback ) ) {
        cout << API_NAME << ": Could not enable control port.\n";
        destroyCamera();
        return -1;
    }

    MMAL_PARAMETER_CAMERA_CONFIG_T camConfig = {
        {MMAL_PARAMETER_CAMERA_CONFIG, sizeof ( camConfig ) },
        width, // max_stills_w
        height, // max_stills_h
        0, // stills_yuv422
        1, // one_shot_stills
        width, // max_preview_video_w
        height, // max_preview_video_h
        3, // num_preview_video_frames
        0, // stills_capture_circular_buffer_height
        0, // fast_preview_resume
        MMAL_PARAM_TIMESTAMP_MODE_RESET_STC // use_stc_timestamp
    };
    if ( mmal_port_parameter_set ( camera->control, &camConfig.hdr ) != MMAL_SUCCESS )
        cout << API_NAME << ": Could not set port parameters.\n";

    commitParameters();

    MMAL_ES_FORMAT_T * format = camera_still_port->format;
    format->encoding = MMAL_ENCODING_OPAQUE;
    format->es->video.width = width;
    format->es->video.height = height;
    format->es->video.crop.x = 0;
    format->es->video.crop.y = 0;
    format->es->video.crop.width = width;
    format->es->video.crop.height = height;
    format->es->video.frame_rate.num = STILLS_FRAME_RATE_NUM;
    format->es->video.frame_rate.den = STILLS_FRAME_RATE_DEN;

    if ( camera_still_port->buffer_size < camera_still_port->buffer_size_min )
        camera_still_port->buffer_size = camera_still_port->buffer_size_min;

    camera_still_port->buffer_num = camera_still_port->buffer_num_recommended;

    if ( mmal_port_format_commit ( camera_still_port ) ) {
        cout << API_NAME << ": Camera still format could not be set.\n";
        destroyCamera();
        return -1;
    }

    if ( mmal_component_enable ( camera ) ) {
        cout << API_NAME << ": Camera component could not be enabled.\n";
        destroyCamera();
        return -1;
    }

    if ( ! ( encoder_pool = mmal_port_pool_create ( camera_still_port, camera_still_port->buffer_num, camera_still_port->buffer_size ) ) ) {
        cout << API_NAME << ": Failed to create buffer header pool for camera.\n";
        destroyCamera();
        return -1;
    }

    return 0;
}