mirror of
https://github.com/pion/mediadevices.git
synced 2025-10-04 16:22:46 +08:00
Add codec property
Add codec property, which stores general encoding parameters, to MediaTrackConstraints.
This commit is contained in:

committed by
Lukas Herman

parent
1e868fc3e3
commit
00bcadc238
@@ -52,6 +52,7 @@ func main() {
|
||||
Audio: func(c *mediadevices.MediaTrackConstraints) {
|
||||
c.Codec = webrtc.Opus
|
||||
c.Enabled = true
|
||||
c.BitRate = 32000 // 32kbps
|
||||
},
|
||||
Video: func(c *mediadevices.MediaTrackConstraints) {
|
||||
c.Codec = videoCodecName
|
||||
@@ -59,6 +60,7 @@ func main() {
|
||||
c.Enabled = true
|
||||
c.Width = 640
|
||||
c.Height = 480
|
||||
c.BitRate = 100000 // 100kbps
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
|
@@ -8,5 +8,5 @@ import (
|
||||
"github.com/pion/mediadevices/pkg/prop"
|
||||
)
|
||||
|
||||
type VideoEncoderBuilder func(r video.Reader, p prop.Video) (io.ReadCloser, error)
|
||||
type AudioEncoderBuilder func(r audio.Reader, p prop.Audio) (io.ReadCloser, error)
|
||||
type VideoEncoderBuilder func(r video.Reader, p prop.Media) (io.ReadCloser, error)
|
||||
type AudioEncoderBuilder func(r audio.Reader, p prop.Media) (io.ReadCloser, error)
|
||||
|
@@ -35,7 +35,11 @@ func init() {
|
||||
codec.Register(webrtc.H264, codec.VideoEncoderBuilder(NewEncoder))
|
||||
}
|
||||
|
||||
func NewEncoder(r video.Reader, p prop.Video) (io.ReadCloser, error) {
|
||||
func NewEncoder(r video.Reader, p prop.Media) (io.ReadCloser, error) {
|
||||
if p.BitRate == 0 {
|
||||
p.BitRate = 100000
|
||||
}
|
||||
|
||||
cEncoder, err := C.enc_new(C.EncoderOptions{
|
||||
width: C.int(p.Width),
|
||||
height: C.int(p.Height),
|
||||
|
@@ -29,7 +29,7 @@ func init() {
|
||||
codec.Register(webrtc.Opus, codec.AudioEncoderBuilder(NewEncoder))
|
||||
}
|
||||
|
||||
func NewEncoder(r audio.Reader, p prop.Audio) (io.ReadCloser, error) {
|
||||
func NewEncoder(r audio.Reader, p prop.Media) (io.ReadCloser, error) {
|
||||
if p.SampleRate == 0 {
|
||||
return nil, fmt.Errorf("opus: inProp.SampleRate is required")
|
||||
}
|
||||
@@ -38,6 +38,10 @@ func NewEncoder(r audio.Reader, p prop.Audio) (io.ReadCloser, error) {
|
||||
p.Latency = 20
|
||||
}
|
||||
|
||||
if p.BitRate == 0 {
|
||||
p.BitRate = 32000
|
||||
}
|
||||
|
||||
// Select the nearest supported latency
|
||||
var targetLatency float64
|
||||
latencyInMS := float64(p.Latency.Milliseconds())
|
||||
@@ -59,6 +63,9 @@ func NewEncoder(r audio.Reader, p prop.Audio) (io.ReadCloser, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := engine.SetBitrate(p.BitRate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
inBuffSize := targetLatency * float64(p.SampleRate) / 1000
|
||||
inBuff := make([][2]float32, int(inBuffSize))
|
||||
|
@@ -23,7 +23,7 @@ func Register(name string, builder interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
func BuildVideoEncoder(name string, r video.Reader, p prop.Video) (io.ReadCloser, error) {
|
||||
func BuildVideoEncoder(name string, r video.Reader, p prop.Media) (io.ReadCloser, error) {
|
||||
b, ok := videoEncoders[name]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("codec: can't find %s video encoder", name)
|
||||
@@ -32,7 +32,7 @@ func BuildVideoEncoder(name string, r video.Reader, p prop.Video) (io.ReadCloser
|
||||
return b(r, p)
|
||||
}
|
||||
|
||||
func BuildAudioEncoder(name string, r audio.Reader, p prop.Audio) (io.ReadCloser, error) {
|
||||
func BuildAudioEncoder(name string, r audio.Reader, p prop.Media) (io.ReadCloser, error) {
|
||||
b, ok := audioEncoders[name]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("codec: can't find %s audio encoder", name)
|
||||
|
@@ -63,16 +63,24 @@ func init() {
|
||||
}
|
||||
|
||||
// NewVP8Encoder creates new VP8 encoder
|
||||
func NewVP8Encoder(r video.Reader, p prop.Video) (io.ReadCloser, error) {
|
||||
func NewVP8Encoder(r video.Reader, p prop.Media) (io.ReadCloser, error) {
|
||||
return newEncoder(r, p, C.ifaceVP8())
|
||||
}
|
||||
|
||||
// NewVP9Encoder creates new VP9 encoder
|
||||
func NewVP9Encoder(r video.Reader, p prop.Video) (io.ReadCloser, error) {
|
||||
func NewVP9Encoder(r video.Reader, p prop.Media) (io.ReadCloser, error) {
|
||||
return newEncoder(r, p, C.ifaceVP9())
|
||||
}
|
||||
|
||||
func newEncoder(r video.Reader, p prop.Video, codecIface *C.vpx_codec_iface_t) (io.ReadCloser, error) {
|
||||
func newEncoder(r video.Reader, p prop.Media, codecIface *C.vpx_codec_iface_t) (io.ReadCloser, error) {
|
||||
if p.BitRate == 0 {
|
||||
p.BitRate = 100000
|
||||
}
|
||||
|
||||
if p.KeyFrameInterval == 0 {
|
||||
p.KeyFrameInterval = 60
|
||||
}
|
||||
|
||||
cfg := &C.vpx_codec_enc_cfg_t{}
|
||||
if ec := C.vpx_codec_enc_config_default(codecIface, cfg, 0); ec != 0 {
|
||||
return nil, fmt.Errorf("vpx_codec_enc_config_default failed (%d)", ec)
|
||||
@@ -101,7 +109,7 @@ func newEncoder(r video.Reader, p prop.Video, codecIface *C.vpx_codec_iface_t) (
|
||||
r: video.ToI420(r),
|
||||
codec: codec,
|
||||
raw: rawNoBuffer,
|
||||
keyframeInterval: 30, // TODO: Set via prop.Video
|
||||
keyframeInterval: p.KeyFrameInterval,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@@ -12,6 +12,7 @@ import (
|
||||
type Media struct {
|
||||
Video
|
||||
Audio
|
||||
Codec
|
||||
}
|
||||
|
||||
func (p *Media) FitnessDistance(o Media) float64 {
|
||||
@@ -62,7 +63,6 @@ type Video struct {
|
||||
Width, Height int
|
||||
FrameRate float32
|
||||
FrameFormat frame.Format
|
||||
BitRate int
|
||||
}
|
||||
|
||||
// Audio represents an audio's properties
|
||||
@@ -72,3 +72,17 @@ type Audio struct {
|
||||
SampleRate int
|
||||
SampleSize int
|
||||
}
|
||||
|
||||
// Codec represents an codec's encoding properties
|
||||
type Codec struct {
|
||||
// Target bitrate in bps.
|
||||
BitRate int
|
||||
|
||||
// Quolity of the encoding [0-9].
|
||||
// Larger value results higher quality and higher CPU usage.
|
||||
// It depends on the selected codec.
|
||||
Quality int
|
||||
|
||||
// Expected interval of the keyframes in frames.
|
||||
KeyFrameInterval int
|
||||
}
|
||||
|
6
track.go
6
track.go
@@ -99,9 +99,7 @@ func newVideoTrack(codecs []*webrtc.RTPCodec, d driver.Driver, constraints Media
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: Remove hardcoded bitrate
|
||||
constraints.BitRate = 100000
|
||||
encoder, err := codec.BuildVideoEncoder(codecName, r, constraints.Video)
|
||||
encoder, err := codec.BuildVideoEncoder(codecName, r, constraints.Media)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -172,7 +170,7 @@ func newAudioTrack(codecs []*webrtc.RTPCodec, d driver.Driver, constraints Media
|
||||
return nil, err
|
||||
}
|
||||
|
||||
encoder, err := codec.BuildAudioEncoder(codecName, reader, constraints.Audio)
|
||||
encoder, err := codec.BuildAudioEncoder(codecName, reader, constraints.Media)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Reference in New Issue
Block a user