Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
gst-plugins-bad
gst-plugins-bad
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 1,024
    • Issues 1,024
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge Requests 208
    • Merge Requests 208
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Operations
    • Operations
    • Incidents
    • Environments
  • Packages & Registries
    • Packages & Registries
    • Container Registry
  • Analytics
    • Analytics
    • CI/CD
    • Repository
    • Value Stream
  • Snippets
    • Snippets
  • Members
    • Members
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • GStreamer
  • gst-plugins-badgst-plugins-bad
  • Issues
  • #1367

Closed
Open
Created Jul 22, 2020 by Anthony Alba@ascanio.alba7

webrtcbin recvonly opus transceiver creates wrong SDP rtpmap line

Issue

Creating a recvonly transceiver by signal emission for OPUS on a webrtcbin and then generate offer SDP creates the wrong rtpmap line (without the required /2):

v=0                                                                                                                                                                     o=- 7654366125257590231 0 IN IP4 0.0.0.0
s=-
t=0 0
a=ice-options:trickle
m=audio 9 UDP/TLS/RTP/SAVPF 96
c=IN IP4 0.0.0.0
a=setup:actpass
a=ice-ufrag:jY1LEwLDg8JgXVAsAVKGyXQxWDTj/8BH
a=ice-pwd:1m23h3zZR1E5Ko4dYBZDt/4saYK94kmP
a=rtcp-mux
a=rtcp-rsize
a=recvonly
a=rtpmap:96 OPUS/48000
a=rtcp-fb:96 nack pli
a=mid:audio0
a=fingerprint:sha-256 C4:87:88:21:F0:B9:67:4B:22:B0:73:F7:0F:E1:C7:5D:72:AE:68:C6:C9:B7:CD:46:AC:15:22:6F:21:BC:30:F5

The transceiver seems to have the correct caps(print transceiver codec_preferences):

Transceiver: application/x-rtp, media=(string)audio, encoding-name=(string)OPUS, clock-rate=(int)48000, channels=(int)2, payload=(int)96;

Expected Behaviour

The SDP should look like (with the /2):

a=recvonly                                                                                                                                                              
a=rtpmap:96 OPUS/48000/2

How to reproduce

I got the pattern (how to create recvonly webrtcbin) from this post: https://stackoverflow.com/questions/57430215/how-to-use-webrtcbin-create-offer-only-receive-video

import sys
import gi
import time

gi.require_version("Gst", "1.0")
from gi.repository import Gst

gi.require_version("GstWebRTC", "1.0")
from gi.repository import GstWebRTC

gi.require_version("GstSdp", "1.0")
from gi.repository import GstSdp


class WebRTCWrapper:
    def send_sdp_offer(self, offer):
        # dump SDP here and error exit
        text = offer.sdp.as_text()
        print("Sending offer:\n%s" % text)
        sys.exit(1)


    def on_offer_created(self, promise, _, __):
        promise.wait()
        reply = promise.get_reply()
        offer = reply["offer"]

        promise = Gst.Promise.new()
        self.webrtc.emit("set-local-description", offer, promise)
        promise.interrupt()
        self.send_sdp_offer(offer)

    def on_negotiation_needed(self, element):
        promise = Gst.Promise.new_with_change_func(self.on_offer_created, element, None)
        element.emit("create-offer", None, promise)

    def start_pipeline(self):

        self.pipe = Gst.Pipeline()
        self.webrtc = Gst.ElementFactory.make("webrtcbin")
        self.pipe.add(self.webrtc)

        self.webrtc.connect("on-negotiation-needed", self.on_negotiation_needed)

        direction = GstWebRTC.WebRTCRTPTransceiverDirection.RECVONLY
        caps = Gst.caps_from_string(
            "application/x-rtp,media=audio,encoding-name=OPUS,clock-rate=48000,channels=2,payload=96"
        )
        tcvr = self.webrtc.emit("add-transceiver", direction, caps)
        print(f"==== Transceiver: {tcvr.codec_preferences[0].to_string()} ====")
        self.webrtc.sync_state_with_parent()

if __name__ == "__main__":
    Gst.init(None)
    obj = WebRTCWrapper()
    obj.start_pipeline()

    obj.pipe.set_state(Gst.State.PLAYING)
    time.sleep(10.0)

Observations

  1. The SDP is almost correct: if I mangle the SDP in the application (add /2 to rtpmap) before sending to the peer, the application works. Application is a Kurento-based media server and rejects the pre-mangled SDP.
Edited Jul 22, 2020 by Anthony Alba
Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking
None
Due date
None