Bug 1712621 - Update cubeb to 5ebe69c. r=cubeb-reviewers,padenot

Differential Revision: https://phabricator.services.mozilla.com/D115837
This commit is contained in:
Matthew Gregan 2021-05-25 10:44:33 +00:00
Родитель cb95fdbd77
Коммит c9635d7b45
5 изменённых файлов: 139 добавлений и 68 удалений

Просмотреть файл

@ -1,5 +1,4 @@
[![Build Status](https://travis-ci.org/kinetiknz/cubeb.svg?branch=master)](https://travis-ci.org/kinetiknz/cubeb)
[![Build status](https://ci.appveyor.com/api/projects/status/osv2r0m1j1nt9csr/branch/master?svg=true)](https://ci.appveyor.com/project/kinetiknz/cubeb/branch/master)
[![Build Status](https://github.com/mozilla/cubeb/actions/workflows/build.yml/badge.svg)](https://github.com/mozilla/cubeb/actions/workflows/build.yml)
See INSTALL.md for build instructions.

Просмотреть файл

@ -19,5 +19,5 @@ origin:
license: "ISC"
# update.sh will update this value
release: "8942382280721117900072945767cece14eef046 (2021-02-17 22:05:37 +1300)"
release: "5ebe69cb3a1c7b022af85c04187456948b209d4b (2021-05-25 08:15:25 +1200)"

Просмотреть файл

@ -784,16 +784,32 @@ oss_put_play_frames(cubeb_stream * s, unsigned int nframes)
static int
oss_wait_playfd_for_space(cubeb_stream * s)
{
/* For non-duplex stream we have to wait until we have space in the
* buffer */
int rate = s->play.info.sample_rate;
struct pollfd pfd;
pfd.events = POLLOUT|POLLHUP;
pfd.events = POLLOUT | POLLHUP;
pfd.revents = 0;
pfd.fd = s->play.fd;
if (poll(&pfd, 1, s->nfr * 1000 + rate - 1 / rate) == -1) {
if (poll(&pfd, 1, 2000) == -1) {
return CUBEB_ERROR;
}
if (pfd.revents & POLLHUP) {
return CUBEB_ERROR;
}
return 0;
}
static int
oss_wait_recfd_for_space(cubeb_stream * s)
{
struct pollfd pfd;
pfd.events = POLLIN | POLLHUP;
pfd.revents = 0;
pfd.fd = s->record.fd;
if (poll(&pfd, 1, 2000) == -1) {
return CUBEB_ERROR;
}
@ -808,10 +824,9 @@ static int
oss_audio_loop(cubeb_stream * s, cubeb_state *new_state)
{
cubeb_state state = CUBEB_STATE_STOPPED;
int trig = 0;
int drain = 0;
int trig = 0, drain = 0;
const bool play_on = s->play.fd != -1, record_on = s->record.fd != -1;
long nfr = s->bufframes;
long nfr = 0;
if (record_on) {
if (ioctl(s->record.fd, SNDCTL_DSP_SETTRIGGER, &trig)) {
@ -819,14 +834,15 @@ oss_audio_loop(cubeb_stream * s, cubeb_state *new_state)
state = CUBEB_STATE_ERROR;
goto breakdown;
}
trig |= PCM_ENABLE_INPUT;
if (ioctl(s->record.fd, SNDCTL_DSP_SETTRIGGER, &trig)) {
memset(s->record.buf, 0, s->bufframes * s->record.frame_size);
if (ioctl(s->record.fd, SNDCTL_DSP_SETTRIGGER, &trig) == -1) {
LOG("Error %d occured when setting trigger on record fd", errno);
state = CUBEB_STATE_ERROR;
goto breakdown;
}
memset(s->record.buf, 0, s->bufframes * s->record.frame_size);
}
if (!play_on && !record_on) {
@ -848,25 +864,20 @@ oss_audio_loop(cubeb_stream * s, cubeb_state *new_state)
long got = 0;
if (nfr > 0) {
if (record_on) {
if (oss_get_rec_frames(s, nfr) == CUBEB_ERROR) {
state = CUBEB_STATE_ERROR;
goto breakdown;
}
if (s->record.floating) {
oss_linear32_to_float(s->record.buf, s->record.info.channels * nfr);
}
}
got = s->data_cb(s, s->user_ptr, s->record.buf, s->play.buf, nfr);
if (got == CUBEB_ERROR) {
state = CUBEB_STATE_ERROR;
goto breakdown;
}
if (play_on) {
float vol;
pthread_mutex_lock(&s->mtx);
vol = s->volume;
pthread_mutex_unlock(&s->mtx);
if (s->play.floating) {
oss_float_to_linear32(s->play.buf, s->play.info.channels * got, vol);
} else {
oss_linear16_set_vol((int16_t *)s->play.buf,
s->play.info.channels * got, vol);
}
}
if (got < nfr) {
if (s->play.fd != -1) {
drain = 1;
@ -876,30 +887,58 @@ oss_audio_loop(cubeb_stream * s, cubeb_state *new_state)
* returned from data_cb() is smaller than number
* of frames required to read. Stop here.
*/
state = CUBEB_STATE_STOPPED;
goto breakdown;
}
}
nfr = 0;
}
if (got > 0) {
if (play_on && oss_put_play_frames(s, got) < 0) {
if (got > 0 && play_on) {
float vol;
pthread_mutex_lock(&s->mtx);
vol = s->volume;
pthread_mutex_unlock(&s->mtx);
if (s->play.floating) {
oss_float_to_linear32(s->play.buf, s->play.info.channels * got, vol);
} else {
oss_linear16_set_vol((int16_t *)s->play.buf,
s->play.info.channels * got, vol);
}
if (oss_put_play_frames(s, got) == CUBEB_ERROR) {
state = CUBEB_STATE_ERROR;
goto breakdown;
}
}
if (drain) {
state = CUBEB_STATE_DRAINED;
goto breakdown;
}
}
if (drain) {
state = CUBEB_STATE_DRAINED;
goto breakdown;
nfr = s->bufframes;
if (record_on) {
long mfr;
if (oss_wait_recfd_for_space(s) != 0) {
state = CUBEB_STATE_ERROR;
goto breakdown;
}
audio_buf_info bi;
if (ioctl(s->record.fd, SNDCTL_DSP_GETISPACE, &bi) == -1) {
state = CUBEB_STATE_ERROR;
goto breakdown;
}
mfr = (bi.fragsize * bi.fragments) / s->record.frame_size;
if (nfr > mfr)
nfr = mfr;
}
if (play_on) {
/*
* In duplex mode, playback direction drives recording direction to
* prevent building up latencies.
*/
long mfr;
if (oss_wait_playfd_for_space(s) != 0) {
state = CUBEB_STATE_ERROR;
@ -907,26 +946,14 @@ oss_audio_loop(cubeb_stream * s, cubeb_state *new_state)
}
audio_buf_info bi;
if (ioctl(s->play.fd, SNDCTL_DSP_GETOSPACE, &bi)) {
if (ioctl(s->play.fd, SNDCTL_DSP_GETOSPACE, &bi) == -1) {
state = CUBEB_STATE_ERROR;
goto breakdown;
}
nfr = bi.fragsize * bi.fragments / s->play.frame_size;
if (nfr > s->bufframes) {
nfr = s->bufframes;
}
} else {
nfr = s->nfr;
}
if (record_on) {
if (oss_get_rec_frames(s, nfr) == CUBEB_ERROR) {
state = CUBEB_STATE_ERROR;
goto breakdown;
}
if (s->record.floating) {
oss_linear32_to_float(s->record.buf, s->record.info.channels * nfr);
}
mfr = (bi.fragsize * bi.fragments) / s->play.frame_size;
if (nfr > mfr)
nfr = mfr;
}
}

Просмотреть файл

@ -118,8 +118,8 @@ public:
assert_correct_thread(producer_id);
#endif
int rd_idx = read_index_.load(std::memory_order::memory_order_relaxed);
int wr_idx = write_index_.load(std::memory_order::memory_order_relaxed);
int rd_idx = read_index_.load(std::memory_order_relaxed);
int wr_idx = write_index_.load(std::memory_order_relaxed);
if (full_internal(rd_idx, wr_idx)) {
return 0;
@ -142,7 +142,7 @@ public:
ConstructDefault(data_.get(), second_part);
}
write_index_.store(increment_index(wr_idx, to_write), std::memory_order::memory_order_release);
write_index_.store(increment_index(wr_idx, to_write), std::memory_order_release);
return to_write;
}
@ -163,8 +163,8 @@ public:
assert_correct_thread(consumer_id);
#endif
int wr_idx = write_index_.load(std::memory_order::memory_order_acquire);
int rd_idx = read_index_.load(std::memory_order::memory_order_relaxed);
int wr_idx = write_index_.load(std::memory_order_acquire);
int rd_idx = read_index_.load(std::memory_order_relaxed);
if (empty_internal(rd_idx, wr_idx)) {
return 0;
@ -181,7 +181,7 @@ public:
Copy(elements + first_part, data_.get(), second_part);
}
read_index_.store(increment_index(rd_idx, to_read), std::memory_order::memory_order_relaxed);
read_index_.store(increment_index(rd_idx, to_read), std::memory_order_relaxed);
return to_read;
}
@ -197,8 +197,8 @@ public:
#ifndef NDEBUG
assert_correct_thread(consumer_id);
#endif
return available_read_internal(read_index_.load(std::memory_order::memory_order_relaxed),
write_index_.load(std::memory_order::memory_order_relaxed));
return available_read_internal(read_index_.load(std::memory_order_relaxed),
write_index_.load(std::memory_order_relaxed));
}
/**
* Get the number of available elements for consuming.
@ -212,8 +212,8 @@ public:
#ifndef NDEBUG
assert_correct_thread(producer_id);
#endif
return available_write_internal(read_index_.load(std::memory_order::memory_order_relaxed),
write_index_.load(std::memory_order::memory_order_relaxed));
return available_write_internal(read_index_.load(std::memory_order_relaxed),
write_index_.load(std::memory_order_relaxed));
}
/**
* Get the total capacity, for this ring buffer.

Просмотреть файл

@ -277,8 +277,10 @@ struct cubeb_stream {
com_ptr<IAudioClient> output_client;
/* Interface pointer to use the event-driven interface. */
com_ptr<IAudioRenderClient> render_client;
#ifdef CUBEB_WASAPI_USE_IAUDIOSTREAMVOLUME
/* Interface pointer to use the volume facilities. */
com_ptr<IAudioStreamVolume> audio_stream_volume;
#endif
/* Interface pointer to use the stream audio clock. */
com_ptr<IAudioClock> audio_clock;
/* Frames written to the stream since it was opened. Reset on device
@ -821,9 +823,11 @@ refill(cubeb_stream * stm, void * input_buffer, long input_frames_count,
/* TODO: Report out_frames < 0 as an error via the API. */
XASSERT(out_frames >= 0);
float volume = 1.0;
{
auto_lock lock(stm->stream_reset_lock);
stm->frames_written += out_frames;
volume = stm->volume;
}
/* Go in draining mode if we got fewer frames than requested. If the stream
@ -839,6 +843,36 @@ refill(cubeb_stream * stm, void * input_buffer, long input_frames_count,
It is alright to have produced less frames if we are draining, though. */
XASSERT(out_frames == output_frames_needed || stm->draining || !has_output(stm) || stm->has_dummy_output);
#ifndef CUBEB_WASAPI_USE_IAUDIOSTREAMVOLUME
if (has_output(stm) && !stm->has_dummy_output && volume != 1.0) {
// Adjust the output volume.
// Note: This could be integrated with the remixing below.
long out_samples = out_frames * stm->output_stream_params.channels;
if (volume == 0.0) {
memset(dest, 0, out_samples * stm->bytes_per_sample);
} else {
switch (stm->output_stream_params.format) {
case CUBEB_SAMPLE_FLOAT32NE: {
float * buf = static_cast<float *>(dest);
for (long i = 0; i < out_samples; ++i) {
buf[i] *= volume;
}
break;
}
case CUBEB_SAMPLE_S16NE: {
short * buf = static_cast<short *>(dest);
for (long i = 0; i < out_samples; ++i) {
buf[i] = static_cast<short>(static_cast<float>(buf[i]) * volume);
}
break;
}
default:
XASSERT(false);
}
}
}
#endif
// We don't bother mixing dummy output as it will be silenced, otherwise mix output if needed
if (!stm->has_dummy_output && has_output(stm) && stm->output_mixer) {
XASSERT(dest == stm->mix_buffer.data());
@ -1488,6 +1522,7 @@ current_stream_delay(cubeb_stream * stm)
return delay;
}
#ifdef CUBEB_WASAPI_USE_IAUDIOSTREAMVOLUME
int
stream_set_volume(cubeb_stream * stm, float volume)
{
@ -1522,6 +1557,7 @@ stream_set_volume(cubeb_stream * stm, float volume)
return CUBEB_OK;
}
#endif
} // namespace anonymous
extern "C" {
@ -2322,12 +2358,15 @@ int setup_wasapi_stream(cubeb_stream * stm)
return rv;
}
HRESULT hr = stm->output_client->GetService(__uuidof(IAudioStreamVolume),
stm->audio_stream_volume.receive_vpp());
HRESULT hr = 0;
#ifdef CUBEB_WASAPI_USE_IAUDIOSTREAMVOLUME
hr = stm->output_client->GetService(__uuidof(IAudioStreamVolume),
stm->audio_stream_volume.receive_vpp());
if (FAILED(hr)) {
LOG("Could not get the IAudioStreamVolume: %lx", hr);
return CUBEB_ERROR;
}
#endif
XASSERT(stm->frames_written == 0);
hr = stm->output_client->GetService(__uuidof(IAudioClock),
@ -2337,11 +2376,13 @@ int setup_wasapi_stream(cubeb_stream * stm)
return CUBEB_ERROR;
}
#ifdef CUBEB_WASAPI_USE_IAUDIOSTREAMVOLUME
/* Restore the stream volume over a device change. */
if (stream_set_volume(stm, stm->volume) != CUBEB_OK) {
LOG("Could not set the volume.");
return CUBEB_ERROR;
}
#endif
}
/* If we have both input and output, we resample to
@ -2569,7 +2610,9 @@ void close_wasapi_stream(cubeb_stream * stm)
stm->output_device = nullptr;
stm->input_device = nullptr;
#ifdef CUBEB_WASAPI_USE_IAUDIOSTREAMVOLUME
stm->audio_stream_volume = nullptr;
#endif
stm->audio_clock = nullptr;
stm->total_frames_written += static_cast<UINT64>(round(stm->frames_written * stream_to_mix_samplerate_ratio(stm->output_stream_params, stm->output_mix_params)));
@ -2850,9 +2893,11 @@ int wasapi_stream_set_volume(cubeb_stream * stm, float volume)
return CUBEB_ERROR;
}
#ifdef CUBEB_WASAPI_USE_IAUDIOSTREAMVOLUME
if (stream_set_volume(stm, volume) != CUBEB_OK) {
return CUBEB_ERROR;
}
#endif
stm->volume = volume;