On Fri Sep 8 01:32:39 2023 +0000, Zebediah Figura wrote:
How are we using the output queue? It doesn't conceptually match how I'd naïvely expect a muxer to work. Can you give an overview of the output interface for wg_muxer?
See the 2 commits:
https://gitlab.winehq.org/wine/wine/-/merge_requests/3303/diffs?commit_id=d1...
https://gitlab.winehq.org/wine/wine/-/merge_requests/3303/diffs?commit_id=54...
The output interface looks like this:
``` gst_private.h:
HRESULT wg_muxer_get_buffer(wg_muxer_t muxer, uint32_t *size, uint64_t *offset); HRESULT wg_muxer_copy_buffer(wg_muxer_t muxer, void *buffer, UINT32 size); void wg_muxer_free_buffer(wg_muxer_t muxer); ```
We will use them like this: (https://gitlab.winehq.org/wine/wine/-/merge_requests/3303/diffs?commit_id=54...) ``` media_sink.c
static HRESULT media_sink_write_stream(struct media_sink *media_sink) { BYTE *data = NULL; ULONG written; QWORD offset; UINT32 size; HRESULT hr;
while (SUCCEEDED(hr = wg_muxer_get_buffer(media_sink->muxer, &size, &offset))) { if (!(data = calloc(1, size))) return E_OUTOFMEMORY;
if (FAILED(hr = wg_muxer_copy_buffer(media_sink->muxer, data, size))) { free(data); WARN("Failed to copy buffer, hr %#lx.", hr); return hr; }
if ((offset != UINT64_MAX && FAILED(hr = IMFByteStream_SetCurrentPosition(media_sink->bytestream, offset))) || FAILED(hr = IMFByteStream_Write(media_sink->bytestream, data, size, &written))) { free(data); return hr; }
free(data); wg_muxer_free_buffer(media_sink->muxer); }
return S_OK; } ```
And we implement them like this: (https://gitlab.winehq.org/wine/wine/-/merge_requests/3303/diffs?commit_id=d1...) ``` wg_muxer.c:
NTSTATUS wg_muxer_get_buffer(void *args) { struct wg_muxer_get_buffer_params *params = args; struct wg_muxer *muxer = get_muxer(params->muxer);
if (!muxer->buffer) { if (!(muxer->buffer = gst_atomic_queue_pop(muxer->output_queue))) return MF_E_SINK_NO_SAMPLES_PROCESSED;
if (!gst_buffer_map(muxer->buffer, &muxer->map_info, GST_MAP_READ)) { GST_ERROR("Failed to map buffer %p, dropped.", muxer->buffer); gst_buffer_unref(muxer->buffer); muxer->buffer = NULL; return E_FAIL; } }
params->size = muxer->map_info.size; if (GST_BUFFER_OFFSET_IS_VALID(muxer->buffer)) params->offset = GST_BUFFER_OFFSET(muxer->buffer);
return S_OK; }
NTSTATUS wg_muxer_copy_buffer(void *args) { struct wg_muxer_copy_buffer_params *params = args; struct wg_muxer *muxer = get_muxer(params->muxer);
if (!muxer->buffer) return MF_E_SINK_NO_SAMPLES_PROCESSED;
if (params->size < muxer->map_info.size) return MF_E_BUFFERTOOSMALL;
memcpy(params->buffer, muxer->map_info.data, muxer->map_info.size);
return S_OK; }
NTSTATUS wg_muxer_free_buffer(void *args) { struct wg_muxer *muxer = get_muxer(*(wg_muxer_t *)args);
if (muxer->buffer) muxer_free_buffer(muxer);
return S_OK; }
```