Skip to content

Commit e777617

Browse files
committed
Tear down PCM frames
1 parent a4e6553 commit e777617

File tree

1 file changed

+34
-6
lines changed

1 file changed

+34
-6
lines changed

virtio-snd.c

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ typedef struct {
234234
uint8_t positions[VIRTIO_SND_CHMAP_MAX_SIZE];
235235
} virtio_snd_chmap_info_t;
236236

237+
/* A queue to hold arbitrary number of PCM frames. */
238+
typedef struct {
239+
void *buf;
240+
struct queue_head q;
241+
} virtio_snd_pcm_frame_t;
237242
/* virtio-snd to hold the settings of each stream */
238243
typedef struct {
239244
virtio_snd_jack_info_t j;
@@ -244,7 +249,8 @@ typedef struct {
244249
bool is_guest_playing;
245250

246251
// PCM frame buffer
247-
void *buf;
252+
virtio_snd_pcm_frame_t *pcm_frames;
253+
struct queue_head pcm_frames_q;
248254
} virtio_snd_prop_t;
249255

250256
static virtio_snd_config_t vsnd_configs[VSND_DEV_CNT_MAX];
@@ -434,8 +440,6 @@ static void virtio_snd_read_pcm_prepare(const virtio_snd_pcm_hdr_t *query,
434440
vsnd_props[stream_id].audio_host =
435441
CNFAInit(NULL, "semu-virtio-snd", virtio_snd_cb, 44100, 0, 1, 0,
436442
vsnd_props[stream_id].pp.buffer_bytes, NULL, NULL, &v);
437-
size_t sz = vsnd_props[stream_id].pp.buffer_bytes;
438-
vsnd_props[stream_id].buf = malloc(sizeof(vsnd_props[stream_id].buf) * sz);
439443

440444
/* Control the callback to prepare the buffer */
441445
/* TODO: add lock to avoid race condition */
@@ -518,7 +522,6 @@ static void virtio_snd_read_pcm_release(const virtio_snd_pcm_hdr_t *query,
518522

519523
vsnd_props[stream_id].pp.hdr.hdr.code = VIRTIO_SND_R_PCM_RELEASE;
520524
CNFAClose(vsnd_props[stream_id].audio_host);
521-
free(vsnd_props[stream_id].buf);
522525

523526
*plen = 0;
524527
fprintf(stderr, "virtio_snd_read_pcm_release\n");
@@ -734,7 +737,10 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd,
734737
#endif
735738
int idx = 0;
736739
uint32_t stream_id;
737-
uintptr_t base = vsnd->ram;
740+
uintptr_t base = (uintptr_t) vsnd->ram;
741+
struct queue_head frame_q = vsnd_props[stream_id].pcm_frames_q;
742+
INIT_QUEUE_HEAD(&frame_q);
743+
virtio_snd_pcm_frame_t *frame = vsnd_props[stream_id].pcm_frames;
738744
queue_for_each_entry(node, &q, q)
739745
{
740746
uint32_t addr = node->vq_desc.addr;
@@ -746,6 +752,7 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd,
746752
(virtio_snd_pcm_xfer_t *) (base + addr);
747753
stream_id = request->stream_id;
748754
fprintf(stderr, "stream_id %" PRIu32 "\n", stream_id);
755+
goto early_continue;
749756
} else if (idx == cnt - 1) { // the last descriptor
750757
virtio_snd_pcm_status_t *response =
751758
(virtio_snd_pcm_status_t *) (base + addr);
@@ -755,12 +762,20 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd,
755762
*plen = sizeof(*response); /* TODO: set the read length of buffer of
756763
PCM frames */
757764
fprintf(stderr, "TX response\n");
765+
goto early_continue;
758766
}
759767

768+
frame = (virtio_snd_pcm_frame_t *) malloc(sizeof(*frame));
769+
void *buf = (void *) (base + addr);
770+
frame->buf = (void *) malloc(sizeof(frame->buf) * len);
771+
memcpy(frame->buf, buf, len);
772+
queue_push(&frame->q, &frame_q);
773+
774+
early_continue:
760775
idx++;
761776
}
762777

763-
/* Tear down the list and free space */
778+
/* Tear down the descriptor list and free space. */
764779
idx = 0;
765780
virtq_desc_queue_node_t *tmp = NULL;
766781
queue_for_each_entry_safe(node, tmp, &q, q)
@@ -772,6 +787,19 @@ static int virtio_snd_tx_desc_handler(virtio_snd_state_t *vsnd,
772787
assert(idx == cnt);
773788
assert(queue_empty(&q));
774789

790+
/* Tear down the PCM frames. (should use in pcm_release) */
791+
idx = 0;
792+
virtio_snd_pcm_frame_t *t = NULL;
793+
queue_for_each_entry_safe(frame, t, &frame_q, q)
794+
{
795+
free(frame->buf);
796+
queue_del(&frame->q);
797+
free(frame);
798+
idx++;
799+
}
800+
assert(idx == cnt - 2);
801+
assert(queue_empty(&frame_q));
802+
775803
return 0;
776804
}
777805

0 commit comments

Comments
 (0)