static void play(short buf[], int samples) {
int ret = 0;
if (alsa_handle == NULL) {
+ pthread_mutex_lock(&alsa_mutex);
ret = open_alsa_device();
open_mixer();
+ pthread_mutex_unlock(&alsa_mutex);
if ((ret == 0) && (audio_alsa.volume))
audio_alsa.volume(set_volume);
}
}
static void flush(void) {
+ pthread_mutex_lock(&alsa_mutex);
int derr;
if (alsa_mix_handle) {
snd_mixer_close(alsa_mix_handle);
snd_pcm_close(alsa_handle);
alsa_handle = NULL;
}
+ pthread_mutex_unlock(&alsa_mutex);
}
static void stop(void) {
}
static void volume(double vol) {
- debug(2, "Setting volume db to %f.", vol);
+ pthread_mutex_lock(&alsa_mutex);
+ debug(2, "Setting volume db to %f.", vol);
set_volume = vol;
if (alsa_mix_handle) {
if (snd_mixer_selem_set_playback_dB_all(alsa_mix_elem, vol, 0) != 0) {
die("Failed to set playback dB volume");
}
}
+ pthread_mutex_unlock(&alsa_mutex);
}
static void linear_volume(double vol) {
} stats_t;
static void *player_thread_func(void *arg) {
- int threads_stop = 0;
+ struct inter_threads_record itr;
+ itr.please_stop = 0;
// create and start the timing, control and audio receiver threads
pthread_t rtp_audio_thread, rtp_control_thread, rtp_timing_thread;
- pthread_create(&rtp_audio_thread, NULL, &rtp_audio_receiver, (void *)&threads_stop);
- pthread_create(&rtp_control_thread, NULL, &rtp_control_receiver, (void *)&threads_stop);
- pthread_create(&rtp_timing_thread, NULL, &rtp_timing_receiver, (void *)&threads_stop);
+ pthread_create(&rtp_audio_thread, NULL, &rtp_audio_receiver, (void *)&itr);
+ pthread_create(&rtp_control_thread, NULL, &rtp_control_receiver, (void *)&itr);
+ pthread_create(&rtp_timing_thread, NULL, &rtp_timing_receiver, (void *)&itr);
session_corrections = 0;
play_segment_reference_frame = 0; // zero signals that we are not in a play segment
}
if (config.output->stop)
config.output->stop();
+ usleep(100000); // allow this time to (?) allow the alsa subsystem to finish cleaning up after itself. 50 ms seems too short
free(outbuf);
free(silence);
debug(1,"Shut down audio, control and timing threads");
- // usleep(1000000);
- threads_stop = 1;
+ itr.please_stop = 1;
pthread_kill(rtp_audio_thread, SIGUSR1);
pthread_kill(rtp_control_thread, SIGUSR1);
pthread_kill(rtp_timing_thread, SIGUSR1);
rtp_shutdown();
pthread_mutex_unlock(&play_lock);
pthread_mutex_unlock(&playing_mutex);
- } else {
- debug(1, "This RTSP conversation thread doesn't think it's playing for a "
- "close RTSP connection.");
- }
+ } // else {
+ //debug(1, "This RTSP conversation thread doesn't think it's playing for a "
+ // "close RTSP connection.");
+ // }
if (auth_nonce)
free(auth_nonce);
conn->running = 0;