GNOME Bugzilla – Bug 795404
webrtcbin: h.264 streams work with Chrome but not with Firefox
Last modified: 2018-11-03 14:21:37 UTC
Created attachment 371158 [details] webrtc h264 test program I wrote a small test program to try out unidirectional transfers with WebRTC from GStreamer to an HTML5 page. It works well with Chrome. But with Firefox, it fails. I noticed some oddities in the SDP. The SDP that is sent from webrtcbin to FF contains a=sendrecv, a=rtpmap:96 H264/90000, and also an ice-ufrag. The SDP that is sent back from FF to webrtcbin however does not contain an ice-ufrag, and instead has a=rtpmap:96 H264/90000 and a=inactive for the mid:video0 stream. Now I do know that FF can handle h.264 over WebRTC, because h.264 works with this example: http://mozilla.github.io/webrtc-landing/pc_test.html but I do not know why, or why it doesn't work with my test. I attached my test code. I do not know that much about SDP or WebRTC, so maybe I am missing something. Or perhaps this is an SDP related bug in webrtcbin / gstsdp? The example comes with its own libsoup based HTTP server, and does the signaling by itself via websockets. Just open the link printed in stderr in Chrome, then in Firefox.
Created attachment 371169 [details] gstwebrtc-firefox dump Here is an about:webrtc dump of the SDPs, ICEs etc. This is the combination that didn't work.
Created attachment 371170 [details] firefox-firefox dump And here is an about:webrtc dump of the SDPs, ICEs etc. This is from the working mozilla example (firefox is both sender and receiver).
The next step to figuring this out is to bisect the two SDPs: when we have an offer SDP in on-negotiation-needed, use the GstSDPMessage API to add more attributes to it and match it with what Firefox sends, then isolate what exactly we're missing.
Found it! Inserting an fmtp attribute with a profile-level-id value seems to fix it. Here is the diff: diff --git a/webrtc-test.cpp b/webrtc-test.cpp index 07c3d81..ba41fd8 100644 --- a/webrtc-test.cpp +++ b/webrtc-test.cpp @@ -201,6 +201,8 @@ private: gst_structure_get(reply, "offer", GST_TYPE_WEBRTC_SESSION_DESCRIPTION, &offer, nullptr); gst_promise_unref(p_promise); + gst_sdp_media_add_attribute((GstSDPMedia *)&g_array_index(offer->sdp->medias, GstSDPMedia, 0), "fmtp", "96 profile-level-id=42e01f"); + GstPromise *local_desc_promise = gst_promise_new(); g_signal_emit_by_name(m_webrtcbin, "set-local-description", offer, local_desc_promise); gst_promise_interrupt(local_desc_promise); (96 is the payload type I use in the example.) Now the next step is to find out why this ID works. Also, perhaps gstwebrtc could add this line by default?
That sounds familiar, I think the same was observed in openwebrtc. The correct value should be in the caps from the RTP payloader though, we should take that one instead of some random number.
Created attachment 371453 [details] webrtc h264 test program, in C, with profile-level-id caps applied Here is the example with profile-level-id support, rewritten in C. This one works with Firefox. I'll add some more comments, and then this could be useful as an addition to the WebRTC examples in gst-plugins-bad, right?
With the patch from bug #795044, the full caps with profile-level-id is now collected and the fmtp is generated and sent in the SDP automatically.
As I explained in https://bugzilla.gnome.org/show_bug.cgi?id=795044#c8 , note that there are additional requirements now for h.264 to work with newer Chrome versions: > 1. Chrome seems to insist on constrained-baseline profile IDs. Just baseline > won't work. > 2. In newer Chrome versions, the fmtp line also needs to include > "packetization-mode=1" : shorturl.at/kvyZ3
-- GitLab Migration Automatic Message -- This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/691.