mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
module-rtp: Replace state_changed callbacks
The state_changed callbacks fulfill multiple roles, which is both a problem regarding separation of concerns and regarding code clarity. De facto, these callbacks cover error reporting, opening connections, and closing connection, all in one, depending on a state that is arguably an internal stream detail. The code in these callbacks tie these internal states to assumptions that opening/closing callbacks is directly tied to specific state changes in a common way, which is not always true. For example, stopping the stream may not _actually_ stop it if a background send timer is still running. The notion of a "state_changed" callback is also problematic because the pw_streams that are used in rtp-sink and rtp-source also have a callback for state changes, causing confusion. Solve this by replacing state_changed with three new callbacks: 1. report_error : Used for reporting nonrecoverable errors to the caller. Note that currently, no one does such error reporting, but the feature does exist, so this callback is introduced to preserve said feature. 2. open_connection : Used for opening a connection. Its optional return value informs about success or failure. 3. close_connection : Used for opening a connection. Its optional return value informs about success or failure. Importantly, these callbacks do not export any internal stream state. This improves encapsulation, and also makes it possible to invoke these callbacks in situations that may not neatly map to a state change. One example could be to close the connection as part of a stream_start call to close any connection(s) left over from a previous run. (Followup commits will in fact introduce such measures.)
This commit is contained in:
parent
2f22c1d595
commit
3476e77714
6 changed files with 156 additions and 78 deletions
|
|
@ -34,10 +34,17 @@ PW_LOG_TOPIC_EXTERN(mod_topic);
|
|||
#define BUFFER_SIZE2 (BUFFER_SIZE>>1)
|
||||
#define BUFFER_MASK2 (BUFFER_SIZE2-1)
|
||||
|
||||
/* IMPORTANT: When using calls that have return values, like
|
||||
* rtp_stream_emit_open_connection, callers must set the variables
|
||||
* that receive the return values to a default value, because in
|
||||
* cases where the callback is not actually set, no call is made,
|
||||
* and thus, uninitialized return variables remain uninitialized.*/
|
||||
#define rtp_stream_emit(s,m,v,...) spa_hook_list_call(&s->listener_list, \
|
||||
struct rtp_stream_events, m, v, ##__VA_ARGS__)
|
||||
#define rtp_stream_emit_destroy(s) rtp_stream_emit(s, destroy, 0)
|
||||
#define rtp_stream_emit_state_changed(s,n,e) rtp_stream_emit(s, state_changed,0,n,e)
|
||||
#define rtp_stream_emit_report_error(s,e) rtp_stream_emit(s, report_error, 0,e)
|
||||
#define rtp_stream_emit_open_connection(s,r) rtp_stream_emit(s, open_connection, 0,r)
|
||||
#define rtp_stream_emit_close_connection(s,r) rtp_stream_emit(s, close_connection, 0,r)
|
||||
#define rtp_stream_emit_param_changed(s,i,p) rtp_stream_emit(s, param_changed,0,i,p)
|
||||
#define rtp_stream_emit_send_packet(s,i,l) rtp_stream_emit(s, send_packet,0,i,l)
|
||||
#define rtp_stream_emit_send_feedback(s,seq) rtp_stream_emit(s, send_feedback,0,seq)
|
||||
|
|
@ -140,9 +147,14 @@ struct impl {
|
|||
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;
|
||||
bool started = *((bool *)data);
|
||||
|
||||
if (started) {
|
||||
rtp_stream_emit_open_connection(impl, NULL);
|
||||
} else {
|
||||
rtp_stream_emit_close_connection(impl, NULL);
|
||||
}
|
||||
|
||||
rtp_stream_emit_state_changed(impl, *started, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -191,6 +203,8 @@ static void stream_destroy(void *d)
|
|||
|
||||
static int stream_start(struct impl *impl)
|
||||
{
|
||||
int res;
|
||||
|
||||
if (impl->started)
|
||||
return 0;
|
||||
|
||||
|
|
@ -206,7 +220,14 @@ static int stream_start(struct impl *impl)
|
|||
|
||||
impl->reset_ringbuffer(impl);
|
||||
|
||||
rtp_stream_emit_state_changed(impl, true, NULL);
|
||||
res = 0;
|
||||
rtp_stream_emit_open_connection(impl, &res);
|
||||
if (res > 0) {
|
||||
pw_log_debug("opened new connection");
|
||||
} else if (res < 0) {
|
||||
pw_log_error("could not open connection: %s", spa_strerror(res));
|
||||
return res;
|
||||
}
|
||||
|
||||
if (impl->separate_sender) {
|
||||
struct spa_dict_item items[1];
|
||||
|
|
@ -230,7 +251,7 @@ static int stream_stop(struct impl *impl)
|
|||
|
||||
/* 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);
|
||||
rtp_stream_emit_close_connection(impl, NULL);
|
||||
|
||||
if (impl->separate_sender) {
|
||||
struct spa_dict_item items[1];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue