From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winegstreamer/gst_private.h | 2 ++ dlls/winegstreamer/unixlib.h | 1 + dlls/winegstreamer/wg_sample.c | 48 +++++++++++++++++++++++++ dlls/winegstreamer/wg_transform.c | 4 +++ dlls/winegstreamer/wm_reader.c | 58 ++++++++++++++----------------- 5 files changed, 81 insertions(+), 32 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 8daa8223584..8fb1bdf9576 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -122,6 +122,8 @@ IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format); void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format);
HRESULT wg_sample_wrap_mf(IMFSample *mf_sample, struct wg_sample **out); +HRESULT wg_sample_wrap_wm(INSSBuffer *wm_sample, QWORD pts, QWORD duration, DWORD flags, + struct wg_sample **out); void wg_sample_unwrap(struct wg_sample *wg_sample);
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj); diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index 79926042f3c..7e639abfd3c 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -121,6 +121,7 @@ enum wg_sample_flag WG_SAMPLE_FLAG_HAS_PTS = 2, WG_SAMPLE_FLAG_HAS_DURATION = 4, WG_SAMPLE_FLAG_SYNC_POINT = 8, + WG_SAMPLE_FLAG_DISCONTINUITY = 0x10, };
struct wg_sample diff --git a/dlls/winegstreamer/wg_sample.c b/dlls/winegstreamer/wg_sample.c index e20e393e396..fd757fa44f6 100644 --- a/dlls/winegstreamer/wg_sample.c +++ b/dlls/winegstreamer/wg_sample.c @@ -24,6 +24,7 @@ #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(mfplat); +WINE_DECLARE_DEBUG_CHANNEL(wmvcore);
struct sample { @@ -31,6 +32,7 @@ struct sample enum wg_sample_type { WG_SAMPLE_TYPE_MF = 1, + WG_SAMPLE_TYPE_WM = 2, } type;
union @@ -40,6 +42,10 @@ struct sample IMFSample *sample; IMFMediaBuffer *buffer; } mf; + struct + { + INSSBuffer *sample; + } wm; } u; };
@@ -89,6 +95,41 @@ failed: return hr; }
+HRESULT wg_sample_wrap_wm(INSSBuffer *wm_sample, QWORD pts, QWORD duration, DWORD flags, + struct wg_sample **out) +{ + DWORD current_length, max_length; + struct sample *sample; + BYTE *buffer; + HRESULT hr; + + if (FAILED(hr = INSSBuffer_GetBufferAndLength(wm_sample, &buffer, ¤t_length))) + return hr; + if (FAILED(hr = INSSBuffer_GetMaxLength(wm_sample, &max_length))) + return hr; + if (!(sample = calloc(1, sizeof(*sample)))) + return E_OUTOFMEMORY; + + if ((sample->wg_sample.pts = pts) != ~(QWORD)0) + sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_PTS; + if ((sample->wg_sample.duration = duration) != ~(QWORD)0) + sample->wg_sample.flags |= WG_SAMPLE_FLAG_HAS_DURATION; + if (flags & WM_SF_CLEANPOINT) + sample->wg_sample.flags |= WG_SAMPLE_FLAG_SYNC_POINT; + if (flags & WM_SF_DISCONTINUITY) + sample->wg_sample.flags |= WG_SAMPLE_FLAG_DISCONTINUITY; + + INSSBuffer_AddRef((sample->u.wm.sample = wm_sample)); + sample->wg_sample.data = buffer; + sample->wg_sample.size = current_length; + sample->wg_sample.max_size = max_length; + sample->type = WG_SAMPLE_TYPE_WM; + + TRACE_(wmvcore)("Created wg_sample %p for sample %p.\n", &sample->wg_sample, wm_sample); + *out = &sample->wg_sample; + return S_OK; +} + void wg_sample_unwrap(struct wg_sample *wg_sample) { struct sample *sample = CONTAINING_RECORD(wg_sample, struct sample, wg_sample); @@ -112,6 +153,13 @@ void wg_sample_unwrap(struct wg_sample *wg_sample) IMFSample_Release(sample->u.mf.sample); break;
+ case WG_SAMPLE_TYPE_WM: + TRACE_(wmvcore)("wg_sample %p\n", wg_sample); + + INSSBuffer_SetLength(sample->u.wm.sample, wg_sample->size); + INSSBuffer_Release(sample->u.wm.sample); + break; + default: FIXME("Unknown wg_sample %p, type %u\n", wg_sample, sample->type); break; diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index 7f0d74340db..bd53c13e84b 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -523,6 +523,8 @@ NTSTATUS wg_transform_push_data(void *args) GST_BUFFER_DURATION(buffer) = sample->duration * 100; if (!(sample->flags & WG_SAMPLE_FLAG_SYNC_POINT)) GST_BUFFER_FLAG_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT); + if (sample->flags & WG_SAMPLE_FLAG_DISCONTINUITY) + GST_BUFFER_FLAG_SET(buffer, GST_BUFFER_FLAG_DISCONT); gst_buffer_list_insert(transform->input, -1, buffer);
GST_INFO("Copied %u bytes from sample %p to input buffer list", sample->size, sample); @@ -648,6 +650,8 @@ NTSTATUS wg_sample_read_from_buffer(GstBuffer *buffer, GstCaps *caps, gsize plan } if (!GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT)) sample->flags |= WG_SAMPLE_FLAG_SYNC_POINT; + if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DISCONT)) + sample->flags |= WG_SAMPLE_FLAG_DISCONTINUITY;
GST_INFO("Copied %u bytes, sample %p, flags %#x", sample->size, sample, sample->flags); return STATUS_SUCCESS; diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index 03adea8a318..72a2d207c57 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -1877,11 +1877,11 @@ HRESULT wm_reader_get_stream_sample(struct wm_reader *reader, WORD stream_number IWMReaderCallbackAdvanced *callback_advanced = reader->callback_advanced; struct wg_parser_stream *wg_stream; struct wg_parser_buffer wg_buffer; + struct wg_sample *wg_sample; struct wm_stream *stream; - DWORD size, capacity; INSSBuffer *sample; + bool success; HRESULT hr; - BYTE *data;
for (;;) { @@ -1930,7 +1930,6 @@ HRESULT wm_reader_get_stream_sample(struct wm_reader *reader, WORD stream_number stream->index + 1, wg_buffer.size, &sample, NULL))) { ERR("Failed to allocate stream sample of %u bytes, hr %#lx.\n", wg_buffer.size, hr); - wg_parser_stream_release_buffer(wg_stream); return hr; } } @@ -1940,7 +1939,6 @@ HRESULT wm_reader_get_stream_sample(struct wm_reader *reader, WORD stream_number stream->index, wg_buffer.size, &sample, NULL))) { ERR("Failed to allocate output sample of %u bytes, hr %#lx.\n", wg_buffer.size, hr); - wg_parser_stream_release_buffer(wg_stream); return hr; } } @@ -1950,10 +1948,7 @@ HRESULT wm_reader_get_stream_sample(struct wm_reader *reader, WORD stream_number
/* FIXME: Should these be pooled? */ if (!(object = calloc(1, offsetof(struct buffer, data[wg_buffer.size])))) - { - wg_parser_stream_release_buffer(wg_stream); return E_OUTOFMEMORY; - }
object->INSSBuffer_iface.lpVtbl = &buffer_vtbl; object->refcount = 1; @@ -1963,38 +1958,37 @@ HRESULT wm_reader_get_stream_sample(struct wm_reader *reader, WORD stream_number sample = &object->INSSBuffer_iface; }
- if (FAILED(hr = INSSBuffer_GetBufferAndLength(sample, &data, &size))) - ERR("Failed to get data pointer, hr %#lx.\n", hr); - if (FAILED(hr = INSSBuffer_GetMaxLength(sample, &capacity))) - ERR("Failed to get capacity, hr %#lx.\n", hr); - if (wg_buffer.size > capacity) - ERR("Returned capacity %lu is less than requested capacity %u.\n", capacity, wg_buffer.size); + if (FAILED(hr = wg_sample_wrap_wm(sample, ~(QWORD)0, ~(QWORD)0, 0, &wg_sample))) + { + ERR("Failed to create wg_sample, hr %#lx.\n", hr); + INSSBuffer_Release(sample); + return hr; + }
- if (!wg_parser_stream_copy_buffer(wg_stream, data, 0, wg_buffer.size)) + if ((success = wg_parser_stream_read_data(wg_stream, wg_sample))) + { + if (!(wg_sample->flags & WG_SAMPLE_FLAG_HAS_PTS)) + FIXME("Missing PTS.\n"); + if (!(wg_sample->flags & WG_SAMPLE_FLAG_HAS_DURATION)) + FIXME("Missing duration.\n"); + + *pts = wg_sample->pts; + *duration = wg_sample->duration; + *flags = 0; + if (wg_sample->flags & WG_SAMPLE_FLAG_DISCONTINUITY) + *flags |= WM_SF_DISCONTINUITY; + if (wg_sample->flags & WG_SAMPLE_FLAG_SYNC_POINT) + *flags |= WM_SF_CLEANPOINT; + } + wg_sample_unwrap(wg_sample); + + if (!success) { /* The GStreamer pin has been flushed. */ INSSBuffer_Release(sample); continue; }
- if (FAILED(hr = INSSBuffer_SetLength(sample, wg_buffer.size))) - ERR("Failed to set size %u, hr %#lx.\n", wg_buffer.size, hr); - - wg_parser_stream_release_buffer(wg_stream); - - if (!wg_buffer.has_pts) - FIXME("Missing PTS.\n"); - if (!wg_buffer.has_duration) - FIXME("Missing duration.\n"); - - *pts = wg_buffer.pts; - *duration = wg_buffer.duration; - *flags = 0; - if (wg_buffer.discontinuity) - *flags |= WM_SF_DISCONTINUITY; - if (!wg_buffer.delta) - *flags |= WM_SF_CLEANPOINT; - *ret_sample = sample; *ret_stream_number = stream_number; return S_OK;