[Spice-devel] [PATCH xf86-video-qxl] Revise the XSpice audio processing to avoid the use of pthreads.
Jeremy White
jwhite at codeweavers.com
Tue Oct 21 13:59:28 PDT 2014
Hey Andrew,
Thanks for the careful review. Comments in line, and a new patch on the
way.
>> +struct fifo_data {
>> + char *buffer;
>> + int size;
>> + int len;
>> + int add_to;
>> + int remove_from;
>
> One of these seems redundant. Usually for a ring buffer you'd just
> have a read offset and an valid data count.
>
> I'm also not a fan of 'len'. I'd probably call it valid, or filled, or
> something.
I've eliminated the 'remove_from', but I really didn't feel a better
synonym for len.
>> + if (f->remove_from > 0 && f->remove_from <= f->add_to) {
>> + if (f->len > 0)
>> + memmove(f->buffer, f->buffer + f->remove_from, f->len);
>> + f->add_to -= f->remove_from;
>> + f->remove_from = 0;
>
> Moving the data around within the ring buffer seems to defeat the
> purpose of a ring buffer... You'll need logic to do two reads (for
> example), but you'll avoid a memcpy and it greatly simplifies the
> increment/decrement logic.
*blush*. That was part of some other logic that no longer makes sense.
Revised.
>> + for (s = 0; f->len > 0 && s < (len / 2); s++) {
>
> I'd use sizeof(int16_t) to make it obvious you're processing a number
> of samples.
Sure.
>
>> + int16_t mix;
>> +
>> + fifo_remove_data(f, (unsigned char *) &mix, sizeof(mix));
>
> This seems like an awful lot of work just to retrieve a single sample.
> Much better to read the array directly to avoid copying, and do the
> offset/length calculations in bulk (once per mix_in_one_fifo).
I don't think the copy penalty is so stiff, but I can (and have)
simplified the retrieval process. Note that this will only trigger when
we're mixing more than 1 fifo; ie, it is not an expected mainline case.
>> + return s * 2;
>
> The return value isn't actually used, so you could get rid of this
> magic number.
Good point; removed.
>> + while (data->ahead < BUFFER_PERIODS && maxlen > 0) {
>> + if (! data->spice_buffer) {
>> + uint32_t chunk_frames;
>> + spice_server_playback_get_buffer(&qxl->playback_sin, &data->spice_buffer, &chunk_frames);
>> + data->spice_buffer_bytes = chunk_frames * sizeof(int16_t) * SPICE_INTERFACE_PLAYBACK_CHAN;
>
> This looks suspicious. What's the relationship between BUFFER_PERIODS
> and the spice buffer chunk size? Are chunks always 10ms? This is why
> I held spice buffers between period callbacks in the old code.
After our discussion, I've completely reworked this. I believe it is
more clear in the new logic, and it continues to pass my tests.
>> - closedir(dir);
>> + condense_fifos(data);
>
> Would it make sense to only call condense_fifos() at the start of
> handle_one_change()? Then we avoid the for-loop every period callback.
Yep, changed.
>> + qxl->playback_opaque = data;
>> + audio_initialize(qxl);
>> +
>> + data->wall_timer = qxl->core->timer_add(wall_ticker, qxl);
>> +
>> + data->dir_watch = inotify_init1(IN_NONBLOCK);
>> + data->fifo_dir_watch = -1;
>> + if (data->dir_watch >= 0)
>> + data->fifo_dir_watch = inotify_add_watch(data->dir_watch, qxl->playback_fifo_dir, IN_CREATE | IN_MOVE);
>> +
>> + if (data->fifo_dir_watch == -1) {
>> + ErrorF("Error %s(%d) watching the fifo dir\n", strerror(errno), errno);
>> return errno;
>> + }
>
> Should the stuff remain initialized (e.g. wall_timer, dir_watch) if
> this errors? I don't know. Maybe it doesn't matter.
Erm. Yeah, I don't know either. There won't be any active code; it'll
just be memory that is leaked. I don't think that's a substantive
change (we already leaked some ram as it was), so I'm going to pass on
this one.
Cheers,
Jeremy
More information about the Spice-devel
mailing list