mirror of
https://github.com/pion/mediadevices.git
synced 2025-10-23 00:29:25 +08:00
Compare commits
3 Commits
add-svt-av
...
master
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e15e8f6880 | ||
![]() |
dd99235d6f | ||
![]() |
a5e2538787 |
4
go.mod
4
go.mod
@@ -9,8 +9,8 @@ require (
|
||||
github.com/kbinani/screenshot v0.0.0-20250624051815-089614a94018
|
||||
github.com/pion/interceptor v0.1.41
|
||||
github.com/pion/logging v0.2.4
|
||||
github.com/pion/rtcp v1.2.15
|
||||
github.com/pion/rtp v1.8.23
|
||||
github.com/pion/rtcp v1.2.16
|
||||
github.com/pion/rtp v1.8.24
|
||||
github.com/pion/webrtc/v4 v4.1.5
|
||||
github.com/stretchr/testify v1.11.1
|
||||
golang.org/x/image v0.23.0
|
||||
|
8
go.sum
8
go.sum
@@ -36,10 +36,10 @@ github.com/pion/mdns/v2 v2.0.7 h1:c9kM8ewCgjslaAmicYMFQIde2H9/lrZpjBkN8VwoVtM=
|
||||
github.com/pion/mdns/v2 v2.0.7/go.mod h1:vAdSYNAT0Jy3Ru0zl2YiW3Rm/fJCwIeM0nToenfOJKA=
|
||||
github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
|
||||
github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
|
||||
github.com/pion/rtcp v1.2.15 h1:LZQi2JbdipLOj4eBjK4wlVoQWfrZbh3Q6eHtWtJBZBo=
|
||||
github.com/pion/rtcp v1.2.15/go.mod h1:jlGuAjHMEXwMUHK78RgX0UmEJFV4zUKOFHR7OP+D3D0=
|
||||
github.com/pion/rtp v1.8.23 h1:kxX3bN4nM97DPrVBGq5I/Xcl332HnTHeP1Swx3/MCnU=
|
||||
github.com/pion/rtp v1.8.23/go.mod h1:rF5nS1GqbR7H/TCpKwylzeq6yDM+MM6k+On5EgeThEM=
|
||||
github.com/pion/rtcp v1.2.16 h1:fk1B1dNW4hsI78XUCljZJlC4kZOPk67mNRuQ0fcEkSo=
|
||||
github.com/pion/rtcp v1.2.16/go.mod h1:/as7VKfYbs5NIb4h6muQ35kQF/J0ZVNz2Z3xKoCBYOo=
|
||||
github.com/pion/rtp v1.8.24 h1:+ICyZXUQDv95EsHN70RrA4XKJf5MGWyC6QQc1u6/ynI=
|
||||
github.com/pion/rtp v1.8.24/go.mod h1:rF5nS1GqbR7H/TCpKwylzeq6yDM+MM6k+On5EgeThEM=
|
||||
github.com/pion/sctp v1.8.39 h1:PJma40vRHa3UTO3C4MyeJDQ+KIobVYRZQZ0Nt7SjQnE=
|
||||
github.com/pion/sctp v1.8.39/go.mod h1:cNiLdchXra8fHQwmIoqw0MbLLMs+f7uQ+dGMG2gWebE=
|
||||
github.com/pion/sdp/v3 v3.0.16 h1:0dKzYO6gTAvuLaAKQkC02eCPjMIi4NuAr/ibAwrGDCo=
|
||||
|
@@ -1,48 +0,0 @@
|
||||
package vpx
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type BitrateTracker struct {
|
||||
windowSize time.Duration
|
||||
buffer []int
|
||||
times []time.Time
|
||||
}
|
||||
|
||||
func NewBitrateTracker(windowSize time.Duration) *BitrateTracker {
|
||||
return &BitrateTracker{
|
||||
windowSize: windowSize,
|
||||
}
|
||||
}
|
||||
|
||||
func (bt *BitrateTracker) AddFrame(sizeBytes int, timestamp time.Time) {
|
||||
bt.buffer = append(bt.buffer, sizeBytes)
|
||||
bt.times = append(bt.times, timestamp)
|
||||
|
||||
// Remove old entries outside the window
|
||||
cutoff := timestamp.Add(-bt.windowSize)
|
||||
i := 0
|
||||
for ; i < len(bt.times); i++ {
|
||||
if bt.times[i].After(cutoff) {
|
||||
break
|
||||
}
|
||||
}
|
||||
bt.buffer = bt.buffer[i:]
|
||||
bt.times = bt.times[i:]
|
||||
}
|
||||
|
||||
func (bt *BitrateTracker) GetBitrate() float64 {
|
||||
if len(bt.times) < 2 {
|
||||
return 0
|
||||
}
|
||||
totalBytes := 0
|
||||
for _, b := range bt.buffer {
|
||||
totalBytes += b
|
||||
}
|
||||
duration := bt.times[len(bt.times)-1].Sub(bt.times[0]).Seconds()
|
||||
if duration <= 0 {
|
||||
return 0
|
||||
}
|
||||
return float64(totalBytes*8) / duration // bits per second
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
package vpx
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestBitrateTracker(t *testing.T) {
|
||||
packetSize := 1000
|
||||
bt := NewBitrateTracker(time.Second)
|
||||
bt.AddFrame(packetSize, time.Now())
|
||||
bt.AddFrame(packetSize, time.Now().Add(time.Millisecond*100))
|
||||
bt.AddFrame(packetSize, time.Now().Add(time.Millisecond*999))
|
||||
eps := float64(packetSize*8) / 10
|
||||
if got, want := bt.GetBitrate(), float64(packetSize*8)*3; math.Abs(got-want) > eps {
|
||||
t.Fatalf("GetBitrate() = %v, want %v (|diff| <= %v)", got, want, eps)
|
||||
}
|
||||
}
|
@@ -1,40 +0,0 @@
|
||||
package vpx
|
||||
|
||||
/*
|
||||
#cgo pkg-config: vpx
|
||||
#include <vpx/vpx_image.h>
|
||||
*/
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
type VpxImage struct {
|
||||
img *C.vpx_image_t
|
||||
}
|
||||
|
||||
func NewImageFromPtr(ptr *C.vpx_image_t) *VpxImage {
|
||||
return &VpxImage{img: ptr}
|
||||
}
|
||||
|
||||
func (i *VpxImage) Width() int {
|
||||
return int(i.img.d_w)
|
||||
}
|
||||
|
||||
func (i *VpxImage) Height() int {
|
||||
return int(i.img.d_h)
|
||||
}
|
||||
|
||||
func (i *VpxImage) YStride() int {
|
||||
return int(i.img.stride[0])
|
||||
}
|
||||
|
||||
func (i *VpxImage) UStride() int {
|
||||
return int(i.img.stride[1])
|
||||
}
|
||||
|
||||
func (i *VpxImage) VStride() int {
|
||||
return int(i.img.stride[2])
|
||||
}
|
||||
|
||||
func (i *VpxImage) Plane(n int) unsafe.Pointer {
|
||||
return unsafe.Pointer(i.img.planes[n])
|
||||
}
|
@@ -1,94 +0,0 @@
|
||||
package vpx
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// TestVpxImageStructure tests the VpxImage struct methods
|
||||
// Note: These tests verify the interface and structure without requiring actual VPX images
|
||||
func TestVpxImageStructure(t *testing.T) {
|
||||
// Test that VpxImage can be created (interface test)
|
||||
// We can't easily test with real C structures in unit tests due to CGO limitations
|
||||
// but we can test the structure and interface
|
||||
|
||||
t.Run("VpxImageInterface", func(t *testing.T) {
|
||||
// This test ensures the VpxImage type exists and has the expected methods
|
||||
// We use a type assertion to verify the interface
|
||||
var _ interface {
|
||||
Width() int
|
||||
Height() int
|
||||
YStride() int
|
||||
UStride() int
|
||||
VStride() int
|
||||
Plane(int) unsafe.Pointer
|
||||
} = (*VpxImage)(nil)
|
||||
})
|
||||
}
|
||||
|
||||
// TestNewImageFromPtr tests the constructor
|
||||
func TestNewImageFromPtr(t *testing.T) {
|
||||
// Test with nil pointer
|
||||
vpxImg := NewImageFromPtr(nil)
|
||||
if vpxImg == nil {
|
||||
t.Error("NewImageFromPtr should not return nil even with nil input")
|
||||
}
|
||||
if vpxImg != nil && vpxImg.img != nil {
|
||||
t.Error("VpxImage should contain nil pointer when created with nil")
|
||||
}
|
||||
}
|
||||
|
||||
// TestVpxImageMethodsWithNil tests that methods panic appropriately with nil pointer
|
||||
// This documents the expected behavior - methods will panic if called with nil C pointer
|
||||
func TestVpxImageMethodsWithNil(t *testing.T) {
|
||||
vpxImg := NewImageFromPtr(nil)
|
||||
|
||||
// These methods should panic with nil img (this is expected behavior)
|
||||
testCases := []struct {
|
||||
name string
|
||||
fn func()
|
||||
}{
|
||||
{"Width", func() { vpxImg.Width() }},
|
||||
{"Height", func() { vpxImg.Height() }},
|
||||
{"YStride", func() { vpxImg.YStride() }},
|
||||
{"UStride", func() { vpxImg.UStride() }},
|
||||
{"VStride", func() { vpxImg.VStride() }},
|
||||
{"Plane0", func() { vpxImg.Plane(0) }},
|
||||
{"Plane1", func() { vpxImg.Plane(1) }},
|
||||
{"Plane2", func() { vpxImg.Plane(2) }},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("Method %s should panic with nil image but didn't", tc.name)
|
||||
}
|
||||
}()
|
||||
tc.fn()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestVpxImageConstants tests expected behavior with common video formats
|
||||
func TestVpxImageConstants(t *testing.T) {
|
||||
// Test that the VpxImage type can be used in common video processing scenarios
|
||||
testCases := []struct {
|
||||
name string
|
||||
planeIndex int
|
||||
description string
|
||||
}{
|
||||
{"Y Plane", 0, "Luma plane"},
|
||||
{"U Plane", 1, "Chroma U plane"},
|
||||
{"V Plane", 2, "Chroma V plane"},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
// Verify plane indices are within expected range
|
||||
if tc.planeIndex < 0 || tc.planeIndex > 2 {
|
||||
t.Errorf("Plane index %d is out of expected range [0-2]", tc.planeIndex)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user