mirror of
https://github.com/harshabose/transcode.git
synced 2025-10-10 05:50:46 +08:00
first-commit
This commit is contained in:
33
go.mod
33
go.mod
@@ -1,29 +1,16 @@
|
|||||||
module harshabose/transcode/v1
|
module github.com/harshabose/simple_webrtc_comm/transcode
|
||||||
|
|
||||||
go 1.23
|
go 1.23
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/asticode/go-astiav v0.33.1 // indirect
|
github.com/asticode/go-astiav v0.33.1
|
||||||
github.com/asticode/go-astikit v0.42.0 // indirect
|
github.com/pion/rtp v1.8.11
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/pion/webrtc/v4 v4.0.10
|
||||||
github.com/pion/datachannel v1.5.10 // indirect
|
github.com/asticode/go-astikit v0.52.0 // indirect
|
||||||
github.com/pion/dtls/v3 v3.0.4 // indirect
|
|
||||||
github.com/pion/ice/v4 v4.0.6 // indirect
|
|
||||||
github.com/pion/interceptor v0.1.37 // 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/randutil v0.1.0 // indirect
|
||||||
github.com/pion/rtcp v1.2.15 // indirect
|
github.com/harshabose/tools/buffer v0.0.0
|
||||||
github.com/pion/rtp v1.8.11 // indirect
|
)
|
||||||
github.com/pion/sctp v1.8.35 // indirect
|
|
||||||
github.com/pion/sdp/v3 v3.0.10 // indirect
|
replace (
|
||||||
github.com/pion/srtp/v3 v3.0.4 // indirect
|
github.com/harshabose/tools/buffer => ../tools/buffer
|
||||||
github.com/pion/stun/v3 v3.0.0 // indirect
|
|
||||||
github.com/pion/transport/v3 v3.0.7 // indirect
|
|
||||||
github.com/pion/turn/v4 v4.0.0 // indirect
|
|
||||||
github.com/pion/webrtc/v4 v4.0.10 // indirect
|
|
||||||
github.com/wlynxg/anet v0.0.5 // indirect
|
|
||||||
golang.org/x/crypto v0.32.0 // indirect
|
|
||||||
golang.org/x/net v0.34.0 // indirect
|
|
||||||
golang.org/x/sys v0.29.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
26
go.sum
26
go.sum
@@ -2,8 +2,20 @@ github.com/asticode/go-astiav v0.33.1 h1:fll7jDP1LCosVTpqJNze0z0TAokuyFj+Jjls+g1
|
|||||||
github.com/asticode/go-astiav v0.33.1/go.mod h1:K7D8UC6GeQt85FUxk2KVwYxHnotrxuEnp5evkkudc2s=
|
github.com/asticode/go-astiav v0.33.1/go.mod h1:K7D8UC6GeQt85FUxk2KVwYxHnotrxuEnp5evkkudc2s=
|
||||||
github.com/asticode/go-astikit v0.42.0 h1:pnir/2KLUSr0527Tv908iAH6EGYYrYta132vvjXsH5w=
|
github.com/asticode/go-astikit v0.42.0 h1:pnir/2KLUSr0527Tv908iAH6EGYYrYta132vvjXsH5w=
|
||||||
github.com/asticode/go-astikit v0.42.0/go.mod h1:h4ly7idim1tNhaVkdVBeXQZEE3L0xblP7fCWbgwipF0=
|
github.com/asticode/go-astikit v0.42.0/go.mod h1:h4ly7idim1tNhaVkdVBeXQZEE3L0xblP7fCWbgwipF0=
|
||||||
|
github.com/asticode/go-astikit v0.52.0 h1:kTl2XjgiVQhUl1H7kim7NhmTtCMwVBbPrXKqhQhbk8Y=
|
||||||
|
github.com/asticode/go-astikit v0.52.0/go.mod h1:fV43j20UZYfXzP9oBn33udkvCvDvCDhzjVqoLFuuYZE=
|
||||||
|
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/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
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/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
|
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||||
|
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||||
|
github.com/onsi/gomega v1.17.0 h1:9Luw4uT5HTjHTN8+aNcSThgH1vdXnmdJ8xIfZ4wyTRE=
|
||||||
|
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||||
github.com/pion/datachannel v1.5.10 h1:ly0Q26K1i6ZkGf42W7D4hQYR90pZwzFOjTq5AuCKk4o=
|
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/datachannel v1.5.10/go.mod h1:p/jJfC9arb29W7WrxyKbepTU20CFgyx5oLo8Rs4Py/M=
|
||||||
github.com/pion/dtls/v3 v3.0.4 h1:44CZekewMzfrn9pmGrj5BNnTMDCFwr+6sLH+cCuLM7U=
|
github.com/pion/dtls/v3 v3.0.4 h1:44CZekewMzfrn9pmGrj5BNnTMDCFwr+6sLH+cCuLM7U=
|
||||||
@@ -36,6 +48,12 @@ 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/turn/v4 v4.0.0/go.mod h1:MuPDkm15nYSklKpN8vWJ9W2M0PlyQZqYt1McGuxG7mA=
|
||||||
github.com/pion/webrtc/v4 v4.0.10 h1:Hq/JLjhqLxi+NmCtE8lnRPDr8H4LcNvwg8OxVcdv56Q=
|
github.com/pion/webrtc/v4 v4.0.10 h1:Hq/JLjhqLxi+NmCtE8lnRPDr8H4LcNvwg8OxVcdv56Q=
|
||||||
github.com/pion/webrtc/v4 v4.0.10/go.mod h1:ViHLVaNpiuvaH8pdiuQxuA9awuE6KVzAXx3vVWilOck=
|
github.com/pion/webrtc/v4 v4.0.10/go.mod h1:ViHLVaNpiuvaH8pdiuQxuA9awuE6KVzAXx3vVWilOck=
|
||||||
|
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/sclevine/agouti v3.0.0+incompatible h1:8IBJS6PWz3uTlMP3YBIR5f+KAldcGuOeFkFbUWfBgK4=
|
||||||
|
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
|
||||||
|
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 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU=
|
||||||
github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
|
github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
|
||||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||||
@@ -44,3 +62,11 @@ golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
|||||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
|
||||||
|
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
||||||
|
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||||
|
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
@@ -1,8 +0,0 @@
|
|||||||
package internal
|
|
||||||
|
|
||||||
import "errors"
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrorElementUnallocated = errors.New("encountered nil in the buffer. this should not happen. check usage")
|
|
||||||
ErrorChannelBufferClose = errors.New("channel buffer has be closed. cannot perform this operation")
|
|
||||||
)
|
|
@@ -4,12 +4,23 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/asticode/go-astiav"
|
"github.com/asticode/go-astiav"
|
||||||
|
"github.com/harshabose/tools/buffer/pkg"
|
||||||
)
|
)
|
||||||
|
|
||||||
type framePool struct {
|
type framePool struct {
|
||||||
pool sync.Pool
|
pool sync.Pool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CreateFramePool() buffer.Pool[astiav.Frame] {
|
||||||
|
return &framePool{
|
||||||
|
pool: sync.Pool{
|
||||||
|
New: func() any {
|
||||||
|
return astiav.AllocFrame()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (pool *framePool) Get() *astiav.Frame {
|
func (pool *framePool) Get() *astiav.Frame {
|
||||||
frame, ok := pool.pool.Get().(*astiav.Frame)
|
frame, ok := pool.pool.Get().(*astiav.Frame)
|
||||||
|
|
||||||
|
@@ -1,106 +0,0 @@
|
|||||||
package internal
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
type limitBuffer[T any] struct {
|
|
||||||
pool Pool[T]
|
|
||||||
bufferChannel chan *T
|
|
||||||
inputBuffer chan *T
|
|
||||||
ctx context.Context
|
|
||||||
}
|
|
||||||
|
|
||||||
func (buffer *limitBuffer[T]) Push(ctx context.Context, element *T) error {
|
|
||||||
select {
|
|
||||||
case buffer.inputBuffer <- element:
|
|
||||||
// WARN: LACKS CHECKS FOR CLOSED CHANNEL
|
|
||||||
return nil
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (buffer *limitBuffer[T]) Pop(ctx context.Context) (*T, error) {
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
return nil, ctx.Err()
|
|
||||||
case data, ok := <-buffer.bufferChannel:
|
|
||||||
if !ok {
|
|
||||||
return nil, ErrorChannelBufferClose
|
|
||||||
}
|
|
||||||
if data == nil {
|
|
||||||
return nil, ErrorElementUnallocated
|
|
||||||
}
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (buffer *limitBuffer[T]) Generate() *T {
|
|
||||||
return buffer.pool.Get()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (buffer *limitBuffer[T]) PutBack(element *T) {
|
|
||||||
if buffer.pool != nil {
|
|
||||||
buffer.pool.Put(element)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (buffer *limitBuffer[T]) GetChannel() chan *T {
|
|
||||||
return buffer.bufferChannel
|
|
||||||
}
|
|
||||||
|
|
||||||
func (buffer *limitBuffer[T]) Size() int {
|
|
||||||
return len(buffer.bufferChannel)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (buffer *limitBuffer[T]) loop() {
|
|
||||||
defer buffer.close()
|
|
||||||
loop:
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-buffer.ctx.Done():
|
|
||||||
return
|
|
||||||
case element, ok := <-buffer.inputBuffer:
|
|
||||||
if !ok || element == nil {
|
|
||||||
continue loop
|
|
||||||
}
|
|
||||||
select {
|
|
||||||
case buffer.bufferChannel <- element: // SUCCESSFULLY BUFFERED
|
|
||||||
continue loop
|
|
||||||
default:
|
|
||||||
select {
|
|
||||||
case oldElement := <-buffer.bufferChannel:
|
|
||||||
buffer.PutBack(oldElement)
|
|
||||||
select {
|
|
||||||
case buffer.bufferChannel <- element:
|
|
||||||
continue loop
|
|
||||||
default:
|
|
||||||
fmt.Println("unexpected buffer state. skipping the element..")
|
|
||||||
buffer.PutBack(element)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (buffer *limitBuffer[T]) close() {
|
|
||||||
loop:
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case element := <-buffer.bufferChannel:
|
|
||||||
if buffer.pool != nil {
|
|
||||||
buffer.pool.Put(element)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
close(buffer.bufferChannel)
|
|
||||||
close(buffer.inputBuffer)
|
|
||||||
break loop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if buffer.pool != nil {
|
|
||||||
buffer.pool.Release()
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,82 +0,0 @@
|
|||||||
package internal
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/asticode/go-astiav"
|
|
||||||
"github.com/pion/rtp"
|
|
||||||
"github.com/pion/webrtc/v4/pkg/media"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Pool[T any] interface {
|
|
||||||
Get() *T
|
|
||||||
Put(*T)
|
|
||||||
Release()
|
|
||||||
}
|
|
||||||
|
|
||||||
type Buffer[T any] interface {
|
|
||||||
Push(context.Context, *T) error
|
|
||||||
Pop(ctx context.Context) (*T, error)
|
|
||||||
Size() int
|
|
||||||
}
|
|
||||||
|
|
||||||
type BufferWithGenerator[T any] interface {
|
|
||||||
Push(context.Context, *T) error
|
|
||||||
Pop(ctx context.Context) (*T, error)
|
|
||||||
Size() int
|
|
||||||
Generate() *T
|
|
||||||
PutBack(*T)
|
|
||||||
GetChannel() chan *T
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateFramePool() Pool[astiav.Frame] {
|
|
||||||
return &framePool{
|
|
||||||
pool: sync.Pool{
|
|
||||||
New: func() any {
|
|
||||||
return astiav.AllocFrame()
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateSamplePool() Pool[media.Sample] {
|
|
||||||
return &samplePool{
|
|
||||||
pool: sync.Pool{
|
|
||||||
New: func() any {
|
|
||||||
return &media.Sample{}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateRTPPool() Pool[rtp.Packet] {
|
|
||||||
return &rtpPool{
|
|
||||||
pool: sync.Pool{
|
|
||||||
New: func() any {
|
|
||||||
return &rtp.Packet{}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreatePacketPool() Pool[astiav.Packet] {
|
|
||||||
return &packetPool{
|
|
||||||
pool: sync.Pool{
|
|
||||||
New: func() any {
|
|
||||||
return astiav.AllocPacket()
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateChannelBuffer[T any](ctx context.Context, size int, pool Pool[T]) BufferWithGenerator[T] {
|
|
||||||
buffer := &limitBuffer[T]{
|
|
||||||
pool: pool,
|
|
||||||
bufferChannel: make(chan *T, size),
|
|
||||||
inputBuffer: make(chan *T),
|
|
||||||
ctx: ctx,
|
|
||||||
}
|
|
||||||
go buffer.loop()
|
|
||||||
return buffer
|
|
||||||
}
|
|
@@ -4,12 +4,23 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/asticode/go-astiav"
|
"github.com/asticode/go-astiav"
|
||||||
|
"github.com/harshabose/tools/buffer/pkg"
|
||||||
)
|
)
|
||||||
|
|
||||||
type packetPool struct {
|
type packetPool struct {
|
||||||
pool sync.Pool
|
pool sync.Pool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CreatePacketPool() buffer.Pool[astiav.Packet] {
|
||||||
|
return &packetPool{
|
||||||
|
pool: sync.Pool{
|
||||||
|
New: func() any {
|
||||||
|
return astiav.AllocPacket()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (pool *packetPool) Get() *astiav.Packet {
|
func (pool *packetPool) Get() *astiav.Packet {
|
||||||
packet, ok := pool.pool.Get().(*astiav.Packet)
|
packet, ok := pool.pool.Get().(*astiav.Packet)
|
||||||
|
|
||||||
|
@@ -3,6 +3,7 @@ package internal
|
|||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/harshabose/tools/buffer/pkg"
|
||||||
"github.com/pion/rtp"
|
"github.com/pion/rtp"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -10,6 +11,16 @@ type rtpPool struct {
|
|||||||
pool sync.Pool
|
pool sync.Pool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CreateRTPPool() buffer.Pool[rtp.Packet] {
|
||||||
|
return &rtpPool{
|
||||||
|
pool: sync.Pool{
|
||||||
|
New: func() any {
|
||||||
|
return &rtp.Packet{}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (pool *rtpPool) Get() *rtp.Packet {
|
func (pool *rtpPool) Get() *rtp.Packet {
|
||||||
packet, ok := pool.pool.Get().(*rtp.Packet)
|
packet, ok := pool.pool.Get().(*rtp.Packet)
|
||||||
|
|
||||||
|
@@ -1,41 +0,0 @@
|
|||||||
package internal
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/pion/webrtc/v4/pkg/media"
|
|
||||||
)
|
|
||||||
|
|
||||||
type samplePool struct {
|
|
||||||
pool sync.Pool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pool *samplePool) Get() *media.Sample {
|
|
||||||
packet, ok := pool.pool.Get().(*media.Sample)
|
|
||||||
|
|
||||||
if packet == nil || !ok {
|
|
||||||
return &media.Sample{}
|
|
||||||
}
|
|
||||||
return packet
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pool *samplePool) Put(sample *media.Sample) {
|
|
||||||
if sample == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
pool.pool.Put(sample)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pool *samplePool) Release() {
|
|
||||||
for {
|
|
||||||
sample, ok := pool.pool.Get().(*media.Sample)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if sample == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
sample = nil
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1 +0,0 @@
|
|||||||
package internal
|
|
21
main.go
21
main.go
@@ -1,21 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TIP <p>To run your code, right-click the code and select <b>Run</b>.</p> <p>Alternatively, click
|
|
||||||
// the <icon src="AllIcons.Actions.Execute"/> icon in the gutter and select the <b>Run</b> menu item from here.</p>
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// TIP <p>Press <shortcut actionId="ShowIntentionActions"/> when your caret is at the underlined text
|
|
||||||
// to see how GoLand suggests fixing the warning.</p><p>Alternatively, if available, click the lightbulb to view possible fixes.</p>
|
|
||||||
s := "gopher"
|
|
||||||
fmt.Printf("Hello and welcome, %s!\n", s)
|
|
||||||
|
|
||||||
for i := 1; i <= 5; i++ {
|
|
||||||
// TIP <p>To start your debugging session, right-click your code in the editor and select the Debug option.</p> <p>We have set one <icon src="AllIcons.Debugger.Db_set_breakpoint"/> breakpoint
|
|
||||||
// for you, but you can always add more by pressing <shortcut actionId="ToggleLineBreakpoint"/>.</p>
|
|
||||||
fmt.Println("i =", 100/i)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,13 +1,22 @@
|
|||||||
package pkg
|
package transcode
|
||||||
|
|
||||||
import "github.com/asticode/go-astiav"
|
import "github.com/asticode/go-astiav"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DefaultVideoPayloadType = 96
|
DefaultVideoPayloadType = 96
|
||||||
DefaultVideoFPS = int(25)
|
DefaultVideoFPS = int(25)
|
||||||
|
DefaultVideoTimeBase = int(9000)
|
||||||
DefaultVideoClockRate = int(90000)
|
DefaultVideoClockRate = int(90000)
|
||||||
DefaultVideoHeight = int(1080)
|
DefaultVideoHeight = int(1080)
|
||||||
DefaultVideoWidth = int(1920)
|
DefaultVideoWidth = int(1920)
|
||||||
DefaultVideoPixFormat = astiav.PixelFormatYuv420P
|
DefaultVideoPixFormat = astiav.PixelFormatYuv420P
|
||||||
DefaultVideoEncoderCodec = astiav.CodecIDH264
|
DefaultVideoEncoderCodec = astiav.CodecIDH264
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DefaultAudioPayloadType = 111
|
||||||
|
DefaultAudioSampleRate = int(48000)
|
||||||
|
DefaultAudioFrameSize = int(960)
|
||||||
|
DefaultAudioSampleFormat = astiav.SampleFormatS16
|
||||||
|
DefaultAudioEncoderCodec = astiav.CodecIDOpus
|
||||||
|
)
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
package pkg
|
package transcode
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -7,22 +7,23 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/asticode/go-astiav"
|
"github.com/asticode/go-astiav"
|
||||||
|
"github.com/harshabose/tools/buffer/pkg"
|
||||||
|
|
||||||
"harshabose/transcode/v1/internal"
|
"github.com/harshabose/simple_webrtc_comm/transcode/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Decoder struct {
|
type Decoder struct {
|
||||||
demuxer *Demuxer
|
demuxer *Demuxer
|
||||||
decoderContext *astiav.CodecContext
|
decoderContext *astiav.CodecContext
|
||||||
codec *astiav.Codec
|
codec *astiav.Codec
|
||||||
buffer internal.BufferWithGenerator[astiav.Frame]
|
buffer buffer.BufferWithGenerator[astiav.Frame]
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateDecoder(ctx context.Context, demuxer *Demuxer, options ...DecoderOption) (*Decoder, error) {
|
func CreateDecoder(ctx context.Context, demuxer *Demuxer, options ...DecoderOption) (*Decoder, error) {
|
||||||
decoder := &Decoder{
|
decoder := &Decoder{
|
||||||
demuxer: demuxer,
|
demuxer: demuxer,
|
||||||
buffer: internal.CreateChannelBuffer(ctx, DefaultVideoFPS*3, internal.CreateFramePool()),
|
buffer: buffer.CreateChannelBuffer(ctx, DefaultVideoFPS*3, internal.CreateFramePool()),
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
package pkg
|
package transcode
|
||||||
|
|
||||||
import "github.com/asticode/go-astiav"
|
import "github.com/asticode/go-astiav"
|
||||||
|
|
||||||
@@ -27,3 +27,26 @@ func VideoSetDecoderContext(codecParameters *astiav.CodecParameters, videoStream
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AudioSetDecoderContext(codecParameters *astiav.CodecParameters, stream *astiav.Stream, formatContext *astiav.FormatContext) func(*Decoder) error {
|
||||||
|
return func(decoder *Decoder) error {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
if decoder.codec = astiav.FindDecoder(codecParameters.CodecID()); decoder.codec == nil {
|
||||||
|
return ErrorNoCodecFound
|
||||||
|
}
|
||||||
|
|
||||||
|
if decoder.decoderContext = astiav.AllocCodecContext(decoder.codec); decoder.decoderContext == nil {
|
||||||
|
return ErrorAllocateCodecContext
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = stream.CodecParameters().ToCodecContext(decoder.decoderContext); err != nil {
|
||||||
|
return ErrorFillCodecContext
|
||||||
|
}
|
||||||
|
|
||||||
|
decoder.decoderContext.SetTimeBase(stream.TimeBase())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,20 +1,22 @@
|
|||||||
package pkg
|
package transcode
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/asticode/go-astiav"
|
"github.com/asticode/go-astiav"
|
||||||
|
"github.com/harshabose/tools/buffer/pkg"
|
||||||
|
|
||||||
"harshabose/transcode/v1/internal"
|
"github.com/harshabose/simple_webrtc_comm/transcode/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Demuxer struct {
|
type Demuxer struct {
|
||||||
formatContext *astiav.FormatContext
|
formatContext *astiav.FormatContext
|
||||||
inputOptions *astiav.Dictionary
|
inputOptions *astiav.Dictionary
|
||||||
|
inputFormat *astiav.InputFormat
|
||||||
stream *astiav.Stream
|
stream *astiav.Stream
|
||||||
codecParameters *astiav.CodecParameters
|
codecParameters *astiav.CodecParameters
|
||||||
buffer internal.BufferWithGenerator[astiav.Packet]
|
buffer buffer.BufferWithGenerator[astiav.Packet]
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,7 +25,7 @@ func CreateDemuxer(ctx context.Context, containerAddress string, options ...Demu
|
|||||||
demuxer := &Demuxer{
|
demuxer := &Demuxer{
|
||||||
formatContext: astiav.AllocFormatContext(),
|
formatContext: astiav.AllocFormatContext(),
|
||||||
inputOptions: astiav.NewDictionary(),
|
inputOptions: astiav.NewDictionary(),
|
||||||
buffer: internal.CreateChannelBuffer(ctx, DefaultVideoFPS*3, internal.CreatePacketPool()),
|
buffer: buffer.CreateChannelBuffer(ctx, DefaultVideoFPS*3, internal.CreatePacketPool()),
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +39,7 @@ func CreateDemuxer(ctx context.Context, containerAddress string, options ...Demu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := demuxer.formatContext.OpenInput(containerAddress, nil, nil); err != nil {
|
if err := demuxer.formatContext.OpenInput(containerAddress, demuxer.inputFormat, demuxer.inputOptions); err != nil {
|
||||||
return nil, ErrorOpenInputContainer
|
return nil, ErrorOpenInputContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
package pkg
|
package transcode
|
||||||
|
|
||||||
|
import "github.com/asticode/go-astiav"
|
||||||
|
|
||||||
type DemuxerOption = func(*Demuxer) error
|
type DemuxerOption = func(*Demuxer) error
|
||||||
|
|
||||||
@@ -23,3 +25,13 @@ func WithRTSPInputOption(demuxer *Demuxer) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithAlsaInputFormatOption(demuxer *Demuxer) error {
|
||||||
|
demuxer.inputFormat = astiav.FindInputFormat("alsa")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithAvFoundationInputFormatOption(demuxer *Demuxer) error {
|
||||||
|
demuxer.inputFormat = astiav.FindInputFormat("avfoundation")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
package pkg
|
package transcode
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -7,16 +7,18 @@ import (
|
|||||||
|
|
||||||
"github.com/asticode/go-astiav"
|
"github.com/asticode/go-astiav"
|
||||||
|
|
||||||
"harshabose/transcode/v1/internal"
|
"github.com/harshabose/tools/buffer/pkg"
|
||||||
|
|
||||||
|
"github.com/harshabose/simple_webrtc_comm/transcode/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Encoder struct {
|
type Encoder struct {
|
||||||
buffer internal.BufferWithGenerator[astiav.Packet]
|
buffer buffer.BufferWithGenerator[astiav.Packet]
|
||||||
filter *Filter
|
filter *Filter
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
codec *astiav.Codec
|
codec *astiav.Codec
|
||||||
encoderContext *astiav.CodecContext
|
encoderContext *astiav.CodecContext
|
||||||
h264options *astiav.Dictionary
|
codecFlags *astiav.Dictionary
|
||||||
encoderSettings encoderCodecSetting
|
encoderSettings encoderCodecSetting
|
||||||
sps []byte
|
sps []byte
|
||||||
pps []byte
|
pps []byte
|
||||||
@@ -24,9 +26,9 @@ type Encoder struct {
|
|||||||
|
|
||||||
func CreateEncoder(ctx context.Context, codecID astiav.CodecID, filter *Filter, options ...EncoderOption) (*Encoder, error) {
|
func CreateEncoder(ctx context.Context, codecID astiav.CodecID, filter *Filter, options ...EncoderOption) (*Encoder, error) {
|
||||||
encoder := &Encoder{
|
encoder := &Encoder{
|
||||||
buffer: internal.CreateChannelBuffer(ctx, DefaultVideoFPS*3, internal.CreatePacketPool()),
|
buffer: buffer.CreateChannelBuffer(ctx, DefaultVideoFPS*3, internal.CreatePacketPool()),
|
||||||
filter: filter,
|
filter: filter,
|
||||||
h264options: astiav.NewDictionary(),
|
codecFlags: astiav.NewDictionary(),
|
||||||
encoderSettings: EncoderCodecNoSetting,
|
encoderSettings: EncoderCodecNoSetting,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
}
|
}
|
||||||
@@ -48,7 +50,7 @@ func CreateEncoder(ctx context.Context, codecID astiav.CodecID, filter *Filter,
|
|||||||
|
|
||||||
encoder.encoderContext.SetFlags(astiav.NewCodecContextFlags(astiav.CodecContextFlagGlobalHeader))
|
encoder.encoderContext.SetFlags(astiav.NewCodecContextFlags(astiav.CodecContextFlagGlobalHeader))
|
||||||
|
|
||||||
if err := encoder.encoderContext.Open(encoder.codec, encoder.h264options); err != nil {
|
if err := encoder.encoderContext.Open(encoder.codec, encoder.codecFlags); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,6 +63,14 @@ func (encoder *Encoder) Start() {
|
|||||||
go encoder.loop()
|
go encoder.loop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (encoder *Encoder) GetFPS() int { // TODO: THIS NEEDS TO BE ABSTRACTED
|
||||||
|
return DefaultVideoFPS
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *Encoder) GetVideoTimeBase() int { // TODO: THIS NEEDS TO BE ABSTRACTED
|
||||||
|
return DefaultVideoClockRate
|
||||||
|
}
|
||||||
|
|
||||||
func (encoder *Encoder) loop() {
|
func (encoder *Encoder) loop() {
|
||||||
var (
|
var (
|
||||||
frame *astiav.Frame
|
frame *astiav.Frame
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
package pkg
|
package transcode
|
||||||
|
|
||||||
type (
|
type (
|
||||||
encoderCodecSetting string
|
encoderCodecSetting string
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
package pkg
|
package transcode
|
||||||
|
|
||||||
import "errors"
|
import "errors"
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
package pkg
|
package transcode
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -6,14 +6,15 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/asticode/go-astiav"
|
"github.com/asticode/go-astiav"
|
||||||
|
"github.com/harshabose/tools/buffer/pkg"
|
||||||
|
|
||||||
"harshabose/transcode/v1/internal"
|
"github.com/harshabose/simple_webrtc_comm/transcode/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Filter struct {
|
type Filter struct {
|
||||||
content string
|
content string
|
||||||
decoder *Decoder
|
decoder *Decoder
|
||||||
buffer internal.BufferWithGenerator[astiav.Frame]
|
buffer buffer.BufferWithGenerator[astiav.Frame]
|
||||||
graph *astiav.FilterGraph
|
graph *astiav.FilterGraph
|
||||||
input *astiav.FilterInOut
|
input *astiav.FilterInOut
|
||||||
output *astiav.FilterInOut
|
output *astiav.FilterInOut
|
||||||
@@ -33,7 +34,7 @@ func CreateFilter(ctx context.Context, decoder *Decoder, filterConfig *Config, o
|
|||||||
filter = &Filter{
|
filter = &Filter{
|
||||||
graph: astiav.AllocFilterGraph(),
|
graph: astiav.AllocFilterGraph(),
|
||||||
decoder: decoder,
|
decoder: decoder,
|
||||||
buffer: internal.CreateChannelBuffer(ctx, DefaultVideoFPS*3, internal.CreateFramePool()),
|
buffer: buffer.CreateChannelBuffer(ctx, DefaultVideoFPS*3, internal.CreateFramePool()),
|
||||||
input: astiav.AllocFilterInOut(),
|
input: astiav.AllocFilterInOut(),
|
||||||
output: astiav.AllocFilterInOut(),
|
output: astiav.AllocFilterInOut(),
|
||||||
srcContextParams: astiav.AllocBuffersrcFilterContextParameters(),
|
srcContextParams: astiav.AllocBuffersrcFilterContextParameters(),
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
package pkg
|
package transcode
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -23,6 +23,8 @@ type Config struct {
|
|||||||
const (
|
const (
|
||||||
videoBufferFilterName Name = "buffer"
|
videoBufferFilterName Name = "buffer"
|
||||||
videoBufferSinkFilterName Name = "buffersink"
|
videoBufferSinkFilterName Name = "buffersink"
|
||||||
|
audioBufferFilterName Name = "abuffer"
|
||||||
|
audioBufferSinkFilterName Name = "abuffersink"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -30,6 +32,10 @@ var (
|
|||||||
Source: videoBufferFilterName,
|
Source: videoBufferFilterName,
|
||||||
Sink: videoBufferSinkFilterName,
|
Sink: videoBufferSinkFilterName,
|
||||||
}
|
}
|
||||||
|
AudioFilters = &Config{
|
||||||
|
Source: audioBufferFilterName,
|
||||||
|
Sink: audioBufferSinkFilterName,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func VideoSetFilterContextParameters(codecContext *astiav.CodecContext) func(*Filter) error {
|
func VideoSetFilterContextParameters(codecContext *astiav.CodecContext) func(*Filter) error {
|
||||||
@@ -71,3 +77,104 @@ func videoFPSFilterContent(filter *Filter) error {
|
|||||||
filter.content += fmt.Sprintf("fps=%d,", DefaultVideoFPS)
|
filter.content += fmt.Sprintf("fps=%d,", DefaultVideoFPS)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
func AudioSetFilterContextParameters(codecContext *astiav.CodecContext) func(*Filter) error {
|
||||||
|
return func(filter *Filter) error {
|
||||||
|
filter.srcContextParams.SetChannelLayout(codecContext.ChannelLayout())
|
||||||
|
filter.srcContextParams.SetSampleFormat(codecContext.SampleFormat())
|
||||||
|
filter.srcContextParams.SetSampleRate(codecContext.SampleRate())
|
||||||
|
filter.srcContextParams.SetTimeBase(codecContext.TimeBase())
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithDefaultAudioFilterContentOptions(filter *Filter) error {
|
||||||
|
if err := audioSampleFormatChannelLayoutContent(filter); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := audioSampleRateContent(filter); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := audioFrameSizeContent(filter); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func audioSampleFormatChannelLayoutContent(filter *Filter) error {
|
||||||
|
filter.content += buildAudioFormatContent(DefaultAudioSampleFormat, DefaultAudioChannelLayout) + ","
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildAudioFormatContent(sampleFormat astiav.SampleFormat, channelLayout astiav.ChannelLayout) string {
|
||||||
|
return fmt.Sprintf("aformat=sample_fmts=%s:channel_layouts=%s", sampleFormat.String(), channelLayout.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func audioSampleRateContent(filter *Filter) error {
|
||||||
|
filter.content += fmt.Sprintf("aresample=%d,", DefaultAudioSampleRate)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func audioFrameSizeContent(filter *Filter) error {
|
||||||
|
filter.content += fmt.Sprintf("asetnsamples=%d,", DefaultAudioFrameSize)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func audioCompressionContent(filter *Filter) error {
|
||||||
|
// NOTE: DYNAMIC RANGE COMPRESSION TO HANDLE SUDDEN VOLUME CHANGES
|
||||||
|
// Possible values 'acompressor=threshold=-12dB:ratio=2:attack=0.05:release=0.2" // MOST POPULAR VALUES
|
||||||
|
filter.content += fmt.Sprintf("acompressor=threshold=%ddB:ratio=%d:attack=%d:release=%d,")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func audioHighPassContent(filter *Filter) error {
|
||||||
|
// NOTE: HIGH-PASS FILTER TO REMOVE WIND NOISE AND TURBULENCE
|
||||||
|
// NOTE: 120HZ CUTOFF MIGHT PRESERVE VOICE WHILE REMOVING LOW RUMBLE; BUT MORE TESTING IS NEEDED
|
||||||
|
filter.content += fmt.Sprintf("highpass=f=%d,")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func audioNotchFilterContent(filter *Filter) error {
|
||||||
|
// NOTE: NOTCH FILTER CAN BE USED TO TARGET SPECIFIC PROPELLER NOISE AND REMOVE THEM
|
||||||
|
// NOTE: THIS MIGHT BE UNIQUE TO DRONE AND POWER LEVELS. I AM NOT SURE HOW TO USE IT TOO.
|
||||||
|
filter.content += "afftfilt=real='re*cos(0)':imag='im*cos(0):win_size=1024:fixed=true',"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WARN: DO NOT USE FOR NOW
|
||||||
|
func audioNeuralNetworkDenoiserContent(filter *Filter) error {
|
||||||
|
// NOTE: A RECURRENT NEURAL NETWORK MIGHT BE THE BEST SOLUTION HERE BUT I AM NOT SURE HOW TO BUILD IT
|
||||||
|
filter.content += "arnndn=m=,"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func audioEqualiser(filter *Filter) error {
|
||||||
|
// NOTE: EQUALISER CAN BE USED TO ENHANCE SPEECH BANDWIDTH (300 - 3kHz). MORE RESEARCH NEEDS TO DONE
|
||||||
|
filter.content += fmt.Sprintf("equalizer=f=%d:t=h:width=%d:g=%d,")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func audioSilenceGateContent(filter *Filter) error {
|
||||||
|
// NOTE: IF EVERYTHING WORKS, WE SHOULD HAVE LIGHT NOISE WHICH CAN BE CONSIDERED AS SILENCE. THIS GATE REMOVES SILENCE
|
||||||
|
// NOTE: POSSIBLE VALUES 'agate=threshold=-30dB:range=-30dB:attack=0.01:release=0.1" // MOST POPULAR; MORE TESTING IS NEEDED
|
||||||
|
filter.content += fmt.Sprintf("agate=threshold=%ddB:range=%ddB:attack=%d:release=%d,")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func audioLoudnessNormaliseContent(filter *Filter) error {
|
||||||
|
// NOTE: NORMALISES THE FINAL AUDIO. MUST BE CALLED AT THE END
|
||||||
|
// NOTE: POSSIBLE VALUES "loudnorm=I=-16:TP=-1.5:LRA=11" // MOST POPULAR
|
||||||
|
filter.content += fmt.Sprintf("loudnorm=I=%d:TP=%d:LRA=%d")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WARN: DO NOT USE FOR NOW
|
||||||
|
func audioNoiseReductionContent(filter *Filter) error {
|
||||||
|
// NOTE: anlmdn IS A NOISE REDUCTION FILTER. THIS MIGHT EFFECT THE QUALITY SIGNIFICANTLY - USE CAREFULLY
|
||||||
|
filter.content += fmt.Sprintf("anlmdn=s=%d,")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user