Fixes: 5ca1d28e8df7e3e87e5b9f3ff51445b07dfcc2fb Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index ff41af1205b..ed65a0a598d 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -2089,7 +2089,7 @@ static HRESULT WINAPI GST_QualityControl_Notify(IQualityControl *iface, IBaseFil
/* The documentation specifies that timestamp + diff must be nonnegative. */ diff = qm.Late * 100; - if (timestamp < -diff) + if (diff < 0 && timestamp < (GstClockTime)-diff) diff = -timestamp;
evt = gst_event_new_qos(type, qm.Proportion / 1000.0, diff, timestamp);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gst_private.h | 22 +++++++++++++++++ dlls/winegstreamer/gstdemux.c | 41 ++++++++++++++++++-------------- 2 files changed, 45 insertions(+), 18 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index e6fb841fc87..8f90b329ff7 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -36,9 +36,31 @@ #include "winuser.h" #include "dshow.h" #include "strmif.h" +#include "wine/debug.h" #include "wine/heap.h" #include "wine/strmbase.h"
+static inline const char *debugstr_time(REFERENCE_TIME time) +{ + ULONGLONG abstime = time >= 0 ? time : -time; + unsigned int i = 0, j = 0; + char buffer[23], rev[23]; + + while (abstime || i <= 8) + { + buffer[i++] = '0' + (abstime % 10); + abstime /= 10; + if (i == 7) buffer[i++] = '.'; + } + if (time < 0) buffer[i++] = '-'; + + while (i--) rev[j++] = buffer[i]; + while (rev[j-1] == '0' && rev[j-2] != '.') --j; + rev[j] = 0; + + return wine_dbg_sprintf("%s", rev); +} + #define MEDIATIME_FROM_BYTES(x) ((LONGLONG)(x) * 10000000)
extern LONG object_locks; diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index ed65a0a598d..42bac1d1a5d 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -2061,45 +2061,50 @@ static ULONG WINAPI GST_QualityControl_Release(IQualityControl *iface) return IPin_Release(&pin->pin.pin.IPin_iface); }
-static HRESULT WINAPI GST_QualityControl_Notify(IQualityControl *iface, IBaseFilter *sender, Quality qm) +static HRESULT WINAPI GST_QualityControl_Notify(IQualityControl *iface, IBaseFilter *sender, Quality q) { struct gstdemux_source *pin = impl_from_IQualityControl(iface); GstQOSType type = GST_QOS_TYPE_OVERFLOW; GstClockTime timestamp; GstClockTimeDiff diff; - GstEvent *evt; + GstEvent *event;
- TRACE("(%p)->(%p, { 0x%x %u %s %s })\n", pin, sender, - qm.Type, qm.Proportion, - wine_dbgstr_longlong(qm.Late), - wine_dbgstr_longlong(qm.TimeStamp)); + TRACE("pin %p, sender %p, type %s, proportion %u, late %s, timestamp %s.\n", + pin, sender, q.Type == Famine ? "Famine" : "Flood", q.Proportion, + debugstr_time(q.Late), debugstr_time(q.TimeStamp));
mark_wine_thread();
- /* GSTQOS_TYPE_OVERFLOW is also used for buffers that arrive on time, but + /* GST_QOS_TYPE_OVERFLOW is also used for buffers that arrive on time, but * DirectShow filters might use Famine, so check that there actually is an * underrun. */ - if (qm.Type == Famine && qm.Proportion > 1000) + if (q.Type == Famine && q.Proportion < 1000) type = GST_QOS_TYPE_UNDERFLOW;
/* DirectShow filters sometimes pass negative timestamps (Audiosurf uses the * current time instead of the time of the last buffer). GstClockTime is * unsigned, so clamp it to 0. */ - timestamp = max(qm.TimeStamp * 100, 0); + timestamp = max(q.TimeStamp * 100, 0);
/* The documentation specifies that timestamp + diff must be nonnegative. */ - diff = qm.Late * 100; + diff = q.Late * 100; if (diff < 0 && timestamp < (GstClockTime)-diff) diff = -timestamp;
- evt = gst_event_new_qos(type, qm.Proportion / 1000.0, diff, timestamp); - - if (!evt) { - WARN("Failed to create QOS event\n"); - return E_INVALIDARG; - } - - gst_pad_push_event(pin->my_sink, evt); + /* DirectShow "Proportion" describes what percentage of buffers the upstream + * filter should keep (i.e. dropping the rest). If frames are late, the + * proportion will be less than 1. For example, a proportion of 500 means + * that the element should drop half of its frames, essentially because + * frames are taking twice as long as they should to arrive. + * + * GStreamer "proportion" is the inverse of this; it describes how much + * faster the upstream element should produce frames. I.e. if frames are + * taking twice as long as they should to arrive, we want the frames to be + * decoded twice as fast, and so we pass 2.0 to GStreamer. */ + if (!(event = gst_event_new_qos(type, 1000.0 / q.Proportion, diff, timestamp))) + ERR("Failed to create QOS event.\n"); + + gst_pad_push_event(pin->my_sink, event);
return S_OK; }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=80773
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/gst_private.h:36 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/gst_private.h:36 Task: Patch failed to apply