mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
Merge branch 'master' into 0.11
This commit is contained in:
commit
7f851794d6
9 changed files with 142 additions and 20 deletions
|
@ -474,6 +474,9 @@ gst_base_camera_src_change_state (GstElement * element,
|
||||||
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||||
|
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
|
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||||
|
gst_element_set_state (self->preview_pipeline->pipeline, GST_STATE_READY);
|
||||||
|
break;
|
||||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||||
gst_element_set_state (self->preview_pipeline->pipeline, GST_STATE_NULL);
|
gst_element_set_state (self->preview_pipeline->pipeline, GST_STATE_NULL);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -638,6 +638,13 @@ gst_camerabin_video_create_elements (GstCameraBinVideo * vid)
|
||||||
G_CALLBACK (gst_camerabin_drop_eos_probe), vid);
|
G_CALLBACK (gst_camerabin_drop_eos_probe), vid);
|
||||||
gst_object_unref (vid_srcpad);
|
gst_object_unref (vid_srcpad);
|
||||||
|
|
||||||
|
/* audio source is not always present and might be set to NULL during operation */
|
||||||
|
if (vid->aud_src
|
||||||
|
&& g_object_class_find_property (G_OBJECT_GET_CLASS (vid->aud_src),
|
||||||
|
"provide-clock")) {
|
||||||
|
g_object_set (vid->aud_src, "provide-clock", FALSE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
GST_DEBUG ("created video elements");
|
GST_DEBUG ("created video elements");
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -1641,6 +1641,7 @@ static void
|
||||||
gst_camerabin_start_video_recording (GstCameraBin * camera)
|
gst_camerabin_start_video_recording (GstCameraBin * camera)
|
||||||
{
|
{
|
||||||
GstStateChangeReturn state_ret;
|
GstStateChangeReturn state_ret;
|
||||||
|
GstCameraBinVideo *vidbin = (GstCameraBinVideo *) camera->vidbin;
|
||||||
/* FIXME: how to ensure resolution and fps is supported by CPU?
|
/* FIXME: how to ensure resolution and fps is supported by CPU?
|
||||||
* use a queue overrun signal?
|
* use a queue overrun signal?
|
||||||
*/
|
*/
|
||||||
|
@ -1654,9 +1655,14 @@ gst_camerabin_start_video_recording (GstCameraBin * camera)
|
||||||
gst_camerabin_rewrite_tags (camera);
|
gst_camerabin_rewrite_tags (camera);
|
||||||
|
|
||||||
/* Pause the pipeline in order to distribute new clock in paused_to_playing */
|
/* Pause the pipeline in order to distribute new clock in paused_to_playing */
|
||||||
|
/* Audio source needs to go to null to reset the ringbuffer */
|
||||||
|
if (vidbin->aud_src)
|
||||||
|
gst_element_set_state (vidbin->aud_src, GST_STATE_NULL);
|
||||||
state_ret = gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PAUSED);
|
state_ret = gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PAUSED);
|
||||||
|
|
||||||
if (state_ret != GST_STATE_CHANGE_FAILURE) {
|
if (state_ret != GST_STATE_CHANGE_FAILURE) {
|
||||||
|
GstClock *clock = gst_element_get_clock (GST_ELEMENT (camera));
|
||||||
|
|
||||||
g_mutex_lock (camera->capture_mutex);
|
g_mutex_lock (camera->capture_mutex);
|
||||||
camera->capturing = TRUE;
|
camera->capturing = TRUE;
|
||||||
g_mutex_unlock (camera->capture_mutex);
|
g_mutex_unlock (camera->capture_mutex);
|
||||||
|
@ -1672,6 +1678,11 @@ gst_camerabin_start_video_recording (GstCameraBin * camera)
|
||||||
g_object_set (G_OBJECT (camera->src_vid_src), "capture-mode", 2, NULL);
|
g_object_set (G_OBJECT (camera->src_vid_src), "capture-mode", 2, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clock might be distributed as NULL to audiosrc, messing timestamping */
|
||||||
|
if (vidbin->aud_src)
|
||||||
|
gst_element_set_clock (vidbin->aud_src, clock);
|
||||||
|
gst_object_unref (clock);
|
||||||
|
|
||||||
/* videobin will not go to playing if file is not writable */
|
/* videobin will not go to playing if file is not writable */
|
||||||
if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
|
if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
|
||||||
GST_STATE_CHANGE_FAILURE) {
|
GST_STATE_CHANGE_FAILURE) {
|
||||||
|
|
|
@ -406,8 +406,10 @@ gst_camera_bin_start_capture (GstCameraBin2 * camerabin)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* store the next preview filename */
|
/* store the next preview filename */
|
||||||
|
g_mutex_lock (camerabin->preview_list_mutex);
|
||||||
camerabin->preview_location_list =
|
camerabin->preview_location_list =
|
||||||
g_slist_append (camerabin->preview_location_list, location);
|
g_slist_append (camerabin->preview_location_list, location);
|
||||||
|
g_mutex_unlock (camerabin->preview_list_mutex);
|
||||||
|
|
||||||
g_signal_emit_by_name (camerabin->src, "start-capture", NULL);
|
g_signal_emit_by_name (camerabin->src, "start-capture", NULL);
|
||||||
if (camerabin->mode == MODE_VIDEO && camerabin->audio_src)
|
if (camerabin->mode == MODE_VIDEO && camerabin->audio_src)
|
||||||
|
@ -518,6 +520,7 @@ gst_camera_bin_dispose (GObject * object)
|
||||||
GstCameraBin2 *camerabin = GST_CAMERA_BIN2_CAST (object);
|
GstCameraBin2 *camerabin = GST_CAMERA_BIN2_CAST (object);
|
||||||
|
|
||||||
g_free (camerabin->location);
|
g_free (camerabin->location);
|
||||||
|
g_mutex_free (camerabin->preview_list_mutex);
|
||||||
|
|
||||||
if (camerabin->src_capture_notify_id)
|
if (camerabin->src_capture_notify_id)
|
||||||
g_signal_handler_disconnect (camerabin->src,
|
g_signal_handler_disconnect (camerabin->src,
|
||||||
|
@ -873,6 +876,7 @@ gst_camera_bin_init (GstCameraBin2 * camera)
|
||||||
camera->zoom = DEFAULT_ZOOM;
|
camera->zoom = DEFAULT_ZOOM;
|
||||||
camera->max_zoom = MAX_ZOOM;
|
camera->max_zoom = MAX_ZOOM;
|
||||||
camera->flags = DEFAULT_FLAGS;
|
camera->flags = DEFAULT_FLAGS;
|
||||||
|
camera->preview_list_mutex = g_mutex_new ();
|
||||||
|
|
||||||
/* capsfilters are created here as we proxy their caps properties and
|
/* capsfilters are created here as we proxy their caps properties and
|
||||||
* this way we avoid having to store the caps while on NULL state to
|
* this way we avoid having to store the caps while on NULL state to
|
||||||
|
@ -945,20 +949,31 @@ gst_camera_bin_handle_message (GstBin * bin, GstMessage * message)
|
||||||
}
|
}
|
||||||
} else if (gst_structure_has_name (structure, "preview-image")) {
|
} else if (gst_structure_has_name (structure, "preview-image")) {
|
||||||
GValue *value;
|
GValue *value;
|
||||||
gchar *location;
|
gchar *location = NULL;
|
||||||
|
|
||||||
location = camerabin->preview_location_list->data;
|
g_mutex_lock (camerabin->preview_list_mutex);
|
||||||
camerabin->preview_location_list =
|
if (camerabin->preview_location_list) {
|
||||||
g_slist_delete_link (camerabin->preview_location_list,
|
location = camerabin->preview_location_list->data;
|
||||||
camerabin->preview_location_list);
|
camerabin->preview_location_list =
|
||||||
GST_DEBUG_OBJECT (camerabin, "Adding preview location to preview "
|
g_slist_delete_link (camerabin->preview_location_list,
|
||||||
"message '%s'", location);
|
camerabin->preview_location_list);
|
||||||
|
GST_DEBUG_OBJECT (camerabin, "Adding preview location to preview "
|
||||||
|
"message '%s'", location);
|
||||||
|
} else {
|
||||||
|
GST_WARNING_OBJECT (camerabin, "Unexpected preview message received, "
|
||||||
|
"won't be able to put location field into the message. This can "
|
||||||
|
"happen if the source is posting previews while camerabin2 is "
|
||||||
|
"shutting down");
|
||||||
|
}
|
||||||
|
g_mutex_unlock (camerabin->preview_list_mutex);
|
||||||
|
|
||||||
value = g_new0 (GValue, 1);
|
if (location) {
|
||||||
g_value_init (value, G_TYPE_STRING);
|
value = g_new0 (GValue, 1);
|
||||||
g_value_take_string (value, location);
|
g_value_init (value, G_TYPE_STRING);
|
||||||
gst_structure_take_value ((GstStructure *) structure, "location",
|
g_value_take_string (value, location);
|
||||||
value);
|
gst_structure_take_value ((GstStructure *) structure, "location",
|
||||||
|
value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1725,9 +1740,11 @@ gst_camera_bin_change_state (GstElement * element, GstStateChange trans)
|
||||||
g_slist_free (camera->image_location_list);
|
g_slist_free (camera->image_location_list);
|
||||||
camera->image_location_list = NULL;
|
camera->image_location_list = NULL;
|
||||||
|
|
||||||
|
g_mutex_lock (camera->preview_list_mutex);
|
||||||
g_slist_foreach (camera->preview_location_list, (GFunc) g_free, NULL);
|
g_slist_foreach (camera->preview_location_list, (GFunc) g_free, NULL);
|
||||||
g_slist_free (camera->preview_location_list);
|
g_slist_free (camera->preview_location_list);
|
||||||
camera->preview_location_list = NULL;
|
camera->preview_location_list = NULL;
|
||||||
|
g_mutex_unlock (camera->preview_list_mutex);
|
||||||
|
|
||||||
/* explicitly set to READY as they might be outside of the bin */
|
/* explicitly set to READY as they might be outside of the bin */
|
||||||
gst_element_set_state (camera->audio_volume, GST_STATE_READY);
|
gst_element_set_state (camera->audio_volume, GST_STATE_READY);
|
||||||
|
|
|
@ -94,8 +94,22 @@ struct _GstCameraBin2
|
||||||
* each buffer capture */
|
* each buffer capture */
|
||||||
GSList *image_location_list;
|
GSList *image_location_list;
|
||||||
|
|
||||||
/* similar to above, but used for giving names to previews */
|
/*
|
||||||
|
* Similar to above, but used for giving names to previews
|
||||||
|
*
|
||||||
|
* Need to protect with a mutex as this list is used when the
|
||||||
|
* camera-source posts a preview image. As we have no control
|
||||||
|
* on how the camera-source will behave (we can only tell how
|
||||||
|
* it should), the preview location list might be used in an
|
||||||
|
* inconsistent way.
|
||||||
|
* One example is the camera-source posting a preview image after
|
||||||
|
* camerabin2 was put to ready, when this preview list will be
|
||||||
|
* freed and set to NULL. Concurrent access might lead to crashes in
|
||||||
|
* this situation. (Concurrency from the state-change freeing the
|
||||||
|
* list and the message handling function looking at preview names)
|
||||||
|
*/
|
||||||
GSList *preview_location_list;
|
GSList *preview_location_list;
|
||||||
|
GMutex *preview_list_mutex;
|
||||||
|
|
||||||
gboolean video_profile_switch;
|
gboolean video_profile_switch;
|
||||||
gboolean image_profile_switch;
|
gboolean image_profile_switch;
|
||||||
|
|
|
@ -45,7 +45,8 @@ enum
|
||||||
PROP_SOCKET_PATH,
|
PROP_SOCKET_PATH,
|
||||||
PROP_PERMS,
|
PROP_PERMS,
|
||||||
PROP_SHM_SIZE,
|
PROP_SHM_SIZE,
|
||||||
PROP_WAIT_FOR_CONNECTION
|
PROP_WAIT_FOR_CONNECTION,
|
||||||
|
PROP_BUFFER_TIME
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GstShmClient
|
struct GstShmClient
|
||||||
|
@ -162,6 +163,13 @@ gst_shm_sink_class_init (GstShmSinkClass * klass)
|
||||||
DEFAULT_WAIT_FOR_CONNECTION,
|
DEFAULT_WAIT_FOR_CONNECTION,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class, PROP_BUFFER_TIME,
|
||||||
|
g_param_spec_uint64 ("buffer-time",
|
||||||
|
"Buffer Time of the shm buffer",
|
||||||
|
"Maximum Size of the shm buffer in nanoseconds (-1 to disable)",
|
||||||
|
0, G_MAXUINT64, GST_CLOCK_TIME_NONE,
|
||||||
|
G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
signals[SIGNAL_CLIENT_CONNECTED] = g_signal_new ("client-connected",
|
signals[SIGNAL_CLIENT_CONNECTED] = g_signal_new ("client-connected",
|
||||||
GST_TYPE_SHM_SINK, G_SIGNAL_RUN_LAST, 0, NULL, NULL,
|
GST_TYPE_SHM_SINK, G_SIGNAL_RUN_LAST, 0, NULL, NULL,
|
||||||
g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
|
g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
|
||||||
|
@ -229,6 +237,12 @@ gst_shm_sink_set_property (GObject * object, guint prop_id,
|
||||||
GST_OBJECT_UNLOCK (object);
|
GST_OBJECT_UNLOCK (object);
|
||||||
g_cond_broadcast (self->cond);
|
g_cond_broadcast (self->cond);
|
||||||
break;
|
break;
|
||||||
|
case PROP_BUFFER_TIME:
|
||||||
|
GST_OBJECT_LOCK (object);
|
||||||
|
self->buffer_time = g_value_get_uint64 (value);
|
||||||
|
GST_OBJECT_UNLOCK (object);
|
||||||
|
g_cond_broadcast (self->cond);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -263,6 +277,9 @@ gst_shm_sink_get_property (GObject * object, guint prop_id,
|
||||||
case PROP_WAIT_FOR_CONNECTION:
|
case PROP_WAIT_FOR_CONNECTION:
|
||||||
g_value_set_boolean (value, self->wait_for_connection);
|
g_value_set_boolean (value, self->wait_for_connection);
|
||||||
break;
|
break;
|
||||||
|
case PROP_BUFFER_TIME:
|
||||||
|
g_value_set_uint64 (value, self->buffer_time);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -358,6 +375,24 @@ gst_shm_sink_stop (GstBaseSink * bsink)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_shm_sink_can_render (GstShmSink * self, GstClockTime time)
|
||||||
|
{
|
||||||
|
ShmBuffer *b;
|
||||||
|
|
||||||
|
if (time == GST_CLOCK_TIME_NONE || self->buffer_time == GST_CLOCK_TIME_NONE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
b = sp_writer_get_pending_buffers (self->pipe);
|
||||||
|
for (; b != NULL; b = sp_writer_get_next_buffer (b)) {
|
||||||
|
GstClockTime t = sp_writer_buf_get_tag (b);
|
||||||
|
if (GST_CLOCK_DIFF (time, t) > self->buffer_time)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_shm_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
gst_shm_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
|
@ -373,8 +408,16 @@ gst_shm_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (!gst_shm_sink_can_render (self, GST_BUFFER_TIMESTAMP (buf))) {
|
||||||
|
g_cond_wait (self->cond, GST_OBJECT_GET_LOCK (self));
|
||||||
|
if (self->unlock) {
|
||||||
|
GST_OBJECT_UNLOCK (self);
|
||||||
|
return GST_FLOW_WRONG_STATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rv = sp_writer_send_buf (self->pipe, (char *) GST_BUFFER_DATA (buf),
|
rv = sp_writer_send_buf (self->pipe, (char *) GST_BUFFER_DATA (buf),
|
||||||
GST_BUFFER_SIZE (buf));
|
GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf));
|
||||||
|
|
||||||
if (rv == -1) {
|
if (rv == -1) {
|
||||||
ShmBlock *block = NULL;
|
ShmBlock *block = NULL;
|
||||||
|
@ -396,10 +439,10 @@ gst_shm_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shmbuf = sp_writer_block_get_buf (block);
|
shmbuf = sp_writer_block_get_buf (block);
|
||||||
memcpy (shmbuf, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
|
memcpy (shmbuf, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
|
||||||
sp_writer_send_buf (self->pipe, shmbuf, GST_BUFFER_SIZE (buf));
|
sp_writer_send_buf (self->pipe, shmbuf, GST_BUFFER_SIZE (buf),
|
||||||
|
GST_BUFFER_TIMESTAMP (buf));
|
||||||
sp_writer_free_block (block);
|
sp_writer_free_block (block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,7 @@ struct _GstShmSink
|
||||||
gboolean wait_for_connection;
|
gboolean wait_for_connection;
|
||||||
gboolean stop;
|
gboolean stop;
|
||||||
gboolean unlock;
|
gboolean unlock;
|
||||||
|
GstClockTime buffer_time;
|
||||||
|
|
||||||
GCond *cond;
|
GCond *cond;
|
||||||
};
|
};
|
||||||
|
|
|
@ -78,7 +78,6 @@ enum
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _ShmArea ShmArea;
|
typedef struct _ShmArea ShmArea;
|
||||||
typedef struct _ShmBuffer ShmBuffer;
|
|
||||||
|
|
||||||
struct _ShmArea
|
struct _ShmArea
|
||||||
{
|
{
|
||||||
|
@ -112,6 +111,8 @@ struct _ShmBuffer
|
||||||
|
|
||||||
int num_clients;
|
int num_clients;
|
||||||
int clients[0];
|
int clients[0];
|
||||||
|
|
||||||
|
uint64_t tag;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -542,7 +543,7 @@ sp_writer_free_block (ShmBlock * block)
|
||||||
/* Returns the number of client this has successfully been sent to */
|
/* Returns the number of client this has successfully been sent to */
|
||||||
|
|
||||||
int
|
int
|
||||||
sp_writer_send_buf (ShmPipe * self, char *buf, size_t size)
|
sp_writer_send_buf (ShmPipe * self, char *buf, size_t size, uint64_t tag)
|
||||||
{
|
{
|
||||||
ShmArea *area = NULL;
|
ShmArea *area = NULL;
|
||||||
unsigned long offset = 0;
|
unsigned long offset = 0;
|
||||||
|
@ -577,6 +578,7 @@ sp_writer_send_buf (ShmPipe * self, char *buf, size_t size)
|
||||||
sb->size = size;
|
sb->size = size;
|
||||||
sb->num_clients = self->num_clients;
|
sb->num_clients = self->num_clients;
|
||||||
sb->ablock = ablock;
|
sb->ablock = ablock;
|
||||||
|
sb->tag = tag;
|
||||||
|
|
||||||
for (client = self->clients; client; client = client->next) {
|
for (client = self->clients; client; client = client->next) {
|
||||||
struct CommandBuffer cb = { 0 };
|
struct CommandBuffer cb = { 0 };
|
||||||
|
@ -892,3 +894,21 @@ sp_writer_get_path (ShmPipe * pipe)
|
||||||
{
|
{
|
||||||
return pipe->socket_path;
|
return pipe->socket_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ShmBuffer *
|
||||||
|
sp_writer_get_pending_buffers (ShmPipe * self)
|
||||||
|
{
|
||||||
|
return self->buffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShmBuffer *
|
||||||
|
sp_writer_get_next_buffer (ShmBuffer * buffer)
|
||||||
|
{
|
||||||
|
return buffer->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
sp_writer_buf_get_tag (ShmBuffer * buffer)
|
||||||
|
{
|
||||||
|
return buffer->tag;
|
||||||
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@
|
||||||
#define __SHMPIPE_H__
|
#define __SHMPIPE_H__
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
@ -75,6 +76,7 @@ extern "C" {
|
||||||
typedef struct _ShmClient ShmClient;
|
typedef struct _ShmClient ShmClient;
|
||||||
typedef struct _ShmPipe ShmPipe;
|
typedef struct _ShmPipe ShmPipe;
|
||||||
typedef struct _ShmBlock ShmBlock;
|
typedef struct _ShmBlock ShmBlock;
|
||||||
|
typedef struct _ShmBuffer ShmBuffer;
|
||||||
|
|
||||||
ShmPipe *sp_writer_create (const char *path, size_t size, mode_t perms);
|
ShmPipe *sp_writer_create (const char *path, size_t size, mode_t perms);
|
||||||
const char *sp_writer_get_path (ShmPipe *pipe);
|
const char *sp_writer_get_path (ShmPipe *pipe);
|
||||||
|
@ -90,7 +92,7 @@ int sp_writer_get_client_fd (ShmClient * client);
|
||||||
|
|
||||||
ShmBlock *sp_writer_alloc_block (ShmPipe * self, size_t size);
|
ShmBlock *sp_writer_alloc_block (ShmPipe * self, size_t size);
|
||||||
void sp_writer_free_block (ShmBlock *block);
|
void sp_writer_free_block (ShmBlock *block);
|
||||||
int sp_writer_send_buf (ShmPipe * self, char *buf, size_t size);
|
int sp_writer_send_buf (ShmPipe * self, char *buf, size_t size, uint64_t tag);
|
||||||
char *sp_writer_block_get_buf (ShmBlock *block);
|
char *sp_writer_block_get_buf (ShmBlock *block);
|
||||||
ShmPipe *sp_writer_block_get_pipe (ShmBlock *block);
|
ShmPipe *sp_writer_block_get_pipe (ShmBlock *block);
|
||||||
|
|
||||||
|
@ -104,6 +106,10 @@ ShmPipe *sp_client_open (const char *path);
|
||||||
long int sp_client_recv (ShmPipe * self, char **buf);
|
long int sp_client_recv (ShmPipe * self, char **buf);
|
||||||
int sp_client_recv_finish (ShmPipe * self, char *buf);
|
int sp_client_recv_finish (ShmPipe * self, char *buf);
|
||||||
|
|
||||||
|
ShmBuffer *sp_writer_get_pending_buffers (ShmPipe * self);
|
||||||
|
ShmBuffer *sp_writer_get_next_buffer (ShmBuffer * buffer);
|
||||||
|
uint64_t sp_writer_buf_get_tag (ShmBuffer * buffer);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue