[PATCH 2/5] winegstreamer: Wait for duration-changed when querying for duration.
Anton Baskanov
baskanov at gmail.com
Mon Jun 21 09:35:03 CDT 2021
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51126
Signed-off-by: Anton Baskanov <baskanov at gmail.com>
---
dlls/winegstreamer/wg_parser.c | 59 ++++++++++++++++++++--------------
1 file changed, 34 insertions(+), 25 deletions(-)
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
index acea68ad27d..49823508568 100644
--- a/dlls/winegstreamer/wg_parser.c
+++ b/dlls/winegstreamer/wg_parser.c
@@ -1536,37 +1536,46 @@ static HRESULT CDECL wg_parser_connect(struct wg_parser *parser, uint64_t file_s
while (!stream->has_caps && !parser->error)
pthread_cond_wait(&parser->init_cond, &parser->mutex);
- if (parser->error)
+ /* For some GStreamer elements we have to wait for duration-changed
+ * before querying for duration. However, elements that provide
+ * duration immediatly don't sent this message, so try to query first
+ * and then wait if the query fails. */
+ for (;;)
{
- pthread_mutex_unlock(&parser->mutex);
- return E_FAIL;
- }
- /* GStreamer doesn't actually provide any guarantees about when duration
- * is available, even for seekable streams. However, many elements (e.g.
- * avidemux, wavparse, qtdemux) in practice record duration before
- * fixing caps, so as a heuristic, wait until we get caps before trying
- * to query for duration. */
- if (gst_pad_query_duration(stream->their_src, GST_FORMAT_TIME, &duration))
- {
- stream->duration = duration / 100;
- }
- else
- {
- WARN("Failed to query time duration; trying to convert from byte length.\n");
-
- /* To accurately get a duration for the stream, we want to only consider the
- * length of that stream. Hence, query for the pad duration, instead of
- * using the file duration. */
- if (gst_pad_query_duration(stream->their_src, GST_FORMAT_BYTES, &byte_length)
- && gst_pad_query_convert(stream->their_src, GST_FORMAT_BYTES, byte_length,
- GST_FORMAT_TIME, &duration))
+ if (parser->error)
+ {
+ pthread_mutex_unlock(&parser->mutex);
+ return E_FAIL;
+ }
+ if (gst_pad_query_duration(stream->their_src, GST_FORMAT_TIME, &duration))
{
stream->duration = duration / 100;
+ break;
}
- else
+ /* GStreamer versions before 1.5.90 fail to compute the duration of
+ * short MP3 files without Xing or VBRI headers, but it's still
+ * possible to get an estimated duration by converting from byte
+ * length. See <gstreamer.git:6d78d32d51970003d7>. */
+ if (stream->eos)
{
- ERR("Failed to query duration.\n");
+ WARN("Failed to query time duration; trying to convert from byte length.\n");
+
+ /* To accurately get a duration for the stream, we want to only consider the
+ * length of that stream. Hence, query for the pad duration, instead of
+ * using the file duration. */
+ if (gst_pad_query_duration(stream->their_src, GST_FORMAT_BYTES, &byte_length)
+ && gst_pad_query_convert(stream->their_src, GST_FORMAT_BYTES, byte_length,
+ GST_FORMAT_TIME, &duration))
+ {
+ stream->duration = duration / 100;
+ }
+ else
+ {
+ ERR("Failed to query duration.\n");
+ }
+ break;
}
+ pthread_cond_wait(&parser->init_cond, &parser->mutex);
}
}
--
2.25.1
More information about the wine-devel
mailing list