Skip to content
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

Simulcast issue #603

Open
Rollooo opened this issue Oct 22, 2021 · 0 comments
Open

Simulcast issue #603

Rollooo opened this issue Oct 22, 2021 · 0 comments

Comments

@Rollooo
Copy link

Rollooo commented Oct 22, 2021

Your environment.

  • Version: Latest
  • Client: echotest
  • Environement: OSX
  • Are you using a TURN server? No
  • Other Information - stacktraces, webrtc dumps, related issues, suggestions how to fix, links for us to have context

What did you do?

Change spatial layer using SubscriberAPI

What did you expect?

Change resolution and framerate of video that I want to change.(only one video)

What happened?

Multiple down tracks those have same track id were removed in receiver.
And then stopped other participant's remote video.

Reason

It try to delete downtrack by id. So it can remove multiple tracks in receiver.

func (w *WebRTCReceiver) writeRTP(layer int) {
	// ...
		if w.isSimulcast {
			if w.pending[layer].get() {
				if pkt.KeyFrame {
					w.Lock()
					for idx, dt := range w.pendingTracks[layer] {
						w.deleteDownTrack(dt.CurrentSpatialLayer(), dt.id)
						w.storeDownTrack(layer, dt)
						dt.SwitchSpatialLayerDone(int32(layer))
						w.pendingTracks[layer][idx] = nil
					}
					w.pendingTracks[layer] = w.pendingTracks[layer][:0]
					w.pending[layer].set(false)
					w.Unlock()
				} else {
					w.SendRTCP(pli)
				}
			}
		}
    // ...
}

// ...

func (w *WebRTCReceiver) deleteDownTrack(layer int, id string) {
	dts := w.downTracks[layer].Load().([]*DownTrack)
	ndts := make([]*DownTrack, 0, len(dts))
	for _, dt := range dts {
		if dt.id != id {
			ndts = append(ndts, dt)
		}
	}
	w.downTracks[layer].Store(ndts)
}

(https://github.com/pion/ion-sfu/blob/802a11b66a21e7e8dd369f25c4c4a8b24b38253d/pkg/sfu/receiver.go#L333)
(https://github.com/pion/ion-sfu/blob/802a11b66a21e7e8dd369f25c4c4a8b24b38253d/pkg/sfu/receiver.go#L252)

So I think when client try to change layer of specific down track, it should delete down track by track like as below

func (w *WebRTCReceiver) writeRTP(layer int) {
	// ...
		if w.isSimulcast {
			if w.pending[layer].get() {
				if pkt.KeyFrame {
					w.Lock()
					for idx, dt := range w.pendingTracks[layer] {
						w.deleteDownTrack(dt.CurrentSpatialLayer(), track)  // <-- Change this
						w.storeDownTrack(layer, dt)
						dt.SwitchSpatialLayerDone(int32(layer))
						w.pendingTracks[layer][idx] = nil
					}
					w.pendingTracks[layer] = w.pendingTracks[layer][:0]
					w.pending[layer].set(false)
					w.Unlock()
				} else {
					w.SendRTCP(pli)
				}
			}
		}

		for _, dt := range w.downTracks[layer].Load().([]*DownTrack) {
			if err = dt.WriteRTP(pkt, layer); err != nil {
				if err == io.EOF && err == io.ErrClosedPipe {
					w.Lock()
					w.deleteDownTrack(layer, dt) // <-- Change this
					w.Unlock()
				}
				log.Error().Err(err).Str("id", dt.id).Msg("Error writing to down track")
			}
		}
      
    // ...
}

// ...

func (w *WebRTCReceiver) deleteDownTrack(layer int, track *DownTrack) {
	dts := w.downTracks[layer].Load().([]*DownTrack)
	ndts := make([]*DownTrack, 0, len(dts))
	for _, dt := range dts {
		if dt != track {
			ndts = append(ndts, dt)
		}
	}
	w.downTracks[layer].Store(ndts)
}
@Rollooo Rollooo changed the title Simulcast isseu Simulcast issue Oct 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant