mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-30 04:45:36 +00:00
rpicamsrc: Checkpoint. Version which writes directly to test.out
Switch to plain basesrc for parent class
This commit is contained in:
parent
f4af399350
commit
7ffb618b20
6 changed files with 333 additions and 313 deletions
|
@ -187,6 +187,7 @@ static int update_cycle_parameter(int *option, int min, int max, int increment)
|
||||||
else
|
else
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -203,6 +204,9 @@ static int update_cycle_parameter(int *option, int min, int max, int increment)
|
||||||
|
|
||||||
int raspicamcontrol_cycle_test(MMAL_COMPONENT_T *camera)
|
int raspicamcontrol_cycle_test(MMAL_COMPONENT_T *camera)
|
||||||
{
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
static int parameter = 0;
|
static int parameter = 0;
|
||||||
static int parameter_option = parameter_reset; // which value the parameter currently has
|
static int parameter_option = parameter_reset; // which value the parameter currently has
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <sysexits.h>
|
#include <sysexits.h>
|
||||||
|
|
||||||
|
|
||||||
#include "bcm_host.h"
|
#include "bcm_host.h"
|
||||||
#include "interface/vcos/vcos.h"
|
#include "interface/vcos/vcos.h"
|
||||||
|
|
||||||
|
@ -68,6 +69,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "interface/mmal/util/mmal_default_components.h"
|
#include "interface/mmal/util/mmal_default_components.h"
|
||||||
#include "interface/mmal/util/mmal_connection.h"
|
#include "interface/mmal/util/mmal_connection.h"
|
||||||
|
|
||||||
|
#include "RaspiCapture.h"
|
||||||
#include "RaspiCamControl.h"
|
#include "RaspiCamControl.h"
|
||||||
#include "RaspiPreview.h"
|
#include "RaspiPreview.h"
|
||||||
|
|
||||||
|
@ -97,42 +99,32 @@ const int ABORT_INTERVAL = 100; // ms
|
||||||
|
|
||||||
int mmal_status_to_int(MMAL_STATUS_T status);
|
int mmal_status_to_int(MMAL_STATUS_T status);
|
||||||
|
|
||||||
/** Structure containing all state information for the current run
|
/** Struct used to pass information in encoder port userdata to callback
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int timeout; /// Time taken before frame is grabbed and app then shuts down. Units are milliseconds
|
RASPIVID_STATE *state; /// pointer to our state in case required in callback
|
||||||
int width; /// Requested width of image
|
int abort; /// Set to 1 in callback if an error occurs to attempt to abort the capture
|
||||||
int height; /// requested height of image
|
} PORT_USERDATA;
|
||||||
int bitrate; /// Requested bitrate
|
|
||||||
int framerate; /// Requested frame rate (fps)
|
struct RASPIVID_STATE_T
|
||||||
int intraperiod; /// Intra-refresh period (key frame rate)
|
{
|
||||||
char *filename; /// filename of output file
|
RASPIVID_CONFIG config;
|
||||||
int verbose; /// !0 if want detailed run information
|
|
||||||
int demoMode; /// Run app in demo mode
|
FILE *output_file;
|
||||||
int demoInterval; /// Interval between camera settings changes
|
|
||||||
int immutableInput; /// Flag to specify whether encoder works in place or creates a new buffer. Result is preview can display either
|
|
||||||
/// the camera output or the encoder output (with compression artifacts)
|
|
||||||
int profile; /// H264 profile to use for encoding
|
|
||||||
RASPIPREVIEW_PARAMETERS preview_parameters; /// Preview setup parameters
|
|
||||||
RASPICAM_CAMERA_PARAMETERS camera_parameters; /// Camera setup parameters
|
|
||||||
|
|
||||||
MMAL_COMPONENT_T *camera_component; /// Pointer to the camera component
|
MMAL_COMPONENT_T *camera_component; /// Pointer to the camera component
|
||||||
MMAL_COMPONENT_T *encoder_component; /// Pointer to the encoder component
|
MMAL_COMPONENT_T *encoder_component; /// Pointer to the encoder component
|
||||||
MMAL_CONNECTION_T *preview_connection; /// Pointer to the connection from camera to preview
|
MMAL_CONNECTION_T *preview_connection; /// Pointer to the connection from camera to preview
|
||||||
MMAL_CONNECTION_T *encoder_connection; /// Pointer to the connection from camera to encoder
|
MMAL_CONNECTION_T *encoder_connection; /// Pointer to the connection from camera to encoder
|
||||||
|
|
||||||
MMAL_POOL_T *encoder_pool; /// Pointer to the pool of buffers used by encoder output port
|
MMAL_PORT_T *camera_still_port;
|
||||||
} RASPIVID_STATE;
|
MMAL_PORT_T *encoder_output_port;
|
||||||
|
|
||||||
/** Struct used to pass information in encoder port userdata to callback
|
MMAL_POOL_T *encoder_pool; /// Pointer to the pool of buffers used by encoder output port
|
||||||
*/
|
|
||||||
typedef struct
|
PORT_USERDATA callback_data;
|
||||||
{
|
};
|
||||||
FILE *file_handle; /// File handle to write buffer data to.
|
|
||||||
RASPIVID_STATE *pstate; /// pointer to our state in case required in callback
|
|
||||||
int abort; /// Set to 1 in callback if an error occurs to attempt to abort the capture
|
|
||||||
} PORT_USERDATA;
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/// Structure to cross reference H264 profile strings against the MMAL parameter equivalent
|
/// Structure to cross reference H264 profile strings against the MMAL parameter equivalent
|
||||||
|
@ -189,36 +181,27 @@ static void dump_state(RASPIVID_STATE *state);
|
||||||
*
|
*
|
||||||
* @param state Pointer to state structure to assign defaults to
|
* @param state Pointer to state structure to assign defaults to
|
||||||
*/
|
*/
|
||||||
void raspi_capture_default_state(RASPIVID_STATE *state)
|
void raspicapture_default_config(RASPIVID_CONFIG *config)
|
||||||
{
|
{
|
||||||
if (!state)
|
|
||||||
{
|
|
||||||
vcos_assert(0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default everything to zero
|
|
||||||
memset(state, 0, sizeof(RASPIVID_STATE));
|
|
||||||
|
|
||||||
// Now set anything non-zero
|
// Now set anything non-zero
|
||||||
state->timeout = 5000; // 5s delay before take image
|
config->timeout = 5000; // 5s delay before take image
|
||||||
state->width = 1920; // Default to 1080p
|
config->width = 1920; // Default to 1080p
|
||||||
state->height = 1080;
|
config->height = 1080;
|
||||||
state->bitrate = 17000000; // This is a decent default bitrate for 1080p
|
config->bitrate = 17000000; // This is a decent default bitrate for 1080p
|
||||||
state->framerate = VIDEO_FRAME_RATE_NUM;
|
config->framerate = VIDEO_FRAME_RATE_NUM;
|
||||||
state->intraperiod = 0; // Not set
|
config->intraperiod = 0; // Not set
|
||||||
state->demoMode = 0;
|
config->demoMode = 0;
|
||||||
state->demoInterval = 250; // ms
|
config->demoInterval = 250; // ms
|
||||||
state->immutableInput = 1;
|
config->immutableInput = 1;
|
||||||
state->profile = MMAL_VIDEO_PROFILE_H264_HIGH;
|
config->profile = MMAL_VIDEO_PROFILE_H264_HIGH;
|
||||||
|
|
||||||
// Setup preview window defaults
|
// Setup preview window defaults
|
||||||
raspipreview_set_defaults(&state->preview_parameters);
|
raspipreview_set_defaults(&config->preview_parameters);
|
||||||
|
|
||||||
// Set up the camera_parameters to default
|
// Set up the camera_parameters to default
|
||||||
raspicamcontrol_set_defaults(&state->camera_parameters);
|
raspicamcontrol_set_defaults(&config->camera_parameters);
|
||||||
|
|
||||||
dump_state(state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -234,12 +217,12 @@ static void dump_state(RASPIVID_STATE *state)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "Width %d, Height %d, filename %s\n", state->width, state->height, state->filename);
|
fprintf(stderr, "Width %d, Height %d, filename %s\n", state->config.width, state->config.height, state->config.filename);
|
||||||
fprintf(stderr, "bitrate %d, framerate %d, time delay %d\n", state->bitrate, state->framerate, state->timeout);
|
fprintf(stderr, "bitrate %d, framerate %d, time delay %d\n", state->config.bitrate, state->config.framerate, state->config.timeout);
|
||||||
//fprintf(stderr, "H264 Profile %s\n", raspicli_unmap_xref(state->profile, profile_map, profile_map_size));
|
//fprintf(stderr, "H264 Profile %s\n", raspicli_unmap_xref(state->config.profile, profile_map, profile_map_size));
|
||||||
|
|
||||||
raspipreview_dump_parameters(&state->preview_parameters);
|
raspipreview_dump_parameters(&state->config.preview_parameters);
|
||||||
raspicamcontrol_dump_parameters(&state->camera_parameters);
|
//raspicamcontrol_dump_parameters(&state->config.camera_parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -521,18 +504,19 @@ static void encoder_buffer_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buf
|
||||||
// We pass our file handle and other stuff in via the userdata field.
|
// We pass our file handle and other stuff in via the userdata field.
|
||||||
|
|
||||||
PORT_USERDATA *pData = (PORT_USERDATA *)port->userdata;
|
PORT_USERDATA *pData = (PORT_USERDATA *)port->userdata;
|
||||||
|
RASPIVID_STATE *state = pData->state;
|
||||||
|
|
||||||
if (pData)
|
if (pData)
|
||||||
{
|
{
|
||||||
int bytes_written = buffer->length;
|
int bytes_written = buffer->length;
|
||||||
|
|
||||||
vcos_assert(pData->file_handle);
|
vcos_assert(state->output_file);
|
||||||
|
|
||||||
if (buffer->length)
|
if (buffer->length)
|
||||||
{
|
{
|
||||||
mmal_buffer_header_mem_lock(buffer);
|
mmal_buffer_header_mem_lock(buffer);
|
||||||
|
|
||||||
bytes_written = fwrite(buffer->data, 1, buffer->length, pData->file_handle);
|
bytes_written = fwrite(buffer->data, 1, buffer->length, state->output_file);
|
||||||
|
|
||||||
mmal_buffer_header_mem_unlock(buffer);
|
mmal_buffer_header_mem_unlock(buffer);
|
||||||
}
|
}
|
||||||
|
@ -554,9 +538,9 @@ static void encoder_buffer_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buf
|
||||||
// and send one back to the port (if still open)
|
// and send one back to the port (if still open)
|
||||||
if (port->is_enabled)
|
if (port->is_enabled)
|
||||||
{
|
{
|
||||||
MMAL_STATUS_T status;
|
MMAL_STATUS_T status = MMAL_SUCCESS;
|
||||||
|
|
||||||
new_buffer = mmal_queue_get(pData->pstate->encoder_pool->queue);
|
new_buffer = mmal_queue_get(state->encoder_pool->queue);
|
||||||
|
|
||||||
if (new_buffer)
|
if (new_buffer)
|
||||||
status = mmal_port_send_buffer(port, new_buffer);
|
status = mmal_port_send_buffer(port, new_buffer);
|
||||||
|
@ -616,12 +600,12 @@ static MMAL_STATUS_T create_camera_component(RASPIVID_STATE *state)
|
||||||
MMAL_PARAMETER_CAMERA_CONFIG_T cam_config =
|
MMAL_PARAMETER_CAMERA_CONFIG_T cam_config =
|
||||||
{
|
{
|
||||||
{ MMAL_PARAMETER_CAMERA_CONFIG, sizeof(cam_config) },
|
{ MMAL_PARAMETER_CAMERA_CONFIG, sizeof(cam_config) },
|
||||||
.max_stills_w = state->width,
|
.max_stills_w = state->config.width,
|
||||||
.max_stills_h = state->height,
|
.max_stills_h = state->config.height,
|
||||||
.stills_yuv422 = 0,
|
.stills_yuv422 = 0,
|
||||||
.one_shot_stills = 0,
|
.one_shot_stills = 0,
|
||||||
.max_preview_video_w = state->width,
|
.max_preview_video_w = state->config.width,
|
||||||
.max_preview_video_h = state->height,
|
.max_preview_video_h = state->config.height,
|
||||||
.num_preview_video_frames = 3,
|
.num_preview_video_frames = 3,
|
||||||
.stills_capture_circular_buffer_height = 0,
|
.stills_capture_circular_buffer_height = 0,
|
||||||
.fast_preview_resume = 0,
|
.fast_preview_resume = 0,
|
||||||
|
@ -641,13 +625,13 @@ static MMAL_STATUS_T create_camera_component(RASPIVID_STATE *state)
|
||||||
format->encoding_variant = MMAL_ENCODING_I420;
|
format->encoding_variant = MMAL_ENCODING_I420;
|
||||||
|
|
||||||
format->encoding = MMAL_ENCODING_OPAQUE;
|
format->encoding = MMAL_ENCODING_OPAQUE;
|
||||||
format->es->video.width = state->width;
|
format->es->video.width = state->config.width;
|
||||||
format->es->video.height = state->height;
|
format->es->video.height = state->config.height;
|
||||||
format->es->video.crop.x = 0;
|
format->es->video.crop.x = 0;
|
||||||
format->es->video.crop.y = 0;
|
format->es->video.crop.y = 0;
|
||||||
format->es->video.crop.width = state->width;
|
format->es->video.crop.width = state->config.width;
|
||||||
format->es->video.crop.height = state->height;
|
format->es->video.crop.height = state->config.height;
|
||||||
format->es->video.frame_rate.num = state->framerate;
|
format->es->video.frame_rate.num = state->config.framerate;
|
||||||
format->es->video.frame_rate.den = VIDEO_FRAME_RATE_DEN;
|
format->es->video.frame_rate.den = VIDEO_FRAME_RATE_DEN;
|
||||||
|
|
||||||
status = mmal_port_format_commit(preview_port);
|
status = mmal_port_format_commit(preview_port);
|
||||||
|
@ -664,13 +648,13 @@ static MMAL_STATUS_T create_camera_component(RASPIVID_STATE *state)
|
||||||
format->encoding_variant = MMAL_ENCODING_I420;
|
format->encoding_variant = MMAL_ENCODING_I420;
|
||||||
|
|
||||||
format->encoding = MMAL_ENCODING_OPAQUE;
|
format->encoding = MMAL_ENCODING_OPAQUE;
|
||||||
format->es->video.width = state->width;
|
format->es->video.width = state->config.width;
|
||||||
format->es->video.height = state->height;
|
format->es->video.height = state->config.height;
|
||||||
format->es->video.crop.x = 0;
|
format->es->video.crop.x = 0;
|
||||||
format->es->video.crop.y = 0;
|
format->es->video.crop.y = 0;
|
||||||
format->es->video.crop.width = state->width;
|
format->es->video.crop.width = state->config.width;
|
||||||
format->es->video.crop.height = state->height;
|
format->es->video.crop.height = state->config.height;
|
||||||
format->es->video.frame_rate.num = state->framerate;
|
format->es->video.frame_rate.num = state->config.framerate;
|
||||||
format->es->video.frame_rate.den = VIDEO_FRAME_RATE_DEN;
|
format->es->video.frame_rate.den = VIDEO_FRAME_RATE_DEN;
|
||||||
|
|
||||||
status = mmal_port_format_commit(video_port);
|
status = mmal_port_format_commit(video_port);
|
||||||
|
@ -693,12 +677,12 @@ static MMAL_STATUS_T create_camera_component(RASPIVID_STATE *state)
|
||||||
format->encoding = MMAL_ENCODING_OPAQUE;
|
format->encoding = MMAL_ENCODING_OPAQUE;
|
||||||
format->encoding_variant = MMAL_ENCODING_I420;
|
format->encoding_variant = MMAL_ENCODING_I420;
|
||||||
|
|
||||||
format->es->video.width = state->width;
|
format->es->video.width = state->config.width;
|
||||||
format->es->video.height = state->height;
|
format->es->video.height = state->config.height;
|
||||||
format->es->video.crop.x = 0;
|
format->es->video.crop.x = 0;
|
||||||
format->es->video.crop.y = 0;
|
format->es->video.crop.y = 0;
|
||||||
format->es->video.crop.width = state->width;
|
format->es->video.crop.width = state->config.width;
|
||||||
format->es->video.crop.height = state->height;
|
format->es->video.crop.height = state->config.height;
|
||||||
format->es->video.frame_rate.num = 1;
|
format->es->video.frame_rate.num = 1;
|
||||||
format->es->video.frame_rate.den = 1;
|
format->es->video.frame_rate.den = 1;
|
||||||
|
|
||||||
|
@ -723,11 +707,11 @@ static MMAL_STATUS_T create_camera_component(RASPIVID_STATE *state)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
raspicamcontrol_set_all_parameters(camera, &state->camera_parameters);
|
raspicamcontrol_set_all_parameters(camera, &state->config.camera_parameters);
|
||||||
|
|
||||||
state->camera_component = camera;
|
state->camera_component = camera;
|
||||||
|
|
||||||
if (state->verbose)
|
if (state->config.verbose)
|
||||||
fprintf(stderr, "Camera component done\n");
|
fprintf(stderr, "Camera component done\n");
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
@ -794,7 +778,7 @@ static MMAL_STATUS_T create_encoder_component(RASPIVID_STATE *state)
|
||||||
// Only supporting H264 at the moment
|
// Only supporting H264 at the moment
|
||||||
encoder_output->format->encoding = MMAL_ENCODING_H264;
|
encoder_output->format->encoding = MMAL_ENCODING_H264;
|
||||||
|
|
||||||
encoder_output->format->bitrate = state->bitrate;
|
encoder_output->format->bitrate = state->config.bitrate;
|
||||||
|
|
||||||
encoder_output->buffer_size = encoder_output->buffer_size_recommended;
|
encoder_output->buffer_size = encoder_output->buffer_size_recommended;
|
||||||
|
|
||||||
|
@ -829,9 +813,9 @@ static MMAL_STATUS_T create_encoder_component(RASPIVID_STATE *state)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->intraperiod)
|
if (state->config.intraperiod)
|
||||||
{
|
{
|
||||||
MMAL_PARAMETER_UINT32_T param = {{ MMAL_PARAMETER_INTRAPERIOD, sizeof(param)}, state->intraperiod};
|
MMAL_PARAMETER_UINT32_T param = {{ MMAL_PARAMETER_INTRAPERIOD, sizeof(param)}, state->config.intraperiod};
|
||||||
status = mmal_port_parameter_set(encoder_output, ¶m.hdr);
|
status = mmal_port_parameter_set(encoder_output, ¶m.hdr);
|
||||||
if (status != MMAL_SUCCESS)
|
if (status != MMAL_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -846,7 +830,7 @@ static MMAL_STATUS_T create_encoder_component(RASPIVID_STATE *state)
|
||||||
param.hdr.id = MMAL_PARAMETER_PROFILE;
|
param.hdr.id = MMAL_PARAMETER_PROFILE;
|
||||||
param.hdr.size = sizeof(param);
|
param.hdr.size = sizeof(param);
|
||||||
|
|
||||||
param.profile[0].profile = state->profile;
|
param.profile[0].profile = state->config.profile;
|
||||||
param.profile[0].level = MMAL_VIDEO_LEVEL_H264_4; // This is the only value supported
|
param.profile[0].level = MMAL_VIDEO_LEVEL_H264_4; // This is the only value supported
|
||||||
|
|
||||||
status = mmal_port_parameter_set(encoder_output, ¶m.hdr);
|
status = mmal_port_parameter_set(encoder_output, ¶m.hdr);
|
||||||
|
@ -858,7 +842,7 @@ static MMAL_STATUS_T create_encoder_component(RASPIVID_STATE *state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (mmal_port_parameter_set_boolean(encoder_input, MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT, state->immutableInput) != MMAL_SUCCESS)
|
if (mmal_port_parameter_set_boolean(encoder_input, MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT, state->config.immutableInput) != MMAL_SUCCESS)
|
||||||
{
|
{
|
||||||
vcos_log_error("Unable to set immutable input flag");
|
vcos_log_error("Unable to set immutable input flag");
|
||||||
// Continue rather than abort..
|
// Continue rather than abort..
|
||||||
|
@ -884,7 +868,7 @@ static MMAL_STATUS_T create_encoder_component(RASPIVID_STATE *state)
|
||||||
state->encoder_pool = pool;
|
state->encoder_pool = pool;
|
||||||
state->encoder_component = encoder;
|
state->encoder_component = encoder;
|
||||||
|
|
||||||
if (state->verbose)
|
if (state->config.verbose)
|
||||||
fprintf(stderr, "Encoder component done\n");
|
fprintf(stderr, "Encoder component done\n");
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
@ -954,258 +938,262 @@ static void check_disable_port(MMAL_PORT_T *port)
|
||||||
mmal_port_disable(port);
|
mmal_port_disable(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void raspicapture_init()
|
||||||
int raspi_capture_start()
|
|
||||||
{
|
{
|
||||||
// Our main data storage vessel..
|
|
||||||
RASPIVID_STATE state;
|
|
||||||
int exit_code = EX_OK;
|
|
||||||
|
|
||||||
MMAL_STATUS_T status = MMAL_SUCCESS;
|
|
||||||
MMAL_PORT_T *camera_preview_port = NULL;
|
|
||||||
MMAL_PORT_T *camera_video_port = NULL;
|
|
||||||
MMAL_PORT_T *camera_still_port = NULL;
|
|
||||||
MMAL_PORT_T *preview_input_port = NULL;
|
|
||||||
MMAL_PORT_T *encoder_input_port = NULL;
|
|
||||||
MMAL_PORT_T *encoder_output_port = NULL;
|
|
||||||
FILE *output_file = NULL;
|
|
||||||
|
|
||||||
bcm_host_init();
|
bcm_host_init();
|
||||||
|
|
||||||
// Register our application with the logging system
|
// Register our application with the logging system
|
||||||
vcos_log_register("RaspiVid", VCOS_LOG_CATEGORY);
|
vcos_log_register("RaspiVid", VCOS_LOG_CATEGORY);
|
||||||
|
}
|
||||||
|
|
||||||
raspi_capture_default_state(&state);
|
RASPIVID_STATE *
|
||||||
|
raspi_capture_start(RASPIVID_CONFIG *config)
|
||||||
|
{
|
||||||
|
// Our main data storage vessel..
|
||||||
|
RASPIVID_STATE *state;
|
||||||
|
//int exit_code = EX_OK;
|
||||||
|
|
||||||
if (state.verbose)
|
MMAL_STATUS_T status = MMAL_SUCCESS;
|
||||||
{
|
MMAL_PORT_T *camera_preview_port = NULL;
|
||||||
dump_state(&state);
|
MMAL_PORT_T *camera_video_port = NULL;
|
||||||
}
|
MMAL_PORT_T *preview_input_port = NULL;
|
||||||
|
MMAL_PORT_T *encoder_input_port = NULL;
|
||||||
|
|
||||||
// OK, we have a nice set of parameters. Now set up our components
|
/* Default everything to zero */
|
||||||
// We have three components. Camera, Preview and encoder.
|
state = calloc(1, sizeof(RASPIVID_STATE));
|
||||||
|
|
||||||
if ((status = create_camera_component(&state)) != MMAL_SUCCESS)
|
/* Apply passed in config */
|
||||||
{
|
state->config = *config;
|
||||||
vcos_log_error("%s: Failed to create camera component", __func__);
|
|
||||||
exit_code = EX_SOFTWARE;
|
|
||||||
}
|
|
||||||
else if ((status = raspipreview_create(&state.preview_parameters)) != MMAL_SUCCESS)
|
|
||||||
{
|
|
||||||
vcos_log_error("%s: Failed to create preview component", __func__);
|
|
||||||
destroy_camera_component(&state);
|
|
||||||
exit_code = EX_SOFTWARE;
|
|
||||||
}
|
|
||||||
else if ((status = create_encoder_component(&state)) != MMAL_SUCCESS)
|
|
||||||
{
|
|
||||||
vcos_log_error("%s: Failed to create encode component", __func__);
|
|
||||||
raspipreview_destroy(&state.preview_parameters);
|
|
||||||
destroy_camera_component(&state);
|
|
||||||
exit_code = EX_SOFTWARE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PORT_USERDATA callback_data;
|
|
||||||
|
|
||||||
if (state.verbose)
|
if (state->config.verbose)
|
||||||
fprintf(stderr, "Starting component connection stage\n");
|
{
|
||||||
|
dump_state(state);
|
||||||
|
}
|
||||||
|
|
||||||
camera_preview_port = state.camera_component->output[MMAL_CAMERA_PREVIEW_PORT];
|
// OK, we have a nice set of parameters. Now set up our components
|
||||||
camera_video_port = state.camera_component->output[MMAL_CAMERA_VIDEO_PORT];
|
// We have three components. Camera, Preview and encoder.
|
||||||
camera_still_port = state.camera_component->output[MMAL_CAMERA_CAPTURE_PORT];
|
|
||||||
preview_input_port = state.preview_parameters.preview_component->input[0];
|
|
||||||
encoder_input_port = state.encoder_component->input[0];
|
|
||||||
encoder_output_port = state.encoder_component->output[0];
|
|
||||||
|
|
||||||
if (state.preview_parameters.wantPreview )
|
if ((status = create_camera_component(state)) != MMAL_SUCCESS)
|
||||||
{
|
{
|
||||||
if (state.verbose)
|
vcos_log_error("%s: Failed to create camera component", __func__);
|
||||||
{
|
return NULL;
|
||||||
fprintf(stderr, "Connecting camera preview port to preview input port\n");
|
}
|
||||||
fprintf(stderr, "Starting video preview\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect camera to preview
|
if ((status = raspipreview_create(&state->config.preview_parameters)) != MMAL_SUCCESS)
|
||||||
status = connect_ports(camera_preview_port, preview_input_port, &state.preview_connection);
|
{
|
||||||
}
|
vcos_log_error("%s: Failed to create preview component", __func__);
|
||||||
else
|
destroy_camera_component(state);
|
||||||
{
|
return NULL;
|
||||||
status = MMAL_SUCCESS;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (status == MMAL_SUCCESS)
|
if ((status = create_encoder_component(state)) != MMAL_SUCCESS)
|
||||||
{
|
{
|
||||||
if (state.verbose)
|
vcos_log_error("%s: Failed to create encode component", __func__);
|
||||||
fprintf(stderr, "Connecting camera stills port to encoder input port\n");
|
raspipreview_destroy(&state->config.preview_parameters);
|
||||||
|
destroy_camera_component(state);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Now connect the camera to the encoder
|
if (state->config.verbose)
|
||||||
status = connect_ports(camera_video_port, encoder_input_port, &state.encoder_connection);
|
fprintf(stderr, "Starting component connection stage\n");
|
||||||
|
|
||||||
if (status != MMAL_SUCCESS)
|
camera_preview_port = state->camera_component->output[MMAL_CAMERA_PREVIEW_PORT];
|
||||||
{
|
camera_video_port = state->camera_component->output[MMAL_CAMERA_VIDEO_PORT];
|
||||||
vcos_log_error("%s: Failed to connect camera video port to encoder input", __func__);
|
preview_input_port = state->config.preview_parameters.preview_component->input[0];
|
||||||
goto error;
|
encoder_input_port = state->encoder_component->input[0];
|
||||||
}
|
state->camera_still_port = state->camera_component->output[MMAL_CAMERA_CAPTURE_PORT];
|
||||||
|
state->encoder_output_port = state->encoder_component->output[0];
|
||||||
|
|
||||||
if (state.filename)
|
if (state->config.preview_parameters.wantPreview )
|
||||||
{
|
{
|
||||||
if (state.filename[0] == '-')
|
if (state->config.verbose)
|
||||||
{
|
{
|
||||||
output_file = stdout;
|
fprintf(stderr, "Connecting camera preview port to preview input port\n");
|
||||||
|
fprintf(stderr, "Starting video preview\n");
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure we don't upset the output stream with diagnostics/info
|
// Connect camera to preview
|
||||||
state.verbose = 0;
|
status = connect_ports(camera_preview_port, preview_input_port, &state->preview_connection);
|
||||||
}
|
if (status != MMAL_SUCCESS)
|
||||||
else
|
{
|
||||||
{
|
mmal_status_to_int(status);
|
||||||
if (state.verbose)
|
vcos_log_error("%s: Failed to connect camera to preview", __func__);
|
||||||
fprintf(stderr, "Opening output file \"%s\"\n", state.filename);
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
output_file = fopen(state.filename, "wb");
|
if (state->config.verbose)
|
||||||
}
|
fprintf(stderr, "Connecting camera stills port to encoder input port\n");
|
||||||
|
|
||||||
if (!output_file)
|
// Now connect the camera to the encoder
|
||||||
{
|
status = connect_ports(camera_video_port, encoder_input_port, &state->encoder_connection);
|
||||||
// Notify user, carry on but discarding encoded output buffers
|
|
||||||
vcos_log_error("%s: Error opening output file: %s\nNo output file will be generated\n", __func__, state.filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up our userdata - this is passed though to the callback where we need the information.
|
if (status != MMAL_SUCCESS)
|
||||||
callback_data.file_handle = output_file;
|
{
|
||||||
callback_data.pstate = &state;
|
vcos_log_error("%s: Failed to connect camera video port to encoder input", __func__);
|
||||||
callback_data.abort = 0;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
encoder_output_port->userdata = (struct MMAL_PORT_USERDATA_T *)&callback_data;
|
if (state->config.filename)
|
||||||
|
{
|
||||||
|
if (state->config.filename[0] == '-')
|
||||||
|
{
|
||||||
|
state->output_file = stdout;
|
||||||
|
|
||||||
if (state.verbose)
|
// Ensure we don't upset the output stream with diagnostics/info
|
||||||
fprintf(stderr, "Enabling encoder output port\n");
|
state->config.verbose = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (state->config.verbose)
|
||||||
|
fprintf(stderr, "Opening output file \"%s\"\n", state->config.filename);
|
||||||
|
|
||||||
// Enable the encoder output port and tell it its callback function
|
state->output_file = fopen(state->config.filename, "wb");
|
||||||
status = mmal_port_enable(encoder_output_port, encoder_buffer_callback);
|
}
|
||||||
|
|
||||||
if (status != MMAL_SUCCESS)
|
if (!state->output_file)
|
||||||
{
|
{
|
||||||
vcos_log_error("Failed to setup encoder output");
|
// Notify user, carry on but discarding encoded output buffers
|
||||||
goto error;
|
vcos_log_error("%s: Error opening output file: %s\nNo output file will be generated\n", __func__, state->config.filename);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (state.demoMode)
|
// Set up our userdata - this is passed though to the callback where we need the information.
|
||||||
{
|
state->callback_data.state = state;
|
||||||
// Run for the user specific time..
|
state->callback_data.abort = 0;
|
||||||
int num_iterations = state.timeout / state.demoInterval;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (state.verbose)
|
state->encoder_output_port->userdata = (struct MMAL_PORT_USERDATA_T *)&state->callback_data;
|
||||||
fprintf(stderr, "Running in demo mode\n");
|
|
||||||
|
|
||||||
for (i=0;state.timeout == 0 || i<num_iterations;i++)
|
if (state->config.verbose)
|
||||||
{
|
fprintf(stderr, "Enabling encoder output port\n");
|
||||||
raspicamcontrol_cycle_test(state.camera_component);
|
|
||||||
vcos_sleep(state.demoInterval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Only encode stuff if we have a filename and it opened
|
|
||||||
if (output_file)
|
|
||||||
{
|
|
||||||
int wait;
|
|
||||||
|
|
||||||
if (state.verbose)
|
// Enable the encoder output port and tell it its callback function
|
||||||
fprintf(stderr, "Starting video capture\n");
|
status = mmal_port_enable(state->encoder_output_port, encoder_buffer_callback);
|
||||||
|
|
||||||
if (mmal_port_parameter_set_boolean(camera_video_port, MMAL_PARAMETER_CAPTURE, 1) != MMAL_SUCCESS)
|
if (status != MMAL_SUCCESS)
|
||||||
{
|
{
|
||||||
goto error;
|
vcos_log_error("Failed to setup encoder output");
|
||||||
}
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
// Send all the buffers to the encoder output port
|
if (state->config.demoMode)
|
||||||
{
|
{
|
||||||
int num = mmal_queue_length(state.encoder_pool->queue);
|
// Run for the user specific time..
|
||||||
int q;
|
int num_iterations = state->config.timeout / state->config.demoInterval;
|
||||||
for (q=0;q<num;q++)
|
int i;
|
||||||
{
|
|
||||||
MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(state.encoder_pool->queue);
|
|
||||||
|
|
||||||
if (!buffer)
|
if (state->config.verbose)
|
||||||
vcos_log_error("Unable to get a required buffer %d from pool queue", q);
|
fprintf(stderr, "Running in demo mode\n");
|
||||||
|
|
||||||
if (mmal_port_send_buffer(encoder_output_port, buffer)!= MMAL_SUCCESS)
|
for (i=0;state->config.timeout == 0 || i<num_iterations;i++)
|
||||||
vcos_log_error("Unable to send a buffer to encoder output port (%d)", q);
|
{
|
||||||
|
raspicamcontrol_cycle_test(state->camera_component);
|
||||||
|
vcos_sleep(state->config.demoInterval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Only encode stuff if we have a filename and it opened
|
||||||
|
if (state->output_file)
|
||||||
|
{
|
||||||
|
int wait;
|
||||||
|
|
||||||
}
|
if (state->config.verbose)
|
||||||
}
|
fprintf(stderr, "Starting video capture\n");
|
||||||
|
|
||||||
// Now wait until we need to stop. Whilst waiting we do need to check to see if we have aborted (for example
|
if (mmal_port_parameter_set_boolean(camera_video_port, MMAL_PARAMETER_CAPTURE, 1) != MMAL_SUCCESS)
|
||||||
// out of storage space)
|
{
|
||||||
// Going to check every ABORT_INTERVAL milliseconds
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
for (wait = 0; state.timeout == 0 || wait < state.timeout; wait+= ABORT_INTERVAL)
|
// Send all the buffers to the encoder output port
|
||||||
{
|
{
|
||||||
vcos_sleep(ABORT_INTERVAL);
|
int num = mmal_queue_length(state->encoder_pool->queue);
|
||||||
if (callback_data.abort)
|
int q;
|
||||||
break;
|
for (q=0;q<num;q++)
|
||||||
}
|
{
|
||||||
|
MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(state->encoder_pool->queue);
|
||||||
|
|
||||||
if (state.verbose)
|
if (!buffer)
|
||||||
fprintf(stderr, "Finished capture\n");
|
vcos_log_error("Unable to get a required buffer %d from pool queue", q);
|
||||||
}
|
|
||||||
else
|
if (mmal_port_send_buffer(state->encoder_output_port, buffer)!= MMAL_SUCCESS)
|
||||||
{
|
vcos_log_error("Unable to send a buffer to encoder output port (%d)", q);
|
||||||
if (state.timeout)
|
|
||||||
vcos_sleep(state.timeout);
|
}
|
||||||
else
|
}
|
||||||
for (;;) vcos_sleep(ABORT_INTERVAL);
|
|
||||||
}
|
// Now wait until we need to stop. Whilst waiting we do need to check to see if we have aborted (for example
|
||||||
}
|
// out of storage space)
|
||||||
}
|
// Going to check every ABORT_INTERVAL milliseconds
|
||||||
else
|
|
||||||
{
|
for (wait = 0; state->config.timeout == 0 || wait < state->config.timeout; wait+= ABORT_INTERVAL)
|
||||||
mmal_status_to_int(status);
|
{
|
||||||
vcos_log_error("%s: Failed to connect camera to preview", __func__);
|
vcos_sleep(ABORT_INTERVAL);
|
||||||
}
|
if (state->callback_data.abort)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->config.verbose)
|
||||||
|
fprintf(stderr, "Finished capture\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (state->config.timeout)
|
||||||
|
vcos_sleep(state->config.timeout);
|
||||||
|
else
|
||||||
|
for (;;) vcos_sleep(ABORT_INTERVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
raspi_capture_stop(state);
|
||||||
|
|
||||||
mmal_status_to_int(status);
|
if (status != MMAL_SUCCESS) {
|
||||||
|
mmal_status_to_int(status);
|
||||||
|
raspicamcontrol_check_configuration(128);
|
||||||
|
}
|
||||||
|
|
||||||
if (state.verbose)
|
return NULL;
|
||||||
fprintf(stderr, "Closing down\n");
|
}
|
||||||
|
|
||||||
// Disable all our ports that are not handled by connections
|
void
|
||||||
check_disable_port(camera_still_port);
|
raspi_capture_stop(RASPIVID_STATE *state)
|
||||||
check_disable_port(encoder_output_port);
|
{
|
||||||
|
if (state->config.verbose)
|
||||||
if (state.preview_parameters.wantPreview )
|
fprintf(stderr, "Closing down\n");
|
||||||
mmal_connection_destroy(state.preview_connection);
|
|
||||||
mmal_connection_destroy(state.encoder_connection);
|
// Disable all our ports that are not handled by connections
|
||||||
|
check_disable_port(state->camera_still_port);
|
||||||
// Can now close our file. Note disabling ports may flush buffers which causes
|
check_disable_port(state->encoder_output_port);
|
||||||
// problems if we have already closed the file!
|
|
||||||
if (output_file && output_file != stdout)
|
if (state->config.preview_parameters.wantPreview )
|
||||||
fclose(output_file);
|
mmal_connection_destroy(state->preview_connection);
|
||||||
|
mmal_connection_destroy(state->encoder_connection);
|
||||||
/* Disable components */
|
|
||||||
if (state.encoder_component)
|
// Can now close our file. Note disabling ports may flush buffers which causes
|
||||||
mmal_component_disable(state.encoder_component);
|
// problems if we have already closed the file!
|
||||||
|
if (state->output_file && state->output_file != stdout)
|
||||||
if (state.preview_parameters.preview_component)
|
fclose(state->output_file);
|
||||||
mmal_component_disable(state.preview_parameters.preview_component);
|
|
||||||
|
/* Disable components */
|
||||||
if (state.camera_component)
|
if (state->encoder_component)
|
||||||
mmal_component_disable(state.camera_component);
|
mmal_component_disable(state->encoder_component);
|
||||||
|
|
||||||
destroy_encoder_component(&state);
|
if (state->config.preview_parameters.preview_component)
|
||||||
raspipreview_destroy(&state.preview_parameters);
|
mmal_component_disable(state->config.preview_parameters.preview_component);
|
||||||
destroy_camera_component(&state);
|
|
||||||
|
if (state->camera_component)
|
||||||
if (state.verbose)
|
mmal_component_disable(state->camera_component);
|
||||||
fprintf(stderr, "Close down completed, all components disconnected, disabled and destroyed\n\n");
|
|
||||||
}
|
destroy_encoder_component(state);
|
||||||
|
raspipreview_destroy(&state->config.preview_parameters);
|
||||||
if (status != MMAL_SUCCESS)
|
destroy_camera_component(state);
|
||||||
raspicamcontrol_check_configuration(128);
|
|
||||||
|
if (state->config.verbose)
|
||||||
return exit_code;
|
fprintf(stderr, "Close down completed, all components disconnected, disabled and destroyed\n\n");
|
||||||
|
|
||||||
|
free(state);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,9 @@ G_BEGIN_DECLS
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
char *filename;
|
||||||
|
int verbose; /// !0 if want detailed run information
|
||||||
|
|
||||||
int timeout; /// Time taken before frame is grabbed and app then shuts down. Units are milliseconds
|
int timeout; /// Time taken before frame is grabbed and app then shuts down. Units are milliseconds
|
||||||
int width; /// Requested width of image
|
int width; /// Requested width of image
|
||||||
int height; /// requested height of image
|
int height; /// requested height of image
|
||||||
|
@ -73,9 +76,14 @@ typedef struct
|
||||||
int profile; /// H264 profile to use for encoding
|
int profile; /// H264 profile to use for encoding
|
||||||
RASPIPREVIEW_PARAMETERS preview_parameters; /// Preview setup parameters
|
RASPIPREVIEW_PARAMETERS preview_parameters; /// Preview setup parameters
|
||||||
RASPICAM_CAMERA_PARAMETERS camera_parameters; /// Camera setup parameters
|
RASPICAM_CAMERA_PARAMETERS camera_parameters; /// Camera setup parameters
|
||||||
} RASPIVID_STATE;
|
} RASPIVID_CONFIG;
|
||||||
|
|
||||||
int raspi_capture_start();
|
typedef struct RASPIVID_STATE_T RASPIVID_STATE;
|
||||||
|
|
||||||
|
void raspicapture_init();
|
||||||
|
void raspicapture_default_config(RASPIVID_CONFIG *config);
|
||||||
|
RASPIVID_STATE *raspi_capture_start(RASPIVID_CONFIG *config);
|
||||||
|
void raspi_capture_stop(RASPIVID_STATE *state);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -290,7 +290,7 @@ static void dump_status(RASPISTILL_STATE *state)
|
||||||
}
|
}
|
||||||
|
|
||||||
raspipreview_dump_parameters(&state->preview_parameters);
|
raspipreview_dump_parameters(&state->preview_parameters);
|
||||||
raspicamcontrol_dump_parameters(&state->camera_parameters);
|
//raspicamcontrol_dump_parameters(&state->camera_parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -109,7 +109,7 @@ static GstStaticPadTemplate video_src_template =
|
||||||
GST_STATIC_PAD_TEMPLATE ("src",
|
GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_PAD_SRC,
|
GST_PAD_SRC,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS (RAW_AND_JPEG_CAPS "; " H264_CAPS)
|
GST_STATIC_CAPS (/*RAW_AND_JPEG_CAPS "; "*/ H264_CAPS)
|
||||||
);
|
);
|
||||||
|
|
||||||
#define gst_rpi_cam_src_parent_class parent_class
|
#define gst_rpi_cam_src_parent_class parent_class
|
||||||
|
@ -120,6 +120,7 @@ static void gst_rpi_cam_src_set_property (GObject * object, guint prop_id,
|
||||||
static void gst_rpi_cam_src_get_property (GObject * object, guint prop_id,
|
static void gst_rpi_cam_src_get_property (GObject * object, guint prop_id,
|
||||||
GValue * value, GParamSpec * pspec);
|
GValue * value, GParamSpec * pspec);
|
||||||
static gboolean gst_rpi_cam_src_start (GstBaseSrc *parent);
|
static gboolean gst_rpi_cam_src_start (GstBaseSrc *parent);
|
||||||
|
static gboolean gst_rpi_cam_src_stop (GstBaseSrc *parent);
|
||||||
static GstFlowReturn gst_rpi_cam_src_fill_buffer (GstPushSrc *parent, GstBuffer *buf);
|
static GstFlowReturn gst_rpi_cam_src_fill_buffer (GstPushSrc *parent, GstBuffer *buf);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -148,7 +149,10 @@ gst_rpi_cam_src_class_init (GstRpiCamSrcClass * klass)
|
||||||
gst_static_pad_template_get (&video_src_template));
|
gst_static_pad_template_get (&video_src_template));
|
||||||
|
|
||||||
basesrc_class->start = GST_DEBUG_FUNCPTR(gst_rpi_cam_src_start);
|
basesrc_class->start = GST_DEBUG_FUNCPTR(gst_rpi_cam_src_start);
|
||||||
|
basesrc_class->stop = GST_DEBUG_FUNCPTR(gst_rpi_cam_src_stop);
|
||||||
pushsrc_class->fill = GST_DEBUG_FUNCPTR(gst_rpi_cam_src_fill_buffer);
|
pushsrc_class->fill = GST_DEBUG_FUNCPTR(gst_rpi_cam_src_fill_buffer);
|
||||||
|
|
||||||
|
raspicapture_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -156,6 +160,11 @@ gst_rpi_cam_src_init (GstRpiCamSrc *src)
|
||||||
{
|
{
|
||||||
gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
|
gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
|
||||||
gst_base_src_set_live (GST_BASE_SRC (src), TRUE);
|
gst_base_src_set_live (GST_BASE_SRC (src), TRUE);
|
||||||
|
raspicapture_default_config(&src->capture_config);
|
||||||
|
|
||||||
|
src->capture_config.verbose = 1;
|
||||||
|
src->capture_config.filename = "test.out";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -184,22 +193,19 @@ gst_rpi_cam_src_get_property (GObject * object, guint prop_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
rpicamsrc_init (GstPlugin * rpicamsrc)
|
|
||||||
{
|
|
||||||
GST_DEBUG_CATEGORY_INIT (gst_rpi_cam_src_debug, "rpicamsrc",
|
|
||||||
0, "rpicamsrc debug");
|
|
||||||
|
|
||||||
return gst_element_register (rpicamsrc, "rpicamsrc", GST_RANK_NONE,
|
|
||||||
GST_TYPE_RPICAMSRC);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_rpi_cam_src_start (GstBaseSrc *parent)
|
gst_rpi_cam_src_start (GstBaseSrc *parent)
|
||||||
{
|
{
|
||||||
GstRpiCamSrc *src = GST_RPICAMSRC(parent);
|
GstRpiCamSrc *src = GST_RPICAMSRC(parent);
|
||||||
g_print ("In start()\n");
|
src->capture_state = raspi_capture_start(&src->capture_config);
|
||||||
raspi_capture_start();
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_rpi_cam_src_stop (GstBaseSrc *parent)
|
||||||
|
{
|
||||||
|
GstRpiCamSrc *src = GST_RPICAMSRC(parent);
|
||||||
|
raspi_capture_stop(src->capture_state);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,6 +215,16 @@ gst_rpi_cam_src_fill_buffer (GstPushSrc *parent, GstBuffer *buf)
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
plugin_init (GstPlugin * rpicamsrc)
|
||||||
|
{
|
||||||
|
GST_DEBUG_CATEGORY_INIT (gst_rpi_cam_src_debug, "rpicamsrc",
|
||||||
|
0, "rpicamsrc debug");
|
||||||
|
|
||||||
|
return gst_element_register (rpicamsrc, "rpicamsrc", GST_RANK_NONE,
|
||||||
|
GST_TYPE_RPICAMSRC);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef PACKAGE
|
#ifndef PACKAGE
|
||||||
#define PACKAGE "gstrpicamsrc"
|
#define PACKAGE "gstrpicamsrc"
|
||||||
#endif
|
#endif
|
||||||
|
@ -218,7 +234,7 @@ GST_PLUGIN_DEFINE (
|
||||||
GST_VERSION_MINOR,
|
GST_VERSION_MINOR,
|
||||||
rpicamsrc,
|
rpicamsrc,
|
||||||
"Raspberry Pi Camera Source",
|
"Raspberry Pi Camera Source",
|
||||||
rpicamsrc_init,
|
plugin_init,
|
||||||
VERSION,
|
VERSION,
|
||||||
"LGPL",
|
"LGPL",
|
||||||
"GStreamer",
|
"GStreamer",
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/base/gstpushsrc.h>
|
#include <gst/base/gstpushsrc.h>
|
||||||
|
#include "RaspiCapture.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
@ -67,6 +68,9 @@ struct _GstRpiCamSrc
|
||||||
GstPushSrc parent;
|
GstPushSrc parent;
|
||||||
|
|
||||||
GstPad *video_srcpad;
|
GstPad *video_srcpad;
|
||||||
|
|
||||||
|
RASPIVID_CONFIG capture_config;
|
||||||
|
RASPIVID_STATE *capture_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstRpiCamSrcClass
|
struct _GstRpiCamSrcClass
|
||||||
|
|
Loading…
Reference in a new issue