summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Blechmann <tim@klingt.org>2024-05-01 21:00:24 +0800
committerTim Blechmann <tim@klingt.org>2024-05-07 08:35:32 +0800
commit32c77267af32a82da040811d4b6d2274b34fa577 (patch)
treeae2045bd3e8ca6706cd5a60a3fbb4ff5c828ea68
parentc599e85c50858d57de92ba4316011ea3872b95a3 (diff)
GStreamer: fix access to duration metadata
Fixes: QTBUG-124544 Pick-to: 6.5 6.7 Change-Id: I6cf975fab3644a7c5d51908f30441a22e6321573 Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io>
-rw-r--r--src/plugins/multimedia/gstreamer/common/qgst_handle_types_p.h13
-rw-r--r--src/plugins/multimedia/gstreamer/common/qgstreamermetadata.cpp52
-rw-r--r--tests/auto/unit/multimedia/gstreamer_backend/tst_gstreamer_backend.cpp1
3 files changed, 63 insertions, 3 deletions
diff --git a/src/plugins/multimedia/gstreamer/common/qgst_handle_types_p.h b/src/plugins/multimedia/gstreamer/common/qgst_handle_types_p.h
index c37ac5971..5cbbfaf19 100644
--- a/src/plugins/multimedia/gstreamer/common/qgst_handle_types_p.h
+++ b/src/plugins/multimedia/gstreamer/common/qgst_handle_types_p.h
@@ -163,6 +163,18 @@ struct QUniqueGErrorHandleTraits
}
};
+
+struct QUniqueGstDateTimeHandleTraits
+{
+ using Type = GstDateTime *;
+ static constexpr Type invalidValue() noexcept { return nullptr; }
+ static bool close(Type handle) noexcept
+ {
+ gst_date_time_unref(handle);
+ return true;
+ }
+};
+
struct QFileDescriptorHandleTraits
{
using Type = int;
@@ -237,6 +249,7 @@ using QGstSampleHandle = QGstImpl::QSharedHandle<QGstImpl::QGstSampleHandleTrait
using QUniqueGstStructureHandle = QUniqueHandle<QGstImpl::QUniqueGstStructureHandleTraits>;
using QUniqueGStringHandle = QUniqueHandle<QGstImpl::QUniqueGStringHandleTraits>;
using QUniqueGErrorHandle = QUniqueHandle<QGstImpl::QUniqueGErrorHandleTraits>;
+using QUniqueGstDateTimeHandle = QUniqueHandle<QGstImpl::QUniqueGstDateTimeHandleTraits>;
using QFileDescriptorHandle = QUniqueHandle<QGstImpl::QFileDescriptorHandleTraits>;
using QGstBufferHandle = QGstImpl::QGstMiniObjectHandleHelper<GstBuffer>::SharedHandle;
using QGstContextHandle = QGstImpl::QGstMiniObjectHandleHelper<GstContext>::UniqueHandle;
diff --git a/src/plugins/multimedia/gstreamer/common/qgstreamermetadata.cpp b/src/plugins/multimedia/gstreamer/common/qgstreamermetadata.cpp
index 3a229877d..fab4750f9 100644
--- a/src/plugins/multimedia/gstreamer/common/qgstreamermetadata.cpp
+++ b/src/plugins/multimedia/gstreamer/common/qgstreamermetadata.cpp
@@ -234,20 +234,68 @@ std::optional<double> parseFractionAsDouble(const GValue &val)
return double(nom) / double(denom);
}
-// internal
+constexpr std::string_view extendedComment{ GST_TAG_EXTENDED_COMMENT };
+
+void addTagsFromExtendedComment(const GstTagList *list, const gchar *tag, QMediaMetaData &metadata)
+{
+ using namespace Qt::Literals;
+ assert(tag == extendedComment);
+
+ int entryCount = gst_tag_list_get_tag_size(list, tag);
+ for (int i = 0; i != entryCount; ++i) {
+ const GValue *value = gst_tag_list_get_value_index(list, tag, i);
+
+ const QLatin1StringView strValue{ g_value_get_string(value) };
+
+ auto equalIndex = strValue.indexOf(QLatin1StringView("="));
+ if (equalIndex == -1) {
+ qDebug() << "Cannot parse GST_TAG_EXTENDED_COMMENT entry: " << value;
+ continue;
+ }
+
+ const QLatin1StringView key = strValue.first(equalIndex);
+ const QLatin1StringView valueString = strValue.last(strValue.size() - equalIndex - 1);
+
+ if (key == "DURATION"_L1) {
+ QUniqueGstDateTimeHandle duration{
+ gst_date_time_new_from_iso8601_string(valueString.data()),
+ };
+
+ if (duration) {
+ using namespace std::chrono;
+
+ auto chronoDuration = hours(gst_date_time_get_hour(duration.get()))
+ + minutes(gst_date_time_get_minute(duration.get()))
+ + seconds(gst_date_time_get_second(duration.get()))
+ + microseconds(gst_date_time_get_microsecond(duration.get()));
+
+ metadata.insert(QMediaMetaData::Duration,
+ QVariant::fromValue(round<milliseconds>(chronoDuration).count()));
+ }
+ }
+ }
+}
+
void addTagToMetaData(const GstTagList *list, const gchar *tag, void *userdata)
{
QMediaMetaData &metadata = *reinterpret_cast<QMediaMetaData *>(userdata);
QMediaMetaData::Key key = tagToKey(tag);
- if (key == QMediaMetaData::Key(-1))
+ if (key == QMediaMetaData::Key(-1)) {
+ if (tag == extendedComment)
+ addTagsFromExtendedComment(list, tag, metadata);
+
return;
+ }
GValue val{};
gst_tag_list_copy_value(&val, list, tag);
GType type = G_VALUE_TYPE(&val);
+ if (auto entryCount = gst_tag_list_get_tag_size(list, tag) != 0; entryCount != 1)
+ qWarning() << "addTagToMetaData: invaled entry count for" << tag << "-" << entryCount;
+
if (type == G_TYPE_STRING) {
const gchar *str_value = g_value_get_string(&val);
diff --git a/tests/auto/unit/multimedia/gstreamer_backend/tst_gstreamer_backend.cpp b/tests/auto/unit/multimedia/gstreamer_backend/tst_gstreamer_backend.cpp
index d51962076..d94d0831a 100644
--- a/tests/auto/unit/multimedia/gstreamer_backend/tst_gstreamer_backend.cpp
+++ b/tests/auto/unit/multimedia/gstreamer_backend/tst_gstreamer_backend.cpp
@@ -70,7 +70,6 @@ void tst_GStreamer::metadata_taglistToMetaData_extractsDuration()
QMediaMetaData parsed = taglistToMetaData(tagList.get());
- QEXPECT_FAIL("", "duration in extended comment", Continue);
QCOMPARE(parsed[QMediaMetaData::Duration].value<int>(), 400);
}