summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pulse/stream.c23
-rw-r--r--src/pulse/stream.h1
-rw-r--r--src/pulsecore/protocol-native.c19
-rw-r--r--src/pulsecore/svolume_mmx.c12
-rw-r--r--src/pulsecore/svolume_sse.c12
-rw-r--r--src/tests/extended-test.c6
6 files changed, 54 insertions, 19 deletions
diff --git a/src/pulse/stream.c b/src/pulse/stream.c
index cd5182ab..aeb897c2 100644
--- a/src/pulse/stream.c
+++ b/src/pulse/stream.c
@@ -86,14 +86,16 @@ static pa_stream *pa_stream_new_with_proplist_internal(
const pa_sample_spec *ss,
const pa_channel_map *map,
pa_format_info * const *formats,
+ unsigned int n_formats,
pa_proplist *p) {
pa_stream *s;
- int i;
+ unsigned int i;
pa_assert(c);
pa_assert(PA_REFCNT_VALUE(c) >= 1);
- pa_assert((ss == NULL && map == NULL) || formats == NULL);
+ pa_assert((ss == NULL && map == NULL) || (formats == NULL && n_formats == 0));
+ pa_assert(n_formats < PA_MAX_FORMATS);
PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
PA_CHECK_VALIDITY_RETURN_NULL(c, name || (p && pa_proplist_contains(p, PA_PROP_MEDIA_NAME)), PA_ERR_INVALID);
@@ -119,12 +121,9 @@ static pa_stream *pa_stream_new_with_proplist_internal(
s->n_formats = 0;
if (formats) {
- for (i = 0; formats[i] && i < PA_MAX_FORMATS; i++) {
- s->n_formats++;
+ s->n_formats = n_formats;
+ for (i = 0; i < n_formats; i++)
s->req_formats[i] = pa_format_info_copy(formats[i]);
- }
- /* Make sure the input array was NULL-terminated */
- pa_assert(formats[i] == NULL);
}
/* We'll get the final negotiated format after connecting */
@@ -221,18 +220,19 @@ pa_stream *pa_stream_new_with_proplist(
if (!map)
PA_CHECK_VALIDITY_RETURN_NULL(c, map = pa_channel_map_init_auto(&tmap, ss->channels, PA_CHANNEL_MAP_DEFAULT), PA_ERR_INVALID);
- return pa_stream_new_with_proplist_internal(c, name, ss, map, NULL, p);
+ return pa_stream_new_with_proplist_internal(c, name, ss, map, NULL, 0, p);
}
pa_stream *pa_stream_new_extended(
pa_context *c,
const char *name,
pa_format_info * const *formats,
+ unsigned int n_formats,
pa_proplist *p) {
PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 21, PA_ERR_NOTSUPPORTED);
- return pa_stream_new_with_proplist_internal(c, name, NULL, NULL, formats, p);
+ return pa_stream_new_with_proplist_internal(c, name, NULL, NULL, formats, n_formats, p);
}
static void stream_unlink(pa_stream *s) {
@@ -303,7 +303,10 @@ static void stream_free(pa_stream *s) {
pa_smoother_free(s->smoother);
for (i = 0; i < s->n_formats; i++)
- pa_xfree(s->req_formats[i]);
+ pa_format_info_free(s->req_formats[i]);
+
+ if (s->format)
+ pa_format_info_free(s->format);
pa_xfree(s->device_name);
pa_xfree(s);
diff --git a/src/pulse/stream.h b/src/pulse/stream.h
index b265fae6..010f968f 100644
--- a/src/pulse/stream.h
+++ b/src/pulse/stream.h
@@ -365,6 +365,7 @@ pa_stream *pa_stream_new_extended(
pa_context *c /**< The context to create this stream in */,
const char *name /**< A name for this stream */,
pa_format_info * const * formats /**< The list of formats that can be provided */,
+ unsigned int n_formats /**< The number of formats being passed in */,
pa_proplist *p /**< The initial property list */);
/** Decrease the reference counter by one */
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index d8df8604..b16793d9 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -1037,6 +1037,9 @@ static playback_stream* playback_stream_new(
pa_bool_t relative_volume,
int *ret) {
+ /* Note: This function takes ownership of the 'formats' param, so we need
+ * to take extra care to not leak it */
+
playback_stream *s, *ssync;
pa_sink_input *sink_input = NULL;
pa_memchunk silence;
@@ -1067,7 +1070,7 @@ static playback_stream* playback_stream_new(
sink = ssync->sink_input->sink;
else if (sink != ssync->sink_input->sink) {
*ret = PA_ERR_INVALID;
- return NULL;
+ goto out;
}
}
@@ -1083,8 +1086,11 @@ static playback_stream* playback_stream_new(
pa_sink_input_new_data_set_sample_spec(&data, ss);
if (pa_channel_map_valid(map))
pa_sink_input_new_data_set_channel_map(&data, map);
- if (formats)
+ if (formats) {
pa_sink_input_new_data_set_formats(&data, formats);
+ /* Ownership transferred to new_data, so we don't free it ourseleves */
+ formats = NULL;
+ }
if (volume) {
pa_sink_input_new_data_set_volume(&data, volume);
data.volume_is_absolute = !relative_volume;
@@ -1102,7 +1108,7 @@ static playback_stream* playback_stream_new(
pa_sink_input_new_data_done(&data);
if (!sink_input)
- return NULL;
+ goto out;
s = pa_msgobject_new(playback_stream);
s->parent.parent.parent.free = playback_stream_free;
@@ -1164,6 +1170,11 @@ static playback_stream* playback_stream_new(
(double) s->configured_sink_latency / PA_USEC_PER_MSEC);
pa_sink_input_put(s->sink_input);
+
+out:
+ if (formats)
+ pa_idxset_free(formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+
return s;
}
@@ -2071,6 +2082,8 @@ static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, u
muted_set = muted_set || muted;
s = playback_stream_new(c, sink, &ss, &map, formats, &attr, volume_set ? &volume : NULL, muted, muted_set, syncid, &missing, flags, p, adjust_latency, early_requests, relative_volume, &ret);
+ /* We no longer own the formats idxset */
+ formats = NULL;
CHECK_VALIDITY_GOTO(c->pstream, s, tag, ret, finish);
diff --git a/src/pulsecore/svolume_mmx.c b/src/pulsecore/svolume_mmx.c
index 7286b4a2..28bbfdd3 100644
--- a/src/pulsecore/svolume_mmx.c
+++ b/src/pulsecore/svolume_mmx.c
@@ -155,7 +155,11 @@ static void pa_volume_s16ne_mmx(int16_t *samples, int32_t *volumes, unsigned cha
" emms \n\t"
: "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp)
- : "rm" ((pa_reg_x86)channels)
+#if defined (__i386__)
+ : "m" ((pa_reg_x86)channels)
+#else
+ : "r" ((pa_reg_x86)channels)
+#endif
: "cc"
);
}
@@ -230,7 +234,11 @@ static void pa_volume_s16re_mmx(int16_t *samples, int32_t *volumes, unsigned cha
" emms \n\t"
: "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp)
- : "rm" ((pa_reg_x86)channels)
+#if defined (__i386__)
+ : "m" ((pa_reg_x86)channels)
+#else
+ : "r" ((pa_reg_x86)channels)
+#endif
: "cc"
);
}
diff --git a/src/pulsecore/svolume_sse.c b/src/pulsecore/svolume_sse.c
index 8fed69b2..dcd71c4b 100644
--- a/src/pulsecore/svolume_sse.c
+++ b/src/pulsecore/svolume_sse.c
@@ -154,7 +154,11 @@ static void pa_volume_s16ne_sse2(int16_t *samples, int32_t *volumes, unsigned ch
"8: \n\t"
: "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp)
- : "rm" ((pa_reg_x86)channels)
+#if defined (__i386__)
+ : "m" ((pa_reg_x86)channels)
+#else
+ : "r" ((pa_reg_x86)channels)
+#endif
: "cc"
);
}
@@ -242,7 +246,11 @@ static void pa_volume_s16re_sse2(int16_t *samples, int32_t *volumes, unsigned ch
"8: \n\t"
: "+r" (samples), "+r" (volumes), "+r" (length), "=D" (channel), "=&r" (temp)
- : "rm" ((pa_reg_x86)channels)
+#if defined (__i386__)
+ : "m" ((pa_reg_x86)channels)
+#else
+ : "r" ((pa_reg_x86)channels)
+#endif
: "cc"
);
}
diff --git a/src/tests/extended-test.c b/src/tests/extended-test.c
index f99a85c3..ab8ab2c0 100644
--- a/src/tests/extended-test.c
+++ b/src/tests/extended-test.c
@@ -122,7 +122,7 @@ static void context_state_callback(pa_context *c, void *userdata) {
for (i = 0; i < NSTREAMS; i++) {
char name[64];
- pa_format_info *formats[2] = { NULL };
+ pa_format_info *formats[1];
formats[0] = pa_format_info_new();
formats[0]->encoding = PA_ENCODING_PCM;
@@ -134,10 +134,12 @@ static void context_state_callback(pa_context *c, void *userdata) {
snprintf(name, sizeof(name), "stream #%i", i);
- streams[i] = pa_stream_new_extended(c, name, formats, NULL);
+ streams[i] = pa_stream_new_extended(c, name, formats, 1, NULL);
assert(streams[i]);
pa_stream_set_state_callback(streams[i], stream_state_callback, (void*) (long) i);
pa_stream_connect_playback(streams[i], NULL, &buffer_attr, PA_STREAM_START_CORKED, NULL, i == 0 ? NULL : streams[0]);
+
+ pa_format_info_free(formats[0]);
}
break;