raop: Add UDP protocol handling

There are two versions in the RAOP protocol; one uses TCP and the
other uses UDP. Current raop implementation only supports TCP
version.

This patch adds an initial UDP protocol support for RAOP.
It is based on Martin Blanchard's work
(http://repo.or.cz/w/pulseaudio-raopUDP.git/shortlog/refs/heads/raop)
which is inspired by Christophe Fergeau's work
(https://github.com/zx2c4/pulseaudio-raop2).

Matrin's modifications were edited by Hajime Fujita, so that it
would support both TCP and UDP protocol in a single module.

Also this patch includes a fix that was found thanks to Matthias,
who reported that his ALAC
codec support fixed the issue.
https://bugs.freedesktop.org/show_bug.cgi?id=42804#c30
This commit is contained in:
Hajime Fujita 2016-11-06 12:53:58 -06:00 committed by Tanu Kaskinen
parent 43bf134aa1
commit 1e51282621
3 changed files with 1400 additions and 159 deletions

View file

@ -20,23 +20,52 @@
along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
***/
#include <pulse/volume.h>
#include <pulsecore/core.h>
#include <pulsecore/memchunk.h>
typedef enum pa_raop_protocol {
RAOP_TCP,
RAOP_UDP,
} pa_raop_protocol_t;
typedef struct pa_raop_client pa_raop_client;
pa_raop_client* pa_raop_client_new(pa_core *core, const char *host);
pa_raop_client* pa_raop_client_new(pa_core *core, const char *host, pa_raop_protocol_t protocol);
void pa_raop_client_free(pa_raop_client *c);
int pa_raop_connect(pa_raop_client *c);
int pa_raop_flush(pa_raop_client *c);
int pa_raop_client_connect(pa_raop_client *c);
int pa_raop_client_flush(pa_raop_client *c);
int pa_raop_client_teardown(pa_raop_client *c);
int pa_raop_client_udp_can_stream(pa_raop_client *c);
void pa_raop_client_set_encryption(pa_raop_client *c, int encryption);
pa_volume_t pa_raop_client_adjust_volume(pa_raop_client *c, pa_volume_t volume);
int pa_raop_client_set_volume(pa_raop_client *c, pa_volume_t volume);
int pa_raop_client_encode_sample(pa_raop_client *c, pa_memchunk *raw, pa_memchunk *encoded);
int pa_raop_client_udp_handle_timing_packet(pa_raop_client *c, const uint8_t packet
[], ssize_t size);
int pa_raop_client_udp_handle_control_packet(pa_raop_client *c, const uint8_t packet[], ssize_t size);
int pa_raop_client_udp_get_blocks_size(pa_raop_client *c, size_t *size);
ssize_t pa_raop_client_udp_send_audio_packet(pa_raop_client *c, pa_memchunk *block);
typedef void (*pa_raop_client_cb_t)(int fd, void *userdata);
void pa_raop_client_set_callback(pa_raop_client *c, pa_raop_client_cb_t callback, void *userdata);
void pa_raop_client_tcp_set_callback(pa_raop_client *c, pa_raop_client_cb_t callback, void *userdata);
typedef void (*pa_raop_client_closed_cb_t)(void *userdata);
void pa_raop_client_set_closed_callback(pa_raop_client *c, pa_raop_client_closed_cb_t callback, void *userdata);
void pa_raop_client_tcp_set_closed_callback(pa_raop_client *c, pa_raop_client_closed_cb_t callback, void *userdata);
typedef void (*pa_raop_client_setup_cb_t)(int control_fd, int timing_fd, void *userdata);
void pa_raop_client_udp_set_setup_callback(pa_raop_client *c, pa_raop_client_setup_cb_t callback, void *userdata);
typedef void (*pa_raop_client_record_cb_t)(void *userdata);
void pa_raop_client_udp_set_record_callback(pa_raop_client *c, pa_raop_client_record_cb_t callback, void *userdata);
typedef void (*pa_raop_client_disconnected_cb_t)(void *userdata);
void pa_raop_client_udp_set_disconnected_callback(pa_raop_client *c, pa_raop_client_disconnected_cb_t callback, void *userdata);
#endif