예제 #1
0
static void
gst_aravis_get_property (GObject * object, guint prop_id, GValue * value,
                         GParamSpec * pspec)
{
    GstAravis *gst_aravis = GST_ARAVIS (object);

    switch (prop_id) {
    case PROP_CAMERA_NAME:
        g_value_set_string (value, gst_aravis->camera_name);
        break;
    case PROP_GAIN:
        g_value_set_int (value, gst_aravis->gain);
        break;
    case PROP_EXPOSURE:
        g_value_set_double (value, gst_aravis->exposure_time_us);
        break;
    case PROP_H_BINNING:
        g_value_set_int (value, gst_aravis->h_binning);
        break;
    case PROP_V_BINNING:
        g_value_set_int (value, gst_aravis->v_binning);
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
        break;
    }
}
예제 #2
0
static void
gst_aravis_finalize (GObject * object)
{
        GstAravis *gst_aravis = GST_ARAVIS (object);

	if (gst_aravis->camera != NULL) {
		g_object_unref (gst_aravis->camera);
		gst_aravis->camera = NULL;
	}
	if (gst_aravis->stream != NULL) {
		g_object_unref (gst_aravis->stream);
		gst_aravis->stream = NULL;
	}
	if (gst_aravis->all_caps != NULL) {
		gst_caps_unref (gst_aravis->all_caps);
		gst_aravis->all_caps = NULL;
	}
	if (gst_aravis->fixed_caps != NULL) {
		gst_caps_unref (gst_aravis->fixed_caps);
		gst_aravis->fixed_caps = NULL;
	}

	g_free (gst_aravis->camera_name);
	gst_aravis->camera_name = NULL;

        G_OBJECT_CLASS (parent_class)->finalize (object);
}
예제 #3
0
static void
gst_aravis_set_property (GObject * object, guint prop_id,
			 const GValue * value, GParamSpec * pspec)
{
	GstAravis *gst_aravis = GST_ARAVIS (object);

	switch (prop_id) {
		case PROP_CAMERA_NAME:
			g_free (gst_aravis->camera_name);
			/* check if we are currently active
			   prevent setting camera and other values to something not representing the active camera */
			if (gst_aravis->stream == NULL) {
				gst_aravis->camera_name = g_strdup (g_value_get_string (value));
				gst_aravis_init_camera (gst_aravis);
			}

			GST_LOG_OBJECT (gst_aravis, "Set camera name to %s", gst_aravis->camera_name);

			break;
		case PROP_GAIN:
			gst_aravis->gain = g_value_get_double (value);
			if (gst_aravis->camera != NULL)
				arv_camera_set_gain (gst_aravis->camera, gst_aravis->gain);
			break;
		case PROP_GAIN_AUTO:
			gst_aravis->gain_auto = g_value_get_boolean (value);
			if (gst_aravis->camera != NULL)
				arv_camera_set_gain_auto (gst_aravis->camera, gst_aravis->gain_auto);
			break;
		case PROP_EXPOSURE:
			gst_aravis->exposure_time_us = g_value_get_double (value);
			if (gst_aravis->camera != NULL)
				arv_camera_set_exposure_time (gst_aravis->camera, gst_aravis->exposure_time_us);
			break;
		case PROP_EXPOSURE_AUTO:
			gst_aravis->exposure_auto = g_value_get_boolean (value);
			if (gst_aravis->camera != NULL)
				arv_camera_set_exposure_time_auto (gst_aravis->camera, gst_aravis->exposure_auto);
			break;
		case PROP_OFFSET_X:
			gst_aravis->offset_x = g_value_get_int (value);
			break;
		case PROP_OFFSET_Y:
			gst_aravis->offset_y = g_value_get_int (value);
			break;
		case PROP_H_BINNING:
			gst_aravis->h_binning = g_value_get_int (value);
			break;
		case PROP_V_BINNING:
			gst_aravis->v_binning = g_value_get_int (value);
			break;
		case PROP_PACKET_RESEND:
			gst_aravis->packet_resend = g_value_get_boolean (value);
			break;
		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
			break;
	}
}
예제 #4
0
static gboolean
gst_aravis_start (GstBaseSrc *src)
{
	GstAravis* gst_aravis = GST_ARAVIS(src);

	GST_LOG_OBJECT (gst_aravis, "Open camera '%s'", gst_aravis->camera_name);

	if (gst_aravis->camera == NULL)
		gst_aravis_init_camera (gst_aravis);

	gst_aravis->all_caps = gst_aravis_get_all_camera_caps (gst_aravis);

	return TRUE;
}
예제 #5
0
static GstCaps *
gst_aravis_get_caps (GstBaseSrc * src)
{
	GstAravis* gst_aravis = GST_ARAVIS(src);
	GstCaps *caps;

	if (gst_aravis->all_caps != NULL)
		caps = gst_caps_copy (gst_aravis->all_caps);
	else
		caps = gst_caps_new_any ();

	GST_LOG_OBJECT (gst_aravis, "Available caps = %" GST_PTR_FORMAT, caps);

	return caps;
}
예제 #6
0
static void
gst_aravis_get_property (GObject * object, guint prop_id, GValue * value,
			 GParamSpec * pspec)
{
	GstAravis *gst_aravis = GST_ARAVIS (object);

	switch (prop_id) {
		case PROP_CAMERA_NAME:
			g_value_set_string (value, gst_aravis->camera_name);
			break;
		case PROP_CAMERA:
			g_value_set_object (value, gst_aravis->camera);
			break;
		case PROP_GAIN:
			g_value_set_double (value, gst_aravis->gain);
			break;
		case PROP_GAIN_AUTO:
			g_value_set_boolean (value, gst_aravis->gain_auto);
			break;
		case PROP_EXPOSURE:
			g_value_set_double (value, gst_aravis->exposure_time_us);
			break;
		case PROP_EXPOSURE_AUTO:
			g_value_set_boolean (value, gst_aravis->exposure_auto);
			break;
		case PROP_OFFSET_X:
			g_value_set_int (value, gst_aravis->offset_x);
			break;
		case PROP_OFFSET_Y:
			g_value_set_int (value, gst_aravis->offset_y);
			break;
		case PROP_H_BINNING:
			g_value_set_int (value, gst_aravis->h_binning);
			break;
		case PROP_V_BINNING:
			g_value_set_int (value, gst_aravis->v_binning);
			break;
		case PROP_PACKET_RESEND:
			g_value_set_boolean (value, gst_aravis->packet_resend);
			break;
		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
			break;
	}
}
예제 #7
0
파일: gstaravis.c 프로젝트: xamox/aravis
static void
gst_aravis_set_property (GObject * object, guint prop_id,
			 const GValue * value, GParamSpec * pspec)
{
	GstAravis *gst_aravis = GST_ARAVIS (object);

	switch (prop_id) {
		case PROP_CAMERA_NAME:
			g_free (gst_aravis->camera_name);
			gst_aravis->camera_name = g_strdup (g_value_get_string (value));

			GST_LOG_OBJECT (gst_aravis, "Set camera name to %s", gst_aravis->camera_name);

			break;
		case PROP_GAIN:
			gst_aravis->gain = g_value_get_int (value);
			break;
		case PROP_GAIN_AUTO:
			gst_aravis->gain_auto = g_value_get_boolean (value);
			break;
		case PROP_EXPOSURE:
			gst_aravis->exposure_time_us = g_value_get_double (value);
			break;
		case PROP_EXPOSURE_AUTO:
			gst_aravis->exposure_auto = g_value_get_boolean (value);
			break;
		case PROP_OFFSET_X:
			gst_aravis->offset_x = g_value_get_int (value);
			break;
		case PROP_OFFSET_Y:
			gst_aravis->offset_y = g_value_get_int (value);
			break;
		case PROP_H_BINNING:
			gst_aravis->h_binning = g_value_get_int (value);
			break;
		case PROP_V_BINNING:
			gst_aravis->v_binning = g_value_get_int (value);
			break;
		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
			break;
	}
}
예제 #8
0
gboolean gst_aravis_stop( GstBaseSrc * src )
{
        GstAravis* gst_aravis = GST_ARAVIS(src);

	arv_camera_stop_acquisition (gst_aravis->camera);

	if (gst_aravis->stream != NULL) {
		g_object_unref (gst_aravis->stream);
		gst_aravis->stream = NULL;

	}
	if (gst_aravis->all_caps != NULL) {
		gst_caps_unref (gst_aravis->all_caps);
		gst_aravis->all_caps = NULL;
	}

        GST_DEBUG_OBJECT (gst_aravis, "Stop acquisition");

        return TRUE;
}
예제 #9
0
static void
gst_aravis_fixate_caps (GstPad * pad, GstCaps * caps)
{
	GstAravis *gst_aravis = GST_ARAVIS (gst_pad_get_parent_element (pad));
	GstStructure *structure;
	gint width;
	gint height;
	double frame_rate;

	arv_camera_get_region (gst_aravis->camera, NULL, NULL, &width, &height);
	frame_rate = arv_camera_get_frame_rate (gst_aravis->camera);

	structure = gst_caps_get_structure (caps, 0);

	gst_structure_fixate_field_nearest_int (structure, "width", width);
	gst_structure_fixate_field_nearest_int (structure, "height", height);
	gst_structure_fixate_field_nearest_fraction (structure, "framerate", (double) (0.5 + frame_rate), 1);

	GST_LOG_OBJECT (gst_aravis, "Fixate caps");

	g_object_unref (gst_aravis);
}
예제 #10
0
static GstCaps *
gst_aravis_fixate_caps (GstBaseSrc * bsrc, GstCaps * caps)
{
	GstAravis *gst_aravis = GST_ARAVIS (bsrc);
	GstStructure *structure;
	gint width;
	gint height;
	double frame_rate;

	arv_camera_get_region (gst_aravis->camera, NULL, NULL, &width, &height);
	frame_rate = arv_camera_get_frame_rate (gst_aravis->camera);

	structure = gst_caps_get_structure (caps, 0);

	gst_structure_fixate_field_nearest_int (structure, "width", width);
	gst_structure_fixate_field_nearest_int (structure, "height", height);
	gst_structure_fixate_field_nearest_fraction (structure, "framerate", (double) (0.5 + frame_rate), 1);

	GST_LOG_OBJECT (gst_aravis, "Fixate caps");

	return GST_BASE_SRC_CLASS(gst_aravis_parent_class)->fixate(bsrc, caps);
}
예제 #11
0
static GstFlowReturn
gst_aravis_create (GstPushSrc * push_src, GstBuffer ** buffer)
{
    GstAravis *gst_aravis;
    ArvBuffer *arv_buffer;

    gst_aravis = GST_ARAVIS (push_src);

    do {
        arv_buffer = arv_stream_timeout_pop_buffer (gst_aravis->stream, gst_aravis->buffer_timeout_us);
        if (arv_buffer != NULL && arv_buffer->status != ARV_BUFFER_STATUS_SUCCESS)
            arv_stream_push_buffer (gst_aravis->stream, arv_buffer);
    } while (arv_buffer != NULL && arv_buffer->status != ARV_BUFFER_STATUS_SUCCESS);

    if (arv_buffer == NULL)
        return GST_FLOW_ERROR;

    *buffer = gst_buffer_new ();

    GST_BUFFER_DATA (*buffer) = arv_buffer->data;
    GST_BUFFER_MALLOCDATA (*buffer) = NULL;
    GST_BUFFER_SIZE (*buffer) = gst_aravis->payload;

    if (gst_aravis->timestamp_offset == 0) {
        gst_aravis->timestamp_offset = arv_buffer->timestamp_ns;
        gst_aravis->last_timestamp = arv_buffer->timestamp_ns;
    }

    GST_BUFFER_TIMESTAMP (*buffer) = arv_buffer->timestamp_ns - gst_aravis->timestamp_offset;
    GST_BUFFER_DURATION (*buffer) = arv_buffer->timestamp_ns - gst_aravis->last_timestamp;

    gst_aravis->last_timestamp = arv_buffer->timestamp_ns;

    arv_stream_push_buffer (gst_aravis->stream, arv_buffer);

    gst_buffer_set_caps (*buffer, gst_aravis->fixed_caps);

    return GST_FLOW_OK;
}
예제 #12
0
static GstFlowReturn
gst_aravis_create (GstPushSrc * push_src, GstBuffer ** buffer)
{
	GstAravis *gst_aravis;
	ArvBuffer *arv_buffer;
	int arv_row_stride;
	int width, height;
	char *buffer_data;
	size_t buffer_size;
	guint64 timestamp_ns;

	gst_aravis = GST_ARAVIS (push_src);

	do {
		arv_buffer = arv_stream_timeout_pop_buffer (gst_aravis->stream, gst_aravis->buffer_timeout_us);
		if (arv_buffer != NULL && arv_buffer_get_status (arv_buffer) != ARV_BUFFER_STATUS_SUCCESS)
			arv_stream_push_buffer (gst_aravis->stream, arv_buffer);
	} while (arv_buffer != NULL && arv_buffer_get_status (arv_buffer) != ARV_BUFFER_STATUS_SUCCESS);

	if (arv_buffer == NULL)
		return GST_FLOW_ERROR;

	*buffer = gst_buffer_new ();

	buffer_data = (char *) arv_buffer_get_data (arv_buffer, &buffer_size);
	arv_buffer_get_image_region (arv_buffer, NULL, NULL, &width, &height);
	arv_row_stride = width * ARV_PIXEL_FORMAT_BIT_PER_PIXEL (arv_buffer_get_image_pixel_format (arv_buffer)) / 8;
	timestamp_ns = arv_buffer_get_timestamp (arv_buffer);

	/* Gstreamer requires row stride to be a multiple of 4 */
	if ((arv_row_stride & 0x3) != 0) {
		int gst_row_stride;
		size_t size;
		void *data;
		int i;

		gst_row_stride = (arv_row_stride & ~(0x3)) + 4;

		size = height * gst_row_stride;
		data = g_malloc (size);

		for (i = 0; i < height; i++)
			memcpy (((char *) data) + i * gst_row_stride, buffer_data + i * arv_row_stride, arv_row_stride);

		GST_BUFFER_DATA (buffer) = data;
		GST_BUFFER_MALLOCDATA (buffer) = data;
		GST_BUFFER_SIZE (buffer) = size;
	} else {
		GST_BUFFER_DATA (*buffer) = buffer_data;
		GST_BUFFER_MALLOCDATA (*buffer) = NULL;
		GST_BUFFER_SIZE (*buffer) = buffer_size;
	}

	if (!gst_base_src_get_do_timestamp(GST_BASE_SRC(push_src))) {
		if (gst_aravis->timestamp_offset == 0) {
			gst_aravis->timestamp_offset = timestamp_ns;
			gst_aravis->last_timestamp = timestamp_ns;
		}

		GST_BUFFER_TIMESTAMP (*buffer) = timestamp_ns - gst_aravis->timestamp_offset;
		GST_BUFFER_DURATION (*buffer) = timestamp_ns - gst_aravis->last_timestamp;

		gst_aravis->last_timestamp = timestamp_ns;
	}

	arv_stream_push_buffer (gst_aravis->stream, arv_buffer);

	gst_buffer_set_caps (*buffer, gst_aravis->fixed_caps);

	return GST_FLOW_OK;
}
예제 #13
0
static gboolean
gst_aravis_set_caps (GstBaseSrc *src, GstCaps *caps)
{
	GstAravis* gst_aravis = GST_ARAVIS(src);
	GstStructure *structure;
	ArvPixelFormat pixel_format;
	int height, width;
	int bpp, depth;
	const GValue *frame_rate;
	const char *caps_string;
	unsigned int i;
	guint32 fourcc;

	GST_LOG_OBJECT (gst_aravis, "Requested caps = %" GST_PTR_FORMAT, caps);

	arv_camera_stop_acquisition (gst_aravis->camera);

	if (gst_aravis->stream != NULL)
		g_object_unref (gst_aravis->stream);

	structure = gst_caps_get_structure (caps, 0);

	gst_structure_get_int (structure, "width", &width);
	gst_structure_get_int (structure, "height", &height);
	frame_rate = gst_structure_get_value (structure, "framerate");
	gst_structure_get_int (structure, "bpp", &bpp);
	gst_structure_get_int (structure, "depth", &depth);

	if (gst_structure_get_field_type (structure, "format") == G_TYPE_STRING) {
		const char *string;

	       	string = gst_structure_get_string (structure, "format");
		fourcc = GST_STR_FOURCC (string);
	} else if (gst_structure_get_field_type (structure, "format") == GST_TYPE_FOURCC) {
		gst_structure_get_fourcc (structure, "format", &fourcc);
	} else
		fourcc = 0;

	pixel_format = arv_pixel_format_from_gst_0_10_caps (gst_structure_get_name (structure), bpp, depth, fourcc);

	arv_camera_set_region (gst_aravis->camera, gst_aravis->offset_x, gst_aravis->offset_y, width, height);
	arv_camera_set_binning (gst_aravis->camera, gst_aravis->h_binning, gst_aravis->v_binning);
	arv_camera_set_pixel_format (gst_aravis->camera, pixel_format);

	if (frame_rate != NULL) {
		double dbl_frame_rate;

		dbl_frame_rate = (double) gst_value_get_fraction_numerator (frame_rate) /
			(double) gst_value_get_fraction_denominator (frame_rate);

		GST_DEBUG_OBJECT (gst_aravis, "Frame rate = %g Hz", dbl_frame_rate);
		arv_camera_set_frame_rate (gst_aravis->camera, dbl_frame_rate);

		if (dbl_frame_rate > 0.0)
			gst_aravis->buffer_timeout_us = MAX (GST_ARAVIS_BUFFER_TIMEOUT_DEFAULT,
							     3e6 / dbl_frame_rate);
		else
			gst_aravis->buffer_timeout_us = GST_ARAVIS_BUFFER_TIMEOUT_DEFAULT;
	} else
		gst_aravis->buffer_timeout_us = GST_ARAVIS_BUFFER_TIMEOUT_DEFAULT;

	GST_DEBUG_OBJECT (gst_aravis, "Buffer timeout = %" G_GUINT64_FORMAT " µs", gst_aravis->buffer_timeout_us);

	GST_DEBUG_OBJECT (gst_aravis, "Actual frame rate = %g Hz", arv_camera_get_frame_rate (gst_aravis->camera));

	if(gst_aravis->gain_auto) {
		arv_camera_set_gain_auto (gst_aravis->camera, ARV_AUTO_CONTINUOUS);
		GST_DEBUG_OBJECT (gst_aravis, "Auto Gain = continuous");
	} else {
		if (gst_aravis->gain >= 0) {
			GST_DEBUG_OBJECT (gst_aravis, "Gain = %g", gst_aravis->gain);
			arv_camera_set_gain_auto (gst_aravis->camera, ARV_AUTO_OFF);
			arv_camera_set_gain (gst_aravis->camera, gst_aravis->gain);
		}
		GST_DEBUG_OBJECT (gst_aravis, "Actual gain = %g", arv_camera_get_gain (gst_aravis->camera));
	}

	if(gst_aravis->exposure_auto) {
		arv_camera_set_exposure_time_auto (gst_aravis->camera, ARV_AUTO_CONTINUOUS);
		GST_DEBUG_OBJECT (gst_aravis, "Auto Exposure = continuous");
	} else {
		if (gst_aravis->exposure_time_us > 0.0) {
			GST_DEBUG_OBJECT (gst_aravis, "Exposure = %g µs", gst_aravis->exposure_time_us);
			arv_camera_set_exposure_time_auto (gst_aravis->camera, ARV_AUTO_OFF);
			arv_camera_set_exposure_time (gst_aravis->camera, gst_aravis->exposure_time_us);
		}
		GST_DEBUG_OBJECT (gst_aravis, "Actual exposure = %g µs", arv_camera_get_exposure_time (gst_aravis->camera));
	}

	if (gst_aravis->fixed_caps != NULL)
		gst_caps_unref (gst_aravis->fixed_caps);

	caps_string = arv_pixel_format_to_gst_0_10_caps_string (pixel_format);
	if (caps_string != NULL) {
		GstStructure *structure;
		GstCaps *caps;

		caps = gst_caps_new_empty ();
		structure = gst_structure_from_string (caps_string, NULL);
		gst_structure_set (structure,
				   "width", G_TYPE_INT, width,
				   "height", G_TYPE_INT, height,
				   NULL);

		if (frame_rate != NULL)
			gst_structure_set_value (structure, "framerate", frame_rate);

		gst_caps_append_structure (caps, structure);

		gst_aravis->fixed_caps = caps;
	} else
		gst_aravis->fixed_caps = NULL;

	gst_aravis->payload = arv_camera_get_payload (gst_aravis->camera);
	gst_aravis->stream = arv_camera_create_stream (gst_aravis->camera, NULL, NULL);

	if (ARV_IS_GV_STREAM (gst_aravis->stream) && gst_aravis->packet_resend)
		g_object_set (gst_aravis->stream, "packet-resend", ARV_GV_STREAM_PACKET_RESEND_ALWAYS, NULL);
	else
		g_object_set (gst_aravis->stream, "packet-resend", ARV_GV_STREAM_PACKET_RESEND_NEVER, NULL);

	for (i = 0; i < GST_ARAVIS_N_BUFFERS; i++)
		arv_stream_push_buffer (gst_aravis->stream,
					arv_buffer_new (gst_aravis->payload, NULL));

	GST_LOG_OBJECT (gst_aravis, "Start acquisition");
	arv_camera_start_acquisition (gst_aravis->camera);

	gst_aravis->timestamp_offset = 0;
	gst_aravis->last_timestamp = 0;

	return TRUE;
}
예제 #14
0
static GstFlowReturn
gst_aravis_create (GstPushSrc * push_src, GstBuffer ** buffer)
{
	GstAravis *gst_aravis;
	ArvBuffer *arv_buffer;
	int arv_row_stride;

	gst_aravis = GST_ARAVIS (push_src);

	do {
		arv_buffer = arv_stream_timeout_pop_buffer (gst_aravis->stream, gst_aravis->buffer_timeout_us);
		if (arv_buffer != NULL && arv_buffer->status != ARV_BUFFER_STATUS_SUCCESS)
			arv_stream_push_buffer (gst_aravis->stream, arv_buffer);
	} while (arv_buffer != NULL && arv_buffer->status != ARV_BUFFER_STATUS_SUCCESS);

	if (arv_buffer == NULL)
		return GST_FLOW_ERROR;

	arv_row_stride = arv_buffer->width * ARV_PIXEL_FORMAT_BIT_PER_PIXEL (arv_buffer->pixel_format) / 8;

	/* Gstreamer requires row stride to be a multiple of 4 */
	if ((arv_row_stride & 0x3) != 0) {
		int gst_row_stride;
		size_t size;
		void *data;
		int i;

		gst_row_stride = (arv_row_stride & ~(0x3)) + 4;

		size = arv_buffer->height * gst_row_stride;
		data = g_malloc (size);

		for (i = 0; i < arv_buffer->height; i++)
			memcpy (((char *) data) + i * gst_row_stride, ((char *) arv_buffer->data) + i * arv_row_stride, arv_row_stride);

		*buffer = gst_buffer_new_wrapped (data, size);
	} else {
		*buffer = gst_buffer_new_wrapped_full (0,
			arv_buffer->data,
			arv_buffer->size,
			0,
			arv_buffer->size,
			NULL,
			NULL);
	}

	if (!gst_base_src_get_do_timestamp(GST_BASE_SRC(push_src))) {
		if (gst_aravis->timestamp_offset == 0) {
			gst_aravis->timestamp_offset = arv_buffer->timestamp_ns;
			gst_aravis->last_timestamp = arv_buffer->timestamp_ns;
		}

		GST_BUFFER_PTS (*buffer) = arv_buffer->timestamp_ns - gst_aravis->timestamp_offset;
		GST_BUFFER_DURATION (*buffer) = arv_buffer->timestamp_ns - gst_aravis->last_timestamp;

		gst_aravis->last_timestamp = arv_buffer->timestamp_ns;
	}

	arv_stream_push_buffer (gst_aravis->stream, arv_buffer);

	return GST_FLOW_OK;
}
예제 #15
0
static gboolean
gst_aravis_set_caps (GstBaseSrc *src, GstCaps *caps)
{
    GstAravis* gst_aravis = GST_ARAVIS(src);
    GstStructure *structure;
    ArvPixelFormat pixel_format;
    int height, width;
    int bpp, depth;
    const GValue *frame_rate;
    const char *caps_string;
    unsigned int i;
    guint32 fourcc;

    GST_LOG_OBJECT (gst_aravis, "Requested caps = %" GST_PTR_FORMAT, caps);

    arv_camera_stop_acquisition (gst_aravis->camera);

    if (gst_aravis->stream != NULL)
        g_object_unref (gst_aravis->stream);

    structure = gst_caps_get_structure (caps, 0);

    gst_structure_get_int (structure, "width", &width);
    gst_structure_get_int (structure, "height", &height);
    frame_rate = gst_structure_get_value (structure, "framerate");
    gst_structure_get_fourcc (structure, "format", &fourcc);
    gst_structure_get_int (structure, "bpp", &bpp);
    gst_structure_get_int (structure, "depth", &depth);

    pixel_format = arv_pixel_format_from_gst_caps (gst_structure_get_name (structure), bpp, depth, fourcc);

    arv_camera_set_region (gst_aravis->camera, 0, 0, width, height);
    arv_camera_set_binning (gst_aravis->camera, gst_aravis->h_binning, gst_aravis->v_binning);
    arv_camera_set_pixel_format (gst_aravis->camera, pixel_format);

    if (frame_rate != NULL) {
        double dbl_frame_rate;

        dbl_frame_rate = (double) gst_value_get_fraction_numerator (frame_rate) /
                         (double) gst_value_get_fraction_denominator (frame_rate);

        GST_DEBUG_OBJECT (gst_aravis, "Frame rate = %g Hz", dbl_frame_rate);
        arv_camera_set_frame_rate (gst_aravis->camera, dbl_frame_rate);

        if (dbl_frame_rate > 0.0)
            gst_aravis->buffer_timeout_us = MAX (GST_ARAVIS_BUFFER_TIMEOUT_DEFAULT,
                                                 3e6 / dbl_frame_rate);
        else
            gst_aravis->buffer_timeout_us = GST_ARAVIS_BUFFER_TIMEOUT_DEFAULT;
    } else
        gst_aravis->buffer_timeout_us = GST_ARAVIS_BUFFER_TIMEOUT_DEFAULT;

    GST_DEBUG_OBJECT (gst_aravis, "Buffer timeout = %Ld µs", gst_aravis->buffer_timeout_us);

    GST_DEBUG_OBJECT (gst_aravis, "Actual frame rate = %g Hz", arv_camera_get_frame_rate (gst_aravis->camera));

    GST_DEBUG_OBJECT (gst_aravis, "Gain       = %d", gst_aravis->gain);
    arv_camera_set_gain (gst_aravis->camera, gst_aravis->gain);
    GST_DEBUG_OBJECT (gst_aravis, "Actual gain       = %d", arv_camera_get_gain (gst_aravis->camera));

    GST_DEBUG_OBJECT (gst_aravis, "Exposure   = %g µs", gst_aravis->exposure_time_us);
    arv_camera_set_exposure_time (gst_aravis->camera, gst_aravis->exposure_time_us);
    GST_DEBUG_OBJECT (gst_aravis, "Actual exposure   = %g µs", arv_camera_get_exposure_time (gst_aravis->camera));

    if (gst_aravis->fixed_caps != NULL)
        gst_caps_unref (gst_aravis->fixed_caps);

    caps_string = arv_pixel_format_to_gst_caps_string (pixel_format);
    if (caps_string != NULL) {
        GstStructure *structure;
        GstCaps *caps;

        caps = gst_caps_new_empty ();
        structure = gst_structure_from_string (caps_string, NULL);
        gst_structure_set (structure,
                           "width", G_TYPE_INT, width,
                           "height", G_TYPE_INT, height,
                           NULL);

        if (frame_rate != NULL)
            gst_structure_set_value (structure, "framerate", frame_rate);

        gst_caps_append_structure (caps, structure);

        gst_aravis->fixed_caps = caps;
    } else
        gst_aravis->fixed_caps = NULL;

    gst_aravis->payload = arv_camera_get_payload (gst_aravis->camera);
    gst_aravis->stream = arv_camera_create_stream (gst_aravis->camera, NULL, NULL);

    for (i = 0; i < GST_ARAVIS_N_BUFFERS; i++)
        arv_stream_push_buffer (gst_aravis->stream,
                                arv_buffer_new (gst_aravis->payload, NULL));

    GST_LOG_OBJECT (gst_aravis, "Start acquisition");
    arv_camera_start_acquisition (gst_aravis->camera);

    gst_aravis->timestamp_offset = 0;
    gst_aravis->last_timestamp = 0;

    return TRUE;
}