Improved handling of "tic_frame_size_at_1fs" daemon parameter, added the possibility to configure it with the WebUI and updated the documentation.
This commit is contained in:
parent
37fa1de81b
commit
745fa05d0b
@ -220,11 +220,12 @@ where:
|
||||
> JSON number specifying the default safety playout delay at 1FS in samples.
|
||||
|
||||
> **tic\_frame\_size\_at\_1fs**
|
||||
> JSON number specifying the RTP frame size at 1FS in samples.
|
||||
> JSON number specifying the TIC frame size at 1FS in samples, valid range is between 6 and 192 samples.
|
||||
> This global setting is used to determine the driver base timer period. For example with a value of 192 samples this period is set to 4ms and the outgoing RTP packets are scheduled for being sent to the network interface every 4ms causing an average latency grater than 4ms.
|
||||
> A user is able to configure Source whose max number of samples range from 125μs (6 samples) to the value of this parameter. For example with a value of 48 samples a user is able to configure sources with a max number of samples ranging from 125μs (6 samples) to 1ms (48 samples) and these will be affected by a 1ms latency.
|
||||
|
||||
> **max\_tic\_frame\_size**
|
||||
> JSON number specifying the max tick frame size.
|
||||
> In case of a high value of *tic_frame_size_at_1fs*, this must be set to 8192.
|
||||
> JSON number specifying the max tick frame size. This is currently set to 1024.
|
||||
|
||||
> **sap\_mcast\_addr**
|
||||
> JSON string specifying the SAP multicast address used for both announcing local sources and browsing remote sources.
|
||||
|
@ -59,9 +59,10 @@ std::shared_ptr<Config> Config::parse(const std::string& filename) {
|
||||
if (config.playout_delay_ > 4000)
|
||||
config.playout_delay_ = 4000;
|
||||
if (config.tic_frame_size_at_1fs_ == 0 ||
|
||||
config.tic_frame_size_at_1fs_ > 8192)
|
||||
config.tic_frame_size_at_1fs_ > 192)
|
||||
config.tic_frame_size_at_1fs_ = 192;
|
||||
if (config.max_tic_frame_size_ == 0 || config.max_tic_frame_size_ > 8192)
|
||||
if (config.max_tic_frame_size_ < config.tic_frame_size_at_1fs_ ||
|
||||
config.max_tic_frame_size_ > 1024)
|
||||
config.max_tic_frame_size_ = 1024;
|
||||
if (config.sample_rate_ == 0)
|
||||
config.sample_rate_ = 44100;
|
||||
|
@ -117,7 +117,7 @@ class Config {
|
||||
std::string http_base_dir_{"../webui/build"};
|
||||
int log_severity_{2};
|
||||
uint32_t playout_delay_{0};
|
||||
uint32_t tic_frame_size_at_1fs_{512};
|
||||
uint32_t tic_frame_size_at_1fs_{48};
|
||||
uint32_t max_tic_frame_size_{1024};
|
||||
uint32_t sample_rate_{44100};
|
||||
std::string rtp_mcast_base_{"239.1.0.1"};
|
||||
|
@ -4,7 +4,7 @@
|
||||
"http_base_dir": "../webui/build",
|
||||
"log_severity": 2,
|
||||
"playout_delay": 0,
|
||||
"tic_frame_size_at_1fs": 192,
|
||||
"tic_frame_size_at_1fs": 48,
|
||||
"max_tic_frame_size": 1024,
|
||||
"sample_rate": 44100,
|
||||
"rtp_mcast_base": "239.1.0.1",
|
||||
|
@ -455,7 +455,9 @@ std::error_code SessionManager::add_source(const StreamSource& source) {
|
||||
info.stream.m_byNbOfChannels = source.map.size();
|
||||
strncpy(info.stream.m_cCodec, source.codec.c_str(),
|
||||
sizeof(info.stream.m_cCodec) - 1);
|
||||
info.stream.m_ui32MaxSamplesPerPacket = source.max_samples_per_packet; // only for Source
|
||||
info.stream.m_ui32MaxSamplesPerPacket =
|
||||
source.max_samples_per_packet > config_->get_tic_frame_size_at_1fs() ?
|
||||
config_->get_tic_frame_size_at_1fs() : source.max_samples_per_packet;
|
||||
info.stream.m_ui32SamplingRate = driver_->get_current_sample_rate(); // last set from driver or config
|
||||
info.stream.m_uiId = source.id;
|
||||
info.stream.m_ui32RTCPSrcIP = config_->get_ip_addr();
|
||||
@ -717,19 +719,11 @@ std::error_code SessionManager::add_sink(const StreamSink& sink) {
|
||||
info.stream.m_ui32FrameSize = config_->get_max_tic_frame_size();
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "session_manager:: sink samples per packet " <<
|
||||
info.stream.m_ui32MaxSamplesPerPacket;
|
||||
BOOST_LOG_TRIVIAL(info) << "session_manager:: sink frame size " <<
|
||||
info.stream.m_ui32FrameSize;
|
||||
BOOST_LOG_TRIVIAL(info) << "session_manager:: playout delay " <<
|
||||
info.stream.m_ui32PlayOutDelay;
|
||||
|
||||
// info.m_ui32SrcIP = addr; // only for Source
|
||||
// info.m_usSrcPort = 5004;
|
||||
// info.m_ui32MaxSamplesPerPacket = 48;
|
||||
// info.m_ui32SSRC = 65544;
|
||||
// info.m_ucDSCP = source.dscp;
|
||||
// info.m_byTTL = source.ttl;
|
||||
auto mcast_mac_addr = get_mcast_mac_addr(info.stream.m_ui32DestIP);
|
||||
std::copy(std::begin(mcast_mac_addr), std::end(mcast_mac_addr),
|
||||
info.stream.m_ui8DestMAC);
|
||||
|
@ -37,7 +37,6 @@ class Config extends Component {
|
||||
playoutDelay: '',
|
||||
playoutDelayErr: false,
|
||||
ticFrameSizeAt1fs: '',
|
||||
ticFrameSizeAt1fsErr: false,
|
||||
maxTicFrameSize: '',
|
||||
maxTicFrameSizeErr: false,
|
||||
sampleRate: '',
|
||||
@ -99,7 +98,6 @@ class Config extends Component {
|
||||
|
||||
inputIsValid() {
|
||||
return !this.state.playoutDelayErr &&
|
||||
!this.state.ticFrameSizeAt1fsErr &&
|
||||
!this.state.maxTicFrameSizeErr &&
|
||||
!this.state.rtpMcastBaseErr &&
|
||||
!this.state.sapMcastAddrErr &&
|
||||
@ -139,11 +137,20 @@ class Config extends Component {
|
||||
<th align="left"> <input type='number' min='0' max='4000' className='input-number' value={this.state.playoutDelay} onChange={e => this.setState({playoutDelay: e.target.value, playoutDelayErr: !e.currentTarget.checkValidity()})} required/> </th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th align="left"> <label>TIC Frame size at @1FS </label> </th>
|
||||
<th align="left"> <input type='number' min='192' max='8192' className='input-number' value={this.state.ticFrameSizeAt1fs} onChange={e => this.setState({ticFrameSizeAt1fs: e.target.value, ticFrameSizeAt1fsErr: !e.currentTarget.checkValidity()})} disabled required/> </th>
|
||||
<th align="left"> <label>TIC frame size @1FS (samples) </label> </th>
|
||||
<th align="left">
|
||||
<select value={this.state.ticFrameSizeAt1fs} onChange={e => this.setState({ticFrameSizeAt1fs: e.target.value})}>
|
||||
<option value="6">6 - 125μs@48Khz</option>
|
||||
<option value="12">12 - 250μs@48Khz</option>
|
||||
<option value="16">16 - 333μs@48Khz</option>
|
||||
<option value="48">48 - 1ms@48Khz</option>
|
||||
<option value="96">96 - 2ms@48Khz</option>
|
||||
<option value="192">192 - 4ms@48Khz</option>
|
||||
</select>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th align="left"> <label>Max TIC frame size </label> </th>
|
||||
<th align="left"> <label>Max TIC frame size (samples) </label> </th>
|
||||
<th align="left"> <input type='number' min='192' max='8192' className='input-number' value={this.state.maxTicFrameSize} onChange={e => this.setState({maxTicFrameSize: e.target.value, maxTicFrameSizeErr: !e.currentTarget.checkValidity()})} disabled required/> </th>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -43,6 +43,7 @@ const max_packet_size = 1440; //bytes
|
||||
class SourceEdit extends Component {
|
||||
static propTypes = {
|
||||
source: PropTypes.object.isRequired,
|
||||
ticFrameSizeAt1fs: PropTypes.number.isRequired,
|
||||
applyEdit: PropTypes.func.isRequired,
|
||||
closeEdit: PropTypes.func.isRequired,
|
||||
editIsOpen: PropTypes.bool.isRequired,
|
||||
@ -58,7 +59,8 @@ class SourceEdit extends Component {
|
||||
name: this.props.source.name,
|
||||
nameErr: false,
|
||||
io: this.props.source.io,
|
||||
maxSamplesPerPacket: this.props.source.max_samples_per_packet,
|
||||
maxSamplesPerPacket: (this.props.source.max_samples_per_packet > this.props.ticFrameSizeAt1fs) ?
|
||||
this.props.ticFrameSizeAt1fs : this.props.source.max_samples_per_packet,
|
||||
codec: this.props.source.codec,
|
||||
ttl: this.props.source.ttl,
|
||||
ttlErr: false,
|
||||
@ -84,6 +86,7 @@ class SourceEdit extends Component {
|
||||
this.onChangeMaxSamplesPerPacket = this.onChangeMaxSamplesPerPacket.bind(this);
|
||||
this.onChangeCodec = this.onChangeCodec.bind(this);
|
||||
this.inputIsValid = this.inputIsValid.bind(this);
|
||||
this.checkMaxSamplesPerPacket = this.checkMaxSamplesPerPacket.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -153,6 +156,10 @@ class SourceEdit extends Component {
|
||||
this.setState({ map: map });
|
||||
}
|
||||
|
||||
checkMaxSamplesPerPacket(value) {
|
||||
return this.props.ticFrameSizeAt1fs >= value;
|
||||
}
|
||||
|
||||
inputIsValid() {
|
||||
return !this.state.nameErr &&
|
||||
!this.state.ttlErr &&
|
||||
@ -186,12 +193,12 @@ class SourceEdit extends Component {
|
||||
<th align="left"> <label>Max samples per packet </label> </th>
|
||||
<th align="left">
|
||||
<select value={this.state.maxSamplesPerPacket} onChange={this.onChangeMaxSamplesPerPacket}>
|
||||
<option value="6">6 - 125μs@48Khz</option>
|
||||
<option value="12">12 - 250μs@48Khz</option>
|
||||
<option value="16">16 - 333μs@48Khz</option>
|
||||
<option value="48">48 - 1ms@48Khz</option>
|
||||
<option value="96">96 - 2ms@48Khz</option>
|
||||
<option value="192">192 - 4ms@48Khz</option>
|
||||
<option value="6" disabled={this.checkMaxSamplesPerPacket(6) ? undefined : true}>6 - 125μs@48Khz</option>
|
||||
<option value="12" disabled={this.checkMaxSamplesPerPacket(12) ? undefined : true}>12 - 250μs@48Khz</option>
|
||||
<option value="16" disabled={this.checkMaxSamplesPerPacket(16) ? undefined : true}>16 - 333μs@48Khz</option>
|
||||
<option value="48" disabled={this.checkMaxSamplesPerPacket(48) ? undefined : true}>48 - 1ms@48Khz</option>
|
||||
<option value="96" disabled={this.checkMaxSamplesPerPacket(96) ? undefined : true}>96 - 2ms@48Khz</option>
|
||||
<option value="192" disabled={this.checkMaxSamplesPerPacket(192) ? undefined : true}>192 - 4ms@48Khz</option>
|
||||
</select>
|
||||
</th>
|
||||
</tr>
|
||||
|
@ -139,11 +139,13 @@ class Sources extends Component {
|
||||
sources: [],
|
||||
source: {},
|
||||
isLoading: false,
|
||||
isConfigLoading: false,
|
||||
isEdit: false,
|
||||
isInfo: false,
|
||||
editIsOpen: false,
|
||||
infoIsOpen: false,
|
||||
removeIsOpen: false,
|
||||
removeIsOpen: false,
|
||||
ticFrameSizeAt1fs: '',
|
||||
editTitle: ''
|
||||
};
|
||||
this.onInfoClick = this.onInfoClick.bind(this);
|
||||
@ -160,12 +162,17 @@ class Sources extends Component {
|
||||
}
|
||||
|
||||
fetchSources() {
|
||||
this.setState({isLoading: true});
|
||||
this.setState({isLoading: true, isConfigLoading: true});
|
||||
RestAPI.getSources()
|
||||
.then(response => response.json())
|
||||
.then(
|
||||
data => this.setState( { sources: data.sources, isLoading: false }))
|
||||
.catch(err => this.setState( { isLoading: false } ));
|
||||
RestAPI.getConfig()
|
||||
.then(response => response.json())
|
||||
.then(
|
||||
data => this.setState( { isConfigLoading: false, ticFrameSizeAt1fs: data.tic_frame_size_at_1fs }))
|
||||
.catch(err => this.setState({ isConfigLoading: false }));
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -253,7 +260,7 @@ class Sources extends Component {
|
||||
));
|
||||
return (
|
||||
<div id='sources'>
|
||||
{ this.state.isLoading ? <Loader/>
|
||||
{ this.state.isLoading || this.state.isConfigLoading ? <Loader/>
|
||||
: <SourceList onAddClick={this.onAddClick}
|
||||
onReloadClick={this.onReloadClick}
|
||||
sources={sources} /> }
|
||||
@ -273,6 +280,7 @@ class Sources extends Component {
|
||||
applyEdit={this.applyEdit}
|
||||
editTitle={this.state.editTitle}
|
||||
isEdit={this.state.isEdit}
|
||||
ticFrameSizeAt1fs={this.state.ticFrameSizeAt1fs}
|
||||
source={this.state.source} />
|
||||
: undefined }
|
||||
{ this.state.removeIsOpen ?
|
||||
|
Loading…
x
Reference in New Issue
Block a user