This is the message session relies on succeeding.
Signed-off-by: Derek Lesho dlesho@codeweavers.com --- dlls/winegstreamer/audioconvert.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c index c5762bfdc60..82467b2f4e2 100644 --- a/dlls/winegstreamer/audioconvert.c +++ b/dlls/winegstreamer/audioconvert.c @@ -517,7 +517,7 @@ static HRESULT WINAPI audio_converter_ProcessMessage(IMFTransform *iface, MFT_ME
switch(message) { - case MFT_MESSAGE_NOTIFY_START_OF_STREAM: + case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING: return S_OK; default: FIXME("Unhandled message type %x.\n", message);
Signed-off-by: Derek Lesho dlesho@codeweavers.com --- dlls/winegstreamer/audioconvert.c | 153 ++++++++++++++++-------------- 1 file changed, 82 insertions(+), 71 deletions(-)
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c index 82467b2f4e2..85f44dd8856 100644 --- a/dlls/winegstreamer/audioconvert.c +++ b/dlls/winegstreamer/audioconvert.c @@ -276,7 +276,9 @@ fail:
static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) { + GUID major_type, subtype; GstCaps *input_caps; + DWORD unused; HRESULT hr;
struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface); @@ -286,34 +288,46 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id if (id != 0) return MF_E_INVALIDSTREAMNUMBER;
- if (type) + if (!type) { - GUID major_type, subtype; - DWORD unused; - - if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type))) - return MF_E_INVALIDTYPE; - if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) - return MF_E_INVALIDTYPE; - if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &unused))) - return MF_E_INVALIDTYPE; - if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &unused))) - return MF_E_INVALIDTYPE; - if (IsEqualGUID(&subtype, &MFAudioFormat_PCM) && FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &unused))) - return MF_E_INVALIDTYPE; - - if (!(IsEqualGUID(&major_type, &MFMediaType_Audio))) - return MF_E_INVALIDTYPE; - - if (!IsEqualGUID(&subtype, &MFAudioFormat_PCM) && !IsEqualGUID(&subtype, &MFAudioFormat_Float)) - return MF_E_INVALIDTYPE; - - if (!(input_caps = caps_from_mf_media_type(type))) - return MF_E_INVALIDTYPE; - - gst_caps_unref(input_caps); + if (flags & MFT_SET_TYPE_TEST_ONLY) + return S_OK; + + EnterCriticalSection(&converter->cs); + + if (converter->input_type) + { + IMFMediaType_Release(converter->input_type); + converter->input_type = NULL; + } + + LeaveCriticalSection(&converter->cs); + + return S_OK; }
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type))) + return MF_E_INVALIDTYPE; + if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) + return MF_E_INVALIDTYPE; + if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &unused))) + return MF_E_INVALIDTYPE; + if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &unused))) + return MF_E_INVALIDTYPE; + if (IsEqualGUID(&subtype, &MFAudioFormat_PCM) && FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &unused))) + return MF_E_INVALIDTYPE; + + if (!(IsEqualGUID(&major_type, &MFMediaType_Audio))) + return MF_E_INVALIDTYPE; + + if (!IsEqualGUID(&subtype, &MFAudioFormat_PCM) && !IsEqualGUID(&subtype, &MFAudioFormat_Float)) + return MF_E_INVALIDTYPE; + + if (!(input_caps = caps_from_mf_media_type(type))) + return MF_E_INVALIDTYPE; + + gst_caps_unref(input_caps); + if (flags & MFT_SET_TYPE_TEST_ONLY) return S_OK;
@@ -321,21 +335,13 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id
hr = S_OK;
- if (type) - { - if (!converter->input_type) - hr = MFCreateMediaType(&converter->input_type); + if (!converter->input_type) + hr = MFCreateMediaType(&converter->input_type);
- if (SUCCEEDED(hr)) - hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->input_type); + if (SUCCEEDED(hr)) + hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->input_type);
- if (FAILED(hr)) - { - IMFMediaType_Release(converter->input_type); - converter->input_type = NULL; - } - } - else if (converter->input_type) + if (FAILED(hr)) { IMFMediaType_Release(converter->input_type); converter->input_type = NULL; @@ -362,33 +368,46 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i if (!converter->input_type) return MF_E_TRANSFORM_TYPE_NOT_SET;
- if (type) + if (!type) { - /* validate the type */ - - if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type))) - return MF_E_INVALIDTYPE; - if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) - return MF_E_INVALIDTYPE; - if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &unused))) - return MF_E_INVALIDTYPE; - if (IsEqualGUID(&subtype, &MFAudioFormat_PCM) && FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &unused))) - return MF_E_INVALIDTYPE; - if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &unused))) - return MF_E_INVALIDTYPE; + if (flags & MFT_SET_TYPE_TEST_ONLY) + return S_OK;
- if (!(IsEqualGUID(&major_type, &MFMediaType_Audio))) - return MF_E_INVALIDTYPE; + EnterCriticalSection(&converter->cs);
- if (!IsEqualGUID(&subtype, &MFAudioFormat_PCM) && !IsEqualGUID(&subtype, &MFAudioFormat_Float)) - return MF_E_INVALIDTYPE; + if (converter->output_type) + { + IMFMediaType_Release(converter->output_type); + converter->output_type = NULL; + }
- if (!(output_caps = caps_from_mf_media_type(type))) - return MF_E_INVALIDTYPE; + LeaveCriticalSection(&converter->cs);
- gst_caps_unref(output_caps); + return S_OK; }
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type))) + return MF_E_INVALIDTYPE; + if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) + return MF_E_INVALIDTYPE; + if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &unused))) + return MF_E_INVALIDTYPE; + if (IsEqualGUID(&subtype, &MFAudioFormat_PCM) && FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &unused))) + return MF_E_INVALIDTYPE; + if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &unused))) + return MF_E_INVALIDTYPE; + + if (!(IsEqualGUID(&major_type, &MFMediaType_Audio))) + return MF_E_INVALIDTYPE; + + if (!IsEqualGUID(&subtype, &MFAudioFormat_PCM) && !IsEqualGUID(&subtype, &MFAudioFormat_Float)) + return MF_E_INVALIDTYPE; + + if (!(output_caps = caps_from_mf_media_type(type))) + return MF_E_INVALIDTYPE; + + gst_caps_unref(output_caps); + if (flags & MFT_SET_TYPE_TEST_ONLY) return S_OK;
@@ -396,21 +415,13 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i
hr = S_OK;
- if (type) - { - if (!converter->output_type) - hr = MFCreateMediaType(&converter->output_type); + if (!converter->output_type) + hr = MFCreateMediaType(&converter->output_type);
- if (SUCCEEDED(hr)) - hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->output_type); + if (SUCCEEDED(hr)) + hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->output_type);
- if (FAILED(hr)) - { - IMFMediaType_Release(converter->output_type); - converter->output_type = NULL; - } - } - else if (converter->output_type) + if (FAILED(hr)) { IMFMediaType_Release(converter->output_type); converter->output_type = NULL;
Signed-off-by: Zebediah Figura z.figura12@gmail.com
Signed-off-by: Derek Lesho dlesho@codeweavers.com --- dlls/winegstreamer/audioconvert.c | 188 ++++++++++++++++++++++++++++-- dlls/winegstreamer/gst_private.h | 1 + dlls/winegstreamer/mfplat.c | 69 +++++++++++ 3 files changed, 250 insertions(+), 8 deletions(-)
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c index 85f44dd8856..e16fc6f1a78 100644 --- a/dlls/winegstreamer/audioconvert.c +++ b/dlls/winegstreamer/audioconvert.c @@ -40,6 +40,8 @@ struct audio_converter IMFMediaType *input_type; IMFMediaType *output_type; CRITICAL_SECTION cs; + BOOL inflight; + GstElement *container, *appsrc, *appsink; };
static struct audio_converter *impl_audio_converter_from_IMFTransform(IMFTransform *iface) @@ -85,6 +87,7 @@ static ULONG WINAPI audio_converter_Release(IMFTransform *iface) { transform->cs.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&transform->cs); + gst_object_unref(transform->container); heap_free(transform); }
@@ -295,6 +298,9 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id
EnterCriticalSection(&converter->cs);
+ converter->inflight = FALSE; + gst_element_set_state(converter->container, GST_STATE_READY); + if (converter->input_type) { IMFMediaType_Release(converter->input_type); @@ -326,14 +332,17 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id if (!(input_caps = caps_from_mf_media_type(type))) return MF_E_INVALIDTYPE;
- gst_caps_unref(input_caps); - if (flags & MFT_SET_TYPE_TEST_ONLY) + { + gst_caps_unref(input_caps); return S_OK; + }
EnterCriticalSection(&converter->cs);
hr = S_OK; + converter->inflight = FALSE; + gst_element_set_state(converter->container, GST_STATE_READY);
if (!converter->input_type) hr = MFCreateMediaType(&converter->input_type); @@ -341,12 +350,18 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id if (SUCCEEDED(hr)) hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->input_type);
+ g_object_set(converter->appsrc, "caps", input_caps, NULL); + gst_caps_unref(input_caps); + if (FAILED(hr)) { IMFMediaType_Release(converter->input_type); converter->input_type = NULL; }
+ if (converter->input_type && converter->output_type) + gst_element_set_state(converter->container, GST_STATE_PLAYING); + LeaveCriticalSection(&converter->cs);
return hr; @@ -375,6 +390,9 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i
EnterCriticalSection(&converter->cs);
+ converter->inflight = FALSE; + gst_element_set_state(converter->container, GST_STATE_READY); + if (converter->output_type) { IMFMediaType_Release(converter->output_type); @@ -406,14 +424,17 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i if (!(output_caps = caps_from_mf_media_type(type))) return MF_E_INVALIDTYPE;
- gst_caps_unref(output_caps); - if (flags & MFT_SET_TYPE_TEST_ONLY) + { + gst_caps_unref(output_caps); return S_OK; + }
EnterCriticalSection(&converter->cs);
hr = S_OK; + converter->inflight = FALSE; + gst_element_set_state(converter->container, GST_STATE_READY);
if (!converter->output_type) hr = MFCreateMediaType(&converter->output_type); @@ -421,12 +442,18 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i if (SUCCEEDED(hr)) hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->output_type);
+ g_object_set(converter->appsink, "caps", output_caps, NULL); + gst_caps_unref(output_caps); + if (FAILED(hr)) { IMFMediaType_Release(converter->output_type); converter->output_type = NULL; }
+ if (converter->input_type && converter->output_type) + gst_element_set_state(converter->container, GST_STATE_PLAYING); + LeaveCriticalSection(&converter->cs);
return hr; @@ -538,17 +565,102 @@ static HRESULT WINAPI audio_converter_ProcessMessage(IMFTransform *iface, MFT_ME
static HRESULT WINAPI audio_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) { - FIXME("%p, %u, %p, %#x.\n", iface, id, sample, flags); + GstBuffer *gst_buffer; + int ret;
- return E_NOTIMPL; + struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface); + + TRACE("%p, %u, %p, %#x.\n", iface, id, sample, flags); + + if (flags) + WARN("Unsupported flags %#x\n", flags); + + if (id != 0) + return MF_E_INVALIDSTREAMNUMBER; + + EnterCriticalSection(&converter->cs); + + if (!converter->input_type || !converter->output_type) + { + LeaveCriticalSection(&converter->cs); + return MF_E_TRANSFORM_TYPE_NOT_SET; + } + + if (converter->inflight) + { + LeaveCriticalSection(&converter->cs); + return MF_E_NOTACCEPTING; + } + + if (!(gst_buffer = gst_buffer_from_mf_sample(sample))) + { + LeaveCriticalSection(&converter->cs); + return E_FAIL; + } + + g_signal_emit_by_name(converter->appsrc, "push-buffer", gst_buffer, &ret); + gst_buffer_unref(gst_buffer); + if (ret != GST_FLOW_OK) + { + ERR("Couldn't push buffer ret, (%s)\n", gst_flow_get_name(ret)); + LeaveCriticalSection(&converter->cs); + return E_FAIL; + } + + converter->inflight = TRUE; + LeaveCriticalSection(&converter->cs); + + return S_OK; }
static HRESULT WINAPI audio_converter_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status) { - FIXME("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status); + GstSample *sample;
- return E_NOTIMPL; + struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface); + + TRACE("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status); + + if (flags) + WARN("Unsupported flags %#x\n", flags); + + if (!count) + return S_OK; + + if (count != 1) + return MF_E_INVALIDSTREAMNUMBER; + + if (samples[0].dwStreamID != 0) + return MF_E_INVALIDSTREAMNUMBER; + + EnterCriticalSection(&converter->cs); + + if (!converter->input_type || !converter->output_type) + { + LeaveCriticalSection(&converter->cs); + return MF_E_TRANSFORM_TYPE_NOT_SET; + } + + if (!converter->inflight) + { + LeaveCriticalSection(&converter->cs); + return MF_E_TRANSFORM_NEED_MORE_INPUT; + } + + g_signal_emit_by_name(converter->appsink, "pull-sample", &sample); + + converter->inflight = FALSE; + + samples[0].pSample = mf_sample_from_gst_buffer(gst_sample_get_buffer(sample)); + gst_sample_unref(sample); + samples[0].dwStatus = S_OK; + samples[0].pEvents = NULL; + *status = 0; + + LeaveCriticalSection(&converter->cs); + + return S_OK; }
static const IMFTransformVtbl audio_converter_vtbl = @@ -583,6 +695,7 @@ static const IMFTransformVtbl audio_converter_vtbl =
HRESULT audio_converter_create(REFIID riid, void **ret) { + GstElement *audioconvert, *resampler; struct audio_converter *object;
TRACE("%s %p\n", debugstr_guid(riid), ret); @@ -596,6 +709,65 @@ HRESULT audio_converter_create(REFIID riid, void **ret) InitializeCriticalSection(&object->cs); object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": audio_converter_lock");
+ object->container = gst_bin_new(NULL); + + if (!(object->appsrc = gst_element_factory_make("appsrc", NULL))) + { + ERR("Failed to create appsrc, are %u-bit Gstreamer "base" plugins installed?\n", + 8 * (int)sizeof(void *)); + IMFTransform_Release(&object->IMFTransform_iface); + return E_FAIL; + } + gst_bin_add(GST_BIN(object->container), object->appsrc); + + if (!(audioconvert = gst_element_factory_make("audioconvert", NULL))) + { + ERR("Failed to create audioconvert, are %u-bit Gstreamer "base" plugins installed?\n", + 8 * (int)sizeof(void *)); + IMFTransform_Release(&object->IMFTransform_iface); + return E_FAIL; + } + gst_bin_add(GST_BIN(object->container), audioconvert); + + if (!(resampler = gst_element_factory_make("audioresample", NULL))) + { + ERR("Failed to create audioresample, are %u-bit Gstreamer "base" plugins installed?\n", + 8 * (int)sizeof(void *)); + IMFTransform_Release(&object->IMFTransform_iface); + return E_FAIL; + } + gst_bin_add(GST_BIN(object->container), resampler); + + if (!(object->appsink = gst_element_factory_make("appsink", NULL))) + { + ERR("Failed to create appsink, are %u-bit Gstreamer "base" plugins installed?\n", + 8 * (int)sizeof(void *)); + IMFTransform_Release(&object->IMFTransform_iface); + return E_FAIL; + } + gst_bin_add(GST_BIN(object->container), object->appsink); + + if (!gst_element_link(object->appsrc, audioconvert)) + { + ERR("Failed to link appsrc to audioconvert\n"); + IMFTransform_Release(&object->IMFTransform_iface); + return E_FAIL; + } + + if (!gst_element_link(audioconvert, resampler)) + { + ERR("Failed to link audioconvert to resampler\n"); + IMFTransform_Release(&object->IMFTransform_iface); + return E_FAIL; + } + + if (!gst_element_link(resampler, object->appsink)) + { + ERR("Failed to link resampler to appsink\n"); + IMFTransform_Release(&object->IMFTransform_iface); + return E_FAIL; + } + *ret = &object->IMFTransform_iface; return S_OK; } diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 9518f721504..14b6a011ac2 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -82,6 +82,7 @@ HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HI IMFMediaType *mf_media_type_from_caps(const GstCaps *caps) DECLSPEC_HIDDEN; GstCaps *caps_from_mf_media_type(IMFMediaType *type) DECLSPEC_HIDDEN; IMFSample *mf_sample_from_gst_buffer(GstBuffer *in) DECLSPEC_HIDDEN; +GstBuffer *gst_buffer_from_mf_sample(IMFSample *in) DECLSPEC_HIDDEN;
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c index f300988fc5c..b2b5b247dac 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c @@ -865,3 +865,72 @@ done:
return out; } + +GstBuffer *gst_buffer_from_mf_sample(IMFSample *mf_sample) +{ + GstBuffer *out = gst_buffer_new(); + IMFMediaBuffer *mf_buffer = NULL; + LONGLONG duration, time; + DWORD buffer_count; + unsigned int i; + HRESULT hr; + + if (FAILED(hr = IMFSample_GetSampleDuration(mf_sample, &duration))) + goto fail; + + if (FAILED(hr = IMFSample_GetSampleTime(mf_sample, &time))) + goto fail; + + GST_BUFFER_DURATION(out) = duration; + GST_BUFFER_PTS(out) = time * 100; + + if (FAILED(hr = IMFSample_GetBufferCount(mf_sample, &buffer_count))) + goto fail; + + for (i = 0; i < buffer_count; i++) + { + DWORD buffer_size; + GstMapInfo map_info; + GstMemory *memory; + BYTE *buf_data; + + if (FAILED(hr = IMFSample_GetBufferByIndex(mf_sample, i, &mf_buffer))) + goto fail; + + if (FAILED(hr = IMFMediaBuffer_GetCurrentLength(mf_buffer, &buffer_size))) + goto fail; + + memory = gst_allocator_alloc(NULL, buffer_size, NULL); + gst_memory_resize(memory, 0, buffer_size); + + if (!gst_memory_map(memory, &map_info, GST_MAP_WRITE)) + { + hr = E_FAIL; + goto fail; + } + + if (FAILED(hr = IMFMediaBuffer_Lock(mf_buffer, &buf_data, NULL, NULL))) + goto fail; + + memcpy(map_info.data, buf_data, buffer_size); + + if (FAILED(hr = IMFMediaBuffer_Unlock(mf_buffer))) + goto fail; + + gst_memory_unmap(memory, &map_info); + + gst_buffer_append_memory(out, memory); + + IMFMediaBuffer_Release(mf_buffer); + mf_buffer = NULL; + } + + return out; + +fail: + ERR("Failed to copy IMFSample to GstBuffer, hr = %#x\n", hr); + if (mf_buffer) + IMFMediaBuffer_Release(mf_buffer); + gst_buffer_unref(out); + return NULL; +}
Signed-off-by: Derek Lesho dlesho@codeweavers.com --- dlls/winegstreamer/audioconvert.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c index e16fc6f1a78..a95fc5506e7 100644 --- a/dlls/winegstreamer/audioconvert.c +++ b/dlls/winegstreamer/audioconvert.c @@ -123,16 +123,34 @@ static HRESULT WINAPI audio_converter_GetStreamIDs(IMFTransform *iface, DWORD in
static HRESULT WINAPI audio_converter_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info) { - FIXME("%p %u %p.\n", iface, id, info); + TRACE("%p %u %p.\n", iface, id, info);
- return E_NOTIMPL; + if (id != 0) + return MF_E_INVALIDSTREAMNUMBER; + + info->dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_DOES_NOT_ADDREF; + info->cbMaxLookahead = 0; + info->cbAlignment = 0; + info->hnsMaxLatency = 0; + /* TODO: this can be calculated using MFCalculateImageSize */ + info->cbSize = 0; + + return S_OK; }
static HRESULT WINAPI audio_converter_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info) { - FIXME("%p %u %p.\n", iface, id, info); + TRACE("%p %u %p.\n", iface, id, info);
- return E_NOTIMPL; + if (id != 0) + return MF_E_INVALIDSTREAMNUMBER; + + info->dwFlags = MFT_OUTPUT_STREAM_PROVIDES_SAMPLES | MFT_OUTPUT_STREAM_WHOLE_SAMPLES; + info->cbAlignment = 0; + /* TODO: this can be calculated using MFCalculateImageSize */ + info->cbSize = 0; + + return S_OK; }
static HRESULT WINAPI audio_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
On 1/18/21 10:30 PM, Derek Lesho wrote:
Was that verified with what converter returns on Windows? I could work on tests for that if you want, because returning something like that looks rather arbitrary. And comment for image size probably does not apply for audio.
On 1/25/21 10:09 AM, Nikolay Sivov wrote:
No, that was not verified, I think the reason I kept this commit around is that the session needs some implementation of it. As for the specific flags, I think that they match the implementation of the transform, we do allocate the output samples, and the whole_samples flag seems to be meaningless in the case of uncompressed audio.
It seems like the tests for fixing this function would be simple enough, so maybe I should just include them in the updated/fixed patch.
Signed-off-by: Derek Lesho dlesho@codeweavers.com --- dlls/winegstreamer/audioconvert.c | 37 +++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-)
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c index a95fc5506e7..2a5f87fec94 100644 --- a/dlls/winegstreamer/audioconvert.c +++ b/dlls/winegstreamer/audioconvert.c @@ -37,6 +37,8 @@ struct audio_converter { IMFTransform IMFTransform_iface; LONG refcount; + IMFAttributes *attributes; + IMFAttributes *output_attributes; IMFMediaType *input_type; IMFMediaType *output_type; CRITICAL_SECTION cs; @@ -87,6 +89,10 @@ static ULONG WINAPI audio_converter_Release(IMFTransform *iface) { transform->cs.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&transform->cs); + if (transform->attributes) + IMFAttributes_Release(transform->attributes); + if (transform->output_attributes) + IMFAttributes_Release(transform->output_attributes); gst_object_unref(transform->container); heap_free(transform); } @@ -155,9 +161,14 @@ static HRESULT WINAPI audio_converter_GetOutputStreamInfo(IMFTransform *iface, D
static HRESULT WINAPI audio_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) { - FIXME("%p, %p.\n", iface, attributes); + struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, attributes); + + *attributes = converter->attributes; + IMFAttributes_AddRef(*attributes); + + return S_OK; }
static HRESULT WINAPI audio_converter_GetInputStreamAttributes(IMFTransform *iface, DWORD id, @@ -171,9 +182,14 @@ static HRESULT WINAPI audio_converter_GetInputStreamAttributes(IMFTransform *ifa static HRESULT WINAPI audio_converter_GetOutputStreamAttributes(IMFTransform *iface, DWORD id, IMFAttributes **attributes) { - FIXME("%p, %u, %p.\n", iface, id, attributes); + struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
- return E_NOTIMPL; + TRACE("%p, %u, %p.\n", iface, id, attributes); + + *attributes = converter->output_attributes; + IMFAttributes_AddRef(*attributes); + + return S_OK; }
static HRESULT WINAPI audio_converter_DeleteInputStream(IMFTransform *iface, DWORD id) @@ -715,6 +731,7 @@ HRESULT audio_converter_create(REFIID riid, void **ret) { GstElement *audioconvert, *resampler; struct audio_converter *object; + HRESULT hr;
TRACE("%s %p\n", debugstr_guid(riid), ret);
@@ -727,6 +744,18 @@ HRESULT audio_converter_create(REFIID riid, void **ret) InitializeCriticalSection(&object->cs); object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": audio_converter_lock");
+ if (FAILED(hr = MFCreateAttributes(&object->attributes, 0))) + { + IMFTransform_Release(&object->IMFTransform_iface); + return hr; + } + + if (FAILED(hr = MFCreateAttributes(&object->output_attributes, 0))) + { + IMFTransform_Release(&object->IMFTransform_iface); + return hr; + } + object->container = gst_bin_new(NULL);
if (!(object->appsrc = gst_element_factory_make("appsrc", NULL)))
Does it make a difference in practice? I think all of that is optional.
On 1/19/21 2:47 PM, Nikolay Sivov wrote:
Does it make a difference in practice? I think all of that is optional.
I think I remember needing to add this for some app, but I honestly can't remember which. Probably best to just wait and see if we can get away without it.