QXmpp  Version: 1.15.1
QXmppCall_p.h
1 // SPDX-FileCopyrightText: 2019 Jeremy LainĂ© <jeremy.laine@m4x.org>
2 // SPDX-FileCopyrightText: 2019 Niels Ole Salscheider <ole@salscheider.org>
3 // SPDX-FileCopyrightText: 2025 Linus Jahn <lnj@kaidan.im>
4 //
5 // SPDX-License-Identifier: LGPL-2.1-or-later
6 
7 #ifndef QXMPPCALL_P_H
8 #define QXMPPCALL_P_H
9 
10 #include "QXmppCall.h"
11 #include "QXmppError.h"
12 #include "QXmppJingleIq.h"
13 
14 #include "GstWrapper.h"
15 #include "StringLiterals.h"
16 
17 #include <gst/gst.h>
18 
19 #include <QList>
20 #include <QPointer>
21 
22 //
23 // W A R N I N G
24 // -------------
25 //
26 // This file is not part of the QXmpp API.
27 // This header file may change from version to version without notice,
28 // or even be removed.
29 //
30 // We mean it.
31 //
32 
33 class QXmppCallStream;
34 
35 class QXmppCallPrivate : public QObject
36 {
37  Q_OBJECT
38 public:
39  using GstElementPtr = QXmpp::Private::GstElementPtr;
40 
41  struct GstCodec {
42  int pt;
43  QString name;
44  int channels;
45  uint clockrate;
46  QLatin1String gstPay;
47  QLatin1String gstDepay;
48  QLatin1String gstEnc;
49  QLatin1String gstDec;
50  struct Property {
51  QLatin1String name;
52  int value;
53  };
54  // Use e.g. gst-inspect-1.0 x264enc to find good encoder settings for live streaming
55  QList<Property> encProps;
56  };
57 
58  explicit QXmppCallPrivate(const QString &jid, const QString &sid, QXmppCall::Direction direction, QPointer<QXmppCallManager> manager, QXmppCall::State state, QXmppError &&error, QXmppCall *qq);
59  ~QXmppCallPrivate();
60 
61  void ssrcActive(uint sessionId, uint ssrc);
62  void padAdded(GstPad *pad);
63  GstCaps *ptMap(uint sessionId, uint pt);
64  static bool isFormatSupported(const QString &codecName);
65  static bool isCodecSupported(const GstCodec &codec);
66 
67  QXmppCallStream *createStream(const QString &media, const QString &creator, const QString &name);
68  QXmppJingleIq::Content localContent(QXmppCallStream *stream) const;
69  QXmppJingleIq createIq(QXmppJingleIq::Action action) const;
70 
71  bool handleDescription(QXmppCallStream *stream, const QXmppJingleIq::Content &content);
72  std::variant<QXmppIq, QXmppStanza::Error> handleRequest(QXmppJingleIq &&iq);
73  bool handleTransport(QXmppCallStream *stream, const QXmppJingleIq::Content &content);
74  void setState(QXmppCall::State state);
75  void sendInvite();
76  void terminate(QXmppJingleReason reason, bool delay = false);
77 
78  bool isOwn(QXmppCallStream *stream) const;
79 
80  QXmppCall::Direction direction;
81  QString jid;
82  bool useDtls = false;
83  bool videoSupported = false;
84  QPointer<QXmppCallManager> manager;
85  QString sid;
87  QXmppError error;
88 
89  GstElementPtr pipeline;
90  GstElement *rtpBin;
91 
92  // Media streams
93  QList<QXmppCallStream *> streams;
94  int nextId = 0;
95 
96  // Supported codecs
97  // See https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml
98  QList<GstCodec> videoCodecs = {
99  GstCodec { .pt = 100, .name = u"H264"_s, .channels = 1, .clockrate = 90000, .gstPay = "rtph264pay"_L1, .gstDepay = "rtph264depay"_L1, .gstEnc = "x264enc"_L1, .gstDec = "avdec_h264"_L1, .encProps = { { "tune"_L1, 4 }, { "speed-preset"_L1, 3 }, { "byte-stream"_L1, true }, { "bitrate"_L1, 512 } } },
100  GstCodec { .pt = 99, .name = u"VP8"_s, .channels = 1, .clockrate = 90000, .gstPay = "rtpvp8pay"_L1, .gstDepay = "rtpvp8depay"_L1, .gstEnc = "vp8enc"_L1, .gstDec = "vp8dec"_L1, .encProps = { { "deadline"_L1, 20000 }, { "target-bitrate"_L1, 512000 } } },
101  // vp9enc and x265enc seem to be very slow. Give them a lower priority for now.
102  GstCodec { .pt = 102, .name = u"HEVC"_s, .channels = 1, .clockrate = 90000, .gstPay = "rtph265pay"_L1, .gstDepay = "rtph265depay"_L1, .gstEnc = "x265enc"_L1, .gstDec = "avdec_h265"_L1, .encProps = { { "tune"_L1, 4 }, { "speed-preset"_L1, 3 }, { "bitrate"_L1, 512 } } },
103  GstCodec { .pt = 101, .name = u"VP9"_s, .channels = 1, .clockrate = 90000, .gstPay = "rtpvp9pay"_L1, .gstDepay = "rtpvp9depay"_L1, .gstEnc = "vp9enc"_L1, .gstDec = "vp9dec"_L1, .encProps = { { "deadline"_L1, 20000 }, { "target-bitrate"_L1, 512000 } } }
104  };
105 
106  QList<GstCodec> audioCodecs = {
107  { .pt = 111, .name = u"opus"_s, .channels = 2, .clockrate = 48000, .gstPay = "rtpopuspay"_L1, .gstDepay = "rtpopusdepay"_L1, .gstEnc = "opusenc"_L1, .gstDec = "opusdec"_L1, .encProps = { { "inband-fec"_L1, true }, { "frame-size"_L1, 40 } } },
108  { .pt = 112, .name = u"opus"_s, .channels = 1, .clockrate = 48000, .gstPay = "rtpopuspay"_L1, .gstDepay = "rtpopusdepay"_L1, .gstEnc = "opusenc"_L1, .gstDec = "opusdec"_L1, .encProps = { { "inband-fec"_L1, true }, { "frame-size"_L1, 40 } } },
109  { .pt = 96, .name = u"speex"_s, .channels = 1, .clockrate = 48000, .gstPay = "rtpspeexpay"_L1, .gstDepay = "rtpspeexdepay"_L1, .gstEnc = "speexenc"_L1, .gstDec = "speexdec"_L1, .encProps = {} },
110  { .pt = 97, .name = u"speex"_s, .channels = 1, .clockrate = 44100, .gstPay = "rtpspeexpay"_L1, .gstDepay = "rtpspeexdepay"_L1, .gstEnc = "speexenc"_L1, .gstDec = "speexdec"_L1, .encProps = {} },
111  { .pt = 100, .name = u"mpeg4-generic"_s, .channels = 2, .clockrate = 48000, .gstPay = "rtpmp4apay"_L1, .gstDepay = "rtpmp4adepay"_L1, .gstEnc = "avenc_aac"_L1, .gstDec = "avdec_aac"_L1, .encProps = {} },
112  { .pt = 101, .name = u"mpeg4-generic"_s, .channels = 2, .clockrate = 44100, .gstPay = "rtpmp4apay"_L1, .gstDepay = "rtpmp4adepay"_L1, .gstEnc = "avenc_aac"_L1, .gstDec = "avdec_aac"_L1, .encProps = {} },
113  { .pt = 102, .name = u"mpeg4-generic"_s, .channels = 1, .clockrate = 48000, .gstPay = "rtpmp4apay"_L1, .gstDepay = "rtpmp4adepay"_L1, .gstEnc = "avenc_aac"_L1, .gstDec = "avdec_aac"_L1, .encProps = {} },
114  { .pt = 103, .name = u"mpeg4-generic"_s, .channels = 1, .clockrate = 44100, .gstPay = "rtpmp4apay"_L1, .gstDepay = "rtpmp4adepay"_L1, .gstEnc = "avenc_aac"_L1, .gstDec = "avdec_aac"_L1, .encProps = {} },
115  { .pt = 8, .name = u"PCMA"_s, .channels = 1, .clockrate = 8000, .gstPay = "rtppcmapay"_L1, .gstDepay = "rtppcmadepay"_L1, .gstEnc = "alawenc"_L1, .gstDec = "alawdec"_L1, .encProps = {} },
116  { .pt = 0, .name = u"PCMU"_s, .channels = 1, .clockrate = 8000, .gstPay = "rtppcmupay"_L1, .gstDepay = "rtppcmudepay"_L1, .gstEnc = "mulawenc"_L1, .gstDec = "mulawdec"_L1, .encProps = {} },
117  };
118 
119 private:
120  QXmppCall *q;
121 };
122 
123 #endif
The QXmppJingleIq class represents an IQ used for initiating media sessions as specified by XEP-0166:...
Definition: QXmppJingleData.h:438
Action
This enum is used to describe a Jingle action.
Definition: QXmppJingleData.h:442
Definition: QXmppError.h:17
Definition: QXmppJingleData.h:351
Direction
This enum is used to describe the direction of a call.
Definition: QXmppCall.h:35
The call is being connected.
Definition: QXmppCall.h:43
Definition: QXmppCall.h:23
Definition: QXmppCallStream.h:21
State
This enum is used to describe the state of a call.
Definition: QXmppCall.h:42