mirror of
https://github.com/livekit/livekit.git
synced 2026-03-30 17:45:40 +00:00
103 lines
2.5 KiB
Go
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(),
|
|
}
|
|
}
|