Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/winegstreamer/gstdemux.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 9114e6610a3..805a7b8c089 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -826,6 +826,9 @@ static GstFlowReturn got_data_sink(GstPad *pad, GstObject *parent, GstBuffer *bu
hr = IMediaSample_SetActualDataLength(sample, info.size); if(FAILED(hr)){ + IMediaSample_Release(sample); + gst_buffer_unmap(buf, &info); + gst_buffer_unref(buf); WARN("SetActualDataLength failed: %08x\n", hr); return GST_FLOW_FLUSHING; }
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/winegstreamer/gstdemux.c | 76 ++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 36 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 805a7b8c089..3ab4ea9c0d6 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -793,51 +793,20 @@ static DWORD CALLBACK push_data(LPVOID iface) return 0; }
-static GstFlowReturn got_data_sink(GstPad *pad, GstObject *parent, GstBuffer *buf) +static HRESULT send_sample(struct gstdemux_source *pin, IMediaSample *sample, GstBuffer *buf, GstMapInfo *info) { - struct gstdemux_source *pin = gst_pad_get_element_private(pad); - struct gstdemux *This = impl_from_strmbase_filter(pin->pin.pin.filter); HRESULT hr; BYTE *ptr = NULL; - IMediaSample *sample; - GstMapInfo info; - - TRACE("%p %p\n", pad, buf); - - if (This->initial) { - gst_buffer_unref(buf); - return GST_FLOW_OK; - }
- hr = BaseOutputPinImpl_GetDeliveryBuffer(&pin->pin, &sample, NULL, NULL, 0); - - if (hr == VFW_E_NOT_CONNECTED) { - gst_buffer_unref(buf); - return GST_FLOW_NOT_LINKED; - } - - if (FAILED(hr)) { - gst_buffer_unref(buf); - ERR("Could not get a delivery buffer (%x), returning GST_FLOW_FLUSHING\n", hr); - return GST_FLOW_FLUSHING; - } - - gst_buffer_map(buf, &info, GST_MAP_READ); - - hr = IMediaSample_SetActualDataLength(sample, info.size); + hr = IMediaSample_SetActualDataLength(sample, info->size); if(FAILED(hr)){ - IMediaSample_Release(sample); - gst_buffer_unmap(buf, &info); - gst_buffer_unref(buf); WARN("SetActualDataLength failed: %08x\n", hr); - return GST_FLOW_FLUSHING; + return hr; }
IMediaSample_GetPointer(sample, &ptr);
- memcpy(ptr, info.data, info.size); - - gst_buffer_unmap(buf, &info); + memcpy(ptr, info->data, info->size);
if (GST_BUFFER_PTS_IS_VALID(buf)) { REFERENCE_TIME rtStart = gst_segment_to_running_time(pin->segment, GST_FORMAT_TIME, buf->pts); @@ -874,8 +843,43 @@ static GstFlowReturn got_data_sink(GstPad *pad, GstObject *parent, GstBuffer *bu
TRACE("sending sample returned: %08x\n", hr);
+ return hr; +} + +static GstFlowReturn got_data_sink(GstPad *pad, GstObject *parent, GstBuffer *buf) +{ + struct gstdemux_source *pin = gst_pad_get_element_private(pad); + struct gstdemux *This = impl_from_strmbase_filter(pin->pin.pin.filter); + HRESULT hr; + IMediaSample *sample; + GstMapInfo info; + + TRACE("%p %p\n", pad, buf); + + if (This->initial) { + gst_buffer_unref(buf); + return GST_FLOW_OK; + } + + hr = BaseOutputPinImpl_GetDeliveryBuffer(&pin->pin, &sample, NULL, NULL, 0); + + if (FAILED(hr)) + { + if (hr != VFW_E_NOT_CONNECTED) + ERR("Could not get a delivery buffer (%x), returning GST_FLOW_FLUSHING\n", hr); + } + else + { + gst_buffer_map(buf, &info, GST_MAP_READ); + + hr = send_sample(pin, sample, buf, &info); + + gst_buffer_unmap(buf, &info); + + IMediaSample_Release(sample); + } + gst_buffer_unref(buf); - IMediaSample_Release(sample);
if (hr == VFW_E_NOT_CONNECTED) return GST_FLOW_NOT_LINKED;
Signed-off-by: Zebediah Figura z.figura12@gmail.com
[Sorry for the slow review...]
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50355 Signed-off-by: Anton Baskanov baskanov@gmail.com --- v2: Set discontinuity and sync point flags only for the first sample. v3: Only split raw audio, set sync point flag for all samples. --- dlls/winegstreamer/gstdemux.c | 80 +++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 18 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 3ab4ea9c0d6..1e91c9f8e7e 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -793,12 +793,13 @@ static DWORD CALLBACK push_data(LPVOID iface) return 0; }
-static HRESULT send_sample(struct gstdemux_source *pin, IMediaSample *sample, GstBuffer *buf, GstMapInfo *info) +static HRESULT send_sample(struct gstdemux_source *pin, IMediaSample *sample, + GstBuffer *buf, GstMapInfo *info, gsize offset, gsize size, DWORD bytes_per_second) { HRESULT hr; BYTE *ptr = NULL;
- hr = IMediaSample_SetActualDataLength(sample, info->size); + hr = IMediaSample_SetActualDataLength(sample, size); if(FAILED(hr)){ WARN("SetActualDataLength failed: %08x\n", hr); return hr; @@ -806,18 +807,27 @@ static HRESULT send_sample(struct gstdemux_source *pin, IMediaSample *sample, Gs
IMediaSample_GetPointer(sample, &ptr);
- memcpy(ptr, info->data, info->size); + memcpy(ptr, &info->data[offset], size);
if (GST_BUFFER_PTS_IS_VALID(buf)) { - REFERENCE_TIME rtStart = gst_segment_to_running_time(pin->segment, GST_FORMAT_TIME, buf->pts); + REFERENCE_TIME rtStart; + GstClockTime ptsStart = buf->pts; + if (offset > 0) + ptsStart = buf->pts + gst_util_uint64_scale(offset, GST_SECOND, bytes_per_second); + rtStart = gst_segment_to_running_time(pin->segment, GST_FORMAT_TIME, ptsStart); if (rtStart >= 0) rtStart /= 100;
if (GST_BUFFER_DURATION_IS_VALID(buf)) { - REFERENCE_TIME tStart = buf->pts / 100; - REFERENCE_TIME tStop = (buf->pts + buf->duration) / 100; REFERENCE_TIME rtStop; - rtStop = gst_segment_to_running_time(pin->segment, GST_FORMAT_TIME, buf->pts + buf->duration); + REFERENCE_TIME tStart; + REFERENCE_TIME tStop; + GstClockTime ptsStop = buf->pts + buf->duration; + if (offset + size < info->size) + ptsStop = buf->pts + gst_util_uint64_scale(offset + size, GST_SECOND, bytes_per_second); + tStart = ptsStart / 100; + tStop = ptsStop / 100; + rtStop = gst_segment_to_running_time(pin->segment, GST_FORMAT_TIME, ptsStop); if (rtStop >= 0) rtStop /= 100; TRACE("Current time on %p: %i to %i ms\n", pin, (int)(rtStart / 10000), (int)(rtStop / 10000)); @@ -832,7 +842,7 @@ static HRESULT send_sample(struct gstdemux_source *pin, IMediaSample *sample, Gs IMediaSample_SetMediaTime(sample, NULL, NULL); }
- IMediaSample_SetDiscontinuity(sample, GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_DISCONT)); + IMediaSample_SetDiscontinuity(sample, !offset && GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_DISCONT)); IMediaSample_SetPreroll(sample, GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_LIVE)); IMediaSample_SetSyncPoint(sample, !GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_DELTA_UNIT));
@@ -850,7 +860,7 @@ static GstFlowReturn got_data_sink(GstPad *pad, GstObject *parent, GstBuffer *bu { struct gstdemux_source *pin = gst_pad_get_element_private(pad); struct gstdemux *This = impl_from_strmbase_filter(pin->pin.pin.filter); - HRESULT hr; + HRESULT hr = S_OK; IMediaSample *sample; GstMapInfo info;
@@ -861,24 +871,58 @@ static GstFlowReturn got_data_sink(GstPad *pad, GstObject *parent, GstBuffer *bu return GST_FLOW_OK; }
- hr = BaseOutputPinImpl_GetDeliveryBuffer(&pin->pin, &sample, NULL, NULL, 0); + gst_buffer_map(buf, &info, GST_MAP_READ);
- if (FAILED(hr)) + if (IsEqualGUID(&pin->pin.pin.mt.formattype, &FORMAT_WaveFormatEx) + && (IsEqualGUID(&pin->pin.pin.mt.subtype, &MEDIASUBTYPE_PCM) + || IsEqualGUID(&pin->pin.pin.mt.subtype, &MEDIASUBTYPE_IEEE_FLOAT))) { - if (hr != VFW_E_NOT_CONNECTED) - ERR("Could not get a delivery buffer (%x), returning GST_FLOW_FLUSHING\n", hr); + WAVEFORMATEX *format = (WAVEFORMATEX *)pin->pin.pin.mt.pbFormat; + gsize offset = 0; + while (offset < info.size) + { + gsize advance; + + hr = BaseOutputPinImpl_GetDeliveryBuffer(&pin->pin, &sample, NULL, NULL, 0); + + if (FAILED(hr)) + { + if (hr != VFW_E_NOT_CONNECTED) + ERR("Could not get a delivery buffer (%x), returning GST_FLOW_FLUSHING\n", hr); + break; + } + + advance = min(IMediaSample_GetSize(sample), info.size - offset); + + hr = send_sample(pin, sample, buf, &info, offset, advance, format->nAvgBytesPerSec); + + IMediaSample_Release(sample); + + if (FAILED(hr)) + break; + + offset += advance; + } } else { - gst_buffer_map(buf, &info, GST_MAP_READ); - - hr = send_sample(pin, sample, buf, &info); + hr = BaseOutputPinImpl_GetDeliveryBuffer(&pin->pin, &sample, NULL, NULL, 0);
- gst_buffer_unmap(buf, &info); + if (FAILED(hr)) + { + if (hr != VFW_E_NOT_CONNECTED) + ERR("Could not get a delivery buffer (%x), returning GST_FLOW_FLUSHING\n", hr); + } + else + { + hr = send_sample(pin, sample, buf, &info, 0, info.size, 0);
- IMediaSample_Release(sample); + IMediaSample_Release(sample); + } }
+ gst_buffer_unmap(buf, &info); + gst_buffer_unref(buf);
if (hr == VFW_E_NOT_CONNECTED)
Signed-off-by: Zebediah Figura z.figura12@gmail.com