New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Port QXmppCallManager to use GStreamer #207
Conversation
Just a question: Would it be possible to do this with QtMultimedia? |
QtMultimedia provides device access and encoders / decoders. But it does not have any of the RTP handling functionality (payloader, depayloader, RTP session management, jitter buffers, encryption, ...) and less filters. I assume we could use QtMultimedia and write these other parts on our own / use some of the code that we already have. But I don't see the advantages. GStreamer seems to be available on the important platforms (Linux, Windows, OS X, Android, iOS and more) and it has all that is needed for a good RTP experience. |
AFAIK most Plasma Mobile/Ubuntu Touch (android) devices don't have hardware acceleration support with GStreamer, but with QtMultimedia. And also just because it's an official part of Qt (less problems with new dependencies). |
I think we can get hardware acceleration on android by trying the gst-omx codecs before the regular ones. They use the OpenMAX API. |
I'm not talking about android, I'm talking about Halium/libhybris on an android device. |
Ah, I see. Well, at least SailfishOS also has hardware acceleration with gst-omx: https://github.com/sailfishos/gst-omx |
QtMultimedia uses gstreamer itself (at least on some platforms), and the accelerated decoding on Plasma Mobile is done as a gstreamer plugin which is then used by QtMultimedia, so using gstreamer here is perfectly fine. |
8cb1970
to
0ea268d
Compare
Codecov Report
@@ Coverage Diff @@
## master #207 +/- ##
==========================================
+ Coverage 70.36% 73.44% +3.08%
==========================================
Files 203 197 -6
Lines 17874 15692 -2182
==========================================
- Hits 12577 11525 -1052
+ Misses 5297 4167 -1130
Continue to review full report at Codecov.
|
The build fails because we don't install qt-gstreamer with homebrew. |
@olesalscheider The wiki page and README of qt-gstreamer say it's unmaintained and out of date: Is this whole thing a good idea then? How hard would it be to use gstreamer directly or to use the C++ bindings instead? |
Oh, I was not aware of that. Yes, it seems like using the qt bindings is not a good idea then. |
@olesalscheider The listed advantages of gstreamer convince me and since it will be an optional dependency (like the codecs before) I see absolutely no problem. :) |
I ported this to the gstreamer C API. It needs some real-world testing though. |
3a4afd2
to
36f3c63
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only had a quick look, but looks good so far. Splitting up the private headers in some places is also a good idea.
src/client/QXmppCall_p.h
Outdated
QList<GstCodec> videoCodecs = { | ||
// vp9enc and x265enc seems to be very slow. Don't offer it for now. | ||
//{.pt = 101, .name = "H265", .channels = 1, .clockrate = 90000, .gstPay = "rtph265pay", .gstDepay = "rtph265depay", .gstEnc = "x265enc", .gstDec = "avdec_h265", .encProps = {{"tune", 4}, {"speed-preset", 1}, {"bitrate", 256}}}, | ||
//{.pt = 100, .name = "VP9", .channels = 1, .clockrate = 90000, .gstPay = "rtpvp9pay", .gstDepay = "rtpvp9depay", .gstEnc = "vp9enc", .gstDec = "vp9dec", .encProps = {{"deadline", 20000}, {"target-bitrate", 256000}}}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The codecs are just very complex. I think we should generally support H.265/VP9, maybe just don't prefer them over H.264.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
VP9 is basically unusable, even on very fast computers. But I added them for now with a lower priority.
We can also add the hardware encoders / decoders that are supported by GStreamer to the list. But I think there are none so far for these new codecs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hardware encoders would also be nice for H.264/VP8 - They could be relevant on mobile devices?
(However this isn't that important for now.)
There are still some things that aren't tested, many Apart from that I think we can merge it. |
1ade523
to
56f7ca6
Compare
This way we can for example add a server for IPv4 and one IPv6.
I tested this over the internet with a friend and it worked quite well and quality was good. More real-world testing with slow hardware or a slow internet connection would be good to see how quality, packet drop and latency are there. Depending on that we can tune the codec parameters a bit and implement the bitrate controller. But maybe that can be done in a second step with some feedback. |
Alright, I think we're ready to go then. Do you want me to merge your commits as they are or do you want to squash some of them before? |
I think it would be good to keep them separate. The first is huge already and the following ones are nicely separated and touch other parts of the code. |
Hi @olesalscheider, |
You can find a small test program that I wrote here: But I think I understand what your problem is. Should we add an opaque pointer to the callbacks? |
Thanks for your response. What made the API hard to use for me was that I was trying to use QtMultimedia instead of gstreamer in the client. |
Having the GStreamer API also has advantages, though. You can add a lot more elements to the pipeline, e.g. for echo cancellation or other post processing. There are also elements for QML or Qt Widgets to display the video, and elements for screen sharing. Lambdas work and you can capture the objects you need. The only question is if that is a good design, or if we should add the user object pointer to the API before it is released. |
Maybe it's possible to provide access to the gstreamer pipeline, but still to wrap the output of it into a QAudioOutput and to accept a QAudioInput. If using the gstreamer APIs works fine, we can maybe also just keep that, though. For the QML elements you probably refer to QtGstreamer, but since it's unmaintained I don't think we should recommend using that.
I think we should also add your example to QXmpp. I think that's very helpful as there's no detailed description in the documentation on how to use it. A note about STUN: |
No, there are also Qt elements (e.g. qmlglsink) in gst-plugins-good: But so far I haven't used them, though. We can add my example but it needs to be cleaned up a bit, I guess. About STUN: I think XEP-0215 is not implemented. How common is it for servers to support this? |
Ah, thanks, that's good to know.
There's a module for prosody, but it's probably not used by many servers. I know that ejabberd has a STUN server enabled by default, but ejabberd (at least the open-source edition) is not supporting XEP-0215. There's also https://wiki.xmpp.org/web/SRV_Records which recommends setting up SRV records for STUN/TURN. Maybe this is also an option. |
This PR ports QXmppCallManager to use QtGStreamer.
The disadvantage is that it adds QtGStreamer as a dependency. But it also brings the following advantages:
o Widgets for Qt and QML
o Different audio and video sources including support for screen casting
o A lot of filters like echo cancelation and noise reduction (cf. webrtcdsp)
What do you think? Before I continue to clean up this patch I would like to hear your oppinion.