Files
go-rtmp/conn_state.go
T
2018-07-17 21:44:18 +09:00

153 lines
3.2 KiB
Go

//
// Copyright (c) 2018- yutopp (yutopp@gmail.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
//
package rtmp
import (
"math"
"github.com/pkg/errors"
"github.com/yutopp/go-rtmp/message"
)
const DefaultChunkSize = 128
const MaxChunkSize = 0xffffff // 5.4.1
type StreamControlState struct {
chunkSize uint32
ackWindowSize int32
bandwidthWindowSize int32
bandwidthLimitType message.LimitType
lastAck uint32
config *StreamControlStateConfig
}
type StreamControlStateConfig struct {
DefaultChunkSize uint32
MaxChunkSize uint32
MaxChunkStreams int
DefaultAckWindowSize int32
MaxAckWindowSize int32
DefaultBandwidthWindowSize int32
DefaultBandwidthLimitType message.LimitType
MaxBandwidthWindowSize int32
MaxMessageSize uint32
MaxMessageStreams int
}
func (cb *StreamControlStateConfig) normalize() *StreamControlStateConfig {
c := StreamControlStateConfig(*cb)
// chunks
if c.DefaultChunkSize == 0 {
c.DefaultChunkSize = DefaultChunkSize
}
if c.MaxChunkSize == 0 {
c.MaxChunkSize = MaxChunkSize
}
if c.MaxChunkStreams == 0 {
c.MaxChunkStreams = math.MaxUint32
}
// ack
if c.DefaultAckWindowSize == 0 {
c.DefaultAckWindowSize = math.MaxInt32
}
if c.MaxAckWindowSize == 0 {
c.MaxAckWindowSize = math.MaxInt32
}
// bandwidth
if c.DefaultBandwidthWindowSize == 0 {
c.DefaultBandwidthWindowSize = math.MaxInt32
}
if c.MaxBandwidthWindowSize == 0 {
c.MaxBandwidthWindowSize = math.MaxInt32
}
// message
if c.MaxMessageStreams == 0 {
c.MaxMessageStreams = math.MaxUint32
}
if c.MaxMessageSize == 0 {
c.MaxMessageSize = MaxChunkSize // as same as chunk size
}
return &c
}
var defaultStreamControlStateConfig = (&StreamControlStateConfig{}).normalize()
func NewStreamControlState(config *StreamControlStateConfig) *StreamControlState {
if config == nil {
config = defaultStreamControlStateConfig
}
return &StreamControlState{
chunkSize: config.DefaultChunkSize,
ackWindowSize: config.DefaultAckWindowSize,
bandwidthWindowSize: config.DefaultBandwidthWindowSize,
bandwidthLimitType: config.DefaultBandwidthLimitType,
config: config,
}
}
func (s *StreamControlState) ChunkSize() uint32 {
return s.chunkSize
}
func (s *StreamControlState) SetChunkSize(chunkSize uint32) error {
if chunkSize > MaxChunkSize {
chunkSize = MaxChunkSize
}
if chunkSize > s.config.MaxChunkSize {
return errors.Errorf("Exceeded configured max chunk size: Limit = %d, Value = %d", s.config.MaxChunkSize, chunkSize)
}
s.chunkSize = chunkSize
return nil
}
func (s *StreamControlState) AckWindowSize() int32 {
return s.ackWindowSize
}
func (s *StreamControlState) SetAckWindowSize(ackWindowSize int32) error {
if ackWindowSize > s.config.MaxAckWindowSize {
return errors.Errorf("Exceeded configured max ack window size: Limit = %d, Value = %d", s.config.MaxAckWindowSize, ackWindowSize)
}
s.ackWindowSize = ackWindowSize
return nil
}
func (s *StreamControlState) BandwidthWindowSize() int32 {
return s.bandwidthWindowSize
}
func (s *StreamControlState) BandwidthLimitType() message.LimitType {
return s.bandwidthLimitType
}