mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
module-rtp-sink: Send all remaining packets when stopping
Don't close rtp_fd until all packets have been sent by the timer, if the timer is running when the stream is stopped.
This commit is contained in:
parent
4cea8eb01f
commit
64d75b6b2e
2 changed files with 36 additions and 7 deletions
|
|
@ -224,9 +224,15 @@ static void rtp_audio_flush_packets(struct impl *impl, uint32_t num_packets)
|
|||
avail = spa_ringbuffer_get_read_index(&impl->ring, ×tamp);
|
||||
tosend = impl->psamples;
|
||||
if (avail < tosend)
|
||||
goto done;
|
||||
|
||||
num_packets = SPA_MIN(num_packets, (uint32_t)(avail / tosend));
|
||||
if (impl->started)
|
||||
goto done;
|
||||
else {
|
||||
/* send last packet before emitting state_changed */
|
||||
tosend = avail;
|
||||
num_packets = 1;
|
||||
}
|
||||
else
|
||||
num_packets = SPA_MIN(num_packets, (uint32_t)(avail / tosend));
|
||||
|
||||
stride = impl->stride;
|
||||
|
||||
|
|
@ -264,8 +270,19 @@ static void rtp_audio_flush_packets(struct impl *impl, uint32_t num_packets)
|
|||
}
|
||||
spa_ringbuffer_read_update(&impl->ring, timestamp);
|
||||
done:
|
||||
if (avail < tosend && impl->timer_running)
|
||||
set_timer(impl, 0, 0);
|
||||
if (impl->timer_running) {
|
||||
if (impl->started) {
|
||||
if (avail < tosend) {
|
||||
set_timer(impl, 0, 0);
|
||||
}
|
||||
} else if (avail <= 0) {
|
||||
bool started = false;
|
||||
|
||||
/* the stream has been stopped and all packets have been sent */
|
||||
set_timer(impl, 0, 0);
|
||||
pw_loop_invoke(impl->main_loop, do_emit_state_changed, SPA_ID_INVALID, &started, sizeof started, false, impl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void rtp_audio_flush_timeout(struct impl *impl, uint64_t expirations)
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ struct impl {
|
|||
unsigned receiving:1;
|
||||
unsigned first:1;
|
||||
|
||||
struct pw_loop *main_loop;
|
||||
struct pw_loop *data_loop;
|
||||
struct spa_source *timer;
|
||||
bool timer_running;
|
||||
|
|
@ -93,6 +94,15 @@ struct impl {
|
|||
void (*flush_timeout)(struct impl *impl, uint64_t expirations);
|
||||
};
|
||||
|
||||
static int do_emit_state_changed(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data)
|
||||
{
|
||||
struct impl *impl = user_data;
|
||||
bool *started = (bool *)data;
|
||||
|
||||
rtp_stream_emit_state_changed(impl, *started, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "module-rtp/audio.c"
|
||||
#include "module-rtp/midi.c"
|
||||
#include "module-rtp/opus.c"
|
||||
|
|
@ -154,7 +164,9 @@ static int stream_stop(struct impl *impl)
|
|||
if (!impl->started)
|
||||
return 0;
|
||||
|
||||
rtp_stream_emit_state_changed(impl, false, NULL);
|
||||
/* if timer is running, the state changed event must be emitted by the timer after all packets have been sent */
|
||||
if (!impl->timer_running)
|
||||
rtp_stream_emit_state_changed(impl, false, NULL);
|
||||
|
||||
impl->started = false;
|
||||
return 0;
|
||||
|
|
@ -171,7 +183,6 @@ static void on_stream_state_changed(void *d, enum pw_stream_state old,
|
|||
break;
|
||||
case PW_STREAM_STATE_ERROR:
|
||||
pw_log_error("stream error: %s", error);
|
||||
rtp_stream_emit_state_changed(impl, false, error);
|
||||
break;
|
||||
case PW_STREAM_STATE_STREAMING:
|
||||
if ((errno = -stream_start(impl)) < 0)
|
||||
|
|
@ -309,6 +320,7 @@ struct rtp_stream *rtp_stream_new(struct pw_core *core,
|
|||
spa_hook_list_init(&impl->listener_list);
|
||||
impl->stream_events = stream_events;
|
||||
context = pw_core_get_context(core);
|
||||
impl->main_loop = pw_context_get_main_loop(context);
|
||||
data_loop = pw_context_get_data_loop(context);
|
||||
impl->data_loop = pw_data_loop_get_loop(data_loop);
|
||||
impl->timer = pw_loop_add_timer(impl->data_loop, on_flush_timeout, impl);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue