Skip to content

Commit

Permalink
Add lastKeyFrameSeen to status endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
Sean-Der committed Jun 4, 2024
1 parent c1a00a1 commit d6777bb
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 6 deletions.
26 changes: 26 additions & 0 deletions internal/webrtc/keyframe_detector.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package webrtc

import (
"github.com/pion/rtp"
)

const (
naluTypeBitmask = 0x1F

idrNALUType = 5
spsNALUType = 7
ppsNALUType = 8
)

func isKeyframe(pkt *rtp.Packet, codec videoTrackCodec, depacketizer rtp.Depacketizer) bool {
if codec == videoTrackCodecH264 {
nalu, err := depacketizer.Unmarshal(pkt.Payload)
if err != nil || len(nalu) < 6 {
return false
}

firstNaluType := nalu[4] & naluTypeBitmask
return firstNaluType == idrNALUType || firstNaluType == spsNALUType || firstNaluType == ppsNALUType
}
return false
}
21 changes: 15 additions & 6 deletions internal/webrtc/webrtc.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ type (
}

videoTrack struct {
rid string
packetsReceived atomic.Uint64
rid string
packetsReceived atomic.Uint64
lastKeyFrameSeen atomic.Value
}

videoTrackCodec int
Expand Down Expand Up @@ -151,6 +152,7 @@ func addTrack(stream *stream, rid string) (*videoTrack, error) {
}

t := &videoTrack{rid: rid}
t.lastKeyFrameSeen.Store(time.Time{})
stream.videoTracks = append(stream.videoTracks, t)
return t, nil
}
Expand Down Expand Up @@ -371,8 +373,9 @@ func Configure() {
}

type StreamStatusVideo struct {
RID string `json:"rid"`
PacketsReceived uint64 `json:"packetsReceived"`
RID string `json:"rid"`
PacketsReceived uint64 `json:"packetsReceived"`
LastKeyFrameSeen time.Time `json:"lastKeyFrameSeen"`
}

type StreamStatus struct {
Expand Down Expand Up @@ -418,9 +421,15 @@ func GetStreamStatuses() []StreamStatus {

streamStatusVideo := []StreamStatusVideo{}
for _, videoTrack := range stream.videoTracks {
var lastKeyFrameSeen time.Time
if v, ok := videoTrack.lastKeyFrameSeen.Load().(time.Time); ok {
lastKeyFrameSeen = v
}

streamStatusVideo = append(streamStatusVideo, StreamStatusVideo{
RID: videoTrack.rid,
PacketsReceived: videoTrack.packetsReceived.Load(),
RID: videoTrack.rid,
PacketsReceived: videoTrack.packetsReceived.Load(),
LastKeyFrameSeen: lastKeyFrameSeen,
})
}

Expand Down
16 changes: 16 additions & 0 deletions internal/webrtc/whip.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import (
"log"
"math"
"strings"
"time"

"github.com/pion/rtcp"
"github.com/pion/rtp"
"github.com/pion/rtp/codecs"
"github.com/pion/webrtc/v4"
)

Expand Down Expand Up @@ -65,6 +67,16 @@ func videoWriter(remoteTrack *webrtc.TrackRemote, stream *stream, peerConnection
rtpPkt := &rtp.Packet{}
codec := getVideoTrackCodec(remoteTrack.Codec().RTPCodecCapability.MimeType)

var depacketizer rtp.Depacketizer
switch codec {
case videoTrackCodecH264:
depacketizer = &codecs.H264Packet{}
case videoTrackCodecVP8:
depacketizer = &codecs.VP8Packet{}
case videoTrackCodecVP9:
depacketizer = &codecs.VP9Packet{}
}

lastTimestamp := uint32(0)
lastTimestampSet := false

Expand All @@ -88,6 +100,10 @@ func videoWriter(remoteTrack *webrtc.TrackRemote, stream *stream, peerConnection

videoTrack.packetsReceived.Add(1)

if isKeyframe(rtpPkt, codec, depacketizer) {
videoTrack.lastKeyFrameSeen.Store(time.Now())
}

rtpPkt.Extension = false
rtpPkt.Extensions = nil

Expand Down

0 comments on commit d6777bb

Please sign in to comment.