pipewire: set CORRUPTED flag when buffer params mismatch
This commit is contained in:
parent
6be82ccabb
commit
78a2496386
1 changed files with 28 additions and 27 deletions
|
@ -54,13 +54,30 @@ static void request_buffer(struct pipewire_state *state)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct spa_buffer *spa_buffer = pw_buffer->buffer;
|
|
||||||
struct pipewire_buffer *buffer = (struct pipewire_buffer *) pw_buffer->user_data;
|
struct pipewire_buffer *buffer = (struct pipewire_buffer *) pw_buffer->user_data;
|
||||||
|
buffer->copying = true;
|
||||||
|
|
||||||
|
// Past this exchange, the PipeWire thread shares the buffer with the
|
||||||
|
// steamcompmgr thread
|
||||||
|
struct pipewire_buffer *old = out_buffer.exchange(buffer);
|
||||||
|
assert(old == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copy_buffer(struct pipewire_state *state, struct pipewire_buffer *buffer)
|
||||||
|
{
|
||||||
|
std::shared_ptr<CVulkanTexture> tex = std::move(buffer->texture);
|
||||||
|
assert(tex != nullptr);
|
||||||
|
assert(tex->m_format == VK_FORMAT_B8G8R8A8_UNORM);
|
||||||
|
|
||||||
|
struct pw_buffer *pw_buffer = buffer->buffer;
|
||||||
|
struct spa_buffer *spa_buffer = pw_buffer->buffer;
|
||||||
|
|
||||||
|
bool needs_reneg = buffer->video_info.size.width != tex->m_width || buffer->video_info.size.height != tex->m_height;
|
||||||
|
|
||||||
struct spa_meta_header *header = (struct spa_meta_header *) spa_buffer_find_meta_data(spa_buffer, SPA_META_Header, sizeof(*header));
|
struct spa_meta_header *header = (struct spa_meta_header *) spa_buffer_find_meta_data(spa_buffer, SPA_META_Header, sizeof(*header));
|
||||||
if (header != nullptr) {
|
if (header != nullptr) {
|
||||||
header->pts = -1;
|
header->pts = -1;
|
||||||
header->flags = 0;
|
header->flags = needs_reneg ? SPA_META_HEADER_FLAG_CORRUPTED : 0;
|
||||||
header->seq = state->seq++;
|
header->seq = state->seq++;
|
||||||
header->dts_offset = 0;
|
header->dts_offset = 0;
|
||||||
}
|
}
|
||||||
|
@ -69,13 +86,14 @@ static void request_buffer(struct pipewire_state *state)
|
||||||
chunk->offset = 0;
|
chunk->offset = 0;
|
||||||
chunk->size = state->video_info.size.height * state->stride;
|
chunk->size = state->video_info.size.height * state->stride;
|
||||||
chunk->stride = state->stride;
|
chunk->stride = state->stride;
|
||||||
|
chunk->flags = needs_reneg ? SPA_CHUNK_FLAG_CORRUPTED : 0;
|
||||||
|
|
||||||
buffer->copying = true;
|
if (!needs_reneg) {
|
||||||
|
int bpp = 4;
|
||||||
// Past this exchange, the PipeWire thread shares the buffer with the
|
for (uint32_t i = 0; i < tex->m_height; i++) {
|
||||||
// steamcompmgr thread
|
memcpy(buffer->data + i * buffer->stride, (uint8_t *) tex->m_pMappedData + i * tex->m_unRowPitch, bpp * tex->m_width);
|
||||||
struct pipewire_buffer *old = out_buffer.exchange(buffer);
|
}
|
||||||
assert(old == nullptr);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dispatch_nudge(struct pipewire_state *state, int fd)
|
static void dispatch_nudge(struct pipewire_state *state, int fd)
|
||||||
|
@ -108,26 +126,9 @@ static void dispatch_nudge(struct pipewire_state *state, int fd)
|
||||||
|
|
||||||
buffer->copying = false;
|
buffer->copying = false;
|
||||||
|
|
||||||
{
|
|
||||||
std::shared_ptr<CVulkanTexture> tex = std::move(buffer->texture);
|
|
||||||
assert( tex->m_format == VK_FORMAT_B8G8R8A8_UNORM );
|
|
||||||
|
|
||||||
if ( buffer->video_info.size.width != tex->m_width || buffer->video_info.size.height != tex->m_height )
|
|
||||||
{
|
|
||||||
// Push black frames until the PipeWire thread realizes the stream size has changed
|
|
||||||
memset( buffer->data, 0, buffer->stride * buffer->video_info.size.height );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int bpp = 4;
|
|
||||||
for ( unsigned int i = 0; i < tex->m_height; i++ )
|
|
||||||
{
|
|
||||||
memcpy( buffer->data + i * buffer->stride, (uint8_t *) tex->m_pMappedData + i * tex->m_unRowPitch, bpp * tex->m_width );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buffer->buffer != nullptr) {
|
if (buffer->buffer != nullptr) {
|
||||||
|
copy_buffer(state, buffer);
|
||||||
|
|
||||||
int ret = pw_stream_queue_buffer(state->stream, buffer->buffer);
|
int ret = pw_stream_queue_buffer(state->stream, buffer->buffer);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pwr_log.errorf("pw_stream_queue_buffer failed");
|
pwr_log.errorf("pw_stream_queue_buffer failed");
|
||||||
|
|
Loading…
Reference in a new issue