On 3/24/20 2:39 PM, Derek Lesho wrote:
Signed-off-by: Derek Lesho dlesho@codeweavers.com
dlls/winegstreamer/gst_private.h | 2 + dlls/winegstreamer/mfplat.c | 162 +++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index a6c3fd3784..13ba467a9e 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -57,5 +57,7 @@ extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
IMFMediaType* media_type_from_caps(GstCaps *caps); GstCaps *caps_from_media_type(IMFMediaType *type); +IMFSample* mf_sample_from_gst_buffer(GstBuffer *in); +GstBuffer* gst_buffer_from_mf_sample(IMFSample *in);
#endif /* __GST_PRIVATE_INCLUDED__ */ diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c index a6f4fbc2ec..e66bc3ffe6 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c @@ -964,3 +964,165 @@ GstCaps *caps_from_media_type(IMFMediaType *type) ERR("Unrecognized major type %s\n", debugstr_guid(&major_type)); return NULL; }
+/* IMFSample = GstBuffer
- IMFBuffer = GstMemory */
IMFBuffer isn't an interface.
I'm not sure that this comment is especially useful anyway, though.
+/* TODO: Future optimization could be to create a custom
- IMFMediaBuffer wrapper around GstMemory, and to utilize
- gst_memory_new_wrapped on IMFMediaBuffer data */
This seems like a better idea than what's done below; any particular reason why not?
+IMFSample* mf_sample_from_gst_buffer(GstBuffer *gst_buffer) +{
- IMFSample *out = NULL;
- LONGLONG duration, time;
- int buffer_count;
- HRESULT hr;
- if (FAILED(hr = MFCreateSample(&out)))
goto fail;- duration = GST_BUFFER_DURATION(gst_buffer);
- time = GST_BUFFER_PTS(gst_buffer);
- if (FAILED(IMFSample_SetSampleDuration(out, duration / 100)))
goto fail;- if (FAILED(IMFSample_SetSampleTime(out, time / 100)))
goto fail;- buffer_count = gst_buffer_n_memory(gst_buffer);
- for (unsigned int i = 0; i < buffer_count; i++)
- {
GstMemory *memory = gst_buffer_get_memory(gst_buffer, i);IMFMediaBuffer *mf_buffer = NULL;GstMapInfo map_info;BYTE *buf_data;if (!memory){hr = ERROR_INTERNAL_ERROR;
That's not an HRESULT.
goto loop_done;}if (!(gst_memory_map(memory, &map_info, GST_MAP_READ))){hr = ERROR_INTERNAL_ERROR;goto loop_done;}if (FAILED(hr = MFCreateMemoryBuffer(map_info.maxsize, &mf_buffer))){gst_memory_unmap(memory, &map_info);goto loop_done;}if (FAILED(hr = IMFMediaBuffer_Lock(mf_buffer, &buf_data, NULL, NULL))){gst_memory_unmap(memory, &map_info);goto loop_done;}memcpy(buf_data, map_info.data, map_info.size);gst_memory_unmap(memory, &map_info);if (FAILED(hr = IMFMediaBuffer_Unlock(mf_buffer)))goto loop_done;if (FAILED(hr = IMFMediaBuffer_SetCurrentLength(mf_buffer, map_info.size)))goto loop_done;if (FAILED(hr = IMFSample_AddBuffer(out, mf_buffer)))goto loop_done;loop_done:if (mf_buffer)IMFMediaBuffer_Release(mf_buffer);if (memory)gst_memory_unref(memory);if (FAILED(hr))goto fail;- }
- return out;
- fail:
- ERR("Failed to copy IMFSample to GstBuffer, hr = %#x\n", hr);
- IMFSample_Release(out);
- return NULL;
+}
+GstBuffer* gst_buffer_from_mf_sample(IMFSample *mf_sample) +{
- GstBuffer *out = gst_buffer_new();
- IMFMediaBuffer *mf_buffer = NULL;
- LONGLONG duration, time;
- DWORD buffer_count;
- 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 (unsigned int i = 0; i < buffer_count; i++)
- {
DWORD buffer_max_size, 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_GetMaxLength(mf_buffer, &buffer_max_size)))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);
Why is this call to gst_memory_resize() here?
if (!(gst_memory_map(memory, &map_info, GST_MAP_WRITE))){hr = ERROR_INTERNAL_ERROR;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;if (FAILED(hr = IMFMediaBuffer_SetCurrentLength(mf_buffer, buffer_size)))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;
+}