mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-14 06:59:57 -05:00
Make new USE_BUFFERS command
Make a new USE_BUFFERS command to atomically send a buffer array to the remote client. We can use this to then clean up an old array and go to the PAUSED state if possible. Work on formats. Make one structure that can hold all video formats. Work on pipeline suspend and resume. Add jpeg support to v4l2. Work on enum_formats with a filter in v4l2.
This commit is contained in:
parent
7e858ff694
commit
b67c216a04
24 changed files with 688 additions and 514 deletions
|
|
@ -43,9 +43,6 @@
|
|||
typedef struct {
|
||||
bool cleanup;
|
||||
uint32_t id;
|
||||
int fd;
|
||||
off_t offset;
|
||||
size_t size;
|
||||
bool used;
|
||||
SpaBuffer *buf;
|
||||
} BufferId;
|
||||
|
|
@ -53,10 +50,8 @@ typedef struct {
|
|||
static void
|
||||
clear_buffer_id (BufferId *id)
|
||||
{
|
||||
munmap (id->buf, id->size);
|
||||
spa_memory_unref (&id->buf->mem.mem);
|
||||
id->buf = NULL;
|
||||
close (id->fd);
|
||||
id->fd = -1;
|
||||
}
|
||||
|
||||
struct _PinosStreamPrivate
|
||||
|
|
@ -822,45 +817,46 @@ parse_control (PinosStream *stream,
|
|||
spa_memory_unref (&p.mem);
|
||||
break;
|
||||
}
|
||||
case SPA_CONTROL_CMD_ADD_BUFFER:
|
||||
case SPA_CONTROL_CMD_USE_BUFFERS:
|
||||
{
|
||||
SpaControlCmdAddBuffer p;
|
||||
SpaControlCmdUseBuffers p;
|
||||
BufferId bid;
|
||||
SpaMemory *mem;
|
||||
unsigned int i;
|
||||
SpaControlBuilder builder;
|
||||
SpaControl control;
|
||||
|
||||
if (spa_control_iter_parse_cmd (&it, &p) < 0)
|
||||
break;
|
||||
|
||||
g_debug ("add buffer %d, %d", p.buffer_id, p.mem.mem.id);
|
||||
mem = spa_memory_find (&p.mem.mem);
|
||||
bid.cleanup = false;
|
||||
bid.id = p.buffer_id;
|
||||
bid.offset = p.mem.offset;
|
||||
bid.size = p.mem.size;
|
||||
bid.buf = SPA_MEMBER (spa_memory_ensure_ptr (mem), p.mem.offset, SpaBuffer);
|
||||
/* clear previous buffers */
|
||||
g_array_set_size (priv->buffer_ids, 0);
|
||||
|
||||
if (bid.id != priv->buffer_ids->len) {
|
||||
g_warning ("unexpected id %u found, expected %u", bid.id, priv->buffer_ids->len);
|
||||
priv->in_order = FALSE;
|
||||
for (i = 0; i < p.n_buffers; i++) {
|
||||
bid.buf = p.buffers[i];
|
||||
bid.cleanup = false;
|
||||
bid.id = bid.buf->id;
|
||||
g_debug ("add buffer %d, %d", bid.id, bid.buf->mem.mem.id);
|
||||
|
||||
if (bid.id != priv->buffer_ids->len) {
|
||||
g_warning ("unexpected id %u found, expected %u", bid.id, priv->buffer_ids->len);
|
||||
priv->in_order = FALSE;
|
||||
}
|
||||
g_array_append_val (priv->buffer_ids, bid);
|
||||
g_signal_emit (stream, signals[SIGNAL_ADD_BUFFER], 0, bid.id);
|
||||
}
|
||||
g_array_append_val (priv->buffer_ids, bid);
|
||||
g_signal_emit (stream, signals[SIGNAL_ADD_BUFFER], 0, p.buffer_id);
|
||||
break;
|
||||
}
|
||||
case SPA_CONTROL_CMD_REMOVE_BUFFER:
|
||||
{
|
||||
SpaControlCmdRemoveBuffer p;
|
||||
BufferId *bid;
|
||||
|
||||
if (spa_control_iter_parse_cmd (&it, &p) < 0)
|
||||
break;
|
||||
|
||||
g_debug ("remove buffer %d", p.buffer_id);
|
||||
if ((bid = find_buffer (stream, p.buffer_id))) {
|
||||
bid->cleanup = TRUE;
|
||||
bid->used = TRUE;
|
||||
g_signal_emit (stream, signals[SIGNAL_REMOVE_BUFFER], 0, p.buffer_id);
|
||||
control_builder_init (stream, &builder);
|
||||
if (p.n_buffers) {
|
||||
add_state_change (stream, &builder, SPA_NODE_STATE_PAUSED);
|
||||
} else {
|
||||
add_state_change (stream, &builder, SPA_NODE_STATE_READY);
|
||||
}
|
||||
spa_control_builder_end (&builder, &control);
|
||||
|
||||
if (spa_control_write (&control, priv->fd) < 0)
|
||||
g_warning ("stream %p: error writing control", stream);
|
||||
|
||||
spa_control_clear (&control);
|
||||
break;
|
||||
}
|
||||
case SPA_CONTROL_CMD_PROCESS_BUFFER:
|
||||
|
|
@ -875,7 +871,7 @@ parse_control (PinosStream *stream,
|
|||
|
||||
g_signal_emit (stream, signals[SIGNAL_NEW_BUFFER], 0, p.buffer_id);
|
||||
|
||||
send_need_input (stream, 0);
|
||||
send_need_input (stream, 0);
|
||||
break;
|
||||
}
|
||||
case SPA_CONTROL_CMD_REUSE_BUFFER:
|
||||
|
|
@ -919,7 +915,6 @@ on_socket_condition (GSocket *socket,
|
|||
case G_IO_IN:
|
||||
{
|
||||
SpaControl *control = &priv->recv_control;
|
||||
guint i;
|
||||
|
||||
if (spa_control_read (control,
|
||||
priv->fd,
|
||||
|
|
@ -933,17 +928,6 @@ on_socket_condition (GSocket *socket,
|
|||
|
||||
parse_control (stream, control);
|
||||
|
||||
for (i = 0; i < priv->buffer_ids->len; i++) {
|
||||
BufferId *bid = &g_array_index (priv->buffer_ids, BufferId, i);
|
||||
if (bid->cleanup) {
|
||||
g_array_remove_index_fast (priv->buffer_ids, i);
|
||||
i--;
|
||||
priv->in_order = FALSE;
|
||||
}
|
||||
}
|
||||
if (!priv->in_order && priv->buffer_ids->len == 0)
|
||||
priv->in_order = TRUE;
|
||||
|
||||
spa_control_clear (control);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ calc_size (GstCapsFeatures *cf, GstStructure *cs, guint *n_infos, guint *n_range
|
|||
n_ranges[0] += c;
|
||||
n_datas[0] += (1 + c) * sizeof (uint32_t);
|
||||
}
|
||||
} else if (gst_structure_has_name (cs, "image/jpeg")) {
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -147,9 +148,9 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
|
|||
if (val) {
|
||||
SpaVideoFormat *sv = p;
|
||||
|
||||
spa_video_raw_fill_prop_info (&bpi[pi],
|
||||
SPA_PROP_ID_VIDEO_FORMAT,
|
||||
SPA_PTRDIFF (p, f));
|
||||
spa_prop_info_fill_video (&bpi[pi],
|
||||
SPA_PROP_ID_VIDEO_FORMAT,
|
||||
SPA_PTRDIFF (p, f));
|
||||
|
||||
if (G_VALUE_TYPE (val) == G_TYPE_STRING) {
|
||||
*sv = gst_video_format_from_string (g_value_get_string (val));
|
||||
|
|
@ -171,7 +172,7 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
|
|||
if (val || val2) {
|
||||
SpaRectangle *sv = p;
|
||||
|
||||
spa_video_raw_fill_prop_info (&bpi[pi],
|
||||
spa_prop_info_fill_video (&bpi[pi],
|
||||
SPA_PROP_ID_VIDEO_SIZE,
|
||||
SPA_PTRDIFF (p, f));
|
||||
|
||||
|
|
@ -224,9 +225,9 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
|
|||
if (val) {
|
||||
SpaFraction *sv = p;
|
||||
|
||||
spa_video_raw_fill_prop_info (&bpi[pi],
|
||||
SPA_PROP_ID_VIDEO_FRAMERATE,
|
||||
SPA_PTRDIFF (p, f));
|
||||
spa_prop_info_fill_video (&bpi[pi],
|
||||
SPA_PROP_ID_VIDEO_FRAMERATE,
|
||||
SPA_PTRDIFF (p, f));
|
||||
|
||||
if (G_VALUE_TYPE (val) == GST_TYPE_FRACTION) {
|
||||
sv->num = gst_value_get_fraction_numerator (val);
|
||||
|
|
@ -284,9 +285,9 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
|
|||
if (val) {
|
||||
SpaAudioFormat *sv = p;
|
||||
|
||||
spa_audio_raw_fill_prop_info (&bpi[pi],
|
||||
SPA_PROP_ID_AUDIO_FORMAT,
|
||||
SPA_PTRDIFF (p, f));
|
||||
spa_prop_info_fill_audio (&bpi[pi],
|
||||
SPA_PROP_ID_AUDIO_FORMAT,
|
||||
SPA_PTRDIFF (p, f));
|
||||
|
||||
if (G_VALUE_TYPE (val) == G_TYPE_STRING) {
|
||||
*sv = gst_audio_format_from_string (g_value_get_string (val));
|
||||
|
|
@ -307,9 +308,9 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
|
|||
if (val) {
|
||||
SpaAudioLayout *sv = p;
|
||||
|
||||
spa_audio_raw_fill_prop_info (&bpi[pi],
|
||||
SPA_PROP_ID_AUDIO_LAYOUT,
|
||||
SPA_PTRDIFF (p, f));
|
||||
spa_prop_info_fill_audio (&bpi[pi],
|
||||
SPA_PROP_ID_AUDIO_LAYOUT,
|
||||
SPA_PTRDIFF (p, f));
|
||||
|
||||
if (G_VALUE_TYPE (val) == G_TYPE_STRING) {
|
||||
const gchar *s = g_value_get_string (val);
|
||||
|
|
@ -334,9 +335,9 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
|
|||
if (val) {
|
||||
uint32_t *sv = p;
|
||||
|
||||
spa_audio_raw_fill_prop_info (&bpi[pi],
|
||||
SPA_PROP_ID_AUDIO_RATE,
|
||||
SPA_PTRDIFF (p, f));
|
||||
spa_prop_info_fill_audio (&bpi[pi],
|
||||
SPA_PROP_ID_AUDIO_RATE,
|
||||
SPA_PTRDIFF (p, f));
|
||||
|
||||
if (G_VALUE_TYPE (val) == G_TYPE_INT) {
|
||||
*sv = g_value_get_int (val);
|
||||
|
|
@ -357,9 +358,9 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
|
|||
if (val) {
|
||||
uint32_t *sv = p;
|
||||
|
||||
spa_audio_raw_fill_prop_info (&bpi[pi],
|
||||
SPA_PROP_ID_AUDIO_CHANNELS,
|
||||
SPA_PTRDIFF (p, f));
|
||||
spa_prop_info_fill_audio (&bpi[pi],
|
||||
SPA_PROP_ID_AUDIO_CHANNELS,
|
||||
SPA_PTRDIFF (p, f));
|
||||
|
||||
if (G_VALUE_TYPE (val) == G_TYPE_INT) {
|
||||
*sv = g_value_get_int (val);
|
||||
|
|
@ -376,6 +377,9 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
|
|||
}
|
||||
pi++;
|
||||
}
|
||||
} else if (gst_structure_has_name (cs, "image/jpeg")) {
|
||||
f->media_type = SPA_MEDIA_TYPE_VIDEO;
|
||||
f->media_subtype = SPA_MEDIA_SUBTYPE_MJPG;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
|
@ -431,16 +435,21 @@ gst_caps_from_format (SpaFormat *format)
|
|||
GstCaps *res = NULL;
|
||||
|
||||
if (format->media_type == SPA_MEDIA_TYPE_VIDEO) {
|
||||
SpaFormatVideo f;
|
||||
|
||||
spa_format_video_parse (format, &f);
|
||||
|
||||
if (format->media_subtype == SPA_MEDIA_SUBTYPE_RAW) {
|
||||
SpaVideoRawFormat f;
|
||||
|
||||
spa_video_raw_format_parse (format, &f);
|
||||
|
||||
res = gst_caps_new_simple ("video/x-raw",
|
||||
"format", G_TYPE_STRING, gst_video_format_to_string (f.info.format),
|
||||
"width", G_TYPE_INT, f.info.size.width,
|
||||
"height", G_TYPE_INT, f.info.size.height,
|
||||
"framerate", GST_TYPE_FRACTION, f.info.framerate.num, f.info.framerate.denom,
|
||||
"format", G_TYPE_STRING, gst_video_format_to_string (f.info.raw.format),
|
||||
"width", G_TYPE_INT, f.info.raw.size.width,
|
||||
"height", G_TYPE_INT, f.info.raw.size.height,
|
||||
"framerate", GST_TYPE_FRACTION, f.info.raw.framerate.num, f.info.raw.framerate.denom,
|
||||
NULL);
|
||||
}
|
||||
else if (format->media_subtype == SPA_MEDIA_SUBTYPE_MJPG) {
|
||||
res = gst_caps_new_simple ("image/jpeg",
|
||||
"framerate", GST_TYPE_FRACTION, f.info.jpeg.framerate.num, f.info.jpeg.framerate.denom,
|
||||
NULL);
|
||||
}
|
||||
} else if (format->media_type == SPA_MEDIA_TYPE_AUDIO) {
|
||||
|
|
|
|||
|
|
@ -224,25 +224,32 @@ setup_node (PinosSpaV4l2Source *this)
|
|||
}
|
||||
|
||||
static void
|
||||
stop_pipeline (PinosSpaV4l2Source *this)
|
||||
pause_pipeline (PinosSpaV4l2Source *this)
|
||||
{
|
||||
PinosSpaV4l2SourcePrivate *priv = this->priv;
|
||||
PinosNode *node = PINOS_NODE (this);
|
||||
SpaResult res;
|
||||
SpaCommand cmd;
|
||||
|
||||
g_debug ("spa-v4l2-source %p: stopping pipeline", this);
|
||||
|
||||
if (priv->running) {
|
||||
priv->running = false;
|
||||
pthread_join (priv->thread, NULL);
|
||||
}
|
||||
g_debug ("spa-v4l2-source %p: pause pipeline", this);
|
||||
|
||||
cmd.type = SPA_COMMAND_PAUSE;
|
||||
if ((res = spa_node_send_command (node->node, &cmd)) < 0)
|
||||
g_debug ("got error %d", res);
|
||||
}
|
||||
|
||||
static void
|
||||
suspend_pipeline (PinosSpaV4l2Source *this)
|
||||
{
|
||||
PinosNode *node = PINOS_NODE (this);
|
||||
SpaResult res;
|
||||
|
||||
g_debug ("spa-v4l2-source %p: suspend pipeline", this);
|
||||
|
||||
if ((res = spa_node_port_set_format (node->node, 0, 0, NULL)) < 0) {
|
||||
g_warning ("error unset format output: %d", res);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_pipeline (PinosSpaV4l2Source *this)
|
||||
{
|
||||
|
|
@ -259,13 +266,14 @@ set_state (PinosNode *node,
|
|||
|
||||
switch (state) {
|
||||
case PINOS_NODE_STATE_SUSPENDED:
|
||||
suspend_pipeline (this);
|
||||
break;
|
||||
|
||||
case PINOS_NODE_STATE_INITIALIZING:
|
||||
break;
|
||||
|
||||
case PINOS_NODE_STATE_IDLE:
|
||||
stop_pipeline (this);
|
||||
pause_pipeline (this);
|
||||
break;
|
||||
|
||||
case PINOS_NODE_STATE_RUNNING:
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ struct _PinosLinkPrivate
|
|||
gboolean active;
|
||||
gboolean negotiated;
|
||||
gboolean allocated;
|
||||
gboolean started;
|
||||
|
||||
PinosPort *output;
|
||||
PinosPort *input;
|
||||
|
|
@ -227,14 +228,16 @@ do_negotiate (PinosLink *this)
|
|||
|
||||
g_debug ("link %p: doing set format", this);
|
||||
|
||||
priv->negotiated = TRUE;
|
||||
|
||||
again:
|
||||
if ((res = spa_node_port_enum_formats (priv->input_node,
|
||||
priv->input_port,
|
||||
&filter,
|
||||
NULL,
|
||||
&istate)) < 0) {
|
||||
g_warning ("error enum formats: %d", res);
|
||||
return res;
|
||||
g_warning ("error input enum formats: %d", res);
|
||||
goto error;
|
||||
}
|
||||
spa_debug_format (filter);
|
||||
|
||||
|
|
@ -247,26 +250,30 @@ again:
|
|||
ostate = NULL;
|
||||
goto again;
|
||||
}
|
||||
g_warning ("error enum formats: %d", res);
|
||||
return res;
|
||||
g_warning ("error output enum formats: %d", res);
|
||||
goto error;
|
||||
}
|
||||
spa_debug_format (format);
|
||||
|
||||
spa_format_fixate (format);
|
||||
|
||||
spa_debug_format (format);
|
||||
|
||||
if ((res = spa_node_port_set_format (priv->output_node, priv->output_port, 0, format)) < 0) {
|
||||
g_warning ("error set format output: %d", res);
|
||||
return res;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((res = spa_node_port_set_format (priv->input_node, priv->input_port, 0, format)) < 0) {
|
||||
g_warning ("error set format input: %d", res);
|
||||
return res;
|
||||
goto error;
|
||||
}
|
||||
|
||||
priv->negotiated = TRUE;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
|
||||
error:
|
||||
{
|
||||
priv->negotiated = FALSE;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
|
|
@ -281,13 +288,15 @@ do_allocation (PinosLink *this)
|
|||
/* find out what's possible */
|
||||
if ((res = spa_node_port_get_info (priv->output_node, priv->output_port, &oinfo)) < 0) {
|
||||
g_warning ("error get port info: %d", res);
|
||||
return res;
|
||||
goto error;
|
||||
}
|
||||
if ((res = spa_node_port_get_info (priv->input_node, priv->input_port, &iinfo)) < 0) {
|
||||
g_warning ("error get port info: %d", res);
|
||||
return res;
|
||||
goto error;
|
||||
}
|
||||
|
||||
priv->allocated = TRUE;
|
||||
|
||||
spa_debug_port_info (oinfo);
|
||||
spa_debug_port_info (iinfo);
|
||||
|
||||
|
|
@ -311,7 +320,7 @@ do_allocation (PinosLink *this)
|
|||
priv->in_buffers,
|
||||
&priv->n_in_buffers)) < 0) {
|
||||
g_warning ("error alloc buffers: %d", res);
|
||||
return res;
|
||||
goto error;
|
||||
}
|
||||
memcpy (priv->out_buffers, priv->in_buffers, priv->n_in_buffers * sizeof (SpaBuffer*));
|
||||
priv->n_out_buffers = priv->n_in_buffers;
|
||||
|
|
@ -321,7 +330,8 @@ do_allocation (PinosLink *this)
|
|||
in_flags = SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS;
|
||||
} else {
|
||||
g_warning ("error no common allocation found");
|
||||
return SPA_RESULT_ERROR;
|
||||
res = SPA_RESULT_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (in_flags & SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS) {
|
||||
|
|
@ -329,7 +339,7 @@ do_allocation (PinosLink *this)
|
|||
oinfo->params, oinfo->n_params,
|
||||
priv->in_buffers, &priv->n_in_buffers)) < 0) {
|
||||
g_warning ("error alloc buffers: %d", res);
|
||||
return res;
|
||||
goto error;
|
||||
}
|
||||
priv->input->n_buffers = priv->n_in_buffers;
|
||||
priv->input->buffers = priv->in_buffers;
|
||||
|
|
@ -339,7 +349,7 @@ do_allocation (PinosLink *this)
|
|||
iinfo->params, iinfo->n_params,
|
||||
priv->out_buffers, &priv->n_out_buffers)) < 0) {
|
||||
g_warning ("error alloc buffers: %d", res);
|
||||
return res;
|
||||
goto error;
|
||||
}
|
||||
priv->output->n_buffers = priv->n_out_buffers;
|
||||
priv->output->buffers = priv->out_buffers;
|
||||
|
|
@ -348,7 +358,7 @@ do_allocation (PinosLink *this)
|
|||
if ((res = spa_node_port_use_buffers (priv->input_node, priv->input_port,
|
||||
priv->out_buffers, priv->n_out_buffers)) < 0) {
|
||||
g_warning ("error use buffers: %d", res);
|
||||
return res;
|
||||
goto error;
|
||||
}
|
||||
priv->input->n_buffers = priv->n_out_buffers;
|
||||
priv->input->buffers = priv->out_buffers;
|
||||
|
|
@ -357,15 +367,19 @@ do_allocation (PinosLink *this)
|
|||
if ((res = spa_node_port_use_buffers (priv->output_node, priv->output_port,
|
||||
priv->in_buffers, priv->n_in_buffers)) < 0) {
|
||||
g_warning ("error use buffers: %d", res);
|
||||
return res;
|
||||
goto error;
|
||||
}
|
||||
priv->output->n_buffers = priv->n_in_buffers;
|
||||
priv->output->buffers = priv->in_buffers;
|
||||
}
|
||||
|
||||
priv->allocated = TRUE;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
|
||||
error:
|
||||
{
|
||||
priv->allocated = FALSE;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
|
|
@ -375,6 +389,8 @@ do_start (PinosLink *this)
|
|||
SpaCommand cmd;
|
||||
SpaResult res;
|
||||
|
||||
priv->started = TRUE;
|
||||
|
||||
cmd.type = SPA_COMMAND_START;
|
||||
if ((res = spa_node_send_command (priv->input_node, &cmd)) < 0)
|
||||
g_warning ("got error %d", res);
|
||||
|
|
@ -391,6 +407,8 @@ do_pause (PinosLink *this)
|
|||
SpaCommand cmd;
|
||||
SpaResult res;
|
||||
|
||||
priv->started = FALSE;
|
||||
|
||||
cmd.type = SPA_COMMAND_PAUSE;
|
||||
if ((res = spa_node_send_command (priv->input_node, &cmd)) < 0)
|
||||
g_warning ("got error %d", res);
|
||||
|
|
@ -408,18 +426,21 @@ check_states (PinosLink *this)
|
|||
|
||||
g_debug ("link %p: input %d, output %d", this, priv->input_state, priv->output_state);
|
||||
|
||||
if (priv->input_state == SPA_NODE_STATE_CONFIGURE &&
|
||||
priv->output_state == SPA_NODE_STATE_CONFIGURE &&
|
||||
if (priv->input_state >= SPA_NODE_STATE_CONFIGURE &&
|
||||
priv->output_state >= SPA_NODE_STATE_CONFIGURE &&
|
||||
!priv->negotiated) {
|
||||
if ((res = do_negotiate (this)) < 0)
|
||||
return res;
|
||||
}
|
||||
if (priv->input_state == SPA_NODE_STATE_READY &&
|
||||
priv->output_state == SPA_NODE_STATE_READY &&
|
||||
if (priv->input_state >= SPA_NODE_STATE_READY &&
|
||||
priv->output_state >= SPA_NODE_STATE_READY &&
|
||||
!priv->allocated) {
|
||||
if ((res = do_allocation (this)) < 0)
|
||||
return res;
|
||||
|
||||
}
|
||||
if (priv->input_state >= SPA_NODE_STATE_PAUSED &&
|
||||
priv->output_state >= SPA_NODE_STATE_PAUSED &&
|
||||
!priv->started) {
|
||||
if ((res = do_start (this)) < 0)
|
||||
return res;
|
||||
}
|
||||
|
|
@ -546,10 +567,15 @@ pinos_link_constructed (GObject * object)
|
|||
static void
|
||||
pinos_link_dispose (GObject * object)
|
||||
{
|
||||
PinosLink *link = PINOS_LINK (object);
|
||||
PinosLinkPrivate *priv = link->priv;
|
||||
PinosLink *this = PINOS_LINK (object);
|
||||
PinosLinkPrivate *priv = this->priv;
|
||||
|
||||
g_debug ("link %p: dispose", link);
|
||||
g_debug ("link %p: dispose", this);
|
||||
|
||||
g_signal_handlers_disconnect_by_data (priv->input, this);
|
||||
g_signal_handlers_disconnect_by_data (priv->output, this);
|
||||
g_signal_handlers_disconnect_by_data (priv->input->node, this);
|
||||
g_signal_handlers_disconnect_by_data (priv->output->node, this);
|
||||
|
||||
pinos_port_remove_send_cb (priv->input, priv->input_id);
|
||||
pinos_port_remove_send_cb (priv->output, priv->output_id);
|
||||
|
|
@ -560,7 +586,7 @@ pinos_link_dispose (GObject * object)
|
|||
}
|
||||
priv->input = NULL;
|
||||
priv->output = NULL;
|
||||
link_unregister_object (link);
|
||||
link_unregister_object (this);
|
||||
|
||||
G_OBJECT_CLASS (pinos_link_parent_class)->dispose (object);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue