mirror of https://github.com/jetkvm/kvm.git
Fix silent failures and improve documentation
- Remove silent fallback to ALSA 'default' device on playback init failure - Return error from SetAudioOutputSource for invalid source values - Fix misleading comment about mutex scope in C audio code - Clarify inputSourceMutex purpose for WebRTC packet serialization
This commit is contained in:
parent
5f7c90649a
commit
4001ef651f
4
audio.go
4
audio.go
|
|
@ -14,7 +14,7 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
audioMutex sync.Mutex
|
audioMutex sync.Mutex
|
||||||
inputSourceMutex sync.Mutex // Serializes Connect() and WriteMessage() calls to input source
|
inputSourceMutex sync.Mutex // Prevents concurrent WebRTC packets from racing during lazy connect + write
|
||||||
outputSource atomic.Pointer[audio.AudioSource]
|
outputSource atomic.Pointer[audio.AudioSource]
|
||||||
inputSource atomic.Pointer[audio.AudioSource]
|
inputSource atomic.Pointer[audio.AudioSource]
|
||||||
outputRelay atomic.Pointer[audio.OutputRelay]
|
outputRelay atomic.Pointer[audio.OutputRelay]
|
||||||
|
|
@ -302,7 +302,7 @@ func SetAudioInputEnabled(enabled bool) error {
|
||||||
// TC358743 hardware characteristics. Callers receive success before audio actually switches.
|
// TC358743 hardware characteristics. Callers receive success before audio actually switches.
|
||||||
func SetAudioOutputSource(source string) error {
|
func SetAudioOutputSource(source string) error {
|
||||||
if source != "hdmi" && source != "usb" {
|
if source != "hdmi" && source != "usb" {
|
||||||
return nil
|
return fmt.Errorf("invalid audio source: %s (must be 'hdmi' or 'usb')", source)
|
||||||
}
|
}
|
||||||
|
|
||||||
ensureConfigLoaded()
|
ensureConfigLoaded()
|
||||||
|
|
|
||||||
|
|
@ -75,12 +75,11 @@ static uint32_t max_backoff_us_global = 500000;
|
||||||
static atomic_int capture_stop_requested = 0;
|
static atomic_int capture_stop_requested = 0;
|
||||||
static atomic_int playback_stop_requested = 0;
|
static atomic_int playback_stop_requested = 0;
|
||||||
|
|
||||||
// Mutexes to protect concurrent access to ALSA handles during close
|
// Mutexes to protect concurrent access to ALSA handles and codecs
|
||||||
// These prevent race conditions when jetkvm_audio_*_close() is called while
|
// These prevent race conditions when jetkvm_audio_*_close() is called while
|
||||||
// jetkvm_audio_read_encode() or jetkvm_audio_decode_write() are executing.
|
// jetkvm_audio_read_encode() or jetkvm_audio_decode_write() are executing.
|
||||||
// The hot path functions acquire these mutexes briefly to validate handle
|
// The mutexes are held during ALSA I/O and codec operations to ensure
|
||||||
// pointers, then release before slow ALSA/Opus operations to avoid holding
|
// handles remain valid throughout the operation.
|
||||||
// locks during I/O. Handle comparison checks detect races after operations.
|
|
||||||
static pthread_mutex_t capture_mutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t capture_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static pthread_mutex_t playback_mutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t playback_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
|
@ -606,7 +605,7 @@ retry_read:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize INPUT path (Opus decoder → device speakers)
|
* Initialize INPUT path (Opus decoder → device speakers)
|
||||||
* Opens ALSA playback device from ALSA_PLAYBACK_DEVICE env (default: hw:1,0), falls back to "default" on error
|
* Opens ALSA playback device from ALSA_PLAYBACK_DEVICE env (default: hw:1,0)
|
||||||
* and creates Opus decoder
|
* and creates Opus decoder
|
||||||
* @return 0 on success, -EBUSY if initializing, -1/-2 on errors
|
* @return 0 on success, -EBUSY if initializing, -1/-2 on errors
|
||||||
*/
|
*/
|
||||||
|
|
@ -652,13 +651,10 @@ int jetkvm_audio_playback_init() {
|
||||||
fprintf(stderr, "Failed to open ALSA playback device %s: %s\n",
|
fprintf(stderr, "Failed to open ALSA playback device %s: %s\n",
|
||||||
alsa_playback_device, snd_strerror(err));
|
alsa_playback_device, snd_strerror(err));
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
err = safe_alsa_open(&pcm_playback_handle, "default", SND_PCM_STREAM_PLAYBACK);
|
|
||||||
if (err < 0) {
|
|
||||||
atomic_store(&playback_stop_requested, 0);
|
atomic_store(&playback_stop_requested, 0);
|
||||||
playback_initializing = 0;
|
playback_initializing = 0;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int actual_rate = 0;
|
unsigned int actual_rate = 0;
|
||||||
uint16_t actual_frame_size = 0;
|
uint16_t actual_frame_size = 0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue