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:
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)
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:
On 1/18/21 10:30 PM, Derek Lesho wrote:
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)
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.
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.