[PATCH 15/16] Introduce IMFSample -> GstBuffer converter.
Derek Lesho
dlesho at codeweavers.com
Wed Mar 25 19:12:40 CDT 2020
Signed-off-by: Derek Lesho <dlesho at codeweavers.com>
---
dlls/winegstreamer/gst_private.h | 1 +
dlls/winegstreamer/mfplat.c | 74 ++++++++++++++++++++++++++++++++
2 files changed, 75 insertions(+)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index e594ed1419..489b543738 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -58,6 +58,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);
enum source_type
{
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index aa042a59d3..5fbb331c89 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -1057,3 +1057,77 @@ IMFSample* mf_sample_from_gst_buffer(GstBuffer *gst_buffer)
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);
+
+ 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;
+
+ 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;
+}
--
2.25.1
More information about the wine-devel
mailing list