Skip to content

Commit

Permalink
add view only on example, and fix deadlock on add remove claim
Browse files Browse the repository at this point in the history
  • Loading branch information
Yohan Totting committed Aug 12, 2024
1 parent 86e013b commit 66b6f33
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 88 deletions.
47 changes: 28 additions & 19 deletions bitratecontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,10 @@ func (bc *bitrateController) Exist(id string) bool {

func (bc *bitrateController) GetClaim(id string) *bitrateClaim {
bc.mu.RLock()
defer bc.mu.RUnlock()
claim, ok := bc.claims[id]
bc.mu.RUnlock()

if claim, ok := bc.claims[id]; ok && claim != nil {
if ok && claim != nil {
return claim
}

Expand Down Expand Up @@ -344,23 +345,26 @@ func (bc *bitrateController) addClaims(clientTracks []iClientTrack) error {
}

func (bc *bitrateController) addClaim(clientTrack iClientTrack, quality QualityLevel) (*bitrateClaim, error) {
bc.mu.Lock()
defer bc.mu.Unlock()

bc.claims[clientTrack.ID()] = &bitrateClaim{
claim := &bitrateClaim{
mu: sync.RWMutex{},
track: clientTrack,
quality: quality,
simulcast: clientTrack.IsSimulcast(),
}

bc.mu.Lock()

bc.claims[clientTrack.ID()] = claim

bc.mu.Unlock()

clientTrack.OnEnded(func() {
bc.removeClaim(clientTrack.ID())

clientTrack.Client().stats.removeSenderStats(clientTrack.ID())
})

return bc.claims[clientTrack.ID()], nil
return claim, nil
}

func (bc *bitrateController) removeClaim(id string) {
Expand Down Expand Up @@ -429,11 +433,7 @@ func (bc *bitrateController) canIncreaseBitrate(availableBw uint32) bool {
for _, claim := range claims {
if claim.IsAdjustable() {
if claim.Quality() < claim.track.MaxQuality() {
if bc.isEnoughBandwidthToIncrase(availableBw, claim) {
return true
} else {
bc.log.Tracef("bitratecontroller: can't increase, track %s not enough bandwidth to increase bitrate", claim.track.ID())
}
return bc.isEnoughBandwidthToIncrase(availableBw, claim)
} else {
bc.log.Tracef("bitratecontroller: can't increase, track %s quality %d is same or higher than max %d", claim.track.ID(), claim.Quality(), claim.track.MaxQuality())
}
Expand All @@ -448,7 +448,7 @@ func (bc *bitrateController) loopMonitor() {
ctx, cancel := context.WithCancel(bc.client.Context())
defer cancel()

ticker := time.NewTicker(3 * time.Second)
ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()

for {
Expand All @@ -464,11 +464,10 @@ func (bc *bitrateController) loopMonitor() {
bc.mu.RUnlock()

if totalSendBitrates == 0 {
bc.log.Trace("bitratecontroller: no track to adjust")
continue
}

bc.log.Debugf("bitratecontroller: available bandwidth %s total bitrate %s", ThousandSeparator(int(bw)), ThousandSeparator(int(totalSendBitrates)))

var availableBw uint32
if bw < totalSendBitrates {
availableBw = 0
Expand All @@ -478,16 +477,20 @@ func (bc *bitrateController) loopMonitor() {

if totalSendBitrates < uint32(bw) {
needAdjustment = bc.canIncreaseBitrate(availableBw)
if needAdjustment {
bc.log.Tracef("bitratecontroller: need to increase bitrate, available bandwidth %s", ThousandSeparator(int(availableBw)))
}
} else {
needAdjustment = bc.canDecreaseBitrate()
if needAdjustment {
bc.log.Tracef("bitratecontroller: need to decrease bitrate, available bandwidth ", ThousandSeparator(int(availableBw)))
}
}

if !needAdjustment {
continue
}

bc.log.Debugf("bitratecontroller: available bandwidth %s total send bitrate %s", ThousandSeparator(int(bw)), ThousandSeparator(int(totalSendBitrates)))

bc.fitBitratesToBandwidth(uint32(bw))

bc.mu.Lock()
Expand Down Expand Up @@ -632,19 +635,25 @@ func (bc *bitrateController) isEnoughBandwidthToIncrase(bandwidthLeft uint32, cl
nextQuality := bc.getNextQuality(claim.Quality())

if nextQuality > QualityHigh {
bc.log.Tracef("bitratecontroller: won't increase track %s quality %d is already high", claim.track.ID(), nextQuality)
return false
}

nextBitrate := claim.QualityLevelToBitrate(nextQuality)
currentBitrate := claim.SendBitrate()

if nextBitrate <= currentBitrate {
bc.log.Tracef("bitratecontroller: can't increase the bitrate, next bitrate %d is less than current %d", nextBitrate, currentBitrate)
return false
}

bandwidthGap := nextBitrate - currentBitrate

bc.log.Tracef("bitratecontroller: track %s bandwidth gap %d , bandwidth left %d", claim.track.ID(), bandwidthGap, bandwidthLeft)
if bandwidthGap < bandwidthLeft {
bc.log.Tracef("bitratecontroller: track %s can increase, next bandwidth %d, bandwidth left %d", claim.track.ID(), bandwidthGap, bandwidthLeft)
return true
}

return bandwidthGap < bandwidthLeft
bc.log.Tracef("bitratecontroller: track %s can't increase, need bandwidth %d to increase, but bandwidth left %d", claim.track.ID(), bandwidthGap, bandwidthLeft)
return false
}
147 changes: 78 additions & 69 deletions examples/http-websocket/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -311,21 +311,26 @@


function startH264() {
start('h264')
start('h264',false)
}

function startVP9() {
start('vp9')
start('vp9',false)
}

function viewOnly(){
start(null,true)
}


async function start(codec) {
async function start(codec,viewOnly) {
await startWs()
document.getElementById("btnStart").disabled = true;
document.getElementById("btnStartH264").disabled = true;
document.getElementById("btnStartVP9").disabled = true;
document.getElementById("btnViewOnly").disabled = true;

const video = {
if(!viewOnly){
const video = {
width: {ideal: 1280},
height: {ideal: 720},
advanced: [{
Expand All @@ -339,37 +344,76 @@
]};


const constraints = {
audio: true,
video: video
// video: true
};
const constraints = {
audio: true,
video: video
// video: true
};

const stream = await navigator.mediaDevices.getUserMedia(constraints)
const streamid = stream.id.replace('{','').replace('}','');
let container = document.getElementById("container-"+streamid);
if (!container) {
container = document.createElement("div");
container.className = "container";
container.id = "container-"+streamid;
document.querySelector('main').appendChild(container);
}

const stream = await navigator.mediaDevices.getUserMedia(constraints)
const streamid = stream.id.replace('{','').replace('}','');
let container = document.getElementById("container-"+streamid);
if (!container) {
container = document.createElement("div");
container.className = "container";
container.id = "container-"+streamid;
document.querySelector('main').appendChild(container);
}
let localVideo = document.getElementById("video-"+streamid);
if (!localVideo) {
localVideo = document.createElement("video");
localVideo.id = "video-"+streamid;
localVideo.autoplay = true;
localVideo.muted = true;
container.appendChild(localVideo);
}

let localVideo = document.getElementById("video-"+streamid);
if (!localVideo) {
localVideo = document.createElement("video");
localVideo.id = "video-"+streamid;
localVideo.autoplay = true;
localVideo.muted = true;
container.appendChild(localVideo);
}
localVideo.srcObject =stream;

localVideo.srcObject =stream;
const audioTcvr= peerConnection.addTransceiver(stream.getAudioTracks()[0], {
direction: 'sendonly',
streams: [stream],
sendEncodings: [{priority: 'high'}],
})


peerConnection.ontrack = function(e) {
e.receiver.playoutDelayHint = 0.1;

if(audioTcvr.setCodecPreferences != undefined && RTCRtpReceiver.getCapabilities != undefined){
const audioCodecs = RTCRtpReceiver.getCapabilities('audio').codecs;

let audioCodecsPref = [];
if (red){
for(let i = 0; i < audioCodecs.length; i++){
// audio/red 48000 111/111
if(audioCodecs[i].mimeType == "audio/red"){
audioCodecsPref.push(audioCodecs[i]);
}
}
}

for(let i = 0; i < audioCodecs.length; i++){
if(audioCodecs[i].mimeType == "audio/opus"){
audioCodecsPref.push(audioCodecs[i]);
}
}

audioTcvr.setCodecPreferences(audioCodecsPref);
}


setCodecPreferences(peerConnection,stream, codec, "L3T3_KEY")
} else {
peerConnection.addTransceiver('video', {
direction: 'sendrecv',
})

peerConnection.addTransceiver('audio', {
direction: 'sendrecv',
})
}

peerConnection.ontrack = function(e) {
e.streams.forEach((stream) => {
console.log("ontrack", stream, e.track);

Expand Down Expand Up @@ -428,43 +472,6 @@

};

// peerConnection.addTrack(stream.getAudioTracks()[0], stream);
// peerConnection.addTrack(stream.getVideoTracks()[0], stream);


const audioTcvr= peerConnection.addTransceiver(stream.getAudioTracks()[0], {
direction: 'sendonly',
streams: [stream],
sendEncodings: [{priority: 'high'}],
})



if(audioTcvr.setCodecPreferences != undefined && RTCRtpReceiver.getCapabilities != undefined){
const audioCodecs = RTCRtpReceiver.getCapabilities('audio').codecs;

let audioCodecsPref = [];
if (red){
for(let i = 0; i < audioCodecs.length; i++){
// audio/red 48000 111/111
if(audioCodecs[i].mimeType == "audio/red"){
audioCodecsPref.push(audioCodecs[i]);
}
}
}

for(let i = 0; i < audioCodecs.length; i++){
if(audioCodecs[i].mimeType == "audio/opus"){
audioCodecsPref.push(audioCodecs[i]);
}
}

audioTcvr.setCodecPreferences(audioCodecsPref);
}


setCodecPreferences(peerConnection,stream, codec, "L3T3_KEY")

const offer=await peerConnection.createOffer()

await peerConnection.setLocalDescription(offer)
Expand Down Expand Up @@ -970,7 +977,8 @@ <h3>Low</h3>
}

document.addEventListener("DOMContentLoaded", function(event) {
document.getElementById("btnStart").onclick = startH264;
document.getElementById("btnViewOnly").onclick = viewOnly;
document.getElementById("btnStartH264").onclick = startH264;
document.getElementById("btnStartVP9").onclick = startVP9;
document.getElementById("btnToggleMic").onclick = toggleMic;
document.getElementById("btnToggleCam").onclick = toggleCam;
Expand All @@ -994,8 +1002,9 @@ <h3>Outbound Video</h3>
<div id="stats-local"></div>
</aside>
<footer>
<button id="btnStart">Start H264</button>
<button id="btnStartH264">Start H264</button>
<button id="btnStartVP9">Start with VP9</button>
<button id="btnViewOnly">View only</button>
<button id="btnToggleMic">Mute Mic</button>
<button id="btnToggleCam">Mute Cam</button>
<span><input id="simulcast" type="checkbox" value="simulcast">Simulcast</span>
Expand Down

0 comments on commit 66b6f33

Please sign in to comment.