X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2Fraop_rtp.c;h=f89538e5667dcc753066cc85f46bafb5e6923700;hb=8e3bf4087b37377e27c07c47ec4dc9c539050d96;hp=3c7c17745bfd551726bdff1d2688a45273349654;hpb=e66980f2bba24986245c30f481ceee6d977d65b9;p=deb_shairplay.git diff --git a/src/lib/raop_rtp.c b/src/lib/raop_rtp.c index 3c7c177..f89538e 100644 --- a/src/lib/raop_rtp.c +++ b/src/lib/raop_rtp.c @@ -39,13 +39,22 @@ struct raop_rtp_s { struct sockaddr_storage remote_saddr; socklen_t remote_saddr_len; + /* MUTEX LOCKED VARIABLES START */ /* These variables only edited mutex locked */ int running; int joined; + float volume; + int volume_changed; + unsigned char *metadata; + int metadata_len; + unsigned char *coverart; + int coverart_len; + int flush; thread_handle_t thread; mutex_handle_t run_mutex; + /* MUTEX LOCKED VARIABLES END */ /* Remote control and timing ports */ unsigned short control_rport; @@ -153,6 +162,8 @@ raop_rtp_destroy(raop_rtp_t *raop_rtp) MUTEX_DESTROY(raop_rtp->run_mutex); raop_buffer_destroy(raop_rtp->buffer); + free(raop_rtp->metadata); + free(raop_rtp->coverart); free(raop_rtp); } } @@ -235,6 +246,78 @@ raop_rtp_resend_callback(void *opaque, unsigned short seqnum, unsigned short cou return 0; } +static int +raop_rtp_process_events(raop_rtp_t *raop_rtp, void *cb_data) +{ + int flush; + float volume; + int volume_changed; + unsigned char *metadata; + int metadata_len; + unsigned char *coverart; + int coverart_len; + + assert(raop_rtp); + + MUTEX_LOCK(raop_rtp->run_mutex); + if (!raop_rtp->running) { + MUTEX_UNLOCK(raop_rtp->run_mutex); + return 1; + } + + /* Read the volume level */ + volume = raop_rtp->volume; + volume_changed = raop_rtp->volume_changed; + raop_rtp->volume_changed = 0; + + /* Read the flush value */ + flush = raop_rtp->flush; + raop_rtp->flush = NO_FLUSH; + + /* Read the metadata */ + metadata = raop_rtp->metadata; + metadata_len = raop_rtp->metadata_len; + raop_rtp->metadata = NULL; + raop_rtp->metadata_len = 0; + + /* Read the coverart */ + coverart = raop_rtp->coverart; + coverart_len = raop_rtp->coverart_len; + raop_rtp->coverart = NULL; + raop_rtp->coverart_len = 0; + MUTEX_UNLOCK(raop_rtp->run_mutex); + + /* Call set_volume callback if changed */ + if (volume_changed) { + if (raop_rtp->callbacks.audio_set_volume) { + raop_rtp->callbacks.audio_set_volume(raop_rtp->callbacks.cls, cb_data, volume); + } + } + + /* Handle flush if requested */ + if (flush != NO_FLUSH) { + raop_buffer_flush(raop_rtp->buffer, flush); + if (raop_rtp->callbacks.audio_flush) { + raop_rtp->callbacks.audio_flush(raop_rtp->callbacks.cls, cb_data); + } + } + if (metadata != NULL) { + if (raop_rtp->callbacks.audio_set_metadata) { + raop_rtp->callbacks.audio_set_metadata(raop_rtp->callbacks.cls, cb_data, metadata, metadata_len); + } + free(metadata); + metadata = NULL; + } + if (coverart != NULL) { + if (raop_rtp->callbacks.audio_set_coverart) { + raop_rtp->callbacks.audio_set_coverart(raop_rtp->callbacks.cls, cb_data, coverart, coverart_len); + } + free(coverart); + coverart = NULL; + } + return 0; +} + static THREAD_RETVAL raop_rtp_thread_udp(void *arg) { @@ -243,7 +326,6 @@ raop_rtp_thread_udp(void *arg) unsigned int packetlen; struct sockaddr_storage saddr; socklen_t saddrlen; - float volume = 0.0; const ALACSpecificConfig *config; void *cb_data = NULL; @@ -257,35 +339,14 @@ raop_rtp_thread_udp(void *arg) config->sampleRate); while(1) { - int volume_changed; - int flush; - fd_set rfds; struct timeval tv; int nfds, ret; - MUTEX_LOCK(raop_rtp->run_mutex); - if (!raop_rtp->running) { - MUTEX_UNLOCK(raop_rtp->run_mutex); + /* Check if we are still running and process callbacks */ + if (raop_rtp_process_events(raop_rtp, cb_data)) { break; } - /* Read the volume level */ - volume_changed = (volume != raop_rtp->volume); - volume = raop_rtp->volume; - - /* Read the flush value */ - flush = raop_rtp->flush; - raop_rtp->flush = NO_FLUSH; - MUTEX_UNLOCK(raop_rtp->run_mutex); - - /* Call set_volume callback if changed */ - if (volume_changed) { - raop_rtp->callbacks.audio_set_volume(raop_rtp->callbacks.cls, cb_data, volume); - } - if (flush != NO_FLUSH) { - raop_buffer_flush(raop_rtp->buffer, flush); - raop_rtp->callbacks.audio_flush(raop_rtp->callbacks.cls, cb_data); - } /* Set timeout value to 5ms */ tv.tv_sec = 0; @@ -372,7 +433,6 @@ raop_rtp_thread_tcp(void *arg) int stream_fd = -1; unsigned char packet[RAOP_PACKET_LEN]; unsigned int packetlen = 0; - float volume = 0.0; const ALACSpecificConfig *config; void *cb_data = NULL; @@ -386,25 +446,14 @@ raop_rtp_thread_tcp(void *arg) config->sampleRate); while (1) { - int volume_changed; - fd_set rfds; struct timeval tv; int nfds, ret; - MUTEX_LOCK(raop_rtp->run_mutex); - if (!raop_rtp->running) { - MUTEX_UNLOCK(raop_rtp->run_mutex); + /* Check if we are still running and process callbacks */ + if (raop_rtp_process_events(raop_rtp, cb_data)) { break; } - volume_changed = (volume != raop_rtp->volume); - volume = raop_rtp->volume; - MUTEX_UNLOCK(raop_rtp->run_mutex); - - /* Call set_volume callback if changed */ - if (volume_changed) { - raop_rtp->callbacks.audio_set_volume(raop_rtp->callbacks.cls, cb_data, volume); - } /* Set timeout value to 5ms */ tv.tv_sec = 0; @@ -557,6 +606,49 @@ raop_rtp_set_volume(raop_rtp_t *raop_rtp, float volume) /* Set volume in thread instead */ MUTEX_LOCK(raop_rtp->run_mutex); raop_rtp->volume = volume; + raop_rtp->volume_changed = 1; + MUTEX_UNLOCK(raop_rtp->run_mutex); +} + +void +raop_rtp_set_metadata(raop_rtp_t *raop_rtp, const char *data, int datalen) +{ + unsigned char *metadata; + + assert(raop_rtp); + + if (datalen <= 0) { + return; + } + metadata = malloc(datalen); + assert(metadata); + memcpy(metadata, data, datalen); + + /* Set metadata in thread instead */ + MUTEX_LOCK(raop_rtp->run_mutex); + raop_rtp->metadata = metadata; + raop_rtp->metadata_len = datalen; + MUTEX_UNLOCK(raop_rtp->run_mutex); +} + +void +raop_rtp_set_coverart(raop_rtp_t *raop_rtp, const char *data, int datalen) +{ + unsigned char *coverart; + + assert(raop_rtp); + + if (datalen <= 0) { + return; + } + coverart = malloc(datalen); + assert(coverart); + memcpy(coverart, data, datalen); + + /* Set coverart in thread instead */ + MUTEX_LOCK(raop_rtp->run_mutex); + raop_rtp->coverart = coverart; + raop_rtp->coverart_len = datalen; MUTEX_UNLOCK(raop_rtp->run_mutex); }