Files
livekit/pkg/sfu/buffer/datastats.go
Raja Subramanian 8c3ec742e6 Use now for end time (#2248)
* Use now for end time

* less arithmetic
2023-11-17 12:00:47 +05:30

103 lines
2.5 KiB
Go

// Copyright 2023 LiveKit, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package buffer
import (
"sync"
"time"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/livekit/protocol/livekit"
)
type DataStatsParam struct {
WindowDuration time.Duration
}
type DataStats struct {
params DataStatsParam
lock sync.RWMutex
totalBytes int64
startTime time.Time
endTime time.Time
windowStart int64
windowBytes int64
}
func NewDataStats(params DataStatsParam) *DataStats {
return &DataStats{
params: params,
startTime: time.Now(),
windowStart: time.Now().UnixNano(),
}
}
func (s *DataStats) Update(bytes int, time int64) {
s.lock.Lock()
defer s.lock.Unlock()
s.totalBytes += int64(bytes)
if s.params.WindowDuration > 0 && time-s.windowStart > s.params.WindowDuration.Nanoseconds() {
s.windowBytes = 0
s.windowStart = time
}
s.windowBytes += int64(bytes)
}
func (s *DataStats) ToProtoActive() *livekit.RTPStats {
if s.params.WindowDuration == 0 {
return &livekit.RTPStats{}
}
s.lock.RLock()
defer s.lock.RUnlock()
now := time.Now().UnixNano()
duration := now - s.windowStart
if duration > s.params.WindowDuration.Nanoseconds() {
return &livekit.RTPStats{}
}
return &livekit.RTPStats{
StartTime: timestamppb.New(time.Unix(s.windowStart/1e9, s.windowStart%1e9)),
EndTime: timestamppb.New(time.Unix(0, now)),
Duration: float64(duration / 1e9),
Bytes: uint64(s.windowBytes),
Bitrate: float64(s.windowBytes) * 8 / float64(duration) / 1e9,
}
}
func (s *DataStats) Stop() {
s.lock.Lock()
s.endTime = time.Now()
s.lock.Unlock()
}
func (s *DataStats) ToProtoAggregateOnly() *livekit.RTPStats {
s.lock.RLock()
defer s.lock.RUnlock()
end := s.endTime
if end.IsZero() {
end = time.Now()
}
return &livekit.RTPStats{
StartTime: timestamppb.New(s.startTime),
EndTime: timestamppb.New(end),
Duration: end.Sub(s.startTime).Seconds(),
Bytes: uint64(s.totalBytes),
Bitrate: float64(s.totalBytes) * 8 / end.Sub(s.startTime).Seconds(),
}
}