Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement frame poisoning #157

Merged
merged 3 commits into from
Jan 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/lib/src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ bool config_receiver(pipeline::ReceiverConfig& out, const roc_receiver_config& i
}

if (in.sample_rate) {
out.sample_rate = in.sample_rate;
out.output.sample_rate = in.sample_rate;
}

switch ((unsigned)in.fec_scheme) {
Expand All @@ -137,8 +137,8 @@ bool config_receiver(pipeline::ReceiverConfig& out, const roc_receiver_config& i
out.default_session.fec.n_repair_packets = in.n_repair_packets;
}

out.default_session.resampling = !(in.flags & ROC_FLAG_DISABLE_RESAMPLER);
out.timing = (in.flags & ROC_FLAG_ENABLE_TIMER);
out.output.resampling = !(in.flags & ROC_FLAG_DISABLE_RESAMPLER);
out.output.timing = (in.flags & ROC_FLAG_ENABLE_TIMER);

return true;
}
Expand Down
4 changes: 4 additions & 0 deletions src/lib/src/private.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,12 @@ struct roc_sender {
roc_context& context;

roc::rtp::FormatMap format_map;

roc::pipeline::SenderConfig config;

roc::pipeline::PortConfig source_port;
roc::pipeline::PortConfig repair_port;

roc::core::UniquePtr<roc::pipeline::Sender> sender;
roc::packet::IWriter* writer;

Expand Down
2 changes: 1 addition & 1 deletion src/lib/src/receiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ roc_receiver::roc_receiver(roc_context& ctx, pipeline::ReceiverConfig& cfg)
context.byte_buffer_pool,
context.sample_buffer_pool,
context.allocator)
, num_channels(packet::num_channels(cfg.channels)) {
, num_channels(packet::num_channels(cfg.output.channels)) {
}

roc_receiver* roc_receiver_open(roc_context* context, const roc_receiver_config* config) {
Expand Down
19 changes: 10 additions & 9 deletions src/lib/src/sender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ namespace {
bool init_pipeline(roc_sender* sender) {
sender->sender.reset(
new (sender->context.allocator) pipeline::Sender(
sender->config, *sender->writer, *sender->writer, sender->format_map,
sender->context.packet_pool, sender->context.byte_buffer_pool,
sender->context.sample_buffer_pool, sender->context.allocator),
sender->config, sender->source_port, *sender->writer, sender->repair_port,
*sender->writer, sender->format_map, sender->context.packet_pool,
sender->context.byte_buffer_pool, sender->context.sample_buffer_pool,
sender->context.allocator),
sender->context.allocator);

if (!sender->sender) {
Expand All @@ -45,12 +46,12 @@ bool init_port(roc_sender* sender, const pipeline::PortConfig& pconfig) {
case pipeline::Proto_RTP:
case pipeline::Proto_RTP_RSm8_Source:
case pipeline::Proto_RTP_LDPC_Source:
if (sender->config.source_port.protocol != pipeline::Proto_None) {
if (sender->source_port.protocol != pipeline::Proto_None) {
roc_log(LogError, "roc_sender: source port is already connected");
return false;
}

sender->config.source_port = pconfig;
sender->source_port = pconfig;

roc_log(LogInfo, "roc_sender: connected source port to %s %s",
packet::address_to_str(pconfig.address).c_str(),
Expand All @@ -60,7 +61,7 @@ bool init_port(roc_sender* sender, const pipeline::PortConfig& pconfig) {

case pipeline::Proto_RSm8_Repair:
case pipeline::Proto_LDPC_Repair:
if (sender->config.repair_port.protocol != pipeline::Proto_None) {
if (sender->repair_port.protocol != pipeline::Proto_None) {
roc_log(LogError, "roc_sender: repair port is already connected");
return false;
}
Expand All @@ -71,7 +72,7 @@ bool init_port(roc_sender* sender, const pipeline::PortConfig& pconfig) {
return false;
}

sender->config.repair_port = pconfig;
sender->repair_port = pconfig;

roc_log(LogInfo, "roc_sender: connected repair port to %s %s",
packet::address_to_str(pconfig.address).c_str(),
Expand All @@ -85,12 +86,12 @@ bool init_port(roc_sender* sender, const pipeline::PortConfig& pconfig) {
}

bool check_connected(roc_sender* sender) {
if (sender->config.source_port.protocol == pipeline::Proto_None) {
if (sender->source_port.protocol == pipeline::Proto_None) {
roc_log(LogError, "roc_sender: source port is not connected");
return false;
}

if (sender->config.repair_port.protocol == pipeline::Proto_None
if (sender->repair_port.protocol == pipeline::Proto_None
&& sender->config.fec.codec != fec::NoCodec) {
roc_log(LogError, "roc_sender: repair port is not connected");
return false;
Expand Down
31 changes: 31 additions & 0 deletions src/modules/roc_audio/poison_reader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2019 Roc authors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include "roc_audio/poison_reader.h"
#include "roc_audio/units.h"

namespace roc {
namespace audio {

PoisonReader::PoisonReader(IReader& reader)
: reader_(reader) {
}

void PoisonReader::read(Frame& frame) {
const size_t frame_size = frame.size();
sample_t* frame_data = frame.data();

for (size_t n = 0; n < frame_size; n++) {
frame_data[n] = SampleMax;
}

reader_.read(frame);
}

} // namespace audio
} // namespace roc
38 changes: 38 additions & 0 deletions src/modules/roc_audio/poison_reader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2019 Roc authors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

//! @file roc_audio/poison_reader.h
//! @brief Poison reader.

#ifndef ROC_AUDIO_POISON_READER_H_
#define ROC_AUDIO_POISON_READER_H_

#include "roc_audio/frame.h"
#include "roc_audio/ireader.h"
#include "roc_core/noncopyable.h"

namespace roc {
namespace audio {

//! Poisons audio frames before reading them.
class PoisonReader : public IReader, public core::NonCopyable<> {
public:
//! Initialize.
PoisonReader(IReader& reader);

//! Read audio frame.
virtual void read(Frame&);

private:
IReader& reader_;
};

} // namespace audio
} // namespace roc

#endif // ROC_AUDIO_POISON_READER_H_
31 changes: 31 additions & 0 deletions src/modules/roc_audio/poison_writer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2019 Roc authors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include "roc_audio/poison_writer.h"
#include "roc_audio/units.h"

namespace roc {
namespace audio {

PoisonWriter::PoisonWriter(IWriter& writer)
: writer_(writer) {
}

void PoisonWriter::write(Frame& frame) {
writer_.write(frame);

const size_t frame_size = frame.size();
sample_t* frame_data = frame.data();

for (size_t n = 0; n < frame_size; n++) {
frame_data[n] = SampleMax;
}
}

} // namespace audio
} // namespace roc
38 changes: 38 additions & 0 deletions src/modules/roc_audio/poison_writer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2019 Roc authors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

//! @file roc_audio/poison_writer.h
//! @brief Poison writer.

#ifndef ROC_AUDIO_POISON_WRITER_H_
#define ROC_AUDIO_POISON_WRITER_H_

#include "roc_audio/frame.h"
#include "roc_audio/iwriter.h"
#include "roc_core/noncopyable.h"

namespace roc {
namespace audio {

//! Poisons audio frames after writing them.
class PoisonWriter : public IWriter, public core::NonCopyable<> {
public:
//! Initialize.
PoisonWriter(IWriter& writer);

//! Write audio frame.
virtual void write(Frame&);

private:
IWriter& writer_;
};

} // namespace audio
} // namespace roc

#endif // ROC_AUDIO_POISON_WRITER_H_
62 changes: 36 additions & 26 deletions src/modules/roc_pipeline/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ struct PortConfig {
}
};

//! Session parameters.
//! Receiver session parameters.
//! @remarks
//! Defines per-session parameters on the receiver side.
struct SessionConfig {
struct ReceiverSessionConfig {
//! Channel mask.
packet::channel_mask_t channels;

Expand All @@ -107,55 +107,61 @@ struct SessionConfig {
//! Resampler parameters.
audio::ResamplerConfig resampler;

//! Perform resampling to to compensate sender and receiver frequency difference.
bool resampling;

//! Insert weird beeps instead of silence on packet loss.
bool beeping;

SessionConfig()
ReceiverSessionConfig()
: channels(DefaultChannelMask)
, samples_per_packet(DefaultPacketSize)
, latency(DefaultPacketSize * 27)
, watchdog(DefaultSampleRate)
, resampling(false)
, beeping(false) {
, watchdog(DefaultSampleRate) {
latency_monitor.min_latency =
(packet::signed_timestamp_t)latency * DefaultMinLatency;
latency_monitor.max_latency =
(packet::signed_timestamp_t)latency * DefaultMaxLatency;
}
};

//! Receiver parameters.
struct ReceiverConfig {
//! Default parameters for session.
SessionConfig default_session;

//! Receiver output parameters.
//! @remarks
//! Defines common output parameters on the receiver side.
struct ReceiverOutputConfig {
//! Number of samples per second per channel.
size_t sample_rate;

//! Channel mask.
packet::channel_mask_t channels;

//! Perform resampling to compensate sender and receiver frequency difference.
bool resampling;

//! Constrain receiver speed using a CPU timer according to the sample rate.
bool timing;

ReceiverConfig()
//! Fill uninitialized data with large values to make them more noticeable.
bool poisoning;

//! Insert weird beeps instead of silence on packet loss.
bool beeping;

ReceiverOutputConfig()
: sample_rate(DefaultSampleRate)
, channels(DefaultChannelMask)
, timing(false) {
, resampling(false)
, timing(false)
, poisoning(false)
, beeping(false) {
}
};

//! Sender parameters.
struct SenderConfig {
//! Parameters for the port to which source packets are sent.
PortConfig source_port;
//! Receiver parameters.
struct ReceiverConfig {
//! Default parameters for receiver session.
ReceiverSessionConfig default_session;

//! Parameters for the port to which repair packets are sent.
PortConfig repair_port;
//! Parameters for receiver output.
ReceiverOutputConfig output;
};

//! Sender parameters.
struct SenderConfig {
//! Resampler parameters.
audio::ResamplerConfig resampler;

Expand Down Expand Up @@ -183,14 +189,18 @@ struct SenderConfig {
//! Constrain receiver speed using a CPU timer according to the sample rate.
bool timing;

//! Fill unitialized data with large values to make them more noticable.
dshil marked this conversation as resolved.
Show resolved Hide resolved
bool poisoning;

SenderConfig()
: sample_rate(DefaultSampleRate)
, channels(DefaultChannelMask)
, payload_type(rtp::PayloadType_L16_Stereo)
, samples_per_packet(DefaultPacketSize)
, resampling(false)
, interleaving(false)
, timing(false) {
, timing(false)
, poisoning(false) {
}
};

Expand Down
Loading