aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2022-05-12 09:22:22 -0700
committerChris Robinson <[email protected]>2022-05-13 15:40:15 -0700
commitdbf5306828f811286feb7e45774cfc46b117da05 (patch)
tree1f3b85aa0801805bea5899382dc6970d221cbd2c
parentd38d9b091eaae5e3d36fde64c597d2ec68370339 (diff)
Use pw_buffer::requested in newer PipeWire versions
-rw-r--r--alc/backends/pipewire.cpp42
1 files changed, 26 insertions, 16 deletions
diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index b573bd5a..165579b2 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -1308,32 +1308,42 @@ void PipeWirePlayback::outputCallback()
pw_buffer *pw_buf{pw_stream_dequeue_buffer(mStream.get())};
if(unlikely(!pw_buf)) return;
+ const al::span<spa_data> datas{pw_buf->buffer->datas,
+ minu(mNumChannels, pw_buf->buffer->n_datas)};
+#if PW_CHECK_VERSION(0,3,49)
+ /* In 0.3.49, pw_buffer::requested specifies the number of samples needed
+ * by the resampler/graph for this audio update.
+ */
+ uint length{static_cast<uint>(pw_buf->requested)};
+#else
+ /* In 0.3.48 and earlier, spa_io_rate_match::size apparently has the number
+ * of samples per update.
+ */
+ uint length{mRateMatch ? mRateMatch->size : 0u};
+#endif
+ /* If no length is specified, use the device's update size as a fallback. */
+ if(unlikely(!length)) length = mDevice->UpdateSize;
+
/* For planar formats, each datas[] seems to contain one channel, so store
* the pointers in an array. Limit the render length in case the available
* buffer length in any one channel is smaller than we wanted (shouldn't
* be, but just in case).
*/
- spa_data *datas{pw_buf->buffer->datas};
- const size_t chancount{minu(mNumChannels, pw_buf->buffer->n_datas)};
- /* TODO: How many samples should actually be written? 'maxsize' can be 16k
- * samples, which is excessive (~341ms @ 48khz). SPA_IO_RateMatch contains
- * a 'size' field that apparently indicates how many samples should be
- * written per update, but it's not obviously right.
- */
- uint length{mRateMatch ? mRateMatch->size : mDevice->UpdateSize};
- for(size_t i{0};i < chancount;++i)
+ float **chanptr_end{mChannelPtrs.get()};
+ for(const auto &data : datas)
{
- length = minu(length, datas[i].maxsize/sizeof(float));
- mChannelPtrs[i] = static_cast<float*>(datas[i].data);
+ length = minu(length, data.maxsize/sizeof(float));
+ *chanptr_end = static_cast<float*>(data.data);
+ ++chanptr_end;
}
- mDevice->renderSamples({mChannelPtrs.get(), chancount}, length);
+ mDevice->renderSamples({mChannelPtrs.get(), chanptr_end}, length);
- for(size_t i{0};i < chancount;++i)
+ for(const auto &data : datas)
{
- datas[i].chunk->offset = 0;
- datas[i].chunk->stride = sizeof(float);
- datas[i].chunk->size = length * sizeof(float);
+ data.chunk->offset = 0;
+ data.chunk->stride = sizeof(float);
+ data.chunk->size = length * sizeof(float);
}
pw_buf->size = length;
pw_stream_queue_buffer(mStream.get(), pw_buf);