mirror of
https://github.com/pion/mediadevices.git
synced 2026-04-23 00:07:29 +08:00
[VPX] vpx dynamic encoding (#647)
* Add vp8 decoder and dynamic vp8 decoding * Add QPController * change parameters into const * move decoder into another PR * use explicit parameter name
This commit is contained in:
@@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"image"
|
||||
"io"
|
||||
"math"
|
||||
"math/rand"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -13,6 +15,7 @@ import (
|
||||
"github.com/pion/mediadevices/pkg/frame"
|
||||
"github.com/pion/mediadevices/pkg/io/video"
|
||||
"github.com/pion/mediadevices/pkg/prop"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestEncoder(t *testing.T) {
|
||||
@@ -360,3 +363,65 @@ func TestEncoderFrameMonotonic(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestVP8DynamicQPControl(t *testing.T) {
|
||||
t.Run("VP8", func(t *testing.T) {
|
||||
p, err := NewVP8Params()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
p.LagInFrames = 0 // Disable frame lag buffering for real-time encoding
|
||||
p.RateControlEndUsage = RateControlCBR
|
||||
totalFrames := 100
|
||||
frameRate := 10
|
||||
initialWidth, initialHeight := 800, 600
|
||||
var cnt uint32
|
||||
|
||||
r, err := p.BuildVideoEncoder(
|
||||
video.ReaderFunc(func() (image.Image, func(), error) {
|
||||
i := atomic.AddUint32(&cnt, 1)
|
||||
if i == uint32(totalFrames+1) {
|
||||
return nil, nil, io.EOF
|
||||
}
|
||||
img := image.NewYCbCr(image.Rect(0, 0, initialWidth, initialHeight), image.YCbCrSubsampleRatio420)
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
for i := range img.Y {
|
||||
img.Y[i] = uint8(r.Intn(256))
|
||||
}
|
||||
for i := range img.Cb {
|
||||
img.Cb[i] = uint8(r.Intn(256))
|
||||
}
|
||||
for i := range img.Cr {
|
||||
img.Cr[i] = uint8(r.Intn(256))
|
||||
}
|
||||
return img, func() {}, nil
|
||||
}),
|
||||
prop.Media{
|
||||
Video: prop.Video{
|
||||
Width: initialWidth,
|
||||
Height: initialHeight,
|
||||
FrameRate: float32(frameRate),
|
||||
FrameFormat: frame.FormatI420,
|
||||
},
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
initialBitrate := 100
|
||||
currentBitrate := initialBitrate
|
||||
targetBitrate := 300
|
||||
for i := 0; i < totalFrames; i++ {
|
||||
r.Controller().(codec.KeyFrameController).ForceKeyFrame()
|
||||
r.Controller().(codec.QPController).DynamicQPControl(currentBitrate, targetBitrate)
|
||||
data, rel, err := r.Read()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rel()
|
||||
encodedSize := len(data)
|
||||
currentBitrate = encodedSize * 8 / 1000 / frameRate
|
||||
}
|
||||
assert.Less(t, math.Abs(float64(targetBitrate-currentBitrate)), math.Abs(float64(initialBitrate-currentBitrate)))
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user