5#include <QtMultimedia/qmediametadata.h>
6#include <QtMultimedia/qtvideo.h>
7#include <QtCore/qdebug.h>
8#include <QtCore/qdatetime.h>
9#include <QtCore/qlocale.h>
10#include <QtCore/qtimezone.h>
11#include <QtGui/qimage.h>
13#include <gst/gstversion.h>
21namespace MetadataLookupImpl {
23#ifdef __cpp_lib_constexpr_algorithms
24# define constexpr_lookup constexpr
26# define constexpr_lookup
35constexpr const char *
toTag(
const char *
t)
53constexpr auto compareByKey = [](
const auto &lhs,
const auto &rhs) {
57constexpr auto compareByTag = [](
const auto &lhs,
const auto &rhs) {
58 return std::strcmp(
toTag(lhs),
toTag(rhs)) < 0;
63 std::array<MetadataKeyValuePair, 22> lookupTable{ {
103 std::sort(lookupTable.begin(), lookupTable.end(),
105 return std::string_view(lhs.tag) < std::string_view(rhs.tag);
124 using namespace MetadataLookupImpl;
125 auto foundIterator = std::lower_bound(gstTagToMetaDataKey.begin(), gstTagToMetaDataKey.end(),
127 if (std::strcmp(foundIterator->tag,
tag) == 0)
128 return foundIterator->key;
135 using namespace MetadataLookupImpl;
136 auto foundIterator = std::lower_bound(metaDataKeyToGstTag.begin(), metaDataKeyToGstTag.end(),
138 if (foundIterator->key ==
key)
139 return foundIterator->tag;
144#undef constexpr_lookup
148 using namespace std::string_view_literals;
150 if (
string ==
"rotate-90"sv)
152 if (
string ==
"rotate-180"sv)
154 if (
string ==
"rotate-270"sv)
156 if (
string ==
"rotate-0"sv)
167 const GDate *
date = (
const GDate *)g_value_get_boxed(&
val);
168 if (!g_date_valid(
date))
171 int year = g_date_get_year(
date);
172 int month = g_date_get_month(
date);
173 int day = g_date_get_day(
date);
179 Q_ASSERT(G_VALUE_TYPE(&
val) == GST_TYPE_DATE_TIME);
181 const GstDateTime *
dateTime = (
const GstDateTime *)g_value_get_boxed(&
val);
182 int year = gst_date_time_has_year(
dateTime) ? gst_date_time_get_year(
dateTime) : 0;
183 int month = gst_date_time_has_month(
dateTime) ? gst_date_time_get_month(
dateTime) : 0;
184 int day = gst_date_time_has_day(
dateTime) ? gst_date_time_get_day(
dateTime) : 0;
189 if (gst_date_time_has_time(
dateTime)) {
190 hour = gst_date_time_get_hour(
dateTime);
191 minute = gst_date_time_get_minute(
dateTime);
192 second = gst_date_time_get_second(
dateTime);
193 tz = gst_date_time_get_time_zone_offset(
dateTime);
196 QDate(year, month, day),
197 QTime(hour, minute, second),
206 GstSample *sample = (GstSample *)g_value_get_boxed(&
val);
207 GstCaps *caps = gst_sample_get_caps(sample);
208 if (caps && !gst_caps_is_empty(caps)) {
209 GstStructure *structure = gst_caps_get_structure(caps, 0);
210 const gchar *
name = gst_structure_get_name(structure);
212 GstBuffer *
buffer = gst_sample_get_buffer(sample);
230 int nom = gst_value_get_fraction_numerator(&
val);
231 int denom = gst_value_get_fraction_denominator(&
val);
234 return double(nom) / double(denom);
244 int entryCount = gst_tag_list_get_tag_size(
list,
tag);
245 for (
int i = 0;
i != entryCount; ++
i) {
246 const GValue *
value = gst_tag_list_get_value_index(
list,
tag,
i);
251 if (equalIndex == -1) {
252 qDebug() <<
"Cannot parse GST_TAG_EXTENDED_COMMENT entry: " <<
value;
259 if (
key ==
"DURATION"_L1) {
261 gst_date_time_new_from_iso8601_string(valueString.
data()),
265 using namespace std::chrono;
267 auto chronoDuration = hours(gst_date_time_get_hour(duration.get()))
268 + minutes(gst_date_time_get_minute(duration.get()))
269 + seconds(gst_date_time_get_second(duration.get()))
270 + microseconds(gst_date_time_get_microsecond(duration.get()));
294 GType
type = G_VALUE_TYPE(&
val);
296 if (
auto entryCount = gst_tag_list_get_tag_size(
list,
tag) != 0; entryCount != 1)
297 qWarning() <<
"addTagToMetaData: invaled entry count for" <<
tag <<
"-" << entryCount;
299 if (
type == G_TYPE_STRING) {
300 const gchar *str_value = g_value_get_string(&
val);
317 }
else if (
type == G_TYPE_INT) {
319 }
else if (
type == G_TYPE_UINT) {
321 }
else if (
type == G_TYPE_LONG) {
323 }
else if (
type == G_TYPE_BOOLEAN) {
325 }
else if (
type == G_TYPE_CHAR) {
327 }
else if (
type == G_TYPE_DOUBLE) {
329 }
else if (
type == G_TYPE_DATE) {
330 if (!metadata.
keys().contains(
key)) {
335 }
else if (
type == GST_TYPE_DATE_TIME) {
337 }
else if (
type == GST_TYPE_SAMPLE) {
341 }
else if (
type == GST_TYPE_FRACTION) {
357 gst_tag_list_foreach(tagList,
reinterpret_cast<GstTagForeachFunc
>(&addTagToMetaData), &
m);
368 gst_tag_setter_reset_tags(element);
376 auto setTag = [&](
const auto &
value) {
377 gst_tag_setter_add_tags(element, GST_TAG_MERGE_REPLACE, tagName,
value,
nullptr);
380 switch (tagValue.
typeId()) {
381 case QMetaType::QString:
385 case QMetaType::LongLong:
386 setTag(tagValue.
toInt());
388 case QMetaType::Double:
391 case QMetaType::QDate:
392 case QMetaType::QDateTime: {
396 gst_date_time_new(
date.offsetFromUtc() / 60. / 60.,
date.date().
year(),
398 date.time().minute(),
date.time().second()),
406 if (tagValue.
typeId() == qMetaTypeId<QLocale::Language>()) {
421 GstTagSetter *tagSetter = qGstSafeCast<GstTagSetter>(element.
element());
425 qWarning() <<
"applyMetaDataToTagSetter failed: element not a GstTagSetter"
431 GstIterator *
elements = gst_bin_iterate_all_by_interface(bin.bin(), GST_TYPE_TAG_SETTER);
434 while (gst_iterator_next(
elements, &
item) == GST_ITERATOR_OK) {
435 GstElement *element =
static_cast<GstElement *
>(g_value_get_object(&
item));
439 GstTagSetter *tagSetter = qGstSafeCast<GstTagSetter>(element);
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
\inmodule QtCore\reentrant
\inmodule QtCore \reentrant
constexpr bool isValid() const
Returns true if this date is valid; otherwise returns false.
int month() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
int day() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
int year() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
GstElement * element() const
const char * name() const
static QImage fromData(QByteArrayView data, const char *format=nullptr)
constexpr const char * data() const noexcept
constexpr QLatin1Char last() const
constexpr QLatin1Char first() const
qsizetype indexOf(QStringView s, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
static QString languageToCode(Language language, LanguageCodeTypes codeTypes=AnyLanguageCode)
Returns the two- or three-letter language code for language, as defined in the ISO 639 standards.
static Language codeToLanguage(QStringView languageCode, LanguageCodeTypes codeTypes=AnyLanguageCode) noexcept
Returns the QLocale::Language enum corresponding to the two- or three-letter languageCode,...
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QByteArray toUtf8() const &
\inmodule QtCore \reentrant
QDateTime toDateTime() const
Returns the variant as a QDateTime if the variant has userType() \l QMetaType::QDateTime,...
double toDouble(bool *ok=nullptr) const
Returns the variant as a double if the variant has userType() \l QMetaType::Double,...
int toInt(bool *ok=nullptr) const
Returns the variant as an int if the variant has userType() \l QMetaType::Int, \l QMetaType::Bool,...
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
int typeId() const
Returns the storage type of the value stored in the variant.
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
QPlaceContent parseImage(const QJsonObject &imageObject, const QPlaceManagerEngineNokiaV2 *engine)
Combined button and popup list for selecting options.
QDateTime parseDateTime(const GValue &val)
QtVideo::Rotation parseRotationTag(const char *string)
std::optional< double > parseFractionAsDouble(const GValue &val)
constexpr std::string_view extendedComment
QDateTime parseDate(const GValue &val)
void addTagsFromExtendedComment(const GstTagList *list, const gchar *tag, QMediaMetaData &metadata)
void addTagToMetaData(const GstTagList *list, const gchar *tag, void *userdata)
AudioChannelLayoutTag tag
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
QUniqueHandle< QGstImpl::QUniqueGstDateTimeHandleTraits > QUniqueGstDateTimeHandle
GLuint64 GLenum void * handle
GLenum GLenum GLsizei count
GLsizei const GLchar *const * string
[0]
static const QTextHtmlElement elements[Html_NumElements]