-
Notifications
You must be signed in to change notification settings - Fork 64
Implement VirtIO sound device capture #115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
jserv
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rebase to avoid unnecessary merge commits.
This comment was marked as resolved.
This comment was marked as resolved.
54a45b5 to
05b22f9
Compare
2db638a to
781ef0a
Compare
virtio-snd.c
Outdated
| static void __virtio_snd_rx_frame_enqueue(void *payload, | ||
| uint32_t n, | ||
| uint32_t stream_id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
__virtio_snd_rx_frame_enqueue() never increments buf_ev_notity or signals the condition variable, but __virtio_snd_rx_frame_dequeue() waits on it:
// In __virtio_snd_rx_frame_dequeue:
while (props->lock.buf_ev_notity < 1)
pthread_cond_wait(&props->lock.readable, ...); // BLOCKS FOREVERThe TX path correctly does:
props->lock.buf_ev_notity++;
pthread_cond_signal(&props->lock.readable);Fix: Add after list_push() in __virtio_snd_rx_frame_enqueue:
props->lock.buf_ev_notity++;
pthread_cond_signal(&props->lock.readable);There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The buf_ev_notity will be increased and then signals the update of CV after consuming all the virtq elements when calling virtio_snd_rx_desc_normal_handler():
// In VSND_GEN_RX_QUEUE_HANDLER macro
virtio_snd_prop_t *props = &vsnd_props[stream_id];
props->lock.buf_ev_notity--;
pthread_cond_signal(&props->lock.writable);The virtio_snd_tx_desc_normal_handler() also has the same design.
The reason is that the driver should populate a period size of PCM frames (except the end of stream) as mentioned by VirtIO standard:
5.14.6.8.2.2 Driver Requirements: Input Stream
- The driver SHOULD populate the rx queue with period_bytes sized empty buffers before starting the stream.
- The driver MUST NOT place device-readable buffers into the rx queue.
| static void __virtio_snd_rx_frame_dequeue(void *out, | ||
| uint32_t n, | ||
| uint32_t stream_id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
__virtio_snd_rx_frame_dequeue() does list_del(&node->q) but never free(node):
if (node->pos >= node->len)
list_del(&node->q); // Missing: free(node);
virtio-snd.c
Outdated
| memcpy(props->intermediate + idx, payload, base); | ||
| if (left != 0) | ||
| memcpy(props->intermediate, payload + base, left); | ||
| props->buf_idx = (props->buf_idx + n) % sz; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The RX circular buffer design stores node->addr = props->intermediate + idx, meaning multiple nodes can point to overlapping regions. When the buffer wraps, older data gets overwritten while nodes still reference it.
If enqueue outruns dequeue, later writes corrupt earlier node data. The TX path copies data differently (uses the queue nodes as independent buffers).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @jserv ,
Thanks for the suggestion.
Though it will take some time, I think let's stick the list of frames rather than the circular buffer design.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though it will take some time, I think let's stick the list of frames rather than the circular buffer design.
You should express with strong reasons.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @jserv ,
The circular buffer design requires no further memory allocation, whereas the list of frames design requires one memory allocation every time the device stores the content of a frame.
|
Debug Printf Pollution |
be341b2 to
1a14913
Compare
|
Can we perform loopback tests with virtio sound device? |
You mean |
The headless verification is crucial for CI/CD integration. |
1a14913 to
cc24c51
Compare
Implement VirtIO sound device capture, with adding notice that the capture usually doesn't work for the reason of 'semu' emulation part.
d0f9c5b to
fd4f538
Compare
Summary by cubic
Implements VirtIO sound capture (RX) with PortAudio input, RX virtqueue handling, and circular buffering so input audio can be delivered to the guest. Also exposes separate input/output streams with accurate device info.
Written for commit fd4f538. Summary will update automatically on new commits.