Compare commits

..

7 Commits

Author SHA1 Message Date
Atsushi Watanabe
bc7653cbc3 Fix reading multiple decoded frames 2025-09-16 13:33:45 +09:00
Lei Kang
bb3a7120ef fix the test 2025-09-12 16:32:50 -07:00
Lei Kang
d5c98cb970 add codec decoder interface 2025-09-12 15:35:07 -07:00
Lei Kang
dd145ac720 add return error code 2025-09-05 16:15:34 -07:00
Lei Kang
8cd08c4280 add null pointer from C 2025-09-04 15:42:13 -07:00
Lei Kang
9218f8bf7c wrap vpx_image into a struct 2025-09-04 15:00:14 -07:00
Lei Kang
d30d98198a add vpx decoder 2025-09-04 14:35:05 -07:00
28 changed files with 150 additions and 662 deletions

View File

@@ -13,13 +13,16 @@ jobs:
strategy:
fail-fast: false
matrix:
go: ["1.25", "1.24"] # auto-update/supported-go-version-list
go:
- '1.21' # oldest version this package supports
- '1.22' # oldstable Go version
- '1.23' # stable Go version
name: Linux Go ${{ matrix.go }}
steps:
- name: Checkout
uses: actions/checkout@v5
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v6
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go }}
- name: Install dependencies
@@ -27,7 +30,6 @@ jobs:
sudo apt-get update -qq \
&& sudo apt-get install --no-install-recommends -y \
libopus-dev \
libsvtav1enc-dev \
libva-dev \
libvpx-dev \
libx11-dev \
@@ -42,24 +44,25 @@ jobs:
strategy:
fail-fast: false
matrix:
go: ["1.25", "1.24"] # auto-update/supported-go-version-list
go:
- '1.22'
- '1.23'
runs-on: macos-latest
name: Darwin Go ${{ matrix.go }}
steps:
- name: Checkout
uses: actions/checkout@v5
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v6
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go }}
- name: Install dependencies
run: |
which brew
brew install \
libvpx \
opus \
pkg-config \
svt-av1 \
opus \
libvpx \
x264
- name: Run Test Suite
run: make test
@@ -71,9 +74,9 @@ jobs:
name: Check Licenses
steps:
- name: Checkout
uses: actions/checkout@v5
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v6
uses: actions/setup-go@v5
with:
go-version: stable
- name: Installing go-licenses

View File

@@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v5
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: fix
@@ -20,6 +20,4 @@ jobs:
github_token: ${{ secrets.PIONBOT_GITHUB_TOKEN }}
commit_style: squash
push: force
go_mod_paths: |
./
./examples/
go_mod_paths: ./

View File

@@ -149,14 +149,6 @@ A codec library which supports H.264 encoding and decoding. It is suitable for u
* Package: [github.com/pion/mediadevices/pkg/codec/openh264](https://pkg.go.dev/github.com/pion/mediadevices/pkg/codec/openh264)
* Installation: no installation needed, included as a static binary
##### svtav1
A free software video codec library from the Alliance for Open Media that implements AV1 video coding formats.
* Package: [github.com/pion/mediadevices/pkg/codec/svtav1](https://pkg.go.dev/github.com/pion/mediadevices/pkg/codec/svtav1)
* Installation:
* Mac: `brew install svt-av1`
* Ubuntu: `apt install libsvtav1enc-dev`
##### vpx
A free software video codec library from Google and the Alliance for Open Media that implements VP8/VP9 video coding formats.

View File

@@ -5,28 +5,28 @@ go 1.21
require (
github.com/esimov/pigo v1.4.6
github.com/pion/mediadevices v0.0.0
github.com/pion/webrtc/v4 v4.1.5
github.com/pion/webrtc/v4 v4.1.2
)
require (
github.com/blackjack/webcam v0.6.1 // indirect
github.com/gen2brain/malgo v0.11.24 // indirect
github.com/gen2brain/malgo v0.11.23 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/pion/datachannel v1.5.10 // indirect
github.com/pion/dtls/v3 v3.0.7 // indirect
github.com/pion/dtls/v3 v3.0.6 // indirect
github.com/pion/ice/v4 v4.0.10 // indirect
github.com/pion/interceptor v0.1.41 // indirect
github.com/pion/logging v0.2.4 // indirect
github.com/pion/interceptor v0.1.40 // indirect
github.com/pion/logging v0.2.3 // indirect
github.com/pion/mdns/v2 v2.0.7 // indirect
github.com/pion/randutil v0.1.0 // indirect
github.com/pion/rtcp v1.2.16 // indirect
github.com/pion/rtp v1.8.24 // indirect
github.com/pion/rtcp v1.2.15 // indirect
github.com/pion/rtp v1.8.18 // indirect
github.com/pion/sctp v1.8.39 // indirect
github.com/pion/sdp/v3 v3.0.16 // indirect
github.com/pion/srtp/v3 v3.0.8 // indirect
github.com/pion/sdp/v3 v3.0.13 // indirect
github.com/pion/srtp/v3 v3.0.5 // indirect
github.com/pion/stun/v3 v3.0.0 // indirect
github.com/pion/transport/v3 v3.0.8 // indirect
github.com/pion/turn/v4 v4.1.1 // indirect
github.com/pion/transport/v3 v3.0.7 // indirect
github.com/pion/turn/v4 v4.0.0 // indirect
github.com/wlynxg/anet v0.0.5 // indirect
golang.org/x/crypto v0.33.0 // indirect
golang.org/x/image v0.23.0 // indirect

View File

@@ -6,47 +6,47 @@ github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44am
github.com/esimov/pigo v1.4.6 h1:wpB9FstbqeGP/CZP+nTR52tUJe7XErq8buG+k4xCXlw=
github.com/esimov/pigo v1.4.6/go.mod h1:uqj9Y3+3IRYhFK071rxz1QYq0ePhA6+R9jrUZavi46M=
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/gen2brain/malgo v0.11.24 h1:hHcIJVfzWcEDHFdPl5Dl/CUSOjzOleY0zzAV8Kx+imE=
github.com/gen2brain/malgo v0.11.24/go.mod h1:f9TtuN7DVrXMiV/yIceMeWpvanyVzJQMlBecJFVMxww=
github.com/gen2brain/malgo v0.11.23 h1:3/VAI8DP9/Wyx1CUDNlUQJVdWUvGErhjHDqYcHVk9ME=
github.com/gen2brain/malgo v0.11.23/go.mod h1:f9TtuN7DVrXMiV/yIceMeWpvanyVzJQMlBecJFVMxww=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/pion/datachannel v1.5.10 h1:ly0Q26K1i6ZkGf42W7D4hQYR90pZwzFOjTq5AuCKk4o=
github.com/pion/datachannel v1.5.10/go.mod h1:p/jJfC9arb29W7WrxyKbepTU20CFgyx5oLo8Rs4Py/M=
github.com/pion/dtls/v3 v3.0.7 h1:bItXtTYYhZwkPFk4t1n3Kkf5TDrfj6+4wG+CZR8uI9Q=
github.com/pion/dtls/v3 v3.0.7/go.mod h1:uDlH5VPrgOQIw59irKYkMudSFprY9IEFCqz/eTz16f8=
github.com/pion/dtls/v3 v3.0.6 h1:7Hkd8WhAJNbRgq9RgdNh1aaWlZlGpYTzdqjy9x9sK2E=
github.com/pion/dtls/v3 v3.0.6/go.mod h1:iJxNQ3Uhn1NZWOMWlLxEEHAN5yX7GyPvvKw04v9bzYU=
github.com/pion/ice/v4 v4.0.10 h1:P59w1iauC/wPk9PdY8Vjl4fOFL5B+USq1+xbDcN6gT4=
github.com/pion/ice/v4 v4.0.10/go.mod h1:y3M18aPhIxLlcO/4dn9X8LzLLSma84cx6emMSu14FGw=
github.com/pion/interceptor v0.1.41 h1:NpvX3HgWIukTf2yTBVjVGFXtpSpWgXjqz7IIpu7NsOw=
github.com/pion/interceptor v0.1.41/go.mod h1:nEt4187unvRXJFyjiw00GKo+kIuXMWQI9K89fsosDLY=
github.com/pion/logging v0.2.4 h1:tTew+7cmQ+Mc1pTBLKH2puKsOvhm32dROumOZ655zB8=
github.com/pion/logging v0.2.4/go.mod h1:DffhXTKYdNZU+KtJ5pyQDjvOAh/GsNSyv1lbkFbe3so=
github.com/pion/interceptor v0.1.40 h1:e0BjnPcGpr2CFQgKhrQisBU7V3GXK6wrfYrGYaU6Jq4=
github.com/pion/interceptor v0.1.40/go.mod h1:Z6kqH7M/FYirg3frjGJ21VLSRJGBXB/KqaTIrdqnOic=
github.com/pion/logging v0.2.3 h1:gHuf0zpoh1GW67Nr6Gj4cv5Z9ZscU7g/EaoC/Ke/igI=
github.com/pion/logging v0.2.3/go.mod h1:z8YfknkquMe1csOrxK5kc+5/ZPAzMxbKLX5aXpbpC90=
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.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/rtcp v1.2.15 h1:LZQi2JbdipLOj4eBjK4wlVoQWfrZbh3Q6eHtWtJBZBo=
github.com/pion/rtcp v1.2.15/go.mod h1:jlGuAjHMEXwMUHK78RgX0UmEJFV4zUKOFHR7OP+D3D0=
github.com/pion/rtp v1.8.18 h1:yEAb4+4a8nkPCecWzQB6V/uEU18X1lQCGAQCjP+pyvU=
github.com/pion/rtp v1.8.18/go.mod h1:bAu2UFKScgzyFqvUKmbvzSdPr+NGbZtv6UB2hesqXBk=
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=
github.com/pion/sdp/v3 v3.0.16/go.mod h1:9tyKzznud3qiweZcD86kS0ff1pGYB3VX+Bcsmkx6IXo=
github.com/pion/srtp/v3 v3.0.8 h1:RjRrjcIeQsilPzxvdaElN0CpuQZdMvcl9VZ5UY9suUM=
github.com/pion/srtp/v3 v3.0.8/go.mod h1:2Sq6YnDH7/UDCvkSoHSDNDeyBcFgWL0sAVycVbAsXFg=
github.com/pion/sdp/v3 v3.0.13 h1:uN3SS2b+QDZnWXgdr69SM8KB4EbcnPnPf2Laxhty/l4=
github.com/pion/sdp/v3 v3.0.13/go.mod h1:88GMahN5xnScv1hIMTqLdu/cOcUkj6a9ytbncwMCq2E=
github.com/pion/srtp/v3 v3.0.5 h1:8XLB6Dt3QXkMkRFpoqC3314BemkpMQK2mZeJc4pUKqo=
github.com/pion/srtp/v3 v3.0.5/go.mod h1:r1G7y5r1scZRLe2QJI/is+/O83W2d+JoEsuIexpw+uM=
github.com/pion/stun/v3 v3.0.0 h1:4h1gwhWLWuZWOJIJR9s2ferRO+W3zA/b6ijOI6mKzUw=
github.com/pion/stun/v3 v3.0.0/go.mod h1:HvCN8txt8mwi4FBvS3EmDghW6aQJ24T+y+1TKjB5jyU=
github.com/pion/transport/v3 v3.0.8 h1:oI3myyYnTKUSTthu/NZZ8eu2I5sHbxbUNNFW62olaYc=
github.com/pion/transport/v3 v3.0.8/go.mod h1:+c2eewC5WJQHiAA46fkMMzoYZSuGzA/7E2FPrOYHctQ=
github.com/pion/turn/v4 v4.1.1 h1:9UnY2HB99tpDyz3cVVZguSxcqkJ1DsTSZ+8TGruh4fc=
github.com/pion/turn/v4 v4.1.1/go.mod h1:2123tHk1O++vmjI5VSD0awT50NywDAq5A2NNNU4Jjs8=
github.com/pion/webrtc/v4 v4.1.5 h1:hJqfKPdRAVcXV9rsg2xcCiuXuMJ38BLW/87GsYJUtUU=
github.com/pion/webrtc/v4 v4.1.5/go.mod h1:vzHh7egVnZRgkK83lYzciWVszdDs759y3/eyu6AvZRA=
github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0=
github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo=
github.com/pion/turn/v4 v4.0.0 h1:qxplo3Rxa9Yg1xXDxxH8xaqcyGUtbHYw4QSCvmFWvhM=
github.com/pion/turn/v4 v4.0.0/go.mod h1:MuPDkm15nYSklKpN8vWJ9W2M0PlyQZqYt1McGuxG7mA=
github.com/pion/webrtc/v4 v4.1.2 h1:mpuUo/EJ1zMNKGE79fAdYNFZBX790KE7kQQpLMjjR54=
github.com/pion/webrtc/v4 v4.1.2/go.mod h1:xsCXiNAmMEjIdFxAYU0MbB3RwRieJsegSB2JZsGN+8U=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU=
github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=

22
go.mod
View File

@@ -4,15 +4,15 @@ go 1.21
require (
github.com/blackjack/webcam v0.6.1
github.com/gen2brain/malgo v0.11.24
github.com/gen2brain/malgo v0.11.23
github.com/google/uuid v1.6.0
github.com/kbinani/screenshot v0.0.0-20250624051815-089614a94018
github.com/pion/interceptor v0.1.41
github.com/pion/interceptor v0.1.40
github.com/pion/logging v0.2.4
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
github.com/pion/rtcp v1.2.15
github.com/pion/rtp v1.8.19
github.com/pion/webrtc/v4 v4.1.2
github.com/stretchr/testify v1.10.0
golang.org/x/image v0.23.0
)
@@ -23,16 +23,16 @@ require (
github.com/jezek/xgb v1.1.1 // indirect
github.com/lxn/win v0.0.0-20210218163916-a377121e959e // indirect
github.com/pion/datachannel v1.5.10 // indirect
github.com/pion/dtls/v3 v3.0.7 // indirect
github.com/pion/dtls/v3 v3.0.6 // indirect
github.com/pion/ice/v4 v4.0.10 // indirect
github.com/pion/mdns/v2 v2.0.7 // indirect
github.com/pion/randutil v0.1.0 // indirect
github.com/pion/sctp v1.8.39 // indirect
github.com/pion/sdp/v3 v3.0.16 // indirect
github.com/pion/srtp/v3 v3.0.8 // indirect
github.com/pion/sdp/v3 v3.0.13 // indirect
github.com/pion/srtp/v3 v3.0.5 // indirect
github.com/pion/stun/v3 v3.0.0 // indirect
github.com/pion/transport/v3 v3.0.8 // indirect
github.com/pion/turn/v4 v4.1.1 // indirect
github.com/pion/transport/v3 v3.0.7 // indirect
github.com/pion/turn/v4 v4.0.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/wlynxg/anet v0.0.5 // indirect
golang.org/x/crypto v0.33.0 // indirect

44
go.sum
View File

@@ -2,8 +2,8 @@ github.com/blackjack/webcam v0.6.1 h1:K0T6Q0zto23U99gNAa5q/hFoye6uGcKr2aE6hFoxVo
github.com/blackjack/webcam v0.6.1/go.mod h1:zs+RkUZzqpFPHPiwBZ6U5B34ZXXe9i+SiHLKnnukJuI=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gen2brain/malgo v0.11.24 h1:hHcIJVfzWcEDHFdPl5Dl/CUSOjzOleY0zzAV8Kx+imE=
github.com/gen2brain/malgo v0.11.24/go.mod h1:f9TtuN7DVrXMiV/yIceMeWpvanyVzJQMlBecJFVMxww=
github.com/gen2brain/malgo v0.11.23 h1:3/VAI8DP9/Wyx1CUDNlUQJVdWUvGErhjHDqYcHVk9ME=
github.com/gen2brain/malgo v0.11.23/go.mod h1:f9TtuN7DVrXMiV/yIceMeWpvanyVzJQMlBecJFVMxww=
github.com/gen2brain/shm v0.1.0 h1:MwPeg+zJQXN0RM9o+HqaSFypNoNEcNpeoGp0BTSx2YY=
github.com/gen2brain/shm v0.1.0/go.mod h1:UgIcVtvmOu+aCJpqJX7GOtiN7X2ct+TKLg4RTxwPIUA=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
@@ -24,40 +24,40 @@ github.com/lxn/win v0.0.0-20210218163916-a377121e959e h1:H+t6A/QJMbhCSEH5rAuRxh+
github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk=
github.com/pion/datachannel v1.5.10 h1:ly0Q26K1i6ZkGf42W7D4hQYR90pZwzFOjTq5AuCKk4o=
github.com/pion/datachannel v1.5.10/go.mod h1:p/jJfC9arb29W7WrxyKbepTU20CFgyx5oLo8Rs4Py/M=
github.com/pion/dtls/v3 v3.0.7 h1:bItXtTYYhZwkPFk4t1n3Kkf5TDrfj6+4wG+CZR8uI9Q=
github.com/pion/dtls/v3 v3.0.7/go.mod h1:uDlH5VPrgOQIw59irKYkMudSFprY9IEFCqz/eTz16f8=
github.com/pion/dtls/v3 v3.0.6 h1:7Hkd8WhAJNbRgq9RgdNh1aaWlZlGpYTzdqjy9x9sK2E=
github.com/pion/dtls/v3 v3.0.6/go.mod h1:iJxNQ3Uhn1NZWOMWlLxEEHAN5yX7GyPvvKw04v9bzYU=
github.com/pion/ice/v4 v4.0.10 h1:P59w1iauC/wPk9PdY8Vjl4fOFL5B+USq1+xbDcN6gT4=
github.com/pion/ice/v4 v4.0.10/go.mod h1:y3M18aPhIxLlcO/4dn9X8LzLLSma84cx6emMSu14FGw=
github.com/pion/interceptor v0.1.41 h1:NpvX3HgWIukTf2yTBVjVGFXtpSpWgXjqz7IIpu7NsOw=
github.com/pion/interceptor v0.1.41/go.mod h1:nEt4187unvRXJFyjiw00GKo+kIuXMWQI9K89fsosDLY=
github.com/pion/interceptor v0.1.40 h1:e0BjnPcGpr2CFQgKhrQisBU7V3GXK6wrfYrGYaU6Jq4=
github.com/pion/interceptor v0.1.40/go.mod h1:Z6kqH7M/FYirg3frjGJ21VLSRJGBXB/KqaTIrdqnOic=
github.com/pion/logging v0.2.4 h1:tTew+7cmQ+Mc1pTBLKH2puKsOvhm32dROumOZ655zB8=
github.com/pion/logging v0.2.4/go.mod h1:DffhXTKYdNZU+KtJ5pyQDjvOAh/GsNSyv1lbkFbe3so=
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.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/rtcp v1.2.15 h1:LZQi2JbdipLOj4eBjK4wlVoQWfrZbh3Q6eHtWtJBZBo=
github.com/pion/rtcp v1.2.15/go.mod h1:jlGuAjHMEXwMUHK78RgX0UmEJFV4zUKOFHR7OP+D3D0=
github.com/pion/rtp v1.8.19 h1:jhdO/3XhL/aKm/wARFVmvTfq0lC/CvN1xwYKmduly3c=
github.com/pion/rtp v1.8.19/go.mod h1:bAu2UFKScgzyFqvUKmbvzSdPr+NGbZtv6UB2hesqXBk=
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=
github.com/pion/sdp/v3 v3.0.16/go.mod h1:9tyKzznud3qiweZcD86kS0ff1pGYB3VX+Bcsmkx6IXo=
github.com/pion/srtp/v3 v3.0.8 h1:RjRrjcIeQsilPzxvdaElN0CpuQZdMvcl9VZ5UY9suUM=
github.com/pion/srtp/v3 v3.0.8/go.mod h1:2Sq6YnDH7/UDCvkSoHSDNDeyBcFgWL0sAVycVbAsXFg=
github.com/pion/sdp/v3 v3.0.13 h1:uN3SS2b+QDZnWXgdr69SM8KB4EbcnPnPf2Laxhty/l4=
github.com/pion/sdp/v3 v3.0.13/go.mod h1:88GMahN5xnScv1hIMTqLdu/cOcUkj6a9ytbncwMCq2E=
github.com/pion/srtp/v3 v3.0.5 h1:8XLB6Dt3QXkMkRFpoqC3314BemkpMQK2mZeJc4pUKqo=
github.com/pion/srtp/v3 v3.0.5/go.mod h1:r1G7y5r1scZRLe2QJI/is+/O83W2d+JoEsuIexpw+uM=
github.com/pion/stun/v3 v3.0.0 h1:4h1gwhWLWuZWOJIJR9s2ferRO+W3zA/b6ijOI6mKzUw=
github.com/pion/stun/v3 v3.0.0/go.mod h1:HvCN8txt8mwi4FBvS3EmDghW6aQJ24T+y+1TKjB5jyU=
github.com/pion/transport/v3 v3.0.8 h1:oI3myyYnTKUSTthu/NZZ8eu2I5sHbxbUNNFW62olaYc=
github.com/pion/transport/v3 v3.0.8/go.mod h1:+c2eewC5WJQHiAA46fkMMzoYZSuGzA/7E2FPrOYHctQ=
github.com/pion/turn/v4 v4.1.1 h1:9UnY2HB99tpDyz3cVVZguSxcqkJ1DsTSZ+8TGruh4fc=
github.com/pion/turn/v4 v4.1.1/go.mod h1:2123tHk1O++vmjI5VSD0awT50NywDAq5A2NNNU4Jjs8=
github.com/pion/webrtc/v4 v4.1.5 h1:hJqfKPdRAVcXV9rsg2xcCiuXuMJ38BLW/87GsYJUtUU=
github.com/pion/webrtc/v4 v4.1.5/go.mod h1:vzHh7egVnZRgkK83lYzciWVszdDs759y3/eyu6AvZRA=
github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0=
github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo=
github.com/pion/turn/v4 v4.0.0 h1:qxplo3Rxa9Yg1xXDxxH8xaqcyGUtbHYw4QSCvmFWvhM=
github.com/pion/turn/v4 v4.0.0/go.mod h1:MuPDkm15nYSklKpN8vWJ9W2M0PlyQZqYt1McGuxG7mA=
github.com/pion/webrtc/v4 v4.1.2 h1:mpuUo/EJ1zMNKGE79fAdYNFZBX790KE7kQQpLMjjR54=
github.com/pion/webrtc/v4 v4.1.2/go.mod h1:xsCXiNAmMEjIdFxAYU0MbB3RwRieJsegSB2JZsGN+8U=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU=
github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=

View File

@@ -2,7 +2,6 @@ package mediadevices
import (
"io"
"slices"
"testing"
"github.com/pion/mediadevices/pkg/codec"
@@ -94,7 +93,13 @@ func TestMediaStreamFilters(t *testing.T) {
}
for _, a := range actual {
found := slices.Contains(expected, a)
found := false
for _, e := range expected {
if e == a {
found = true
break
}
}
if !found {
t.Fatalf("%s: Expected to find %p in the query results", t.Name(), a)

View File

@@ -167,7 +167,7 @@ type VideoDecoder interface {
// EncoderController is the interface allowing to control the encoder behaviour after it's initialisation.
// It will possibly have common control method in the future.
// A controller can have optional methods represented by *Controller interfaces
type EncoderController any
type EncoderController interface{}
// Controllable is a interface representing a encoder which can be controlled
// after it's initialisation with an EncoderController

View File

@@ -1,127 +0,0 @@
#include <EbSvtAv1.h>
#include <EbSvtAv1Enc.h>
#include <EbSvtAv1ErrorCodes.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#define ERR_INIT_ENC_HANDLER 1
#define ERR_SET_ENC_PARAM 2
#define ERR_ENC_INIT 3
#define ERR_SEND_PICTURE 4
#define ERR_GET_PACKET 5
typedef struct Encoder {
EbSvtAv1EncConfiguration *param;
EbComponentType *handle;
EbBufferHeaderType *in_buf;
bool force_keyframe;
} Encoder;
int enc_free(Encoder *e) {
free(e->in_buf->p_buffer);
free(e->in_buf);
free(e->param);
free(e);
return 0;
}
int enc_new(Encoder **e) {
*e = malloc(sizeof(Encoder));
(*e)->param = malloc(sizeof(EbSvtAv1EncConfiguration));
(*e)->in_buf = malloc(sizeof(EbBufferHeaderType));
memset((*e)->in_buf, 0, sizeof(EbBufferHeaderType));
(*e)->in_buf->p_buffer = malloc(sizeof(EbSvtIOFormat));
(*e)->in_buf->size = sizeof(EbBufferHeaderType);
#if SVT_AV1_CHECK_VERSION(3, 0, 0)
const EbErrorType sret = svt_av1_enc_init_handle(&(*e)->handle, (*e)->param);
#else
const EbErrorType sret = svt_av1_enc_init_handle(&(*e)->handle, NULL, (*e)->param);
#endif
if (sret != EB_ErrorNone) {
enc_free(*e);
return ERR_INIT_ENC_HANDLER;
}
return 0;
}
int enc_init(Encoder *e) {
EbErrorType sret;
e->param->encoder_bit_depth = 8;
e->param->encoder_color_format = EB_YUV420;
sret = svt_av1_enc_set_parameter(e->handle, e->param);
if (sret != EB_ErrorNone) {
return ERR_SET_ENC_PARAM;
}
sret = svt_av1_enc_init(e->handle);
if (sret != EB_ErrorNone) {
return ERR_ENC_INIT;
}
return 0;
}
int enc_apply_param(Encoder *e) {
const EbErrorType sret = svt_av1_enc_set_parameter(e->handle, e->param);
if (sret != EB_ErrorNone) {
return ERR_SET_ENC_PARAM;
}
return 0;
}
int enc_force_keyframe(Encoder *e) {
e->force_keyframe = true;
return 0;
}
int enc_send_frame(Encoder *e, uint8_t *y, uint8_t *cb, uint8_t *cr, int ystride, int cstride) {
EbSvtIOFormat *in_data = (EbSvtIOFormat *)e->in_buf->p_buffer;
in_data->luma = y;
in_data->cb = cb;
in_data->cr = cr;
in_data->y_stride = ystride;
in_data->cb_stride = cstride;
in_data->cr_stride = cstride;
e->in_buf->pic_type = EB_AV1_INVALID_PICTURE; // auto
if (e->force_keyframe) {
e->in_buf->pic_type = EB_AV1_KEY_PICTURE;
e->force_keyframe = false;
}
e->in_buf->flags = 0;
e->in_buf->pts++;
e->in_buf->n_filled_len = ystride * e->param->source_height;
e->in_buf->n_filled_len += 2 * cstride * e->param->source_height / 2;
const EbErrorType sret = svt_av1_enc_send_picture(e->handle, e->in_buf);
if (sret != EB_ErrorNone) {
return ERR_SEND_PICTURE;
}
return 0;
}
int enc_get_packet(Encoder *e, EbBufferHeaderType **out) {
const EbErrorType sret = svt_av1_enc_get_packet(e->handle, out, 0);
if (sret == EB_NoErrorEmptyQueue) {
return 0;
}
if (sret != EB_ErrorNone) {
return ERR_GET_PACKET;
}
return 0;
}
void memcpy_uint8(uint8_t *dst, const uint8_t *src, size_t n) {
// Just make CGO types compatible
memcpy(dst, src, n);
}

View File

@@ -1,14 +0,0 @@
package svtav1
import (
"errors"
)
var (
ErrUnknownErrorCode = errors.New("unknown error code")
ErrInitEncHandler = errors.New("failed to initialize encoder handler")
ErrSetEncParam = errors.New("failed to set encoder parameters")
ErrEncInit = errors.New("failed to initialize encoder")
ErrSendPicture = errors.New("failed to send picture")
ErrGetPacket = errors.New("failed to get packet")
)

View File

@@ -1,47 +0,0 @@
package svtav1
import (
"time"
"github.com/pion/mediadevices/pkg/codec"
"github.com/pion/mediadevices/pkg/io/video"
"github.com/pion/mediadevices/pkg/prop"
)
// Params stores libx264 specific encoding parameters.
type Params struct {
codec.BaseParams
// Preset configuration number of SVT-AV1
// 1-3: extremely high efficiency but heavy
// 4-6: a balance of efficiency and reasonable compute time
// 7-13: real-time encoding
Preset int
StartingBufferLevel time.Duration
OptimalBufferLevel time.Duration
MaximumBufferSize time.Duration
}
// NewParams returns default x264 codec specific parameters.
func NewParams() (Params, error) {
return Params{
BaseParams: codec.BaseParams{
KeyFrameInterval: 60,
},
Preset: 9,
StartingBufferLevel: 400 * time.Millisecond,
OptimalBufferLevel: 200 * time.Millisecond,
MaximumBufferSize: 500 * time.Millisecond,
}, nil
}
// RTPCodec represents the codec metadata
func (p *Params) RTPCodec() *codec.RTPCodec {
return codec.NewRTPAV1Codec(90000)
}
// BuildVideoEncoder builds x264 encoder with given params
func (p *Params) BuildVideoEncoder(r video.Reader, property prop.Media) (codec.ReadCloser, error) {
return newEncoder(r, property, *p)
}

View File

@@ -1,184 +0,0 @@
// Package svtav1 implements AV1 encoder.
// This package requires libSvtAv1Enc headers and libraries to be built.
package svtav1
// #cgo pkg-config: SvtAv1Enc
// #include "bridge.h"
import "C"
import (
"image"
"io"
"sync"
"github.com/pion/mediadevices/pkg/codec"
"github.com/pion/mediadevices/pkg/io/video"
"github.com/pion/mediadevices/pkg/prop"
)
type encoder struct {
engine *C.Encoder
r video.Reader
mu sync.Mutex
closed bool
outPool sync.Pool
}
func newEncoder(r video.Reader, p prop.Media, params Params) (codec.ReadCloser, error) {
var enc *C.Encoder
if p.FrameRate == 0 {
p.FrameRate = 30
}
if err := errFromC(C.enc_new(&enc)); err != nil {
return nil, err
}
enc.param.source_width = C.uint32_t(p.Width)
enc.param.source_height = C.uint32_t(p.Height)
enc.param.profile = C.MAIN_PROFILE
enc.param.enc_mode = C.int8_t(params.Preset)
enc.param.rate_control_mode = C.SVT_AV1_RC_MODE_CBR
enc.param.pred_structure = C.SVT_AV1_PRED_LOW_DELAY_B
enc.param.target_bit_rate = C.uint32_t(params.BitRate)
enc.param.frame_rate_numerator = C.uint32_t(p.FrameRate * 1000)
enc.param.frame_rate_denominator = 1000
enc.param.intra_refresh_type = C.SVT_AV1_KF_REFRESH
enc.param.intra_period_length = C.int32_t(params.KeyFrameInterval)
enc.param.starting_buffer_level_ms = C.int64_t(params.StartingBufferLevel.Milliseconds())
enc.param.optimal_buffer_level_ms = C.int64_t(params.OptimalBufferLevel.Milliseconds())
enc.param.maximum_buffer_size_ms = C.int64_t(params.MaximumBufferSize.Milliseconds())
if err := errFromC(C.enc_init(enc)); err != nil {
_ = C.enc_free(enc)
return nil, err
}
e := encoder{
engine: enc,
r: video.ToI420(r),
outPool: sync.Pool{
New: func() any {
return []byte(nil)
},
},
}
return &e, nil
}
func errFromC(ret C.int) error {
switch ret {
case 0:
return nil
case C.ERR_INIT_ENC_HANDLER:
return ErrInitEncHandler
case C.ERR_SET_ENC_PARAM:
return ErrSetEncParam
case C.ERR_ENC_INIT:
return ErrEncInit
case C.ERR_SEND_PICTURE:
return ErrSendPicture
case C.ERR_GET_PACKET:
return ErrGetPacket
default:
return ErrUnknownErrorCode
}
}
func (e *encoder) Read() ([]byte, func(), error) {
e.mu.Lock()
defer e.mu.Unlock()
if e.closed {
return nil, func() {}, io.EOF
}
for {
img, release, err := e.r.Read()
if err != nil {
return nil, func() {}, err
}
defer release()
yuvImg := img.(*image.YCbCr)
if err := errFromC(C.enc_send_frame(
e.engine,
(*C.uchar)(&yuvImg.Y[0]),
(*C.uchar)(&yuvImg.Cb[0]),
(*C.uchar)(&yuvImg.Cr[0]),
C.int(yuvImg.YStride),
C.int(yuvImg.CStride),
)); err != nil {
return nil, func() {}, err
}
var buf *C.EbBufferHeaderType
if err := errFromC(C.enc_get_packet(e.engine, &buf)); err != nil {
return nil, func() {}, err
}
if buf == nil {
// Feed frames until receiving a packet
continue
}
n := int(buf.n_filled_len)
outBuf := e.outPool.Get().([]byte)
if cap(outBuf) < n {
outBuf = make([]byte, n)
} else {
outBuf = outBuf[:n]
}
C.memcpy_uint8((*C.uchar)(&outBuf[0]), buf.p_buffer, C.size_t(n))
C.svt_av1_enc_release_out_buffer(&buf)
return outBuf, func() {
e.outPool.Put(outBuf)
}, err
}
}
func (e *encoder) ForceKeyFrame() error {
e.mu.Lock()
defer e.mu.Unlock()
if err := errFromC(C.enc_force_keyframe(e.engine)); err != nil {
return err
}
return nil
}
func (e *encoder) SetBitRate(bitrate int) error {
e.mu.Lock()
defer e.mu.Unlock()
e.engine.param.target_bit_rate = C.uint32_t(bitrate)
if err := errFromC(C.enc_apply_param(e.engine)); err != nil {
return err
}
return nil
}
func (e *encoder) Controller() codec.EncoderController {
return e
}
func (e *encoder) Close() error {
e.mu.Lock()
defer e.mu.Unlock()
if e.closed {
return nil
}
if err := errFromC(C.enc_free(e.engine)); err != nil {
return err
}
e.closed = true
return nil
}

View File

@@ -1,146 +0,0 @@
package svtav1
import (
"image"
"testing"
"github.com/pion/mediadevices/pkg/codec"
"github.com/pion/mediadevices/pkg/codec/internal/codectest"
"github.com/pion/mediadevices/pkg/frame"
"github.com/pion/mediadevices/pkg/io/video"
"github.com/pion/mediadevices/pkg/prop"
)
func getTestVideoEncoder() (codec.ReadCloser, error) {
p, err := NewParams()
if err != nil {
return nil, err
}
p.BitRate = 200000
enc, err := p.BuildVideoEncoder(video.ReaderFunc(func() (image.Image, func(), error) {
return image.NewYCbCr(
image.Rect(0, 0, 256, 144),
image.YCbCrSubsampleRatio420,
), nil, nil
}), prop.Media{
Video: prop.Video{
Width: 256,
Height: 144,
FrameFormat: frame.FormatI420,
},
})
if err != nil {
return nil, err
}
return enc, nil
}
func TestEncoder(t *testing.T) {
t.Run("SimpleRead", func(t *testing.T) {
p, err := NewParams()
if err != nil {
t.Fatal(err)
}
p.BitRate = 200000
codectest.VideoEncoderSimpleReadTest(t, &p,
prop.Media{
Video: prop.Video{
Width: 256,
Height: 144,
FrameFormat: frame.FormatI420,
},
},
image.NewYCbCr(
image.Rect(0, 0, 256, 144),
image.YCbCrSubsampleRatio420,
),
)
})
t.Run("CloseTwice", func(t *testing.T) {
p, err := NewParams()
if err != nil {
t.Fatal(err)
}
p.BitRate = 200000
codectest.VideoEncoderCloseTwiceTest(t, &p, prop.Media{
Video: prop.Video{
Width: 640,
Height: 480,
FrameRate: 30,
FrameFormat: frame.FormatI420,
},
})
})
t.Run("ReadAfterClose", func(t *testing.T) {
p, err := NewParams()
if err != nil {
t.Fatal(err)
}
p.BitRate = 200000
codectest.VideoEncoderReadAfterCloseTest(t, &p,
prop.Media{
Video: prop.Video{
Width: 256,
Height: 144,
FrameFormat: frame.FormatI420,
},
},
image.NewYCbCr(
image.Rect(0, 0, 256, 144),
image.YCbCrSubsampleRatio420,
),
)
})
}
func TestShouldImplementKeyFrameControl(t *testing.T) {
e := &encoder{}
if _, ok := e.Controller().(codec.KeyFrameController); !ok {
t.Error()
}
}
func TestNoErrorOnForceKeyFrame(t *testing.T) {
enc, err := getTestVideoEncoder()
if err != nil {
t.Fatal(err)
}
kfc, ok := enc.Controller().(codec.KeyFrameController)
if !ok {
t.Fatal("Failed to get KeyFrameController")
}
if err := kfc.ForceKeyFrame(); err != nil {
t.Error(err)
}
_, rel, err := enc.Read() // try to read the encoded frame
rel()
if err != nil {
t.Fatal(err)
}
}
func TestShouldImplementBitRateControl(t *testing.T) {
e := &encoder{}
if _, ok := e.Controller().(codec.BitRateController); !ok {
t.Error()
}
}
func TestNoErrorOnSetBitRate(t *testing.T) {
enc, err := getTestVideoEncoder()
if err != nil {
t.Fatal(err)
}
brc, ok := enc.Controller().(codec.BitRateController)
if !ok {
t.Fatal("Failed to get BitRateController")
}
if err := brc.SetBitRate(1000); err != nil { // 1000 bit/second is ridiculously low, but this is a testcase.
t.Error(err)
}
_, rel, err := enc.Read() // try to read the encoded frame
rel()
if err != nil {
t.Fatal(err)
}
}

View File

@@ -512,7 +512,9 @@ func TestVP8EncodeDecode(t *testing.T) {
}
}
writer.Close()
// ✅ wait until decoder goroutine is done
wg.Wait()
assert.Equal(t, totalFrames, counter)
assert.Equal(t, counter, totalFrames)
})
}

View File

@@ -1,8 +1,7 @@
// Package vnc implements a VNC client.
//
// References:
//
// [PROTOCOL]: http://tools.ietf.org/html/rfc6143
// [PROTOCOL]: http://tools.ietf.org/html/rfc6143
package vnc
import (
@@ -97,7 +96,7 @@ func (c *ClientConn) CutText(text string) error {
var buf bytes.Buffer
// This is the fixed size data we'll send
fixedData := []any{
fixedData := []interface{}{
uint8(6),
uint8(0),
uint8(0),
@@ -142,7 +141,7 @@ func (c *ClientConn) FramebufferUpdateRequest(incremental bool, x, y, width, hei
incrementalByte = 1
}
data := []any{
data := []interface{}{
uint8(3),
incrementalByte,
x, y, width, height,
@@ -173,7 +172,7 @@ func (c *ClientConn) KeyEvent(keysym uint32, down bool) error {
downFlag = 1
}
data := []any{
data := []interface{}{
uint8(4),
downFlag,
uint8(0),
@@ -200,7 +199,7 @@ func (c *ClientConn) KeyEvent(keysym uint32, down bool) error {
func (c *ClientConn) PointerEvent(mask ButtonMask, x, y uint16) error {
var buf bytes.Buffer
data := []any{
data := []interface{}{
uint8(5),
uint8(mask),
x,
@@ -226,7 +225,7 @@ func (c *ClientConn) PointerEvent(mask ButtonMask, x, y uint16) error {
//
// See RFC 6143 Section 7.5.2
func (c *ClientConn) SetEncodings(encs []Encoding) error {
data := make([]any, 3+len(encs))
data := make([]interface{}, 3+len(encs))
data[0] = uint8(2)
data[1] = uint8(0)
data[2] = uint16(len(encs))
@@ -320,7 +319,7 @@ func (c *ClientConn) handshake() error {
}
// Respond with the version we will support
if maxMinor < 8 {
if maxMinor<8 {
if _, err = c.c.Write([]byte("RFB 003.003\n")); err != nil {
return err
}
@@ -332,7 +331,7 @@ func (c *ClientConn) handshake() error {
if numSecurityTypes == 0 {
return fmt.Errorf("no security types: %s", c.readErrorReason())
}
} else {
}else{
if _, err = c.c.Write([]byte("RFB 003.008\n")); err != nil {
return err
}

View File

@@ -63,7 +63,7 @@ func (*FramebufferUpdateMessage) Read(c *ClientConn, r io.Reader) (ServerMessage
var encodingType int32
rect := &rects[i]
data := []any{
data := []interface{}{
&rect.X,
&rect.Y,
&rect.Width,
@@ -128,7 +128,7 @@ func (*SetColorMapEntriesMessage) Read(c *ClientConn, r io.Reader) (ServerMessag
for i := uint16(0); i < numColors; i++ {
color := &result.Colors[i]
data := []any{
data := []interface{}{
&color.R,
&color.G,
&color.B,

View File

@@ -27,7 +27,7 @@ func NewBroadcaster(source Reader, config *BroadcasterConfig) *Broadcaster {
coreConfig = config.Core
}
broadcaster := io.NewBroadcaster(io.ReaderFunc(func() (any, func(), error) {
broadcaster := io.NewBroadcaster(io.ReaderFunc(func() (interface{}, func(), error) {
return source.Read()
}), coreConfig)
@@ -39,11 +39,11 @@ func NewBroadcaster(source Reader, config *BroadcasterConfig) *Broadcaster {
// buffer, this means that slow readers might miss some data if they're really late and the data is no longer
// in the ring buffer.
func (broadcaster *Broadcaster) NewReader(copyChunk bool) Reader {
copyFn := func(src any) any { return src }
copyFn := func(src interface{}) interface{} { return src }
if copyChunk {
buffer := wave.NewBuffer()
copyFn = func(src any) any {
copyFn = func(src interface{}) interface{} {
realSrc, _ := src.(wave.Audio)
buffer.StoreCopy(realSrc)
return buffer.Load()
@@ -60,7 +60,7 @@ func (broadcaster *Broadcaster) NewReader(copyChunk bool) Reader {
// ReplaceSource replaces the underlying source. This operation is thread safe.
func (broadcaster *Broadcaster) ReplaceSource(source Reader) error {
return broadcaster.ioBroadcaster.ReplaceSource(io.ReaderFunc(func() (any, func(), error) {
return broadcaster.ioBroadcaster.ReplaceSource(io.ReaderFunc(func() (interface{}, func(), error) {
return source.Read()
}))
}

View File

@@ -17,7 +17,7 @@ const (
var errEmptySource = fmt.Errorf("Source can't be nil")
type broadcasterData struct {
data any
data interface{}
count uint32
err error
}
@@ -124,10 +124,10 @@ func NewBroadcaster(source Reader, config *BroadcasterConfig) *Broadcaster {
// copyFn is used to copy the data from the source to individual readers. Broadcaster uses a small ring
// buffer, this means that slow readers might miss some data if they're really late and the data is no longer
// in the ring buffer.
func (broadcaster *Broadcaster) NewReader(copyFn func(any) any) Reader {
func (broadcaster *Broadcaster) NewReader(copyFn func(interface{}) interface{}) Reader {
currentCount := broadcaster.buffer.lastCount()
return ReaderFunc(func() (data any, release func(), err error) {
return ReaderFunc(func() (data interface{}, release func(), err error) {
currentCount++
if push := broadcaster.buffer.acquire(currentCount); push != nil {
data, _, err = broadcaster.source.Load().(Reader).Read()

View File

@@ -57,7 +57,7 @@ func TestBroadcast(t *testing.T) {
frameCount := 0
frameSent := 0
lastSend := time.Now()
src = ReaderFunc(func() (any, func(), error) {
src = ReaderFunc(func() (interface{}, func(), error) {
if pauseCond.src && frameSent == 30 {
time.Sleep(time.Second)
}
@@ -85,7 +85,7 @@ func TestBroadcast(t *testing.T) {
wg.Add(n)
for i := 0; i < n; i++ {
go func() {
reader := broadcaster.NewReader(func(src any) any { return src })
reader := broadcaster.NewReader(func(src interface{}) interface{} { return src })
count := 0
lastFrameCount := -1
droppedFrames := 0

View File

@@ -11,13 +11,13 @@ type Reader interface {
// there will be new allocations during streaming, and old unused memory will become garbage. As a consequence,
// these garbage will put a lot of pressure to the garbage collector and makes it to run more often and finish
// slower as the heap memory usage increases and more garbage to collect.
Read() (data any, release func(), err error)
Read() (data interface{}, release func(), err error)
}
// ReaderFunc is a proxy type for Reader
type ReaderFunc func() (data any, release func(), err error)
type ReaderFunc func() (data interface{}, release func(), err error)
func (f ReaderFunc) Read() (data any, release func(), err error) {
func (f ReaderFunc) Read() (data interface{}, release func(), err error) {
data, release, err = f()
return
}

View File

@@ -27,7 +27,7 @@ func NewBroadcaster(source Reader, config *BroadcasterConfig) *Broadcaster {
coreConfig = config.Core
}
broadcaster := io.NewBroadcaster(io.ReaderFunc(func() (any, func(), error) {
broadcaster := io.NewBroadcaster(io.ReaderFunc(func() (interface{}, func(), error) {
return source.Read()
}), coreConfig)
@@ -39,11 +39,11 @@ func NewBroadcaster(source Reader, config *BroadcasterConfig) *Broadcaster {
// buffer, this means that slow readers might miss some data if they're really late and the data is no longer
// in the ring buffer.
func (broadcaster *Broadcaster) NewReader(copyFrame bool) Reader {
copyFn := func(src any) any { return src }
copyFn := func(src interface{}) interface{} { return src }
if copyFrame {
buffer := NewFrameBuffer(0)
copyFn = func(src any) any {
copyFn = func(src interface{}) interface{} {
realSrc, _ := src.(image.Image)
buffer.StoreCopy(realSrc)
return buffer.Load()
@@ -60,7 +60,7 @@ func (broadcaster *Broadcaster) NewReader(copyFrame bool) Reader {
// ReplaceSource replaces the underlying source. This operation is thread safe.
func (broadcaster *Broadcaster) ReplaceSource(source Reader) error {
return broadcaster.ioBroadcaster.ReplaceSource(io.ReaderFunc(func() (any, func(), error) {
return broadcaster.ioBroadcaster.ReplaceSource(io.ReaderFunc(func() (interface{}, func(), error) {
return source.Read()
}))
}

View File

@@ -3,7 +3,6 @@ package prop
import (
"fmt"
"math"
"slices"
"strings"
"time"
)
@@ -55,8 +54,10 @@ type DurationOneOf []time.Duration
// Compare implements DurationConstraint.
func (d DurationOneOf) Compare(a time.Duration) (float64, bool) {
if slices.Contains(d, a) {
return 0.0, true
for _, ii := range d {
if ii == a {
return 0.0, true
}
}
return 1.0, false
}

View File

@@ -3,7 +3,6 @@ package prop
import (
"fmt"
"math"
"slices"
"strings"
)
@@ -54,8 +53,10 @@ type FloatOneOf []float32
// Compare implements FloatConstraint.
func (f FloatOneOf) Compare(a float32) (float64, bool) {
if slices.Contains(f, a) {
return 0.0, true
for _, ff := range f {
if ff == a {
return 0.0, true
}
}
return 1.0, false
}

View File

@@ -3,7 +3,6 @@ package prop
import (
"fmt"
"github.com/pion/mediadevices/pkg/frame"
"slices"
"strings"
)
@@ -57,8 +56,10 @@ type FrameFormatOneOf []frame.Format
// Compare implements FrameFormatConstraint.
func (f FrameFormatOneOf) Compare(a frame.Format) (float64, bool) {
if slices.Contains(f, a) {
return 0.0, true
for _, ff := range f {
if ff == a {
return 0.0, true
}
}
return 1.0, false
}

View File

@@ -3,7 +3,6 @@ package prop
import (
"fmt"
"math"
"slices"
"strings"
)
@@ -54,8 +53,10 @@ type IntOneOf []int
// Compare implements IntConstraint.
func (i IntOneOf) Compare(a int) (float64, bool) {
if slices.Contains(i, a) {
return 0.0, true
for _, ii := range i {
if ii == a {
return 0.0, true
}
}
return 1.0, false
}

View File

@@ -32,7 +32,7 @@ func (m *Media) String() string {
return prettifyStruct(m)
}
func prettifyStruct(i any) string {
func prettifyStruct(i interface{}) string {
var rows []string
var addRows func(int, reflect.Value)
addRows = func(level int, obj reflect.Value) {
@@ -67,7 +67,7 @@ type setterFn func(fieldA, fieldB reflect.Value)
// merge merges all the field values from o to p, except zero values. It's guaranteed that setterFn will be called
// when fieldA and fieldB are not struct.
func (p *Media) merge(o any, set setterFn) {
func (p *Media) merge(o interface{}, set setterFn) {
rp := reflect.ValueOf(p).Elem()
ro := reflect.ValueOf(o)
@@ -86,8 +86,10 @@ func (p *Media) merge(o any, set setterFn) {
continue
}
// TODO: Replace this with fieldB.IsZero() when we move to go1.13
// If non-boolean or non-discrete values are zeroes we skip them
if fieldB.IsZero() && fieldB.Kind() != reflect.Bool {
if fieldB.Interface() == reflect.Zero(fieldB.Type()).Interface() &&
fieldB.Kind() != reflect.Bool {
continue
}
@@ -157,13 +159,13 @@ func (p *MediaConstraints) FitnessDistance(o Media) (float64, bool) {
}
type comparisons []struct {
desired, actual any
desired, actual interface{}
}
func (c *comparisons) add(desired, actual any) {
func (c *comparisons) add(desired, actual interface{}) {
if desired != nil {
*c = append(*c,
struct{ desired, actual any }{
struct{ desired, actual interface{} }{
desired, actual,
},
)

View File

@@ -2,7 +2,6 @@ package prop
import (
"fmt"
"slices"
"strings"
)
@@ -56,8 +55,10 @@ type StringOneOf []string
// Compare implements StringConstraint.
func (f StringOneOf) Compare(a string) (float64, bool) {
if slices.Contains(f, a) {
return 0.0, true
for _, ff := range f {
if ff == a {
return 0.0, true
}
}
return 1.0, false
}