mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-01 22:58:47 -04:00
Compare commits
13 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f839526a5 | ||
|
|
566849c4af | ||
|
|
0647fcb622 | ||
|
|
9a428e4c50 | ||
|
|
a8b28d86cd | ||
|
|
f2836dc6b6 | ||
|
|
686ae9c696 | ||
|
|
e5ad31e873 | ||
|
|
e4d54dae91 | ||
|
|
0e896eb518 | ||
|
|
ca8c5242eb | ||
|
|
437cfe4630 | ||
|
|
8299a7f100 |
12 changed files with 115 additions and 45 deletions
36
NEWS
36
NEWS
|
|
@ -1,3 +1,39 @@
|
|||
PulseAudio 16.2
|
||||
|
||||
A bug fix release.
|
||||
|
||||
* A couple of time-smoother-2 fixes, mainly manifesting in issues for GStreamer clients
|
||||
* Fix a crash in some restricted environments
|
||||
* Minor RTP spec compliance fix
|
||||
* Minur completion and tests fixups
|
||||
|
||||
Contributors
|
||||
|
||||
Arun Raghavan
|
||||
Georg Chini
|
||||
Igor V. Kovalenko
|
||||
flyingOwl
|
||||
|
||||
|
||||
PulseAudio 16.1
|
||||
|
||||
A bug fix release.
|
||||
|
||||
* Fix parsing of percentage volumes with decimal points in pactl
|
||||
* Fix crash with the "pacmd play-file" command when reads from the disk aren't frame-aligned
|
||||
* Fix module-rtp-recv sometimes thinking it's receiving an Opus stream when it's not
|
||||
* Fix frequent crashing in module-combine-sink, regression in 16.0
|
||||
* Fix crashing on 32-bit architectures when using the GStreamer codecs for LDAC and AptX
|
||||
|
||||
Contributors
|
||||
|
||||
Georg Chini
|
||||
Igor V. Kovalenko
|
||||
Jaechul Lee
|
||||
Jan Palus
|
||||
Sean Greenslade
|
||||
|
||||
|
||||
PulseAudio 16.0
|
||||
|
||||
Changes at a glance:
|
||||
|
|
|
|||
|
|
@ -500,7 +500,7 @@ _pulseaudio()
|
|||
--start -k --kill --check --system= -D --daemonize= --fail= --high-priority=
|
||||
--realtime= --disallow-module-loading= --disallow-exit= --exit-idle-time=
|
||||
--scache-idle-time= --log-level= -v --log-target= --log-meta= --log-time=
|
||||
--log-backtrace= -p --dl-search-path= --resample-method= --use-pit-file=
|
||||
--log-backtrace= -p --dl-search-path= --resample-method= --use-pid-file=
|
||||
--no-cpu-limit= --disable-shm= --enable-memfd= -L --load= -F --file= -C -n'
|
||||
_init_completion -n = || return
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#endif
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <pulsecore/log.h>
|
||||
#include <pulsecore/macro.h>
|
||||
|
|
@ -82,7 +83,7 @@ fail:
|
|||
static GstCaps *gst_create_caps_from_sample_spec(const pa_sample_spec *ss) {
|
||||
gchar *sample_format;
|
||||
GstCaps *caps;
|
||||
int channel_mask;
|
||||
uint64_t channel_mask;
|
||||
|
||||
switch (ss->format) {
|
||||
case PA_SAMPLE_S16LE:
|
||||
|
|
|
|||
|
|
@ -213,7 +213,9 @@ int pa_sap_recv(pa_sap_context *c, bool *goodbye) {
|
|||
if ((unsigned) size >= sizeof(MIME_TYPE) && pa_streq(e, MIME_TYPE)) {
|
||||
e += sizeof(MIME_TYPE);
|
||||
size -= (int) sizeof(MIME_TYPE);
|
||||
} else if ((unsigned) size < sizeof(PA_SDP_HEADER)-1 || strncmp(e, PA_SDP_HEADER, sizeof(PA_SDP_HEADER)-1)) {
|
||||
} else if ((unsigned) size < sizeof(PA_SDP_HEADER)-1 || strncmp(e, PA_SDP_HEADER, sizeof(PA_SDP_HEADER)-1)
|
||||
|| strcspn(e, "\r\n") != sizeof(PA_SDP_HEADER)-1) {
|
||||
/* SDP header does not start with v=0[\r]\n */
|
||||
pa_log_warn("Invalid SDP header.");
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ char *pa_sdp_build(int af, const void *src, const void *dst, const char *name, u
|
|||
pa_assert_se(inet_ntop(af, dst, buf_dst, sizeof(buf_dst)));
|
||||
|
||||
return pa_sprintf_malloc(
|
||||
PA_SDP_HEADER
|
||||
PA_SDP_HEADER "\n"
|
||||
"o=%s %lu 0 IN %s %s\n"
|
||||
"s=%s\n"
|
||||
"c=IN %s %s\n"
|
||||
|
|
@ -129,18 +129,31 @@ pa_sdp_info *pa_sdp_parse(const char *t, pa_sdp_info *i, int is_goodbye) {
|
|||
i->origin = i->session_name = NULL;
|
||||
i->salen = 0;
|
||||
i->payload = 255;
|
||||
i->enable_opus = false;
|
||||
|
||||
if (!pa_startswith(t, PA_SDP_HEADER)) {
|
||||
if (pa_startswith(t, PA_SDP_HEADER)) {
|
||||
t += sizeof(PA_SDP_HEADER) - 1;
|
||||
|
||||
/* CR delimiter is optional */
|
||||
if (*t == '\r')
|
||||
t++;
|
||||
|
||||
/* LF delimiter is mandatory */
|
||||
if (*t == '\n')
|
||||
t++;
|
||||
else {
|
||||
pa_log("Failed to parse SDP data: missing header record terminator LF.");
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
pa_log("Failed to parse SDP data: invalid header.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
t += sizeof(PA_SDP_HEADER)-1;
|
||||
|
||||
while (*t) {
|
||||
size_t l;
|
||||
|
||||
l = strcspn(t, "\n");
|
||||
l = strcspn(t, "\r\n");
|
||||
|
||||
if (l <= 2) {
|
||||
pa_log("Failed to parse SDP data: line too short: >%s<.", t);
|
||||
|
|
@ -240,8 +253,17 @@ pa_sdp_info *pa_sdp_parse(const char *t, pa_sdp_info *i, int is_goodbye) {
|
|||
|
||||
t += l;
|
||||
|
||||
/* CR delimiter is optional */
|
||||
if (*t == '\r')
|
||||
t++;
|
||||
|
||||
/* LF delimiter is mandatory */
|
||||
if (*t == '\n')
|
||||
t++;
|
||||
else {
|
||||
pa_log("Failed to parse SDP data: missing record terminator LF.");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (!i->origin || (!is_goodbye && (!i->salen || i->payload > 127 || !ss_valid || port == 0))) {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#include <pulse/sample.h>
|
||||
|
||||
#define PA_SDP_HEADER "v=0\n"
|
||||
#define PA_SDP_HEADER "v=0"
|
||||
|
||||
typedef struct pa_sdp_info {
|
||||
char *origin;
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ char *pa_get_host_name(char *s, size_t l) {
|
|||
|
||||
char *pa_get_home_dir(char *s, size_t l) {
|
||||
char *e;
|
||||
char *dir;
|
||||
char *dir = NULL;
|
||||
#ifdef HAVE_PWD_H
|
||||
struct passwd *r;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1016,20 +1016,29 @@ size_t pa_sink_process_input_underruns(pa_sink *s, size_t left_to_play) {
|
|||
if (i->origin_sink) {
|
||||
size_t filter_result, left_to_play_origin;
|
||||
|
||||
/* The recursive call works in the origin sink domain ... */
|
||||
left_to_play_origin = pa_convert_size(left_to_play, &i->sink->sample_spec, &i->origin_sink->sample_spec);
|
||||
/* The combine sink sets i->origin sink but has a different threading model
|
||||
* than the filter sinks. Therefore the recursion below may not be executed
|
||||
* because pa_sink_process_input_underruns() was not called in the thread
|
||||
* context of the origin sink.
|
||||
* FIXME: It is unclear if some other kind of recursion would be necessary
|
||||
* for the combine sink. */
|
||||
if (!i->module || !pa_safe_streq(i->module->name, "module-combine-sink")) {
|
||||
|
||||
/* .. and returns the time to sleep before waking up. We need the
|
||||
* underrun duration for comparisons, so we undo the subtraction on
|
||||
* the return value... */
|
||||
filter_result = left_to_play_origin - pa_sink_process_input_underruns(i->origin_sink, left_to_play_origin);
|
||||
/* The recursive call works in the origin sink domain ... */
|
||||
left_to_play_origin = pa_convert_size(left_to_play, &i->sink->sample_spec, &i->origin_sink->sample_spec);
|
||||
|
||||
/* ... and convert it back to the master sink domain */
|
||||
filter_result = pa_convert_size(filter_result, &i->origin_sink->sample_spec, &i->sink->sample_spec);
|
||||
/* .. and returns the time to sleep before waking up. We need the
|
||||
* underrun duration for comparisons, so we undo the subtraction on
|
||||
* the return value... */
|
||||
filter_result = left_to_play_origin - pa_sink_process_input_underruns(i->origin_sink, left_to_play_origin);
|
||||
|
||||
/* Remember the longest underrun so far */
|
||||
if (filter_result > result)
|
||||
result = filter_result;
|
||||
/* ... and convert it back to the master sink domain */
|
||||
filter_result = pa_convert_size(filter_result, &i->origin_sink->sample_spec, &i->sink->sample_spec);
|
||||
|
||||
/* Remember the longest underrun so far */
|
||||
if (filter_result > result)
|
||||
result = filter_result;
|
||||
}
|
||||
}
|
||||
|
||||
if (uf == 0) {
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk
|
|||
|
||||
tchunk.length = (size_t) n * fs;
|
||||
|
||||
pa_memblockq_push(u->memblockq, &tchunk);
|
||||
pa_memblockq_push_align(u->memblockq, &tchunk);
|
||||
pa_memblock_unref(tchunk.memblock);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -295,7 +295,7 @@ pa_usec_t pa_smoother_2_get(pa_smoother_2 *s, pa_usec_t time_stamp) {
|
|||
|
||||
/* If the smoother has not started, just return system time since resume */
|
||||
if (!s->start_time) {
|
||||
if (time_stamp >= s->resume_time)
|
||||
if (time_stamp >= s->resume_time && !s->paused)
|
||||
current_time = time_stamp - s->resume_time;
|
||||
else
|
||||
current_time = 0;
|
||||
|
|
@ -307,7 +307,8 @@ pa_usec_t pa_smoother_2_get(pa_smoother_2 *s, pa_usec_t time_stamp) {
|
|||
/* If we are initializing, add the time since resume to the card time at pause_time */
|
||||
else if (s->init) {
|
||||
current_time += (s->pause_time - s->start_time - s->time_offset - s->fixup_time) * s->time_factor;
|
||||
current_time += (time_stamp - s->resume_time) * s->time_factor;
|
||||
if (time_stamp > s->resume_time)
|
||||
current_time += (time_stamp - s->resume_time) * s->time_factor;
|
||||
|
||||
/* Smoother is running, calculate current sound card time */
|
||||
} else
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ static void run_volume_test(
|
|||
int channels,
|
||||
bool correct,
|
||||
bool perf) {
|
||||
fail_unless(align % channels == 0);
|
||||
|
||||
PA_DECLARE_ALIGNED(8, int16_t, s[SAMPLES]) = { 0 };
|
||||
PA_DECLARE_ALIGNED(8, int16_t, s_ref[SAMPLES]) = { 0 };
|
||||
|
|
@ -56,8 +57,6 @@ static void run_volume_test(
|
|||
samples_ref = s_ref + (8 - align);
|
||||
samples_orig = s_orig + (8 - align);
|
||||
nsamples = SAMPLES - (8 - align);
|
||||
if (nsamples % channels)
|
||||
nsamples -= nsamples % channels;
|
||||
size = nsamples * sizeof(int16_t);
|
||||
|
||||
pa_random(samples, size);
|
||||
|
|
@ -119,12 +118,12 @@ START_TEST (svolume_mmx_test) {
|
|||
|
||||
pa_log_debug("Checking MMX svolume");
|
||||
for (i = 1; i <= 3; i++) {
|
||||
for (j = 0; j < 7; j++)
|
||||
run_volume_test(mmx_func, orig_func, j, i, true, false);
|
||||
for (j = 0; j <= 7; j += i)
|
||||
run_volume_test(mmx_func, orig_func, j, i, true, j == 0);
|
||||
}
|
||||
run_volume_test(mmx_func, orig_func, 7, 1, true, true);
|
||||
run_volume_test(mmx_func, orig_func, 7, 2, true, true);
|
||||
run_volume_test(mmx_func, orig_func, 7, 3, true, true);
|
||||
run_volume_test(mmx_func, orig_func, 6, 2, true, true);
|
||||
run_volume_test(mmx_func, orig_func, 6, 3, true, true);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
|
@ -146,12 +145,12 @@ START_TEST (svolume_sse_test) {
|
|||
|
||||
pa_log_debug("Checking SSE2 svolume");
|
||||
for (i = 1; i <= 3; i++) {
|
||||
for (j = 0; j < 7; j++)
|
||||
run_volume_test(sse_func, orig_func, j, i, true, false);
|
||||
for (j = 0; j < 7; j += i)
|
||||
run_volume_test(sse_func, orig_func, j, i, true, j == 0);
|
||||
}
|
||||
run_volume_test(sse_func, orig_func, 7, 1, true, true);
|
||||
run_volume_test(sse_func, orig_func, 7, 2, true, true);
|
||||
run_volume_test(sse_func, orig_func, 7, 3, true, true);
|
||||
run_volume_test(sse_func, orig_func, 6, 2, true, true);
|
||||
run_volume_test(sse_func, orig_func, 6, 3, true, true);
|
||||
}
|
||||
END_TEST
|
||||
#endif /* defined (__i386__) || defined (__amd64__) */
|
||||
|
|
@ -175,12 +174,12 @@ START_TEST (svolume_arm_test) {
|
|||
|
||||
pa_log_debug("Checking ARM svolume");
|
||||
for (i = 1; i <= 3; i++) {
|
||||
for (j = 0; j < 7; j++)
|
||||
run_volume_test(arm_func, orig_func, j, i, true, false);
|
||||
for (j = 0; j < 7; j += i)
|
||||
run_volume_test(arm_func, orig_func, j, i, true, j == 0);
|
||||
}
|
||||
run_volume_test(arm_func, orig_func, 7, 1, true, true);
|
||||
run_volume_test(arm_func, orig_func, 7, 2, true, true);
|
||||
run_volume_test(arm_func, orig_func, 7, 3, true, true);
|
||||
run_volume_test(arm_func, orig_func, 6, 2, true, true);
|
||||
run_volume_test(arm_func, orig_func, 6, 3, true, true);
|
||||
}
|
||||
END_TEST
|
||||
#endif /* defined (__arm__) && defined (__linux__) */
|
||||
|
|
@ -207,11 +206,11 @@ START_TEST (svolume_orc_test) {
|
|||
|
||||
pa_log_debug("Checking Orc svolume");
|
||||
for (i = 1; i <= 2; i++) {
|
||||
for (j = 0; j < 7; j++)
|
||||
run_volume_test(orc_func, orig_func, j, i, true, false);
|
||||
for (j = 0; j < 7; j += i)
|
||||
run_volume_test(orc_func, orig_func, j, i, true, j == 0);
|
||||
}
|
||||
run_volume_test(orc_func, orig_func, 7, 1, true, true);
|
||||
run_volume_test(orc_func, orig_func, 7, 2, true, true);
|
||||
run_volume_test(orc_func, orig_func, 6, 2, true, true);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
|
|
|||
|
|
@ -2527,16 +2527,16 @@ static int parse_volume(const char *vol_spec, pa_volume_t *vol, enum volume_flag
|
|||
vs = pa_xstrdup(vol_spec);
|
||||
|
||||
*vol_flags = (pa_startswith(vs, "+") || pa_startswith(vs, "-")) ? VOL_RELATIVE : VOL_ABSOLUTE;
|
||||
if (strchr(vs, '.'))
|
||||
*vol_flags |= VOL_LINEAR;
|
||||
if (pa_endswith(vs, "%")) {
|
||||
*vol_flags |= VOL_PERCENT;
|
||||
vs[strlen(vs)-1] = 0;
|
||||
}
|
||||
if (pa_endswith(vs, "db") || pa_endswith(vs, "dB")) {
|
||||
else if (pa_endswith(vs, "db") || pa_endswith(vs, "dB")) {
|
||||
*vol_flags |= VOL_DECIBEL;
|
||||
vs[strlen(vs)-2] = 0;
|
||||
}
|
||||
else if (strchr(vs, '.'))
|
||||
*vol_flags |= VOL_LINEAR;
|
||||
|
||||
atod_input = vs;
|
||||
|
||||
|
|
@ -2597,7 +2597,7 @@ static int parse_volumes(char *args[], unsigned n) {
|
|||
|
||||
volume.channels = n;
|
||||
for (i = 0; i < volume.channels; i++) {
|
||||
enum volume_flags flags;
|
||||
enum volume_flags flags = 0;
|
||||
|
||||
if (parse_volume(args[i], &volume.values[i], &flags) < 0)
|
||||
return -1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue