sound: dynamically construct streams/chmaps based on --streams flag
Also fixes existing bug where chmaps count was hard-coded to 1 despite 2 chmap entries being created. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8050df66f0
commit
500a78cd68
1 changed files with 75 additions and 22 deletions
|
|
@ -493,39 +493,50 @@ pub struct VhostUserSoundBackend {
|
|||
|
||||
impl VhostUserSoundBackend {
|
||||
pub fn new(config: SoundConfig) -> Result<Self> {
|
||||
let streams = vec![
|
||||
Stream {
|
||||
id: 0,
|
||||
direction: Direction::Output,
|
||||
..Stream::default()
|
||||
},
|
||||
Stream {
|
||||
id: 1,
|
||||
direction: Direction::Input,
|
||||
..Stream::default()
|
||||
},
|
||||
];
|
||||
let streams_no = streams.len();
|
||||
let streams = Arc::new(RwLock::new(streams));
|
||||
let jacks: Arc<RwLock<Vec<VirtioSoundJackInfo>>> = Arc::new(RwLock::new(Vec::new()));
|
||||
let mut streams = Vec::new();
|
||||
let mut chmaps_info: Vec<VirtioSoundChmapInfo> = Vec::new();
|
||||
|
||||
let mut positions = [VIRTIO_SND_CHMAP_NONE; VIRTIO_SND_CHMAP_MAX_SIZE];
|
||||
positions[0] = VIRTIO_SND_CHMAP_FL;
|
||||
positions[1] = VIRTIO_SND_CHMAP_FR;
|
||||
let chmaps_info: Vec<VirtioSoundChmapInfo> = vec![
|
||||
VirtioSoundChmapInfo {
|
||||
|
||||
if config.has_output() {
|
||||
streams.push(Stream {
|
||||
id: streams.len(),
|
||||
direction: Direction::Output,
|
||||
..Stream::default()
|
||||
});
|
||||
chmaps_info.push(VirtioSoundChmapInfo {
|
||||
direction: VIRTIO_SND_D_OUTPUT,
|
||||
channels: 2,
|
||||
positions,
|
||||
..VirtioSoundChmapInfo::default()
|
||||
},
|
||||
VirtioSoundChmapInfo {
|
||||
});
|
||||
}
|
||||
|
||||
if config.has_input() {
|
||||
streams.push(Stream {
|
||||
id: streams.len(),
|
||||
direction: Direction::Input,
|
||||
..Stream::default()
|
||||
});
|
||||
chmaps_info.push(VirtioSoundChmapInfo {
|
||||
direction: VIRTIO_SND_D_INPUT,
|
||||
channels: 2,
|
||||
positions,
|
||||
..VirtioSoundChmapInfo::default()
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
let chmaps_no = chmaps_info.len();
|
||||
let streams_no = streams.len();
|
||||
let streams = Arc::new(RwLock::new(streams));
|
||||
let jacks: Arc<RwLock<Vec<VirtioSoundJackInfo>>> = Arc::new(RwLock::new(Vec::new()));
|
||||
let chmaps: Arc<RwLock<Vec<VirtioSoundChmapInfo>>> = Arc::new(RwLock::new(chmaps_info));
|
||||
|
||||
if streams_no == 0 {
|
||||
return Err(Error::UnexpectedAudioBackendConfiguration);
|
||||
}
|
||||
log::trace!("VhostUserSoundBackend::new(config = {:?})", &config);
|
||||
let threads = if config.multi_thread {
|
||||
vec![
|
||||
|
|
@ -576,7 +587,7 @@ impl VhostUserSoundBackend {
|
|||
virtio_cfg: VirtioSoundConfig {
|
||||
jacks: 0.into(),
|
||||
streams: Le32::from(streams_no as u32),
|
||||
chmaps: 1.into(),
|
||||
chmaps: Le32::from(chmaps_no as u32),
|
||||
controls: 0.into(),
|
||||
},
|
||||
exit_consumer,
|
||||
|
|
@ -1066,4 +1077,46 @@ mod tests {
|
|||
|
||||
test_dir.close().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sound_backend_output_only() {
|
||||
crate::init_logger();
|
||||
let config = SoundConfig::new(false, BackendType::Null, true, false);
|
||||
let backend = VhostUserSoundBackend::new(config).expect("Could not create backend.");
|
||||
|
||||
// VirtioSoundConfig: jacks(4) + streams(4) + chmaps(4) + controls(4) = 16 bytes
|
||||
let cfg = backend.get_config(0, 16);
|
||||
assert_eq!(cfg.len(), 16);
|
||||
// streams is at offset 4, little-endian u32
|
||||
let streams = u32::from_le_bytes([cfg[4], cfg[5], cfg[6], cfg[7]]);
|
||||
let chmaps = u32::from_le_bytes([cfg[8], cfg[9], cfg[10], cfg[11]]);
|
||||
assert_eq!(streams, 1);
|
||||
assert_eq!(chmaps, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sound_backend_input_only() {
|
||||
crate::init_logger();
|
||||
let config = SoundConfig::new(false, BackendType::Null, false, true);
|
||||
let backend = VhostUserSoundBackend::new(config).expect("Could not create backend.");
|
||||
|
||||
let cfg = backend.get_config(0, 16);
|
||||
let streams = u32::from_le_bytes([cfg[4], cfg[5], cfg[6], cfg[7]]);
|
||||
let chmaps = u32::from_le_bytes([cfg[8], cfg[9], cfg[10], cfg[11]]);
|
||||
assert_eq!(streams, 1);
|
||||
assert_eq!(chmaps, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sound_backend_both_streams() {
|
||||
crate::init_logger();
|
||||
let config = SoundConfig::new(false, BackendType::Null, true, true);
|
||||
let backend = VhostUserSoundBackend::new(config).expect("Could not create backend.");
|
||||
|
||||
let cfg = backend.get_config(0, 16);
|
||||
let streams = u32::from_le_bytes([cfg[4], cfg[5], cfg[6], cfg[7]]);
|
||||
let chmaps = u32::from_le_bytes([cfg[8], cfg[9], cfg[10], cfg[11]]);
|
||||
assert_eq!(streams, 2);
|
||||
assert_eq!(chmaps, 2); // Also verifies the chmaps bug fix (was hard-coded to 1)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue