MmalVideoCamera::MmalVideoCamera(int imageWidth, int imageHeight, int frameRate) : m_imageWidth(imageWidth), m_imageHeight(imageHeight), m_frameRate(frameRate), m_imagePreviewWidth(VCOS_ALIGN_UP(imageWidth, 32)), m_imagePreviewHeight(VCOS_ALIGN_UP(imageHeight, 16)), m_callbackData(NULL), m_cs(), m_camera(NULL), m_pool(NULL), m_videoPort(NULL), m_stillPort(NULL), m_previewPort(NULL), m_videoPortEnabled(false) { std::cout << "Creating callback data..." << std::endl; m_callbackData = new MmalVideoCallbackData(m_imageWidth, m_imageHeight, 3); std::cout << "Creating camera..." << std::endl; createCameraComponent(); std::cout << "Created camera" << std::endl; std::cout << "Target Image Width: " << m_imageWidth << std::endl; std::cout << "Target Image Height: " << m_imageHeight << std::endl; createBufferPool(); std::cout << "Initialized camera" << std::endl; }
MmalStillCamera::MmalStillCamera(int imageWidth, int imageHeight, bool enableBurstMode) : m_imageWidth(imageWidth), m_imageHeight(imageHeight), m_callbackData(NULL), m_cs(), m_camera(NULL), m_preview(NULL), m_encoder(NULL), m_pool(NULL), m_previewPort(NULL), m_videoPort(NULL), m_stillPort(NULL), m_targetPort(NULL) { m_callbackData = new MmalStillCallbackData(m_imageWidth, m_imageHeight, 3); createCameraComponent(); std::cout << "Created camera" << std::endl; createPreview(); std::cout << "Created preview" << std::endl; std::cout << "Target Image Width: " << VCOS_ALIGN_UP(m_imageWidth, 32) << std::endl; std::cout << "Target Image Height: " << VCOS_ALIGN_UP(m_imageHeight, 16) << std::endl; MMAL_STATUS_T status; m_targetPort = m_stillPort; // Create pool of buffer headers for the output port to consume m_pool = mmal_port_pool_create(m_targetPort, m_targetPort->buffer_num, m_targetPort->buffer_size); if (m_pool == NULL) { throw Exception("Failed to create buffer header pool for encoder output port"); } MMAL_CONNECTION_T *preview_connection = NULL; status = connect_ports(m_previewPort, m_preview->input[0], &preview_connection); if (status != MMAL_SUCCESS) { throw Exception("Error connecting preview port"); } m_targetPort->userdata = (struct MMAL_PORT_USERDATA_T *) m_callbackData; m_callbackData->image = NULL; m_callbackData->pool = m_pool; // Enable the encoder output port and tell it its callback function if (mmal_port_enable(m_targetPort, EncoderBufferCallback) != MMAL_SUCCESS) { std::cerr << "Error enabling the encoder buffer callback" << std::endl; } // Send all the buffers to the encoder output port int num = mmal_queue_length(m_pool->queue); for (int q = 0; q < num; q++) { MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(m_pool->queue); if (buffer == NULL) { std::cerr << "Unable to get buffer " << q << " from the pool" << std::endl; } if (mmal_port_send_buffer(m_targetPort, buffer)!= MMAL_SUCCESS) { std::cerr << "Unable to send a buffer " << q << " to encoder output port " << std::endl; } } // Enable burst mode if (enableBurstMode) { if (mmal_port_parameter_set_boolean(m_camera->control, MMAL_PARAMETER_CAMERA_BURST_CAPTURE, 1) != MMAL_SUCCESS) { std::cerr << "Error enabling burst mode" << std::endl; } std::cout << "Enabled burst mode for still images" << std::endl; } std::cout << "Initialized camera" << std::endl; }
void MmalStillCamera::initialize(CameraMode cameraMode) { m_resolution = MmalUtil::get()->getClosestResolution(m_name, cameraMode); if (m_imageWidth != -1) { throw Exception("Camera is already initialized"); } m_imageWidth = m_resolution.width; m_imageHeight = m_resolution.height; m_callbackData = new MmalStillCallbackData(m_imageWidth, m_imageHeight, 3); // Handle the sensor properties real sensorWidth, sensorHeight, focalLength; MmalUtil::get()->getSensorProperties(m_name, sensorWidth, sensorHeight, focalLength); setSensorProperties(sensorWidth, sensorHeight, focalLength); createCameraComponent(); InfoLog << "Created camera" << Logger::ENDL; createPreview(); InfoLog << "Created preview" << Logger::ENDL; InfoLog << "Target Image Width: " << VCOS_ALIGN_UP(m_imageWidth, 32) << Logger::ENDL; InfoLog << "Target Image Height: " << VCOS_ALIGN_UP(m_imageHeight, 16) << Logger::ENDL; MMAL_STATUS_T status; m_targetPort = m_stillPort; // Create pool of buffer headers for the output port to consume m_pool = mmal_port_pool_create(m_targetPort, m_targetPort->buffer_num, m_targetPort->buffer_size); if (m_pool == NULL) { throw Exception("Failed to create buffer header pool for encoder output port"); } MMAL_CONNECTION_T *preview_connection = NULL; status = connect_ports(m_previewPort, m_preview->input[0], &preview_connection); if (status != MMAL_SUCCESS) { throw Exception("Error connecting preview port"); } m_targetPort->userdata = (struct MMAL_PORT_USERDATA_T *) m_callbackData; m_callbackData->image = NULL; m_callbackData->pool = m_pool; // Enable the encoder output port and tell it its callback function if (mmal_port_enable(m_targetPort, EncoderBufferCallback) != MMAL_SUCCESS) { ErrorLog << "Error enabling the encoder buffer callback" << Logger::ENDL; } // Send all the buffers to the encoder output port int num = mmal_queue_length(m_pool->queue); for (int q = 0; q < num; q++) { MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(m_pool->queue); if (buffer == NULL) { ErrorLog << "Unable to get buffer " << q << " from the pool" << Logger::ENDL; } if (mmal_port_send_buffer(m_targetPort, buffer) != MMAL_SUCCESS) { ErrorLog << "Unable to send a buffer " << q << " to encoder output port " << Logger::ENDL; } } // Enable burst mode if (m_burstModeEnabled) { if (mmal_port_parameter_set_boolean(m_camera->control, MMAL_PARAMETER_CAMERA_BURST_CAPTURE, 1) != MMAL_SUCCESS) { ErrorLog << "Error enabling burst mode" << Logger::ENDL; } InfoLog << "Enabled burst mode for still images" << Logger::ENDL; } InfoLog << "Initialized camera" << Logger::ENDL; }