mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
TEST: Upgrade pion to v3.2.9. (#3567)
------ Co-authored-by: chundonglinlin <chundonglinlin@163.com>
This commit is contained in:
parent
104cf14d68
commit
df854339ea
1383 changed files with 118469 additions and 41421 deletions
4
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/.gitignore
generated
vendored
4
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/.gitignore
generated
vendored
|
@ -1,3 +1,6 @@
|
|||
# SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
### JetBrains IDE ###
|
||||
#####################
|
||||
.idea/
|
||||
|
@ -22,3 +25,4 @@ cover.out
|
|||
*.wasm
|
||||
examples/sfu-ws/cert.pem
|
||||
examples/sfu-ws/key.pem
|
||||
wasm_exec.js
|
||||
|
|
60
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/.golangci.yml
generated
vendored
60
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/.golangci.yml
generated
vendored
|
@ -1,3 +1,6 @@
|
|||
# SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
linters-settings:
|
||||
govet:
|
||||
check-shadowing: true
|
||||
|
@ -10,19 +13,34 @@ linters-settings:
|
|||
modules:
|
||||
- github.com/pkg/errors:
|
||||
recommendations:
|
||||
- errors
|
||||
- errors
|
||||
forbidigo:
|
||||
forbid:
|
||||
- ^fmt.Print(f|ln)?$
|
||||
- ^log.(Panic|Fatal|Print)(f|ln)?$
|
||||
- ^os.Exit$
|
||||
- ^panic$
|
||||
- ^print(ln)?$
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers
|
||||
- bidichk # Checks for dangerous unicode character sequences
|
||||
- bodyclose # checks whether HTTP response body is closed successfully
|
||||
- deadcode # Finds unused code
|
||||
- contextcheck # check the function whether use a non-inherited context
|
||||
- decorder # check declaration order and count of types, constants, variables and functions
|
||||
- depguard # Go linter that checks if package imports are in a list of acceptable packages
|
||||
- dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())
|
||||
- dupl # Tool for code clone detection
|
||||
- durationcheck # check for two durations multiplied together
|
||||
- errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases
|
||||
- errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted.
|
||||
- errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`.
|
||||
- errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13.
|
||||
- exhaustive # check exhaustiveness of enum switch statements
|
||||
- exportloopref # checks for pointers to enclosing loop variables
|
||||
- forbidigo # Forbids identifiers
|
||||
- forcetypeassert # finds forced type assertions
|
||||
- gci # Gci control golang package import order and make it always deterministic.
|
||||
- gochecknoglobals # Checks that no globals are present in Go code
|
||||
- gochecknoinits # Checks that no init functions are present in Go code
|
||||
|
@ -35,40 +53,59 @@ linters:
|
|||
- gofumpt # Gofumpt checks whether code was gofumpt-ed.
|
||||
- goheader # Checks is file header matches to pattern
|
||||
- goimports # Goimports does everything that gofmt does. Additionally it checks unused imports
|
||||
- golint # Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes
|
||||
- gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod.
|
||||
- gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations.
|
||||
- goprintffuncname # Checks that printf-like functions are named with `f` at the end
|
||||
- gosec # Inspects source code for security problems
|
||||
- gosimple # Linter for Go source code that specializes in simplifying a code
|
||||
- govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string
|
||||
- grouper # An analyzer to analyze expression groups.
|
||||
- importas # Enforces consistent import aliases
|
||||
- ineffassign # Detects when assignments to existing variables are not used
|
||||
- misspell # Finds commonly misspelled English words in comments
|
||||
- nakedret # Finds naked returns in functions greater than a specified function length
|
||||
- nilerr # Finds the code that returns nil even if it checks that the error is not nil.
|
||||
- nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value.
|
||||
- noctx # noctx finds sending http request without context.Context
|
||||
- scopelint # Scopelint checks for unpinned variables in go programs
|
||||
- predeclared # find code that shadows one of Go's predeclared identifiers
|
||||
- revive # golint replacement, finds style mistakes
|
||||
- staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks
|
||||
- structcheck # Finds unused struct fields
|
||||
- stylecheck # Stylecheck is a replacement for golint
|
||||
- tagliatelle # Checks the struct tags.
|
||||
- tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17
|
||||
- tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes
|
||||
- typecheck # Like the front-end of a Go compiler, parses and type-checks Go code
|
||||
- unconvert # Remove unnecessary type conversions
|
||||
- unparam # Reports unused function parameters
|
||||
- unused # Checks Go code for unused constants, variables, functions and types
|
||||
- varcheck # Finds unused global variables and constants
|
||||
- wastedassign # wastedassign finds wasted assignment statements
|
||||
- whitespace # Tool for detection of leading and trailing whitespace
|
||||
disable:
|
||||
- containedctx # containedctx is a linter that detects struct contained context.Context field
|
||||
- cyclop # checks function and package cyclomatic complexity
|
||||
- exhaustivestruct # Checks if all struct's fields are initialized
|
||||
- funlen # Tool for detection of long functions
|
||||
- gocyclo # Computes and checks the cyclomatic complexity of functions
|
||||
- godot # Check if comments end in a period
|
||||
- gomnd # An analyzer to detect magic numbers.
|
||||
- ifshort # Checks that your code uses short syntax for if-statements whenever possible
|
||||
- ireturn # Accept Interfaces, Return Concrete Types
|
||||
- lll # Reports long lines
|
||||
- maintidx # maintidx measures the maintainability index of each function.
|
||||
- makezero # Finds slice declarations with non-zero initial length
|
||||
- maligned # Tool to detect Go structs that would take less memory if their fields were sorted
|
||||
- nestif # Reports deeply nested if statements
|
||||
- nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity
|
||||
- nolintlint # Reports ill-formed or insufficient nolint directives
|
||||
- paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test
|
||||
- prealloc # Finds slice declarations that could potentially be preallocated
|
||||
- promlinter # Check Prometheus metrics naming via promlint
|
||||
- rowserrcheck # checks whether Err of rows is checked successfully
|
||||
- sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed.
|
||||
- testpackage # linter that makes you use a separate _test package
|
||||
- thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers
|
||||
- varnamelen # checks that the length of a variable's name matches its scope
|
||||
- wrapcheck # Checks that errors returned from external packages are wrapped
|
||||
- wsl # Whitespace Linter - Forces you to use empty lines!
|
||||
|
||||
issues:
|
||||
|
@ -78,12 +115,23 @@ issues:
|
|||
- path: _test\.go
|
||||
linters:
|
||||
- gocognit
|
||||
- forbidigo
|
||||
|
||||
# Allow complex main function in examples
|
||||
- path: examples
|
||||
text: "of func `main` is high"
|
||||
linters:
|
||||
- gocognit
|
||||
|
||||
# Allow forbidden identifiers in examples
|
||||
- path: examples
|
||||
linters:
|
||||
- forbidigo
|
||||
|
||||
# Allow forbidden identifiers in CLI commands
|
||||
- path: cmd
|
||||
linters:
|
||||
- forbidigo
|
||||
|
||||
run:
|
||||
skip-dirs-use-default: false
|
||||
|
|
5
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/.goreleaser.yml
generated
vendored
Normal file
5
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/.goreleaser.yml
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
# SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
builds:
|
||||
- skip: true
|
30
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/AUTHORS.txt
generated
vendored
Normal file
30
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/AUTHORS.txt
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
# Thank you to everyone that made Pion possible. If you are interested in contributing
|
||||
# we would love to have you https://github.com/pion/webrtc/wiki/Contributing
|
||||
#
|
||||
# This file is auto generated, using git to list all individuals contributors.
|
||||
# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting
|
||||
Aaron Boushley <boushley@gmail.com>
|
||||
Adam Kiss <masterada@gmail.com>
|
||||
adamroach <adam@nostrum.com>
|
||||
Aditya Kumar <k.aditya00@gmail.com>
|
||||
aler9 <46489434+aler9@users.noreply.github.com>
|
||||
Antoine Baché <antoine@tenten.app>
|
||||
Atsushi Watanabe <atsushi.w@ieee.org>
|
||||
Bobby Peck <rpeck@mux.com>
|
||||
boks1971 <raja.gobi@tutanota.com>
|
||||
David Zhao <david@davidzhao.com>
|
||||
Jonathan Müller <jonathan@fotokite.com>
|
||||
Kevin Caffrey <kcaffrey@gmail.com>
|
||||
Maksim Nesterov <msnesterov@avito.ru>
|
||||
Mathis Engelbart <mathis.engelbart@gmail.com>
|
||||
Miroslav <sedivy.miro@gmail.com>
|
||||
Miroslav Šedivý <sedivy.miro@gmail.com>
|
||||
Quentin Renard <contact@asticode.com>
|
||||
Rayleigh Li <rayleigh.li@zoom.us>
|
||||
Sean DuBois <sean@siobud.com>
|
||||
Steffen Vogel <post@steffenvogel.de>
|
||||
XLPolar <guangjin_pan@163.com>
|
||||
ziminghua <565209960@qq.com>
|
||||
|
||||
# List of contributors not appearing in Git history
|
||||
|
20
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/LICENSE
generated
vendored
20
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/LICENSE
generated
vendored
|
@ -1,21 +1,9 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018
|
||||
Copyright (c) 2023 The Pion community <https://pion.ly>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
|
37
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/README.md
generated
vendored
37
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/README.md
generated
vendored
|
@ -8,7 +8,8 @@
|
|||
<a href="https://pion.ly"><img src="https://img.shields.io/badge/pion-interceptor-gray.svg?longCache=true&colorB=brightgreen" alt="Pion Interceptor"></a>
|
||||
<a href="https://pion.ly/slack"><img src="https://img.shields.io/badge/join-us%20on%20slack-gray.svg?longCache=true&logo=slack&colorB=brightgreen" alt="Slack Widget"></a>
|
||||
<br>
|
||||
<a href="https://pkg.go.dev/github.com/pion/interceptor"><img src="https://godoc.org/github.com/pion/interceptor?status.svg" alt="GoDoc"></a>
|
||||
<img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/pion/interceptor/test.yaml">
|
||||
<a href="https://pkg.go.dev/github.com/pion/interceptor"><img src="https://pkg.go.dev/badge/github.com/pion/interceptor.svg" alt="Go Reference"></a>
|
||||
<a href="https://codecov.io/gh/pion/interceptor"><img src="https://codecov.io/gh/pion/interceptor/branch/master/graph/badge.svg" alt="Coverage Status"></a>
|
||||
<a href="https://goreportcard.com/report/github.com/pion/interceptor"><img src="https://goreportcard.com/badge/github.com/pion/interceptor" alt="Go Report Card"></a>
|
||||
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
|
||||
|
@ -27,18 +28,21 @@ by anyone. With the following tenets in mind.
|
|||
* Encourage modification. Add your own interceptors without forking. Mixing with the ones we provide.
|
||||
* Empower learning. This code base should be useful to read and learn even if you aren't using Pion.
|
||||
|
||||
#### Current Interceptors
|
||||
* NACK Generator/Responder
|
||||
### Current Interceptors
|
||||
* [NACK Generator/Responder](https://github.com/pion/interceptor/tree/master/pkg/nack)
|
||||
* [Sender and Receiver Reports](https://github.com/pion/interceptor/tree/master/pkg/report)
|
||||
* [Transport Wide Congestion Control Feedback](https://github.com/pion/interceptor/tree/master/pkg/twcc)
|
||||
* [Packet Dump](https://github.com/pion/interceptor/tree/master/pkg/packetdump)
|
||||
* [Google Congestion Control](https://github.com/pion/interceptor/tree/master/pkg/gcc)
|
||||
* [Stats](https://github.com/pion/interceptor/tree/master/pkg/stats) A [webrtc-stats](https://www.w3.org/TR/webrtc-stats/) compliant statistics generation
|
||||
* [Interval PLI](https://github.com/pion/interceptor/tree/master/pkg/intervalpli) Generate PLI on a interval. Useful when no decoder is available.
|
||||
|
||||
#### Planned Interceptors
|
||||
* [Sender and Receiver Reports](https://tools.ietf.org/html/rfc3550#section-6.4)
|
||||
- Bandwidth Estimation from Receiver Reports
|
||||
* [Transport Wide Congestion Control Feedback](https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01)
|
||||
### Planned Interceptors
|
||||
* Bandwidth Estimation
|
||||
- [NADA](https://tools.ietf.org/html/rfc8698)
|
||||
- [Google Congestion Control](https://tools.ietf.org/html/draft-ietf-rmcat-gcc-02)
|
||||
* JitterBuffer, re-order packets and wait for arrival
|
||||
* [FlexFec](https://tools.ietf.org/html/draft-ietf-payload-flexible-fec-scheme-20)
|
||||
* [webrtc-stats](https://www.w3.org/TR/webrtc-stats/) compliant statistics generation
|
||||
* [RTCP Feedback for Congestion Control](https://datatracker.ietf.org/doc/html/rfc8888) the standardized alternative to TWCC.
|
||||
|
||||
### Interceptor Public API
|
||||
The public interface is defined in [interceptor.go](https://github.com/pion/interceptor/blob/master/interceptor.go).
|
||||
|
@ -62,20 +66,19 @@ sequentially as the packet moves through them.
|
|||
The [examples](https://github.com/pion/interceptor/blob/master/examples) directory provides some basic examples. If you need more please file an issue!
|
||||
You should also look in [pion/webrtc](https://github.com/pion/webrtc) for real world examples.
|
||||
|
||||
### Roadmap
|
||||
The library is used as a part of our WebRTC implementation. Please refer to that [roadmap](https://github.com/pion/webrtc/issues/9) to track our major milestones.
|
||||
|
||||
### Community
|
||||
Pion has an active community on the [Golang Slack](https://invite.slack.golangbridge.org/). Sign up and join the **#pion** channel for discussions and support. You can also use [Pion mailing list](https://groups.google.com/forum/#!forum/pion).
|
||||
Pion has an active community on the [Slack](https://pion.ly/slack).
|
||||
|
||||
Follow the [Pion Twitter](https://twitter.com/_pion) for project updates and important WebRTC news.
|
||||
|
||||
We are always looking to support **your projects**. Please reach out if you have something to build!
|
||||
|
||||
If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly)
|
||||
|
||||
### Contributing
|
||||
Check out the **[contributing wiki](https://github.com/pion/webrtc/wiki/Contributing)** to join the group of amazing people making this project possible:
|
||||
|
||||
* [Adam Kiss](https://github.com/masterada) - *Original Author*
|
||||
* [Sean DuBois](https://github.com/sean-der) - *Original Author*
|
||||
* [Atsushi Watanabe](https://github.com/at-wat)
|
||||
* [Alessandro Ros](https://github.com/aler9)
|
||||
Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt)
|
||||
|
||||
### License
|
||||
MIT License - see [LICENSE](LICENSE) for full text
|
||||
|
|
68
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/attributes.go
generated
vendored
Normal file
68
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/attributes.go
generated
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package interceptor
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/pion/rtcp"
|
||||
"github.com/pion/rtp"
|
||||
)
|
||||
|
||||
type unmarshaledDataKeyType int
|
||||
|
||||
const (
|
||||
rtpHeaderKey unmarshaledDataKeyType = iota
|
||||
rtcpPacketsKey
|
||||
)
|
||||
|
||||
var errInvalidType = errors.New("found value of invalid type in attributes map")
|
||||
|
||||
// Attributes are a generic key/value store used by interceptors
|
||||
type Attributes map[interface{}]interface{}
|
||||
|
||||
// Get returns the attribute associated with key.
|
||||
func (a Attributes) Get(key interface{}) interface{} {
|
||||
return a[key]
|
||||
}
|
||||
|
||||
// Set sets the attribute associated with key to the given value.
|
||||
func (a Attributes) Set(key interface{}, val interface{}) {
|
||||
a[key] = val
|
||||
}
|
||||
|
||||
// GetRTPHeader gets the RTP header if present. If it is not present, it will be
|
||||
// unmarshalled from the raw byte slice and stored in the attribtues.
|
||||
func (a Attributes) GetRTPHeader(raw []byte) (*rtp.Header, error) {
|
||||
if val, ok := a[rtpHeaderKey]; ok {
|
||||
if header, ok := val.(*rtp.Header); ok {
|
||||
return header, nil
|
||||
}
|
||||
return nil, errInvalidType
|
||||
}
|
||||
header := &rtp.Header{}
|
||||
if _, err := header.Unmarshal(raw); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
a[rtpHeaderKey] = header
|
||||
return header, nil
|
||||
}
|
||||
|
||||
// GetRTCPPackets gets the RTCP packets if present. If the packet slice is not
|
||||
// present, it will be unmarshaled from the raw byte slice and stored in the
|
||||
// attributes.
|
||||
func (a Attributes) GetRTCPPackets(raw []byte) ([]rtcp.Packet, error) {
|
||||
if val, ok := a[rtcpPacketsKey]; ok {
|
||||
if packets, ok := val.([]rtcp.Packet); ok {
|
||||
return packets, nil
|
||||
}
|
||||
return nil, errInvalidType
|
||||
}
|
||||
pkts, err := rtcp.Unmarshal(raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
a[rtcpPacketsKey] = pkts
|
||||
return pkts, nil
|
||||
}
|
3
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/chain.go
generated
vendored
3
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/chain.go
generated
vendored
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package interceptor
|
||||
|
||||
// Chain is an interceptor that runs all child interceptors in order.
|
||||
|
|
2
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/codecov.yml
generated
vendored
2
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/codecov.yml
generated
vendored
|
@ -3,6 +3,8 @@
|
|||
#
|
||||
# It is automatically copied from https://github.com/pion/.goassets repository.
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
coverage:
|
||||
status:
|
||||
|
|
7
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/errors.go
generated
vendored
7
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/errors.go
generated
vendored
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package interceptor
|
||||
|
||||
import (
|
||||
|
@ -18,7 +21,7 @@ func flattenErrs(errs []error) error {
|
|||
return multiError(errs2)
|
||||
}
|
||||
|
||||
type multiError []error
|
||||
type multiError []error //nolint
|
||||
|
||||
func (me multiError) Error() string {
|
||||
var errstrings []string
|
||||
|
@ -41,7 +44,7 @@ func (me multiError) Is(err error) bool {
|
|||
if errors.Is(e, err) {
|
||||
return true
|
||||
}
|
||||
if me2, ok := e.(multiError); ok {
|
||||
if me2, ok := e.(multiError); ok { //nolint
|
||||
if me2.Is(err) {
|
||||
return true
|
||||
}
|
||||
|
|
10
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/go.mod
generated
vendored
10
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/go.mod
generated
vendored
|
@ -1,10 +0,0 @@
|
|||
module github.com/pion/interceptor
|
||||
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/pion/logging v0.2.2
|
||||
github.com/pion/rtcp v1.2.6
|
||||
github.com/pion/rtp v1.6.2
|
||||
github.com/stretchr/testify v1.7.0
|
||||
)
|
21
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/go.sum
generated
vendored
21
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/go.sum
generated
vendored
|
@ -1,21 +0,0 @@
|
|||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
|
||||
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
|
||||
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.6 h1:1zvwBbyd0TeEuuWftrd/4d++m+/kZSeiguxU61LFWpo=
|
||||
github.com/pion/rtcp v1.2.6/go.mod h1:52rMNPWFsjr39z9B9MhnkqhPLoeHTv1aN63o/42bWE0=
|
||||
github.com/pion/rtp v1.6.2 h1:iGBerLX6JiDjB9NXuaPzHyxHFG9JsIEdgwTC0lp5n/U=
|
||||
github.com/pion/rtp v1.6.2/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
|
||||
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/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
22
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/interceptor.go
generated
vendored
22
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/interceptor.go
generated
vendored
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Package interceptor contains the Interceptor interface, with some useful interceptors that should be safe to use
|
||||
// in most cases.
|
||||
package interceptor
|
||||
|
@ -9,10 +12,14 @@ import (
|
|||
"github.com/pion/rtp"
|
||||
)
|
||||
|
||||
// Factory provides an interface for constructing interceptors
|
||||
type Factory interface {
|
||||
NewInterceptor(id string) (Interceptor, error)
|
||||
}
|
||||
|
||||
// Interceptor can be used to add functionality to you PeerConnections by modifying any incoming/outgoing rtp/rtcp
|
||||
// packets, or sending your own packets as needed.
|
||||
type Interceptor interface {
|
||||
|
||||
// BindRTCPReader lets you modify any incoming RTCP packets. It is called once per sender/receiver, however this might
|
||||
// change in the future. The returned method will be called once per packet batch.
|
||||
BindRTCPReader(reader RTCPReader) RTCPReader
|
||||
|
@ -62,9 +69,6 @@ type RTCPReader interface {
|
|||
Read([]byte, Attributes) (int, Attributes, error)
|
||||
}
|
||||
|
||||
// Attributes are a generic key/value store used by interceptors
|
||||
type Attributes map[interface{}]interface{}
|
||||
|
||||
// RTPWriterFunc is an adapter for RTPWrite interface
|
||||
type RTPWriterFunc func(header *rtp.Header, payload []byte, attributes Attributes) (int, error)
|
||||
|
||||
|
@ -96,13 +100,3 @@ func (f RTCPWriterFunc) Write(pkts []rtcp.Packet, attributes Attributes) (int, e
|
|||
func (f RTCPReaderFunc) Read(b []byte, a Attributes) (int, Attributes, error) {
|
||||
return f(b, a)
|
||||
}
|
||||
|
||||
// Get returns the attribute associated with key.
|
||||
func (a Attributes) Get(key interface{}) interface{} {
|
||||
return a[key]
|
||||
}
|
||||
|
||||
// Set sets the attribute associated with key to the given value.
|
||||
func (a Attributes) Set(key interface{}, val interface{}) {
|
||||
a[key] = val
|
||||
}
|
||||
|
|
30
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/internal/ntp/ntp.go
generated
vendored
Normal file
30
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/internal/ntp/ntp.go
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Package ntp provides conversion methods between time.Time and NTP timestamps
|
||||
// stored in uint64
|
||||
package ntp
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// ToNTP converts a time.Time oboject to an uint64 NTP timestamp
|
||||
func ToNTP(t time.Time) uint64 {
|
||||
// seconds since 1st January 1900
|
||||
s := (float64(t.UnixNano()) / 1000000000) + 2208988800
|
||||
|
||||
// higher 32 bits are the integer part, lower 32 bits are the fractional part
|
||||
integerPart := uint32(s)
|
||||
fractionalPart := uint32((s - float64(integerPart)) * 0xFFFFFFFF)
|
||||
return uint64(integerPart)<<32 | uint64(fractionalPart)
|
||||
}
|
||||
|
||||
// ToTime converts a uint64 NTP timestamps to a time.Time object
|
||||
func ToTime(t uint64) time.Time {
|
||||
seconds := (t & 0xFFFFFFFF00000000) >> 32
|
||||
fractional := float64(t&0x00000000FFFFFFFF) / float64(0xFFFFFFFF)
|
||||
d := time.Duration(seconds)*time.Second + time.Duration(fractional*1e9)*time.Nanosecond
|
||||
|
||||
return time.Unix(0, 0).Add(-2208988800 * time.Second).Add(d)
|
||||
}
|
3
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/noop.go
generated
vendored
3
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/noop.go
generated
vendored
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package interceptor
|
||||
|
||||
// NoOp is an Interceptor that does not modify any packets. It can embedded in other interceptors, so it's
|
||||
|
|
9
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/nack/errors.go
generated
vendored
9
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/nack/errors.go
generated
vendored
|
@ -1,6 +1,15 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package nack
|
||||
|
||||
import "errors"
|
||||
|
||||
// ErrInvalidSize is returned by newReceiveLog/newSendBuffer, when an incorrect buffer size is supplied.
|
||||
var ErrInvalidSize = errors.New("invalid buffer size")
|
||||
|
||||
var (
|
||||
errPacketReleased = errors.New("could not retain packet, already released")
|
||||
errFailedToCastHeaderPool = errors.New("could not access header pool, failed cast")
|
||||
errFailedToCastPayloadPool = errors.New("could not access payload pool, failed cast")
|
||||
)
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package nack
|
||||
|
||||
import (
|
||||
|
@ -8,9 +11,37 @@ import (
|
|||
"github.com/pion/interceptor"
|
||||
"github.com/pion/logging"
|
||||
"github.com/pion/rtcp"
|
||||
"github.com/pion/rtp"
|
||||
)
|
||||
|
||||
// GeneratorInterceptorFactory is a interceptor.Factory for a GeneratorInterceptor
|
||||
type GeneratorInterceptorFactory struct {
|
||||
opts []GeneratorOption
|
||||
}
|
||||
|
||||
// NewInterceptor constructs a new ReceiverInterceptor
|
||||
func (g *GeneratorInterceptorFactory) NewInterceptor(_ string) (interceptor.Interceptor, error) {
|
||||
i := &GeneratorInterceptor{
|
||||
size: 512,
|
||||
skipLastN: 0,
|
||||
interval: time.Millisecond * 100,
|
||||
receiveLogs: map[uint32]*receiveLog{},
|
||||
close: make(chan struct{}),
|
||||
log: logging.NewDefaultLoggerFactory().NewLogger("nack_generator"),
|
||||
}
|
||||
|
||||
for _, opt := range g.opts {
|
||||
if err := opt(i); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := newReceiveLog(i.size); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// GeneratorInterceptor interceptor generates nack feedback messages.
|
||||
type GeneratorInterceptor struct {
|
||||
interceptor.NoOp
|
||||
|
@ -26,28 +57,9 @@ type GeneratorInterceptor struct {
|
|||
receiveLogsMu sync.Mutex
|
||||
}
|
||||
|
||||
// NewGeneratorInterceptor returns a new GeneratorInterceptor interceptor
|
||||
func NewGeneratorInterceptor(opts ...GeneratorOption) (*GeneratorInterceptor, error) {
|
||||
r := &GeneratorInterceptor{
|
||||
size: 8192,
|
||||
skipLastN: 0,
|
||||
interval: time.Millisecond * 100,
|
||||
receiveLogs: map[uint32]*receiveLog{},
|
||||
close: make(chan struct{}),
|
||||
log: logging.NewDefaultLoggerFactory().NewLogger("nack_generator"),
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
if err := opt(r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := newReceiveLog(r.size); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r, nil
|
||||
// NewGeneratorInterceptor returns a new GeneratorInterceptorFactory
|
||||
func NewGeneratorInterceptor(opts ...GeneratorOption) (*GeneratorInterceptorFactory, error) {
|
||||
return &GeneratorInterceptorFactory{opts}, nil
|
||||
}
|
||||
|
||||
// BindRTCPWriter lets you modify any outgoing RTCP packets. It is called once per PeerConnection. The returned method
|
||||
|
@ -86,18 +98,21 @@ func (n *GeneratorInterceptor) BindRemoteStream(info *interceptor.StreamInfo, re
|
|||
return 0, nil, err
|
||||
}
|
||||
|
||||
pkt := rtp.Packet{}
|
||||
if err = pkt.Unmarshal(b[:i]); err != nil {
|
||||
if attr == nil {
|
||||
attr = make(interceptor.Attributes)
|
||||
}
|
||||
header, err := attr.GetRTPHeader(b[:i])
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
receiveLog.add(pkt.Header.SequenceNumber)
|
||||
receiveLog.add(header.SequenceNumber)
|
||||
|
||||
return i, attr, nil
|
||||
})
|
||||
}
|
||||
|
||||
// UnbindLocalStream is called when the Stream is removed. It can be used to clean up any data related to that track.
|
||||
func (n *GeneratorInterceptor) UnbindLocalStream(info *interceptor.StreamInfo) {
|
||||
// UnbindRemoteStream is called when the Stream is removed. It can be used to clean up any data related to that track.
|
||||
func (n *GeneratorInterceptor) UnbindRemoteStream(info *interceptor.StreamInfo) {
|
||||
n.receiveLogsMu.Lock()
|
||||
delete(n.receiveLogs, info.SSRC)
|
||||
n.receiveLogsMu.Unlock()
|
||||
|
@ -122,6 +137,7 @@ func (n *GeneratorInterceptor) loop(rtcpWriter interceptor.RTCPWriter) {
|
|||
senderSSRC := rand.Uint32() // #nosec
|
||||
|
||||
ticker := time.NewTicker(n.interval)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package nack
|
||||
|
||||
import (
|
||||
|
|
3
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/nack/nack.go
generated
vendored
3
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/nack/nack.go
generated
vendored
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Package nack provides interceptors to implement sending and receiving negative acknowledgements
|
||||
package nack
|
||||
|
||||
|
|
6
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/nack/receive_log.go
generated
vendored
6
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/nack/receive_log.go
generated
vendored
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package nack
|
||||
|
||||
import (
|
||||
|
@ -127,8 +130,9 @@ func (s *receiveLog) getReceived(seq uint16) bool {
|
|||
|
||||
func (s *receiveLog) fixLastConsecutive() {
|
||||
i := s.lastConsecutive + 1
|
||||
for ; i != s.end+1 && s.getReceived(i); i++ {
|
||||
for ; i != s.end+1 && s.getReceived(i); i++ { //nolint:revive
|
||||
// find all consecutive packets
|
||||
}
|
||||
|
||||
s.lastConsecutive = i - 1
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package nack
|
||||
|
||||
import (
|
||||
|
@ -9,11 +12,46 @@ import (
|
|||
"github.com/pion/rtp"
|
||||
)
|
||||
|
||||
// ResponderInterceptorFactory is a interceptor.Factory for a ResponderInterceptor
|
||||
type ResponderInterceptorFactory struct {
|
||||
opts []ResponderOption
|
||||
}
|
||||
|
||||
type packetFactory interface {
|
||||
NewPacket(header *rtp.Header, payload []byte) (*retainablePacket, error)
|
||||
}
|
||||
|
||||
// NewInterceptor constructs a new ResponderInterceptor
|
||||
func (r *ResponderInterceptorFactory) NewInterceptor(_ string) (interceptor.Interceptor, error) {
|
||||
i := &ResponderInterceptor{
|
||||
size: 1024,
|
||||
log: logging.NewDefaultLoggerFactory().NewLogger("nack_responder"),
|
||||
streams: map[uint32]*localStream{},
|
||||
}
|
||||
|
||||
for _, opt := range r.opts {
|
||||
if err := opt(i); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if i.packetFactory == nil {
|
||||
i.packetFactory = newPacketManager()
|
||||
}
|
||||
|
||||
if _, err := newSendBuffer(i.size); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// ResponderInterceptor responds to nack feedback messages
|
||||
type ResponderInterceptor struct {
|
||||
interceptor.NoOp
|
||||
size uint16
|
||||
log logging.LeveledLogger
|
||||
size uint16
|
||||
log logging.LeveledLogger
|
||||
packetFactory packetFactory
|
||||
|
||||
streams map[uint32]*localStream
|
||||
streamsMu sync.Mutex
|
||||
|
@ -24,25 +62,9 @@ type localStream struct {
|
|||
rtpWriter interceptor.RTPWriter
|
||||
}
|
||||
|
||||
// NewResponderInterceptor returns a new GeneratorInterceptor interceptor
|
||||
func NewResponderInterceptor(opts ...ResponderOption) (*ResponderInterceptor, error) {
|
||||
r := &ResponderInterceptor{
|
||||
size: 8192,
|
||||
log: logging.NewDefaultLoggerFactory().NewLogger("nack_responder"),
|
||||
streams: map[uint32]*localStream{},
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
if err := opt(r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := newSendBuffer(r.size); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r, nil
|
||||
// NewResponderInterceptor returns a new ResponderInterceptorFactor
|
||||
func NewResponderInterceptor(opts ...ResponderOption) (*ResponderInterceptorFactory, error) {
|
||||
return &ResponderInterceptorFactory{opts}, nil
|
||||
}
|
||||
|
||||
// BindRTCPReader lets you modify any incoming RTCP packets. It is called once per sender/receiver, however this might
|
||||
|
@ -54,7 +76,10 @@ func (n *ResponderInterceptor) BindRTCPReader(reader interceptor.RTCPReader) int
|
|||
return 0, nil, err
|
||||
}
|
||||
|
||||
pkts, err := rtcp.Unmarshal(b[:i])
|
||||
if attr == nil {
|
||||
attr = make(interceptor.Attributes)
|
||||
}
|
||||
pkts, err := attr.GetRTCPPackets(b[:i])
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
@ -85,7 +110,11 @@ func (n *ResponderInterceptor) BindLocalStream(info *interceptor.StreamInfo, wri
|
|||
n.streamsMu.Unlock()
|
||||
|
||||
return interceptor.RTPWriterFunc(func(header *rtp.Header, payload []byte, attributes interceptor.Attributes) (int, error) {
|
||||
sendBuffer.add(&rtp.Packet{Header: *header, Payload: payload})
|
||||
pkt, err := n.packetFactory.NewPacket(header, payload)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
sendBuffer.add(pkt)
|
||||
return writer.Write(header, payload, attributes)
|
||||
})
|
||||
}
|
||||
|
@ -108,9 +137,10 @@ func (n *ResponderInterceptor) resendPackets(nack *rtcp.TransportLayerNack) {
|
|||
for i := range nack.Nacks {
|
||||
nack.Nacks[i].Range(func(seq uint16) bool {
|
||||
if p := stream.sendBuffer.get(seq); p != nil {
|
||||
if _, err := stream.rtpWriter.Write(&p.Header, p.Payload, interceptor.Attributes{}); err != nil {
|
||||
if _, err := stream.rtpWriter.Write(p.Header(), p.Payload(), interceptor.Attributes{}); err != nil {
|
||||
n.log.Warnf("failed resending nacked packet: %+v", err)
|
||||
}
|
||||
p.Release()
|
||||
}
|
||||
|
||||
return true
|
||||
|
|
12
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/nack/responder_option.go
generated
vendored
12
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/nack/responder_option.go
generated
vendored
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package nack
|
||||
|
||||
import "github.com/pion/logging"
|
||||
|
@ -21,3 +24,12 @@ func ResponderLog(log logging.LeveledLogger) ResponderOption {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DisableCopy bypasses copy of underlying packets. It should be used when
|
||||
// you are not re-using underlying buffers of packets that have been written
|
||||
func DisableCopy() ResponderOption {
|
||||
return func(s *ResponderInterceptor) error {
|
||||
s.packetFactory = &noOpPacketFactory{}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
132
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/nack/retainable_packet.go
generated
vendored
Normal file
132
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/nack/retainable_packet.go
generated
vendored
Normal file
|
@ -0,0 +1,132 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package nack
|
||||
|
||||
import (
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/pion/rtp"
|
||||
)
|
||||
|
||||
const maxPayloadLen = 1460
|
||||
|
||||
type packetManager struct {
|
||||
headerPool *sync.Pool
|
||||
payloadPool *sync.Pool
|
||||
}
|
||||
|
||||
func newPacketManager() *packetManager {
|
||||
return &packetManager{
|
||||
headerPool: &sync.Pool{
|
||||
New: func() interface{} {
|
||||
return &rtp.Header{}
|
||||
},
|
||||
},
|
||||
payloadPool: &sync.Pool{
|
||||
New: func() interface{} {
|
||||
buf := make([]byte, maxPayloadLen)
|
||||
return &buf
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (m *packetManager) NewPacket(header *rtp.Header, payload []byte) (*retainablePacket, error) {
|
||||
if len(payload) > maxPayloadLen {
|
||||
return nil, io.ErrShortBuffer
|
||||
}
|
||||
|
||||
p := &retainablePacket{
|
||||
onRelease: m.releasePacket,
|
||||
// new packets have retain count of 1
|
||||
count: 1,
|
||||
}
|
||||
|
||||
var ok bool
|
||||
p.header, ok = m.headerPool.Get().(*rtp.Header)
|
||||
if !ok {
|
||||
return nil, errFailedToCastHeaderPool
|
||||
}
|
||||
|
||||
*p.header = header.Clone()
|
||||
|
||||
if payload != nil {
|
||||
p.buffer, ok = m.payloadPool.Get().(*[]byte)
|
||||
if !ok {
|
||||
return nil, errFailedToCastPayloadPool
|
||||
}
|
||||
|
||||
size := copy(*p.buffer, payload)
|
||||
p.payload = (*p.buffer)[:size]
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (m *packetManager) releasePacket(header *rtp.Header, payload *[]byte) {
|
||||
m.headerPool.Put(header)
|
||||
if payload != nil {
|
||||
m.payloadPool.Put(payload)
|
||||
}
|
||||
}
|
||||
|
||||
type noOpPacketFactory struct{}
|
||||
|
||||
func (f *noOpPacketFactory) NewPacket(header *rtp.Header, payload []byte) (*retainablePacket, error) {
|
||||
return &retainablePacket{
|
||||
onRelease: f.releasePacket,
|
||||
count: 1,
|
||||
header: header,
|
||||
payload: payload,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (f *noOpPacketFactory) releasePacket(_ *rtp.Header, _ *[]byte) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
type retainablePacket struct {
|
||||
onRelease func(*rtp.Header, *[]byte)
|
||||
|
||||
countMu sync.Mutex
|
||||
count int
|
||||
|
||||
header *rtp.Header
|
||||
buffer *[]byte
|
||||
payload []byte
|
||||
}
|
||||
|
||||
func (p *retainablePacket) Header() *rtp.Header {
|
||||
return p.header
|
||||
}
|
||||
|
||||
func (p *retainablePacket) Payload() []byte {
|
||||
return p.payload
|
||||
}
|
||||
|
||||
func (p *retainablePacket) Retain() error {
|
||||
p.countMu.Lock()
|
||||
defer p.countMu.Unlock()
|
||||
if p.count == 0 {
|
||||
// already released
|
||||
return errPacketReleased
|
||||
}
|
||||
p.count++
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *retainablePacket) Release() {
|
||||
p.countMu.Lock()
|
||||
defer p.countMu.Unlock()
|
||||
p.count--
|
||||
|
||||
if p.count == 0 {
|
||||
// release back to pool
|
||||
p.onRelease(p.header, p.buffer)
|
||||
p.header = nil
|
||||
p.buffer = nil
|
||||
p.payload = nil
|
||||
}
|
||||
}
|
50
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/nack/send_buffer.go
generated
vendored
50
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/nack/send_buffer.go
generated
vendored
|
@ -1,9 +1,11 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package nack
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pion/rtp"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -11,10 +13,12 @@ const (
|
|||
)
|
||||
|
||||
type sendBuffer struct {
|
||||
packets []*rtp.Packet
|
||||
packets []*retainablePacket
|
||||
size uint16
|
||||
lastAdded uint16
|
||||
started bool
|
||||
|
||||
m sync.RWMutex
|
||||
}
|
||||
|
||||
func newSendBuffer(size uint16) (*sendBuffer, error) {
|
||||
|
@ -33,13 +37,16 @@ func newSendBuffer(size uint16) (*sendBuffer, error) {
|
|||
}
|
||||
|
||||
return &sendBuffer{
|
||||
packets: make([]*rtp.Packet, size),
|
||||
packets: make([]*retainablePacket, size),
|
||||
size: size,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *sendBuffer) add(packet *rtp.Packet) {
|
||||
seq := packet.SequenceNumber
|
||||
func (s *sendBuffer) add(packet *retainablePacket) {
|
||||
s.m.Lock()
|
||||
defer s.m.Unlock()
|
||||
|
||||
seq := packet.Header().SequenceNumber
|
||||
if !s.started {
|
||||
s.packets[seq%s.size] = packet
|
||||
s.lastAdded = seq
|
||||
|
@ -52,15 +59,28 @@ func (s *sendBuffer) add(packet *rtp.Packet) {
|
|||
return
|
||||
} else if diff < uint16SizeHalf {
|
||||
for i := s.lastAdded + 1; i != seq; i++ {
|
||||
s.packets[i%s.size] = nil
|
||||
idx := i % s.size
|
||||
prevPacket := s.packets[idx]
|
||||
if prevPacket != nil {
|
||||
prevPacket.Release()
|
||||
}
|
||||
s.packets[idx] = nil
|
||||
}
|
||||
}
|
||||
|
||||
s.packets[seq%s.size] = packet
|
||||
idx := seq % s.size
|
||||
prevPacket := s.packets[idx]
|
||||
if prevPacket != nil {
|
||||
prevPacket.Release()
|
||||
}
|
||||
s.packets[idx] = packet
|
||||
s.lastAdded = seq
|
||||
}
|
||||
|
||||
func (s *sendBuffer) get(seq uint16) *rtp.Packet {
|
||||
func (s *sendBuffer) get(seq uint16) *retainablePacket {
|
||||
s.m.RLock()
|
||||
defer s.m.RUnlock()
|
||||
|
||||
diff := s.lastAdded - seq
|
||||
if diff >= uint16SizeHalf {
|
||||
return nil
|
||||
|
@ -70,5 +90,15 @@ func (s *sendBuffer) get(seq uint16) *rtp.Packet {
|
|||
return nil
|
||||
}
|
||||
|
||||
return s.packets[seq%s.size]
|
||||
pkt := s.packets[seq%s.size]
|
||||
if pkt != nil {
|
||||
if pkt.Header().SequenceNumber != seq {
|
||||
return nil
|
||||
}
|
||||
// already released
|
||||
if err := pkt.Retain(); err != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return pkt
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package report
|
||||
|
||||
import (
|
||||
|
@ -7,9 +10,36 @@ import (
|
|||
"github.com/pion/interceptor"
|
||||
"github.com/pion/logging"
|
||||
"github.com/pion/rtcp"
|
||||
"github.com/pion/rtp"
|
||||
)
|
||||
|
||||
// ReceiverInterceptorFactory is a interceptor.Factory for a ReceiverInterceptor
|
||||
type ReceiverInterceptorFactory struct {
|
||||
opts []ReceiverOption
|
||||
}
|
||||
|
||||
// NewInterceptor constructs a new ReceiverInterceptor
|
||||
func (r *ReceiverInterceptorFactory) NewInterceptor(_ string) (interceptor.Interceptor, error) {
|
||||
i := &ReceiverInterceptor{
|
||||
interval: 1 * time.Second,
|
||||
now: time.Now,
|
||||
log: logging.NewDefaultLoggerFactory().NewLogger("receiver_interceptor"),
|
||||
close: make(chan struct{}),
|
||||
}
|
||||
|
||||
for _, opt := range r.opts {
|
||||
if err := opt(i); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// NewReceiverInterceptor returns a new ReceiverInterceptorFactory
|
||||
func NewReceiverInterceptor(opts ...ReceiverOption) (*ReceiverInterceptorFactory, error) {
|
||||
return &ReceiverInterceptorFactory{opts}, nil
|
||||
}
|
||||
|
||||
// ReceiverInterceptor interceptor generates receiver reports.
|
||||
type ReceiverInterceptor struct {
|
||||
interceptor.NoOp
|
||||
|
@ -22,24 +52,6 @@ type ReceiverInterceptor struct {
|
|||
close chan struct{}
|
||||
}
|
||||
|
||||
// NewReceiverInterceptor returns a new ReceiverInterceptor interceptor.
|
||||
func NewReceiverInterceptor(opts ...ReceiverOption) (*ReceiverInterceptor, error) {
|
||||
r := &ReceiverInterceptor{
|
||||
interval: 1 * time.Second,
|
||||
now: time.Now,
|
||||
log: logging.NewDefaultLoggerFactory().NewLogger("receiver_interceptor"),
|
||||
close: make(chan struct{}),
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
if err := opt(r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (r *ReceiverInterceptor) isClosed() bool {
|
||||
select {
|
||||
case <-r.close:
|
||||
|
@ -83,18 +95,15 @@ func (r *ReceiverInterceptor) loop(rtcpWriter interceptor.RTCPWriter) {
|
|||
defer r.wg.Done()
|
||||
|
||||
ticker := time.NewTicker(r.interval)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
now := r.now()
|
||||
r.streams.Range(func(key, value interface{}) bool {
|
||||
stream := value.(*receiverStream)
|
||||
|
||||
var pkts []rtcp.Packet
|
||||
|
||||
pkts = append(pkts, stream.generateReport(now))
|
||||
|
||||
if _, err := rtcpWriter.Write(pkts, interceptor.Attributes{}); err != nil {
|
||||
if stream, ok := value.(*receiverStream); !ok {
|
||||
r.log.Warnf("failed to cast ReceiverInterceptor stream")
|
||||
} else if _, err := rtcpWriter.Write([]rtcp.Packet{stream.generateReport(now)}, interceptor.Attributes{}); err != nil {
|
||||
r.log.Warnf("failed sending: %+v", err)
|
||||
}
|
||||
|
||||
|
@ -119,12 +128,15 @@ func (r *ReceiverInterceptor) BindRemoteStream(info *interceptor.StreamInfo, rea
|
|||
return 0, nil, err
|
||||
}
|
||||
|
||||
pkt := rtp.Packet{}
|
||||
if err = pkt.Unmarshal(b[:i]); err != nil {
|
||||
if attr == nil {
|
||||
attr = make(interceptor.Attributes)
|
||||
}
|
||||
header, err := attr.GetRTPHeader(b[:i])
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
stream.processRTP(r.now(), &pkt)
|
||||
stream.processRTP(r.now(), header)
|
||||
|
||||
return i, attr, nil
|
||||
})
|
||||
|
@ -144,7 +156,10 @@ func (r *ReceiverInterceptor) BindRTCPReader(reader interceptor.RTCPReader) inte
|
|||
return 0, nil, err
|
||||
}
|
||||
|
||||
pkts, err := rtcp.Unmarshal(b[:i])
|
||||
if attr == nil {
|
||||
attr = make(interceptor.Attributes)
|
||||
}
|
||||
pkts, err := attr.GetRTCPPackets(b[:i])
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
@ -156,8 +171,11 @@ func (r *ReceiverInterceptor) BindRTCPReader(reader interceptor.RTCPReader) inte
|
|||
continue
|
||||
}
|
||||
|
||||
stream := value.(*receiverStream)
|
||||
stream.processSenderReport(r.now(), sr)
|
||||
if stream, ok := value.(*receiverStream); !ok {
|
||||
r.log.Warnf("failed to cast ReceiverInterceptor stream")
|
||||
} else {
|
||||
stream.processSenderReport(r.now(), sr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package report
|
||||
|
||||
import (
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package report
|
||||
|
||||
import (
|
||||
|
@ -40,21 +43,21 @@ func newReceiverStream(ssrc uint32, clockRate uint32) *receiverStream {
|
|||
}
|
||||
}
|
||||
|
||||
func (stream *receiverStream) processRTP(now time.Time, pkt *rtp.Packet) {
|
||||
func (stream *receiverStream) processRTP(now time.Time, pktHeader *rtp.Header) {
|
||||
stream.m.Lock()
|
||||
defer stream.m.Unlock()
|
||||
|
||||
if !stream.started { // first frame
|
||||
stream.started = true
|
||||
stream.setReceived(pkt.SequenceNumber)
|
||||
stream.lastSeqnum = pkt.SequenceNumber
|
||||
stream.lastReportSeqnum = pkt.SequenceNumber - 1
|
||||
stream.lastRTPTimeRTP = pkt.Timestamp
|
||||
stream.setReceived(pktHeader.SequenceNumber)
|
||||
stream.lastSeqnum = pktHeader.SequenceNumber
|
||||
stream.lastReportSeqnum = pktHeader.SequenceNumber - 1
|
||||
stream.lastRTPTimeRTP = pktHeader.Timestamp
|
||||
stream.lastRTPTimeTime = now
|
||||
} else { // following frames
|
||||
stream.setReceived(pkt.SequenceNumber)
|
||||
stream.setReceived(pktHeader.SequenceNumber)
|
||||
|
||||
diff := int32(pkt.SequenceNumber) - int32(stream.lastSeqnum)
|
||||
diff := int32(pktHeader.SequenceNumber) - int32(stream.lastSeqnum)
|
||||
if diff > 0 || diff < -0x0FFF {
|
||||
// overflow
|
||||
if diff < -0x0FFF {
|
||||
|
@ -62,22 +65,22 @@ func (stream *receiverStream) processRTP(now time.Time, pkt *rtp.Packet) {
|
|||
}
|
||||
|
||||
// set missing packets as missing
|
||||
for i := stream.lastSeqnum + 1; i != pkt.SequenceNumber; i++ {
|
||||
for i := stream.lastSeqnum + 1; i != pktHeader.SequenceNumber; i++ {
|
||||
stream.delReceived(i)
|
||||
}
|
||||
|
||||
stream.lastSeqnum = pkt.SequenceNumber
|
||||
stream.lastSeqnum = pktHeader.SequenceNumber
|
||||
}
|
||||
|
||||
// compute jitter
|
||||
// https://tools.ietf.org/html/rfc3550#page-39
|
||||
D := now.Sub(stream.lastRTPTimeTime).Seconds()*stream.clockRate -
|
||||
(float64(pkt.Timestamp) - float64(stream.lastRTPTimeRTP))
|
||||
(float64(pktHeader.Timestamp) - float64(stream.lastRTPTimeRTP))
|
||||
if D < 0 {
|
||||
D = -D
|
||||
}
|
||||
stream.jitter += (D - stream.jitter) / 16
|
||||
stream.lastRTPTimeRTP = pkt.Timestamp
|
||||
stream.lastRTPTimeRTP = pktHeader.Timestamp
|
||||
stream.lastRTPTimeTime = now
|
||||
}
|
||||
}
|
||||
|
|
3
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/report/report.go
generated
vendored
3
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/report/report.go
generated
vendored
|
@ -1,2 +1,5 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Package report provides interceptors to implement sending sender and receiver reports.
|
||||
package report
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package report
|
||||
|
||||
import (
|
||||
|
@ -10,14 +13,32 @@ import (
|
|||
"github.com/pion/rtp"
|
||||
)
|
||||
|
||||
func ntpTime(t time.Time) uint64 {
|
||||
// seconds since 1st January 1900
|
||||
s := (float64(t.UnixNano()) / 1000000000) + 2208988800
|
||||
// SenderInterceptorFactory is a interceptor.Factory for a SenderInterceptor
|
||||
type SenderInterceptorFactory struct {
|
||||
opts []SenderOption
|
||||
}
|
||||
|
||||
// higher 32 bits are the integer part, lower 32 bits are the fractional part
|
||||
integerPart := uint32(s)
|
||||
fractionalPart := uint32((s - float64(integerPart)) * 0xFFFFFFFF)
|
||||
return uint64(integerPart)<<32 | uint64(fractionalPart)
|
||||
// NewInterceptor constructs a new SenderInterceptor
|
||||
func (s *SenderInterceptorFactory) NewInterceptor(_ string) (interceptor.Interceptor, error) {
|
||||
i := &SenderInterceptor{
|
||||
interval: 1 * time.Second,
|
||||
now: time.Now,
|
||||
log: logging.NewDefaultLoggerFactory().NewLogger("sender_interceptor"),
|
||||
close: make(chan struct{}),
|
||||
}
|
||||
|
||||
for _, opt := range s.opts {
|
||||
if err := opt(i); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// NewSenderInterceptor returns a new SenderInterceptorFactory
|
||||
func NewSenderInterceptor(opts ...SenderOption) (*SenderInterceptorFactory, error) {
|
||||
return &SenderInterceptorFactory{opts}, nil
|
||||
}
|
||||
|
||||
// SenderInterceptor interceptor generates sender reports.
|
||||
|
@ -32,24 +53,6 @@ type SenderInterceptor struct {
|
|||
close chan struct{}
|
||||
}
|
||||
|
||||
// NewSenderInterceptor returns a new SenderInterceptor interceptor.
|
||||
func NewSenderInterceptor(opts ...SenderOption) (*SenderInterceptor, error) {
|
||||
s := &SenderInterceptor{
|
||||
interval: 1 * time.Second,
|
||||
now: time.Now,
|
||||
log: logging.NewDefaultLoggerFactory().NewLogger("sender_interceptor"),
|
||||
close: make(chan struct{}),
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
if err := opt(s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *SenderInterceptor) isClosed() bool {
|
||||
select {
|
||||
case <-s.close:
|
||||
|
@ -93,26 +96,15 @@ func (s *SenderInterceptor) loop(rtcpWriter interceptor.RTCPWriter) {
|
|||
defer s.wg.Done()
|
||||
|
||||
ticker := time.NewTicker(s.interval)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
now := s.now()
|
||||
s.streams.Range(func(key, value interface{}) bool {
|
||||
ssrc := key.(uint32)
|
||||
stream := value.(*senderStream)
|
||||
|
||||
stream.m.Lock()
|
||||
defer stream.m.Unlock()
|
||||
|
||||
sr := &rtcp.SenderReport{
|
||||
SSRC: ssrc,
|
||||
NTPTime: ntpTime(now),
|
||||
RTPTime: stream.lastRTPTimeRTP + uint32(now.Sub(stream.lastRTPTimeTime).Seconds()*stream.clockRate),
|
||||
PacketCount: stream.packetCount,
|
||||
OctetCount: stream.octetCount,
|
||||
}
|
||||
|
||||
if _, err := rtcpWriter.Write([]rtcp.Packet{sr}, interceptor.Attributes{}); err != nil {
|
||||
if stream, ok := value.(*senderStream); !ok {
|
||||
s.log.Warnf("failed to cast SenderInterceptor stream")
|
||||
} else if _, err := rtcpWriter.Write([]rtcp.Packet{stream.generateReport(now)}, interceptor.Attributes{}); err != nil {
|
||||
s.log.Warnf("failed sending: %+v", err)
|
||||
}
|
||||
|
||||
|
@ -128,7 +120,7 @@ func (s *SenderInterceptor) loop(rtcpWriter interceptor.RTCPWriter) {
|
|||
// BindLocalStream lets you modify any outgoing RTP packets. It is called once for per LocalStream. The returned method
|
||||
// will be called once per rtp packet.
|
||||
func (s *SenderInterceptor) BindLocalStream(info *interceptor.StreamInfo, writer interceptor.RTPWriter) interceptor.RTPWriter {
|
||||
stream := newSenderStream(info.ClockRate)
|
||||
stream := newSenderStream(info.SSRC, info.ClockRate)
|
||||
s.streams.Store(info.SSRC, stream)
|
||||
|
||||
return interceptor.RTPWriterFunc(func(header *rtp.Header, payload []byte, a interceptor.Attributes) (int, error) {
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package report
|
||||
|
||||
import (
|
||||
|
|
22
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/report/sender_stream.go
generated
vendored
22
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/report/sender_stream.go
generated
vendored
|
@ -1,13 +1,19 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package report
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/pion/interceptor/internal/ntp"
|
||||
"github.com/pion/rtcp"
|
||||
"github.com/pion/rtp"
|
||||
)
|
||||
|
||||
type senderStream struct {
|
||||
ssrc uint32
|
||||
clockRate float64
|
||||
m sync.Mutex
|
||||
|
||||
|
@ -18,8 +24,9 @@ type senderStream struct {
|
|||
octetCount uint32
|
||||
}
|
||||
|
||||
func newSenderStream(clockRate uint32) *senderStream {
|
||||
func newSenderStream(ssrc uint32, clockRate uint32) *senderStream {
|
||||
return &senderStream{
|
||||
ssrc: ssrc,
|
||||
clockRate: float64(clockRate),
|
||||
}
|
||||
}
|
||||
|
@ -35,3 +42,16 @@ func (stream *senderStream) processRTP(now time.Time, header *rtp.Header, payloa
|
|||
stream.packetCount++
|
||||
stream.octetCount += uint32(len(payload))
|
||||
}
|
||||
|
||||
func (stream *senderStream) generateReport(now time.Time) *rtcp.SenderReport {
|
||||
stream.m.Lock()
|
||||
defer stream.m.Unlock()
|
||||
|
||||
return &rtcp.SenderReport{
|
||||
SSRC: stream.ssrc,
|
||||
NTPTime: ntp.ToNTP(now),
|
||||
RTPTime: stream.lastRTPTimeRTP + uint32(now.Sub(stream.lastRTPTimeTime).Seconds()*stream.clockRate),
|
||||
PacketCount: stream.packetCount,
|
||||
OctetCount: stream.octetCount,
|
||||
}
|
||||
}
|
||||
|
|
66
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/twcc/header_extension_interceptor.go
generated
vendored
Normal file
66
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/twcc/header_extension_interceptor.go
generated
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package twcc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/pion/interceptor"
|
||||
"github.com/pion/rtp"
|
||||
)
|
||||
|
||||
var errHeaderIsNil = errors.New("header is nil")
|
||||
|
||||
// HeaderExtensionInterceptorFactory is a interceptor.Factory for a HeaderExtensionInterceptor
|
||||
type HeaderExtensionInterceptorFactory struct{}
|
||||
|
||||
// NewInterceptor constructs a new HeaderExtensionInterceptor
|
||||
func (h *HeaderExtensionInterceptorFactory) NewInterceptor(_ string) (interceptor.Interceptor, error) {
|
||||
return &HeaderExtensionInterceptor{}, nil
|
||||
}
|
||||
|
||||
// NewHeaderExtensionInterceptor returns a HeaderExtensionInterceptorFactory
|
||||
func NewHeaderExtensionInterceptor() (*HeaderExtensionInterceptorFactory, error) {
|
||||
return &HeaderExtensionInterceptorFactory{}, nil
|
||||
}
|
||||
|
||||
// HeaderExtensionInterceptor adds transport wide sequence numbers as header extension to each RTP packet
|
||||
type HeaderExtensionInterceptor struct {
|
||||
interceptor.NoOp
|
||||
nextSequenceNr uint32
|
||||
}
|
||||
|
||||
const transportCCURI = "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01"
|
||||
|
||||
// BindLocalStream returns a writer that adds a rtp.TransportCCExtension
|
||||
// header with increasing sequence numbers to each outgoing packet.
|
||||
func (h *HeaderExtensionInterceptor) BindLocalStream(info *interceptor.StreamInfo, writer interceptor.RTPWriter) interceptor.RTPWriter {
|
||||
var hdrExtID uint8
|
||||
for _, e := range info.RTPHeaderExtensions {
|
||||
if e.URI == transportCCURI {
|
||||
hdrExtID = uint8(e.ID)
|
||||
break
|
||||
}
|
||||
}
|
||||
if hdrExtID == 0 { // Don't add header extension if ID is 0, because 0 is an invalid extension ID
|
||||
return writer
|
||||
}
|
||||
return interceptor.RTPWriterFunc(func(header *rtp.Header, payload []byte, attributes interceptor.Attributes) (int, error) {
|
||||
sequenceNumber := atomic.AddUint32(&h.nextSequenceNr, 1) - 1
|
||||
|
||||
tcc, err := (&rtp.TransportCCExtension{TransportSequence: uint16(sequenceNumber)}).Marshal()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if header == nil {
|
||||
return 0, errHeaderIsNil
|
||||
}
|
||||
err = header.SetExtension(hdrExtID, tcc)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return writer.Write(header, payload, attributes)
|
||||
})
|
||||
}
|
207
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/twcc/sender_interceptor.go
generated
vendored
Normal file
207
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/twcc/sender_interceptor.go
generated
vendored
Normal file
|
@ -0,0 +1,207 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package twcc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/pion/interceptor"
|
||||
"github.com/pion/logging"
|
||||
"github.com/pion/rtp"
|
||||
)
|
||||
|
||||
// SenderInterceptorFactory is a interceptor.Factory for a SenderInterceptor
|
||||
type SenderInterceptorFactory struct {
|
||||
opts []Option
|
||||
}
|
||||
|
||||
var errClosed = errors.New("interceptor is closed")
|
||||
|
||||
// NewInterceptor constructs a new SenderInterceptor
|
||||
func (s *SenderInterceptorFactory) NewInterceptor(_ string) (interceptor.Interceptor, error) {
|
||||
i := &SenderInterceptor{
|
||||
log: logging.NewDefaultLoggerFactory().NewLogger("twcc_sender_interceptor"),
|
||||
packetChan: make(chan packet),
|
||||
close: make(chan struct{}),
|
||||
interval: 100 * time.Millisecond,
|
||||
startTime: time.Now(),
|
||||
}
|
||||
|
||||
for _, opt := range s.opts {
|
||||
err := opt(i)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// NewSenderInterceptor returns a new SenderInterceptorFactory configured with the given options.
|
||||
func NewSenderInterceptor(opts ...Option) (*SenderInterceptorFactory, error) {
|
||||
return &SenderInterceptorFactory{opts: opts}, nil
|
||||
}
|
||||
|
||||
// SenderInterceptor sends transport wide congestion control reports as specified in:
|
||||
// https://datatracker.ietf.org/doc/html/draft-holmer-rmcat-transport-wide-cc-extensions-01
|
||||
type SenderInterceptor struct {
|
||||
interceptor.NoOp
|
||||
|
||||
log logging.LeveledLogger
|
||||
|
||||
m sync.Mutex
|
||||
wg sync.WaitGroup
|
||||
close chan struct{}
|
||||
|
||||
interval time.Duration
|
||||
startTime time.Time
|
||||
|
||||
recorder *Recorder
|
||||
packetChan chan packet
|
||||
}
|
||||
|
||||
// An Option is a function that can be used to configure a SenderInterceptor
|
||||
type Option func(*SenderInterceptor) error
|
||||
|
||||
// SendInterval sets the interval at which the interceptor
|
||||
// will send new feedback reports.
|
||||
func SendInterval(interval time.Duration) Option {
|
||||
return func(s *SenderInterceptor) error {
|
||||
s.interval = interval
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// BindRTCPWriter lets you modify any outgoing RTCP packets. It is called once per PeerConnection. The returned method
|
||||
// will be called once per packet batch.
|
||||
func (s *SenderInterceptor) BindRTCPWriter(writer interceptor.RTCPWriter) interceptor.RTCPWriter {
|
||||
s.m.Lock()
|
||||
defer s.m.Unlock()
|
||||
|
||||
s.recorder = NewRecorder(rand.Uint32()) // #nosec
|
||||
|
||||
if s.isClosed() {
|
||||
return writer
|
||||
}
|
||||
|
||||
s.wg.Add(1)
|
||||
|
||||
go s.loop(writer)
|
||||
|
||||
return writer
|
||||
}
|
||||
|
||||
type packet struct {
|
||||
hdr *rtp.Header
|
||||
sequenceNumber uint16
|
||||
arrivalTime int64
|
||||
ssrc uint32
|
||||
}
|
||||
|
||||
// BindRemoteStream lets you modify any incoming RTP packets. It is called once for per RemoteStream. The returned method
|
||||
// will be called once per rtp packet.
|
||||
func (s *SenderInterceptor) BindRemoteStream(info *interceptor.StreamInfo, reader interceptor.RTPReader) interceptor.RTPReader {
|
||||
var hdrExtID uint8
|
||||
for _, e := range info.RTPHeaderExtensions {
|
||||
if e.URI == transportCCURI {
|
||||
hdrExtID = uint8(e.ID)
|
||||
break
|
||||
}
|
||||
}
|
||||
if hdrExtID == 0 { // Don't try to read header extension if ID is 0, because 0 is an invalid extension ID
|
||||
return reader
|
||||
}
|
||||
return interceptor.RTPReaderFunc(func(buf []byte, attributes interceptor.Attributes) (int, interceptor.Attributes, error) {
|
||||
i, attr, err := reader.Read(buf, attributes)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
if attr == nil {
|
||||
attr = make(interceptor.Attributes)
|
||||
}
|
||||
header, err := attr.GetRTPHeader(buf[:i])
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
var tccExt rtp.TransportCCExtension
|
||||
if ext := header.GetExtension(hdrExtID); ext != nil {
|
||||
err = tccExt.Unmarshal(ext)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
p := packet{
|
||||
hdr: header,
|
||||
sequenceNumber: tccExt.TransportSequence,
|
||||
arrivalTime: time.Since(s.startTime).Microseconds(),
|
||||
ssrc: info.SSRC,
|
||||
}
|
||||
select {
|
||||
case <-s.close:
|
||||
return 0, nil, errClosed
|
||||
case s.packetChan <- p:
|
||||
}
|
||||
}
|
||||
|
||||
return i, attr, nil
|
||||
})
|
||||
}
|
||||
|
||||
// Close closes the interceptor.
|
||||
func (s *SenderInterceptor) Close() error {
|
||||
defer s.wg.Wait()
|
||||
s.m.Lock()
|
||||
defer s.m.Unlock()
|
||||
|
||||
if !s.isClosed() {
|
||||
close(s.close)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SenderInterceptor) isClosed() bool {
|
||||
select {
|
||||
case <-s.close:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SenderInterceptor) loop(w interceptor.RTCPWriter) {
|
||||
defer s.wg.Done()
|
||||
|
||||
select {
|
||||
case <-s.close:
|
||||
return
|
||||
case p := <-s.packetChan:
|
||||
s.recorder.Record(p.ssrc, p.sequenceNumber, p.arrivalTime)
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(s.interval)
|
||||
for {
|
||||
select {
|
||||
case <-s.close:
|
||||
ticker.Stop()
|
||||
return
|
||||
case p := <-s.packetChan:
|
||||
s.recorder.Record(p.ssrc, p.sequenceNumber, p.arrivalTime)
|
||||
|
||||
case <-ticker.C:
|
||||
// build and send twcc
|
||||
pkts := s.recorder.BuildFeedbackPacket()
|
||||
if pkts == nil {
|
||||
continue
|
||||
}
|
||||
if _, err := w.Write(pkts, nil); err != nil {
|
||||
s.log.Error(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
276
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/twcc/twcc.go
generated
vendored
Normal file
276
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/pkg/twcc/twcc.go
generated
vendored
Normal file
|
@ -0,0 +1,276 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Package twcc provides interceptors to implement transport wide congestion control.
|
||||
package twcc
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/pion/rtcp"
|
||||
)
|
||||
|
||||
type pktInfo struct {
|
||||
sequenceNumber uint32
|
||||
arrivalTime int64
|
||||
}
|
||||
|
||||
// Recorder records incoming RTP packets and their delays and creates
|
||||
// transport wide congestion control feedback reports as specified in
|
||||
// https://datatracker.ietf.org/doc/html/draft-holmer-rmcat-transport-wide-cc-extensions-01
|
||||
type Recorder struct {
|
||||
receivedPackets []pktInfo
|
||||
|
||||
cycles uint32
|
||||
lastSequenceNumber uint16
|
||||
|
||||
senderSSRC uint32
|
||||
mediaSSRC uint32
|
||||
fbPktCnt uint8
|
||||
}
|
||||
|
||||
// NewRecorder creates a new Recorder which uses the given senderSSRC in the created
|
||||
// feedback packets.
|
||||
func NewRecorder(senderSSRC uint32) *Recorder {
|
||||
return &Recorder{
|
||||
receivedPackets: []pktInfo{},
|
||||
senderSSRC: senderSSRC,
|
||||
}
|
||||
}
|
||||
|
||||
// Record marks a packet with mediaSSRC and a transport wide sequence number sequenceNumber as received at arrivalTime.
|
||||
func (r *Recorder) Record(mediaSSRC uint32, sequenceNumber uint16, arrivalTime int64) {
|
||||
r.mediaSSRC = mediaSSRC
|
||||
if sequenceNumber < 0x0fff && (r.lastSequenceNumber&0xffff) > 0xf000 {
|
||||
r.cycles += 1 << 16
|
||||
}
|
||||
r.receivedPackets = insertSorted(r.receivedPackets, pktInfo{
|
||||
sequenceNumber: r.cycles | uint32(sequenceNumber),
|
||||
arrivalTime: arrivalTime,
|
||||
})
|
||||
r.lastSequenceNumber = sequenceNumber
|
||||
}
|
||||
|
||||
func insertSorted(list []pktInfo, element pktInfo) []pktInfo {
|
||||
if len(list) == 0 {
|
||||
return append(list, element)
|
||||
}
|
||||
for i := len(list) - 1; i >= 0; i-- {
|
||||
if list[i].sequenceNumber < element.sequenceNumber {
|
||||
list = append(list, pktInfo{})
|
||||
copy(list[i+2:], list[i+1:])
|
||||
list[i+1] = element
|
||||
return list
|
||||
}
|
||||
if list[i].sequenceNumber == element.sequenceNumber {
|
||||
list[i] = element
|
||||
return list
|
||||
}
|
||||
}
|
||||
// element.sequenceNumber is between 0 and first ever received sequenceNumber
|
||||
return append([]pktInfo{element}, list...)
|
||||
}
|
||||
|
||||
// BuildFeedbackPacket creates a new RTCP packet containing a TWCC feedback report.
|
||||
func (r *Recorder) BuildFeedbackPacket() []rtcp.Packet {
|
||||
if len(r.receivedPackets) < 2 {
|
||||
return nil
|
||||
}
|
||||
|
||||
feedback := newFeedback(r.senderSSRC, r.mediaSSRC, r.fbPktCnt)
|
||||
r.fbPktCnt++
|
||||
feedback.setBase(uint16(r.receivedPackets[0].sequenceNumber&0xffff), r.receivedPackets[0].arrivalTime)
|
||||
|
||||
var pkts []rtcp.Packet
|
||||
for _, pkt := range r.receivedPackets {
|
||||
ok := feedback.addReceived(uint16(pkt.sequenceNumber&0xffff), pkt.arrivalTime)
|
||||
if !ok {
|
||||
pkts = append(pkts, feedback.getRTCP())
|
||||
feedback = newFeedback(r.senderSSRC, r.mediaSSRC, r.fbPktCnt)
|
||||
r.fbPktCnt++
|
||||
feedback.addReceived(uint16(pkt.sequenceNumber&0xffff), pkt.arrivalTime)
|
||||
}
|
||||
}
|
||||
r.receivedPackets = []pktInfo{}
|
||||
pkts = append(pkts, feedback.getRTCP())
|
||||
|
||||
return pkts
|
||||
}
|
||||
|
||||
type feedback struct {
|
||||
rtcp *rtcp.TransportLayerCC
|
||||
baseSequenceNumber uint16
|
||||
refTimestamp64MS int64
|
||||
lastTimestampUS int64
|
||||
nextSequenceNumber uint16
|
||||
sequenceNumberCount uint16
|
||||
len int
|
||||
lastChunk chunk
|
||||
chunks []rtcp.PacketStatusChunk
|
||||
deltas []*rtcp.RecvDelta
|
||||
}
|
||||
|
||||
func newFeedback(senderSSRC, mediaSSRC uint32, count uint8) *feedback {
|
||||
return &feedback{
|
||||
rtcp: &rtcp.TransportLayerCC{
|
||||
SenderSSRC: senderSSRC,
|
||||
MediaSSRC: mediaSSRC,
|
||||
FbPktCount: count,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (f *feedback) setBase(sequenceNumber uint16, timeUS int64) {
|
||||
f.baseSequenceNumber = sequenceNumber
|
||||
f.nextSequenceNumber = f.baseSequenceNumber
|
||||
f.refTimestamp64MS = timeUS / 64e3
|
||||
f.lastTimestampUS = f.refTimestamp64MS * 64e3
|
||||
}
|
||||
|
||||
func (f *feedback) getRTCP() *rtcp.TransportLayerCC {
|
||||
f.rtcp.PacketStatusCount = f.sequenceNumberCount
|
||||
f.rtcp.ReferenceTime = uint32(f.refTimestamp64MS)
|
||||
f.rtcp.BaseSequenceNumber = f.baseSequenceNumber
|
||||
for len(f.lastChunk.deltas) > 0 {
|
||||
f.chunks = append(f.chunks, f.lastChunk.encode())
|
||||
}
|
||||
f.rtcp.PacketChunks = append(f.rtcp.PacketChunks, f.chunks...)
|
||||
f.rtcp.RecvDeltas = f.deltas
|
||||
|
||||
padLen := 20 + len(f.rtcp.PacketChunks)*2 + f.len // 4 bytes header + 16 bytes twcc header + 2 bytes for each chunk + length of deltas
|
||||
padding := padLen%4 != 0
|
||||
for padLen%4 != 0 {
|
||||
padLen++
|
||||
}
|
||||
f.rtcp.Header = rtcp.Header{
|
||||
Count: rtcp.FormatTCC,
|
||||
Type: rtcp.TypeTransportSpecificFeedback,
|
||||
Padding: padding,
|
||||
Length: uint16((padLen / 4) - 1),
|
||||
}
|
||||
|
||||
return f.rtcp
|
||||
}
|
||||
|
||||
func (f *feedback) addReceived(sequenceNumber uint16, timestampUS int64) bool {
|
||||
deltaUS := timestampUS - f.lastTimestampUS
|
||||
delta250US := deltaUS / 250
|
||||
if delta250US < math.MinInt16 || delta250US > math.MaxInt16 { // delta doesn't fit into 16 bit, need to create new packet
|
||||
return false
|
||||
}
|
||||
|
||||
for ; f.nextSequenceNumber != sequenceNumber; f.nextSequenceNumber++ {
|
||||
if !f.lastChunk.canAdd(rtcp.TypeTCCPacketNotReceived) {
|
||||
f.chunks = append(f.chunks, f.lastChunk.encode())
|
||||
}
|
||||
f.lastChunk.add(rtcp.TypeTCCPacketNotReceived)
|
||||
f.sequenceNumberCount++
|
||||
}
|
||||
|
||||
var recvDelta uint16
|
||||
switch {
|
||||
case delta250US >= 0 && delta250US <= 0xff:
|
||||
f.len++
|
||||
recvDelta = rtcp.TypeTCCPacketReceivedSmallDelta
|
||||
default:
|
||||
f.len += 2
|
||||
recvDelta = rtcp.TypeTCCPacketReceivedLargeDelta
|
||||
}
|
||||
|
||||
if !f.lastChunk.canAdd(recvDelta) {
|
||||
f.chunks = append(f.chunks, f.lastChunk.encode())
|
||||
}
|
||||
f.lastChunk.add(recvDelta)
|
||||
f.deltas = append(f.deltas, &rtcp.RecvDelta{
|
||||
Type: recvDelta,
|
||||
Delta: deltaUS,
|
||||
})
|
||||
f.lastTimestampUS = timestampUS
|
||||
f.sequenceNumberCount++
|
||||
f.nextSequenceNumber++
|
||||
return true
|
||||
}
|
||||
|
||||
const (
|
||||
maxRunLengthCap = 0x1fff // 13 bits
|
||||
maxOneBitCap = 14 // bits
|
||||
maxTwoBitCap = 7 // bits
|
||||
)
|
||||
|
||||
type chunk struct {
|
||||
hasLargeDelta bool
|
||||
hasDifferentTypes bool
|
||||
deltas []uint16
|
||||
}
|
||||
|
||||
func (c *chunk) canAdd(delta uint16) bool {
|
||||
if len(c.deltas) < maxTwoBitCap {
|
||||
return true
|
||||
}
|
||||
if len(c.deltas) < maxOneBitCap && !c.hasLargeDelta && delta != rtcp.TypeTCCPacketReceivedLargeDelta {
|
||||
return true
|
||||
}
|
||||
if len(c.deltas) < maxRunLengthCap && !c.hasDifferentTypes && delta == c.deltas[0] {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *chunk) add(delta uint16) {
|
||||
c.deltas = append(c.deltas, delta)
|
||||
c.hasLargeDelta = c.hasLargeDelta || delta == rtcp.TypeTCCPacketReceivedLargeDelta
|
||||
c.hasDifferentTypes = c.hasDifferentTypes || delta != c.deltas[0]
|
||||
}
|
||||
|
||||
func (c *chunk) encode() rtcp.PacketStatusChunk {
|
||||
if !c.hasDifferentTypes {
|
||||
defer c.reset()
|
||||
return &rtcp.RunLengthChunk{
|
||||
PacketStatusSymbol: c.deltas[0],
|
||||
RunLength: uint16(len(c.deltas)),
|
||||
}
|
||||
}
|
||||
if len(c.deltas) == maxOneBitCap {
|
||||
defer c.reset()
|
||||
return &rtcp.StatusVectorChunk{
|
||||
SymbolSize: rtcp.TypeTCCSymbolSizeOneBit,
|
||||
SymbolList: c.deltas,
|
||||
}
|
||||
}
|
||||
|
||||
minCap := min(maxTwoBitCap, len(c.deltas))
|
||||
svc := &rtcp.StatusVectorChunk{
|
||||
SymbolSize: rtcp.TypeTCCSymbolSizeTwoBit,
|
||||
SymbolList: c.deltas[:minCap],
|
||||
}
|
||||
c.deltas = c.deltas[minCap:]
|
||||
c.hasDifferentTypes = false
|
||||
c.hasLargeDelta = false
|
||||
|
||||
if len(c.deltas) > 0 {
|
||||
tmp := c.deltas[0]
|
||||
for _, d := range c.deltas {
|
||||
if tmp != d {
|
||||
c.hasDifferentTypes = true
|
||||
}
|
||||
if d == rtcp.TypeTCCPacketReceivedLargeDelta {
|
||||
c.hasLargeDelta = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
func (c *chunk) reset() {
|
||||
c.deltas = []uint16{}
|
||||
c.hasLargeDelta = false
|
||||
c.hasDifferentTypes = false
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
27
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/registry.go
generated
vendored
27
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/registry.go
generated
vendored
|
@ -1,20 +1,33 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package interceptor
|
||||
|
||||
// Registry is a collector for interceptors.
|
||||
type Registry struct {
|
||||
interceptors []Interceptor
|
||||
factories []Factory
|
||||
}
|
||||
|
||||
// Add adds a new Interceptor to the registry.
|
||||
func (i *Registry) Add(icpr Interceptor) {
|
||||
i.interceptors = append(i.interceptors, icpr)
|
||||
func (r *Registry) Add(f Factory) {
|
||||
r.factories = append(r.factories, f)
|
||||
}
|
||||
|
||||
// Build constructs a single Interceptor from a InterceptorRegistry
|
||||
func (i *Registry) Build() Interceptor {
|
||||
if len(i.interceptors) == 0 {
|
||||
return &NoOp{}
|
||||
func (r *Registry) Build(id string) (Interceptor, error) {
|
||||
if len(r.factories) == 0 {
|
||||
return &NoOp{}, nil
|
||||
}
|
||||
|
||||
return NewChain(i.interceptors)
|
||||
interceptors := []Interceptor{}
|
||||
for _, f := range r.factories {
|
||||
i, err := f.NewInterceptor(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
interceptors = append(interceptors, i)
|
||||
}
|
||||
|
||||
return NewChain(interceptors), nil
|
||||
}
|
||||
|
|
13
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/renovate.json
generated
vendored
13
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/renovate.json
generated
vendored
|
@ -1,15 +1,6 @@
|
|||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:base"
|
||||
],
|
||||
"postUpdateOptions": [
|
||||
"gomodTidy"
|
||||
],
|
||||
"commitBody": "Generated by renovateBot",
|
||||
"packageRules": [
|
||||
{
|
||||
"packagePatterns": ["^golang.org/x/"],
|
||||
"schedule": ["on the first day of the month"]
|
||||
}
|
||||
"github>pion/renovate-config"
|
||||
]
|
||||
}
|
||||
|
|
3
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/streaminfo.go
generated
vendored
3
trunk/3rdparty/srs-bench/vendor/github.com/pion/interceptor/streaminfo.go
generated
vendored
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package interceptor
|
||||
|
||||
// RTPHeaderExtension represents a negotiated RFC5285 RTP header extension.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue