Commit 49bcc342 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Queue negotiation if not in stable state.

If we send two offers back to back, the second answer will arive in
stable state, which will confuse us.  Instead, queue the second offer.
parent cf6c1203
...@@ -129,6 +129,12 @@ func (down *rtpDownTrack) SetCname(cname string) { ...@@ -129,6 +129,12 @@ func (down *rtpDownTrack) SetCname(cname string) {
down.cname.Store(cname) down.cname.Store(cname)
} }
const (
negotiationUnneeded = iota
negotiationNeeded
negotiationRestartIce
)
type rtpDownConnection struct { type rtpDownConnection struct {
id string id string
pc *webrtc.PeerConnection pc *webrtc.PeerConnection
...@@ -136,6 +142,7 @@ type rtpDownConnection struct { ...@@ -136,6 +142,7 @@ type rtpDownConnection struct {
tracks []*rtpDownTrack tracks []*rtpDownTrack
maxREMBBitrate *bitrate maxREMBBitrate *bitrate
iceCandidates []*webrtc.ICECandidateInit iceCandidates []*webrtc.ICECandidateInit
negotiationNeeded int
} }
func newDownConn(c group.Client, id string, remote conn.Up) (*rtpDownConnection, error) { func newDownConn(c group.Client, id string, remote conn.Up) (*rtpDownConnection, error) {
......
...@@ -423,6 +423,18 @@ func addDownTrack(c *webClient, conn *rtpDownConnection, remoteTrack conn.UpTrac ...@@ -423,6 +423,18 @@ func addDownTrack(c *webClient, conn *rtpDownConnection, remoteTrack conn.UpTrac
} }
func negotiate(c *webClient, down *rtpDownConnection, renegotiate, restartIce bool) error { func negotiate(c *webClient, down *rtpDownConnection, renegotiate, restartIce bool) error {
if down.pc.SignalingState() == webrtc.SignalingStateHaveLocalOffer {
// avoid sending multiple offers back-to-back
if restartIce {
down.negotiationNeeded = negotiationRestartIce
} else if down.negotiationNeeded == negotiationUnneeded {
down.negotiationNeeded = negotiationNeeded
}
return nil
}
down.negotiationNeeded = negotiationUnneeded
options := webrtc.OfferOptions{ICERestart: restartIce} options := webrtc.OfferOptions{ICERestart: restartIce}
offer, err := down.pc.CreateOffer(&options) offer, err := down.pc.CreateOffer(&options)
if err != nil { if err != nil {
...@@ -808,6 +820,9 @@ func clientLoop(c *webClient, ws *websocket.Conn) error { ...@@ -808,6 +820,9 @@ func clientLoop(c *webClient, ws *websocket.Conn) error {
if down != nil { if down != nil {
err = negotiate(c, down, false, false) err = negotiate(c, down, false, false)
if err != nil { if err != nil {
log.Printf(
"Negotiation failed: %v",
err)
delDownConn(c, down.id) delDownConn(c, down.id)
c.error(group.UserError( c.error(group.UserError(
"Negotiation failed", "Negotiation failed",
...@@ -1154,13 +1169,26 @@ func handleClientMessage(c *webClient, m clientMessage) error { ...@@ -1154,13 +1169,26 @@ func handleClientMessage(c *webClient, m clientMessage) error {
} }
return failDownConnection(c, m.Id, message) return failDownConnection(c, m.Id, message)
} }
down := getDownConn(c, m.Id)
if down.negotiationNeeded > negotiationUnneeded {
err := negotiate(
c, down, true,
down.negotiationNeeded == negotiationRestartIce,
)
if err != nil {
return failDownConnection(
c, m.Id, "negotiation failed",
)
}
}
case "renegotiate": case "renegotiate":
down := getDownConn(c, m.Id) down := getDownConn(c, m.Id)
if down != nil { if down != nil {
err := negotiate(c, down, true, true) err := negotiate(c, down, true, true)
if err != nil { if err != nil {
return failDownConnection(c, m.Id, return failDownConnection(
"renegotiation failed") c, m.Id, "renegotiation failed",
)
} }
} else { } else {
log.Printf("Trying to renegotiate unknown connection") log.Printf("Trying to renegotiate unknown connection")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment