mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-21 06:59:59 -05:00
raop: Add autoreconnect feature
This patch adds the autoreconnect feature to the raop module. This is mainly to be used in a server context, but can be used also in a desktop usage context. With autoreconnect feature, the raop module behaves like this: - At initialisation or in case of the RTSP TCP connection lost, it tries to reconnect every 5 seconds - In case of any fatal error, it tries to reconnect every 5 seconds - In UDP mode, if no timing packets received anymore for a long time, RTSP connection is closed, then it tries to reconnect.. - After reconnection, once RTSP session has been established again, playing is resumed automatically. - When the connection is not established yet (or loss), the sink behaves like a null sink. In the source code I called it "autonull", even if autonull is set to autoreconnect param value, it could be split into two different params.
This commit is contained in:
parent
46dd3be8ce
commit
4854524058
6 changed files with 293 additions and 65 deletions
|
|
@ -27,6 +27,8 @@
|
|||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <pulse/rtclock.h>
|
||||
#include <pulse/timeval.h>
|
||||
|
||||
#ifdef HAVE_SYS_FILIO_H
|
||||
#include <sys/filio.h>
|
||||
|
|
@ -42,9 +44,12 @@
|
|||
#include <pulsecore/ioline.h>
|
||||
#include <pulsecore/arpa-inet.h>
|
||||
#include <pulsecore/random.h>
|
||||
#include <pulsecore/core-rtclock.h>
|
||||
|
||||
#include "rtsp_client.h"
|
||||
|
||||
#define RECONNECT_INTERVAL (5 * PA_USEC_PER_SEC)
|
||||
|
||||
struct pa_rtsp_client {
|
||||
pa_mainloop_api *mainloop;
|
||||
char *hostname;
|
||||
|
|
@ -73,9 +78,11 @@ struct pa_rtsp_client {
|
|||
uint32_t cseq;
|
||||
char *session;
|
||||
char *transport;
|
||||
pa_time_event *reconnect_event;
|
||||
bool autoreconnect;
|
||||
};
|
||||
|
||||
pa_rtsp_client* pa_rtsp_client_new(pa_mainloop_api *mainloop, const char *hostname, uint16_t port, const char *useragent) {
|
||||
pa_rtsp_client* pa_rtsp_client_new(pa_mainloop_api *mainloop, const char *hostname, uint16_t port, const char *useragent, bool autoreconnect) {
|
||||
pa_rtsp_client *c;
|
||||
|
||||
pa_assert(mainloop);
|
||||
|
|
@ -93,12 +100,23 @@ pa_rtsp_client* pa_rtsp_client_new(pa_mainloop_api *mainloop, const char *hostna
|
|||
else
|
||||
c->useragent = "PulseAudio RTSP Client";
|
||||
|
||||
c->autoreconnect = autoreconnect;
|
||||
return c;
|
||||
}
|
||||
|
||||
static void free_events(pa_rtsp_client *c) {
|
||||
pa_assert(c);
|
||||
|
||||
if (c->reconnect_event) {
|
||||
c->mainloop->time_free(c->reconnect_event);
|
||||
c->reconnect_event = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void pa_rtsp_client_free(pa_rtsp_client *c) {
|
||||
pa_assert(c);
|
||||
|
||||
free_events(c);
|
||||
if (c->sc)
|
||||
pa_socket_client_unref(c->sc);
|
||||
|
||||
|
|
@ -293,6 +311,13 @@ static void line_callback(pa_ioline *line, const char *s, void *userdata) {
|
|||
pa_xfree(s2);
|
||||
}
|
||||
|
||||
static void reconnect_cb(pa_mainloop_api *a, pa_time_event *e, const struct timeval *t, void *userdata) {
|
||||
if (userdata) {
|
||||
pa_rtsp_client *c = userdata;
|
||||
pa_rtsp_connect(c);
|
||||
}
|
||||
}
|
||||
|
||||
static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata) {
|
||||
pa_rtsp_client *c = userdata;
|
||||
union {
|
||||
|
|
@ -310,7 +335,18 @@ static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata
|
|||
c->sc = NULL;
|
||||
|
||||
if (!io) {
|
||||
pa_log("Connection failed: %s", pa_cstrerror(errno));
|
||||
if (c->autoreconnect) {
|
||||
struct timeval tv;
|
||||
|
||||
pa_log_warn("Connection to server %s:%d failed: %s - will try later", c->hostname, c->port, pa_cstrerror(errno));
|
||||
|
||||
if (!c->reconnect_event)
|
||||
c->reconnect_event = c->mainloop->time_new(c->mainloop, pa_timeval_rtstore(&tv, pa_rtclock_now() + RECONNECT_INTERVAL, true), reconnect_cb, c);
|
||||
else
|
||||
c->mainloop->time_restart(c->reconnect_event, pa_timeval_rtstore(&tv, pa_rtclock_now() + RECONNECT_INTERVAL, true));
|
||||
} else {
|
||||
pa_log("Connection to server %s:%d failed: %s", c->hostname, c->port, pa_cstrerror(errno));
|
||||
}
|
||||
return;
|
||||
}
|
||||
pa_assert(!c->ioline);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue