1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <common/qgstutils_p.h>
5#include <common/qgst_p.h>
6
7#include <QtMultimedia/qaudioformat.h>
8
9#include <chrono>
10
11QT_BEGIN_NAMESPACE
12
13namespace {
14
15const char *audioSampleFormatNames[QAudioFormat::NSampleFormats] = {
16 nullptr,
17#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
18 "U8",
19 "S16LE",
20 "S32LE",
21 "F32LE"
22#else
23 "U8",
24 "S16BE",
25 "S32BE",
26 "F32BE"
27#endif
28};
29
30QAudioFormat::SampleFormat gstSampleFormatToSampleFormat(const char *fmt)
31{
32 if (fmt) {
33 for (int i = 1; i < QAudioFormat::NSampleFormats; ++i) {
34 if (strcmp(s1: fmt, s2: audioSampleFormatNames[i]))
35 continue;
36 return QAudioFormat::SampleFormat(i);
37 }
38 }
39 return QAudioFormat::Unknown;
40}
41
42} // namespace
43
44/*
45 Returns audio format for a sample \a sample.
46 If the buffer doesn't have a valid audio format, an empty QAudioFormat is returned.
47*/
48QAudioFormat QGstUtils::audioFormatForSample(GstSample *sample)
49{
50 auto caps = QGstCaps(gst_sample_get_caps(sample), QGstCaps::NeedsRef);
51 if (caps.isNull())
52 return {};
53 return audioFormatForCaps(caps);
54}
55
56QAudioFormat QGstUtils::audioFormatForCaps(const QGstCaps &caps)
57{
58 QAudioFormat format;
59 QGstStructureView s = caps.at(index: 0);
60 if (s.name() != "audio/x-raw")
61 return format;
62
63 auto rate = s["rate"].toInt();
64 auto channels = s["channels"].toInt();
65 QAudioFormat::SampleFormat fmt = gstSampleFormatToSampleFormat(fmt: s["format"].toString());
66 if (!rate || !channels || fmt == QAudioFormat::Unknown)
67 return format;
68
69 format.setSampleRate(*rate);
70 format.setChannelCount(*channels);
71 format.setSampleFormat(fmt);
72
73 return format;
74}
75
76/*
77 Builds GstCaps for an audio format \a format.
78 Returns 0 if the audio format is not valid.
79
80 \note Caller must unreference GstCaps.
81*/
82
83QGstCaps QGstUtils::capsForAudioFormat(const QAudioFormat &format)
84{
85 if (!format.isValid())
86 return {};
87
88 auto sampleFormat = format.sampleFormat();
89 auto caps = gst_caps_new_simple(
90 media_type: "audio/x-raw",
91 fieldname: "format" , G_TYPE_STRING, audioSampleFormatNames[sampleFormat],
92 "rate" , G_TYPE_INT , format.sampleRate(),
93 "channels", G_TYPE_INT , format.channelCount(),
94 "layout" , G_TYPE_STRING, "interleaved",
95 nullptr);
96
97 return QGstCaps(caps, QGstCaps::HasRef);
98}
99
100QList<QAudioFormat::SampleFormat> QGValue::getSampleFormats() const
101{
102 if (!GST_VALUE_HOLDS_LIST(value))
103 return {};
104
105 QList<QAudioFormat::SampleFormat> formats;
106 guint nFormats = gst_value_list_get_size(value);
107 for (guint f = 0; f < nFormats; ++f) {
108 QGValue v = QGValue{ gst_value_list_get_value(value, index: f) };
109 auto *name = v.toString();
110 QAudioFormat::SampleFormat fmt = gstSampleFormatToSampleFormat(fmt: name);
111 if (fmt == QAudioFormat::Unknown)
112 continue;
113 formats.append(t: fmt);
114 }
115 return formats;
116}
117
118void QGstUtils::setFrameTimeStampsFromBuffer(QVideoFrame *frame, GstBuffer *buffer)
119{
120 using namespace std::chrono;
121 using namespace std::chrono_literals;
122
123 // GStreamer uses nanoseconds, Qt uses microseconds
124 nanoseconds startTime{ GST_BUFFER_TIMESTAMP(buffer) };
125 if (startTime >= 0ns) {
126 frame->setStartTime(floor<microseconds>(d: startTime).count());
127
128 nanoseconds duration{ GST_BUFFER_DURATION(buffer) };
129 if (duration >= 0ns)
130 frame->setEndTime(floor<microseconds>(d: startTime + duration).count());
131 }
132}
133
134GList *qt_gst_video_sinks()
135{
136 return gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_SINK
137 | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO,
138 minrank: GST_RANK_MARGINAL);
139}
140
141QLocale::Language QGstUtils::codeToLanguage(const gchar *lang)
142{
143 return QLocale::codeToLanguage(languageCode: QString::fromUtf8(utf8: lang), codeTypes: QLocale::AnyLanguageCode);
144}
145
146QT_END_NAMESPACE
147

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtmultimedia/src/plugins/multimedia/gstreamer/common/qgstutils.cpp