From 0573f31a79ce1d7c3efaf6b1144c9010aa0f57dd Mon Sep 17 00:00:00 2001 From: Victor Gaydov Date: Sun, 23 Jun 2024 21:43:17 +0400 Subject: [PATCH] [wip] draft-731: Soft reads and partial reads in Depacketizer - forward status codes from packet reader - support soft reads - generate partial reads to separate signal and losses into different frames - use ModePeek to avoid advancing pipeline when next available packet is too far, and in soft read - remove beeping support --- .../roc_audio/depacketizer.cpp | 277 ++++++++++++------ src/internal_modules/roc_audio/depacketizer.h | 47 +-- src/internal_modules/roc_pipeline/config.cpp | 3 +- src/internal_modules/roc_pipeline/config.h | 3 - .../roc_pipeline/receiver_session.cpp | 3 +- .../roc_rtp/timestamp_injector.cpp | 5 - src/tests/roc_audio/test_depacketizer.cpp | 63 ++-- src/tools/roc_recv/cmdline.ggo | 2 - src/tools/roc_recv/main.cpp | 1 - 9 files changed, 251 insertions(+), 153 deletions(-) diff --git a/src/internal_modules/roc_audio/depacketizer.cpp b/src/internal_modules/roc_audio/depacketizer.cpp index d0b3d06e0..1af32c328 100644 --- a/src/internal_modules/roc_audio/depacketizer.cpp +++ b/src/internal_modules/roc_audio/depacketizer.cpp @@ -20,23 +20,12 @@ namespace { const core::nanoseconds_t LogInterval = 20 * core::Second; -inline void write_zeros(sample_t* buf, size_t bufsz) { - memset(buf, 0, bufsz * sizeof(sample_t)); -} - -inline void write_beep(sample_t* buf, size_t bufsz) { - for (size_t n = 0; n < bufsz; n++) { - buf[n] = (sample_t)std::sin(2 * M_PI / 44100 * 880 * n); - } -} - } // namespace Depacketizer::Depacketizer(packet::IReader& packet_reader, IFrameDecoder& payload_decoder, FrameFactory& frame_factory, - const SampleSpec& sample_spec, - bool beep) + const SampleSpec& sample_spec) : frame_factory_(frame_factory) , packet_reader_(packet_reader) , payload_decoder_(payload_decoder) @@ -45,13 +34,12 @@ Depacketizer::Depacketizer(packet::IReader& packet_reader, , next_capture_ts_(0) , valid_capture_ts_(false) , padding_samples_(0) - , missing_samples_(0) , decoded_samples_(0) + , missing_samples_(0) , fetched_packets_(0) , dropped_packets_(0) + , is_started_(false) , rate_limiter_(LogInterval) - , beep_(beep) - , first_packet_(true) , init_status_(status::NoStatus) { roc_panic_if_msg(!sample_spec_.is_valid() || !sample_spec_.is_raw(), "depacketizer: required valid sample spec with raw format: %s", @@ -70,13 +58,13 @@ status::StatusCode Depacketizer::init_status() const { bool Depacketizer::is_started() const { roc_panic_if(init_status_ != status::StatusOK); - return !first_packet_; + return is_started_; } packet::stream_timestamp_t Depacketizer::next_timestamp() const { roc_panic_if(init_status_ != status::StatusOK); - if (first_packet_) { + if (!is_started_) { return 0; } return stream_ts_; @@ -97,92 +85,149 @@ status::StatusCode Depacketizer::read(Frame& frame, frame.set_raw(true); + FrameStats frame_stats; + sample_t* buff_ptr = frame.raw_samples(); sample_t* buff_end = frame.raw_samples() + frame.num_raw_samples(); - FrameStats frame_stats; - while (buff_ptr < buff_end) { - const status::StatusCode code = update_packet_(frame_stats); + const size_t requested_samples = size_t(buff_end - buff_ptr); + const status::StatusCode code = + update_packet_(requested_samples, mode, frame_stats); + + if (code == status::StatusDrain && mode == ModeSoft) { + break; // In soft read mode, stop on packet loss. + } if (code != status::StatusOK && code != status::StatusDrain) { return code; } - buff_ptr = read_samples_(buff_ptr, buff_end, frame_stats); + sample_t* next_buff_ptr = read_samples_(buff_ptr, buff_end, mode, frame_stats); + if (!next_buff_ptr) { // Partial or drained read. + break; + } + + buff_ptr = next_buff_ptr; + } + + roc_panic_if_not(buff_ptr >= frame.raw_samples() && buff_ptr <= buff_end); + + const size_t frame_samples = size_t(buff_ptr - frame.raw_samples()); + if (frame_samples == 0) { + return status::StatusDrain; } - roc_panic_if(buff_ptr != buff_end); - commit_frame_(frame, frame_stats); - report_stats_(); + commit_frame_(frame, frame_samples, frame_stats); + periodic_report_(); - return capped_duration == requested_duration ? status::StatusOK : status::StatusPart; + return frame.duration() == requested_duration ? status::StatusOK : status::StatusPart; } -sample_t* -Depacketizer::read_samples_(sample_t* buff_ptr, sample_t* buff_end, FrameStats& stats) { +sample_t* Depacketizer::read_samples_(sample_t* buff_ptr, + sample_t* buff_end, + FrameReadMode mode, + FrameStats& stats) { if (packet_) { - packet::stream_timestamp_t next_timestamp = payload_decoder_.position(); - - if (stream_ts_ != next_timestamp) { - roc_panic_if_not(packet::stream_timestamp_lt(stream_ts_, next_timestamp)); + packet::stream_timestamp_t next_decoder_ts = payload_decoder_.position(); + + // Fill gap between stream timestamp and decoder timestamp, if it's present. + // + // next_decoder_ts, next_capture_ts_ + // ↓ + // Packet |■■■■■■■■■••••••••| + // stream_ts_ + // ↓ + // Frame |•••□□□□□■■■■■■■■■| + // gap + if (packet::stream_timestamp_lt(stream_ts_, next_decoder_ts)) { + if (mode == ModeSoft || stats.n_decoded_samples != 0) { + // In soft mode, stop reading on loss. + // Also, in any mode, don't mix signal and losses in one frame. + return NULL; + } + const size_t max_samples = (size_t)(buff_end - buff_ptr); const size_t mis_samples = sample_spec_.num_channels() - * (size_t)packet::stream_timestamp_diff(next_timestamp, stream_ts_); + * (size_t)packet::stream_timestamp_diff(next_decoder_ts, stream_ts_); - const size_t max_samples = (size_t)(buff_end - buff_ptr); const size_t n_samples = std::min(mis_samples, max_samples); buff_ptr = read_missing_samples_(buff_ptr, buff_ptr + n_samples); - // next_capture_ts_ - // next_timestamp - // ↓ - // Packet |-----------------| - // timestamp_ - // ↓ - // Frame |----------------| - stats.n_filled_samples += n_samples; + stats.n_written_samples += n_samples; + stats.n_missing_samples += n_samples; + if (!stats.capture_ts && valid_capture_ts_) { stats.capture_ts = next_capture_ts_ - - sample_spec_.samples_overall_2_ns(stats.n_filled_samples); + - sample_spec_.samples_overall_2_ns(stats.n_written_samples); } } + // Now stream timestamp is aligned with the decoder timestamp. + // Decode samples from packet. + // + // next_decoder_ts, next_capture_ts_ + // ↓ + // Packet |■■■■■■■■■■■••••••| + // stream_ts_ + // ↓ + // Frame |•••••■■■■■■■■■■■| if (buff_ptr < buff_end) { - sample_t* new_buff_ptr = read_packet_samples_(buff_ptr, buff_end); - const size_t n_samples = size_t(new_buff_ptr - buff_ptr); + if (stats.n_missing_samples != 0) { + // Don't mix signal and losses in one frame. + return NULL; + } + + sample_t* next_buff_ptr = read_decoded_samples_(buff_ptr, buff_end); + + const size_t n_samples = size_t(next_buff_ptr - buff_ptr); - stats.n_decoded_samples += n_samples; if (n_samples && !stats.capture_ts && valid_capture_ts_) { stats.capture_ts = next_capture_ts_ - - sample_spec_.samples_overall_2_ns(stats.n_filled_samples); + - sample_spec_.samples_overall_2_ns(stats.n_written_samples); } if (valid_capture_ts_) { next_capture_ts_ += sample_spec_.samples_overall_2_ns(n_samples); } - stats.n_filled_samples += n_samples; - buff_ptr = new_buff_ptr; + stats.n_written_samples += n_samples; + stats.n_decoded_samples += n_samples; + + buff_ptr = next_buff_ptr; } return buff_ptr; } else { + // No packet, fill requested area with zeros. + // + // stream_ts_ + // ↓ + // Frame |••••••□□□□□□□□□□□| + // gap + if (mode == ModeSoft || stats.n_decoded_samples != 0) { + // In soft mode, stop reading on loss. + // Also, in any mode, don't mix signal and losses in one frame. + return NULL; + } + const size_t n_samples = size_t(buff_end - buff_ptr); if (!stats.capture_ts && valid_capture_ts_) { stats.capture_ts = next_capture_ts_ - - sample_spec_.samples_overall_2_ns(stats.n_filled_samples); + - sample_spec_.samples_overall_2_ns(stats.n_written_samples); } if (valid_capture_ts_) { next_capture_ts_ += sample_spec_.samples_overall_2_ns(n_samples); } - stats.n_filled_samples += n_samples; + stats.n_written_samples += n_samples; + stats.n_missing_samples += n_samples; + return read_missing_samples_(buff_ptr, buff_end); } } -sample_t* Depacketizer::read_packet_samples_(sample_t* buff_ptr, sample_t* buff_end) { +sample_t* Depacketizer::read_decoded_samples_(sample_t* buff_ptr, sample_t* buff_end) { const size_t requested_samples = size_t(buff_end - buff_ptr) / sample_spec_.num_channels(); @@ -204,15 +249,11 @@ sample_t* Depacketizer::read_missing_samples_(sample_t* buff_ptr, sample_t* buff const size_t num_samples = (size_t)(buff_end - buff_ptr) / sample_spec_.num_channels(); - if (beep_) { - write_beep(buff_ptr, num_samples * sample_spec_.num_channels()); - } else { - write_zeros(buff_ptr, num_samples * sample_spec_.num_channels()); - } + memset(buff_ptr, 0, num_samples * sample_spec_.num_channels() * sizeof(sample_t)); stream_ts_ += (packet::stream_timestamp_t)num_samples; - if (first_packet_) { + if (!is_started_) { padding_samples_ += (packet::stream_timestamp_t)num_samples; } else { missing_samples_ += (packet::stream_timestamp_t)num_samples; @@ -221,24 +262,28 @@ sample_t* Depacketizer::read_missing_samples_(sample_t* buff_ptr, sample_t* buff return (buff_ptr + num_samples * sample_spec_.num_channels()); } -status::StatusCode Depacketizer::update_packet_(FrameStats& frame_stats) { - if (packet_) { - // Already have packet. +status::StatusCode Depacketizer::update_packet_(size_t requested_samples, + FrameReadMode mode, + FrameStats& stats) { + if (packet_) { // Already have packet. return status::StatusOK; } for (;;) { - const status::StatusCode code = fetch_packet_(); + status::StatusCode code = fetch_packet_(requested_samples, mode); if (code != status::StatusOK) { return code; } - if (start_packet_()) { + if ((code = start_packet_()) != status::StatusOK) { + return code; + } + if (packet_) { break; } - // Try next packet. - frame_stats.n_dropped_packets++; + // Packet dropped, try another one. + stats.n_dropped_packets++; } roc_panic_if(!packet_); @@ -246,25 +291,63 @@ status::StatusCode Depacketizer::update_packet_(FrameStats& frame_stats) { return status::StatusOK; } -status::StatusCode Depacketizer::fetch_packet_() { - packet::PacketPtr pp; - const status::StatusCode code = packet_reader_.read(pp, packet::ModeFetch); +status::StatusCode Depacketizer::fetch_packet_(size_t requested_samples, + FrameReadMode mode) { + roc_panic_if(packet_); + // Disable soft reads until we initialize stream timestamps. + if (!is_started_ && mode == ModeSoft) { + return status::StatusDrain; + } + + if (is_started_) { + // Region which we want to decode. + const packet::stream_timestamp_t frame_begin = stream_ts_; + const packet::stream_timestamp_t frame_end = stream_ts_ + + packet::stream_timestamp_t(requested_samples / sample_spec_.num_channels()); + + // Get packet without removing it from queue. + packet::PacketPtr pkt; + const status::StatusCode code = packet_reader_.read(pkt, packet::ModePeek); + if (code != status::StatusOK && code != status::StatusDrain) { + roc_log(LogError, "depacketizer: failed to read packet: mode=peek status=%s", + status::code_to_str(code)); + return code; + } + + // In soft read mode, if there is a gap between current timestamp and next + // available packet (or there is no packet), stop reading. + if (mode == ModeSoft + && (!pkt + || packet::stream_timestamp_lt(frame_begin, pkt->stream_timestamp()))) { + return status::StatusDrain; + } + + // If next available packet is outside of the decode range, there is no need + // to fetch it now. We should give a chance for more packets to arrive. + if (pkt && packet::stream_timestamp_le(frame_end, pkt->stream_timestamp())) { + return status::StatusDrain; + } + } + + // The packet is viable, fetch it. + packet::PacketPtr pkt; + const status::StatusCode code = packet_reader_.read(pkt, packet::ModeFetch); if (code != status::StatusOK) { if (code != status::StatusDrain) { - roc_log(LogError, "depacketizer: failed to read packet: status=%s", + roc_log(LogError, "depacketizer: failed to read packet: mode=fetch status=%s", status::code_to_str(code)); } return code; } - packet_ = pp; + packet_ = pkt; fetched_packets_++; - return status::StatusOK; + return code; } -bool Depacketizer::start_packet_() { +status::StatusCode Depacketizer::start_packet_() { roc_panic_if(!packet_); payload_decoder_.begin_frame(packet_->stream_timestamp(), packet_->payload().data(), @@ -273,7 +356,15 @@ bool Depacketizer::start_packet_() { const packet::stream_timestamp_t pkt_begin = payload_decoder_.position(); const packet::stream_timestamp_t pkt_end = pkt_begin + payload_decoder_.available(); - if (!first_packet_ && !packet::stream_timestamp_lt(stream_ts_, pkt_end)) { + // If packet ends before current stream position, drop the whole packet. + // + // stream_ts_ + // ↓ + // Frame |■■■■■•••••••••••| + // pkt_end + // ↓ + // Packet |□□□□□□□□□□□□□□| + if (is_started_ && packet::stream_timestamp_le(pkt_end, stream_ts_)) { roc_log(LogTrace, "depacketizer: dropping late packet: stream_ts=%lu pkt_ts=%lu", (unsigned long)stream_ts_, (unsigned long)pkt_begin); @@ -282,7 +373,7 @@ bool Depacketizer::start_packet_() { payload_decoder_.end_frame(); packet_ = NULL; - return false; + return status::StatusOK; } next_capture_ts_ = packet_->capture_timestamp(); @@ -290,16 +381,23 @@ bool Depacketizer::start_packet_() { valid_capture_ts_ = true; } - if (first_packet_) { + if (!is_started_) { roc_log(LogDebug, "depacketizer: got first packet: padding_samples=%lu", (unsigned long)padding_samples_); stream_ts_ = pkt_begin; - first_packet_ = false; + is_started_ = true; } - // Packet |-----------------| - // NextFrame |----------------| + // If packet begins before current stream position, drop samples from + // the beginning of the packet. + // + // stream_ts_ + // ↓ + // Frame |•••••■■■■■•••••••| + // pkt_begin + // ↓ + // Packet |□□□□□□□□□■■■■■| if (packet::stream_timestamp_lt(pkt_begin, stream_ts_)) { const size_t diff_samples = (size_t)packet::stream_timestamp_diff(stream_ts_, pkt_begin); @@ -312,26 +410,35 @@ bool Depacketizer::start_packet_() { } } - return true; + return status::StatusOK; } -void Depacketizer::commit_frame_(Frame& frame, const FrameStats& frame_stats) { - unsigned flags = 0; +void Depacketizer::commit_frame_(Frame& frame, + size_t frame_samples, + const FrameStats& frame_stats) { + roc_panic_if_msg(frame_stats.n_written_samples + != frame_stats.n_decoded_samples + frame_stats.n_missing_samples, + "depacketizer: incorrect sample counters"); + + roc_panic_if_msg(frame_stats.n_decoded_samples != 0 + && frame_stats.n_missing_samples != 0, + "depacketizer: incorrect sample counters"); + unsigned flags = 0; if (frame_stats.n_decoded_samples != 0) { flags |= Frame::HasSignal; } - - if (frame_stats.n_decoded_samples < frame.num_raw_samples()) { + if (frame_stats.n_missing_samples != 0) { flags |= Frame::HasGaps; } - if (frame_stats.n_dropped_packets != 0) { flags |= Frame::HasDrops; } frame.set_flags(flags); - frame.set_duration(frame.num_raw_samples() / sample_spec_.num_channels()); + frame.set_num_raw_samples(frame_samples); + frame.set_duration( + packet::stream_timestamp_t(frame_samples / sample_spec_.num_channels())); if (frame_stats.capture_ts > 0) { // Do not produce negative cts, which may happen when first packet was in @@ -340,7 +447,7 @@ void Depacketizer::commit_frame_(Frame& frame, const FrameStats& frame_stats) { } } -void Depacketizer::report_stats_() { +void Depacketizer::periodic_report_() { if (!rate_limiter_.allow()) { return; } diff --git a/src/internal_modules/roc_audio/depacketizer.h b/src/internal_modules/roc_audio/depacketizer.h index 04baf9785..611812195 100644 --- a/src/internal_modules/roc_audio/depacketizer.h +++ b/src/internal_modules/roc_audio/depacketizer.h @@ -36,12 +36,10 @@ class Depacketizer : public IFrameReader, public core::NonCopyable<> { //! - @p packet_reader is used to read packets //! - @p payload_decoder is used to extract samples from packets //! - @p sample_spec describes output frames - //! - @p beep enables weird beeps instead of silence on packet loss Depacketizer(packet::IReader& packet_reader, IFrameDecoder& payload_decoder, FrameFactory& frame_factory, - const SampleSpec& sample_spec, - bool beep); + const SampleSpec& sample_spec); //! Check if the object was successfully constructed. status::StatusCode init_status() const; @@ -59,39 +57,48 @@ class Depacketizer : public IFrameReader, public core::NonCopyable<> { packet::stream_timestamp_t next_timestamp() const; private: + // Statistics collected during decoding of one frame. struct FrameStats { - // Number of samples decoded from packets into the frame. + // Total number of samples written to frame. + size_t n_written_samples; + + // How much of all samples written to frame were decoded from packets. size_t n_decoded_samples; - // Number of samples filled out in the frame. - size_t n_filled_samples; + // How much of all samples written to frame were missing and zeroized. + size_t n_missing_samples; - // Number of packets dropped during frame construction. + // Number of packets dropped during decoding of this frame. size_t n_dropped_packets; // This frame first sample timestamp. core::nanoseconds_t capture_ts; FrameStats() - : n_decoded_samples(0) - , n_filled_samples(0) + : n_written_samples(0) + , n_decoded_samples(0) + , n_missing_samples(0) , n_dropped_packets(0) , capture_ts(0) { } }; - sample_t* read_samples_(sample_t* buff_ptr, sample_t* buff_end, FrameStats& stats); + sample_t* read_samples_(sample_t* buff_ptr, + sample_t* buff_end, + FrameReadMode mode, + FrameStats& stats); - sample_t* read_packet_samples_(sample_t* buff_ptr, sample_t* buff_end); + sample_t* read_decoded_samples_(sample_t* buff_ptr, sample_t* buff_end); sample_t* read_missing_samples_(sample_t* buff_ptr, sample_t* buff_end); - status::StatusCode update_packet_(FrameStats& frame_stats); - status::StatusCode fetch_packet_(); - bool start_packet_(); + status::StatusCode + update_packet_(size_t requested_samples, FrameReadMode mode, FrameStats& stats); + status::StatusCode fetch_packet_(size_t requested_samples, FrameReadMode mode); + status::StatusCode start_packet_(); - void commit_frame_(Frame& frame, const FrameStats& stats); + void commit_frame_(Frame& frame, size_t frame_samples, const FrameStats& stats); - void report_stats_(); + void periodic_report_(); FrameFactory& frame_factory_; packet::IReader& packet_reader_; @@ -106,17 +113,15 @@ class Depacketizer : public IFrameReader, public core::NonCopyable<> { bool valid_capture_ts_; size_t padding_samples_; - size_t missing_samples_; size_t decoded_samples_; + size_t missing_samples_; size_t fetched_packets_; size_t dropped_packets_; - core::RateLimiter rate_limiter_; - - const bool beep_; + bool is_started_; - bool first_packet_; + core::RateLimiter rate_limiter_; status::StatusCode init_status_; }; diff --git a/src/internal_modules/roc_pipeline/config.cpp b/src/internal_modules/roc_pipeline/config.cpp index af3b822ca..0bbd91cfd 100644 --- a/src/internal_modules/roc_pipeline/config.cpp +++ b/src/internal_modules/roc_pipeline/config.cpp @@ -44,8 +44,7 @@ void ReceiverCommonConfig::deduce_defaults() { } ReceiverSessionConfig::ReceiverSessionConfig() - : payload_type(0) - , enable_beeping(false) { + : payload_type(0) { } void ReceiverSessionConfig::deduce_defaults() { diff --git a/src/internal_modules/roc_pipeline/config.h b/src/internal_modules/roc_pipeline/config.h index 2076f8550..d033badb2 100644 --- a/src/internal_modules/roc_pipeline/config.h +++ b/src/internal_modules/roc_pipeline/config.h @@ -167,9 +167,6 @@ struct ReceiverSessionConfig { //! Resampler parameters. audio::ResamplerConfig resampler; - //! Insert weird beeps instead of silence on packet loss. - bool enable_beeping; - //! Initialize config. ReceiverSessionConfig(); diff --git a/src/internal_modules/roc_pipeline/receiver_session.cpp b/src/internal_modules/roc_pipeline/receiver_session.cpp index c3bc36bde..5e54e72d6 100644 --- a/src/internal_modules/roc_pipeline/receiver_session.cpp +++ b/src/internal_modules/roc_pipeline/receiver_session.cpp @@ -168,8 +168,7 @@ ReceiverSession::ReceiverSession(const ReceiverSessionConfig& session_config, pkt_encoding->sample_spec.channel_set()); depacketizer_.reset(new (depacketizer_) audio::Depacketizer( - *pkt_reader, *payload_decoder_, frame_factory, out_spec, - session_config.enable_beeping)); + *pkt_reader, *payload_decoder_, frame_factory, out_spec)); if ((init_status_ = depacketizer_->init_status()) != status::StatusOK) { return; } diff --git a/src/internal_modules/roc_rtp/timestamp_injector.cpp b/src/internal_modules/roc_rtp/timestamp_injector.cpp index 251d3a0dd..6b7de9250 100644 --- a/src/internal_modules/roc_rtp/timestamp_injector.cpp +++ b/src/internal_modules/roc_rtp/timestamp_injector.cpp @@ -46,11 +46,6 @@ status::StatusCode TimestampInjector::read(packet::PacketPtr& pkt, roc_panic("timestamp injector: unexpected non-rtp packet"); } - if (pkt->rtp()->capture_timestamp != 0) { - roc_panic("timestamp injector: unexpected non-zero cts in packet: %lld", - (long long)pkt->rtp()->capture_timestamp); - } - if (has_ts_) { const packet::stream_timestamp_diff_t rtp_dn = packet::stream_timestamp_diff(pkt->rtp()->stream_timestamp, rtp_ts_); diff --git a/src/tests/roc_audio/test_depacketizer.cpp b/src/tests/roc_audio/test_depacketizer.cpp index db15bc9e9..c30d60d63 100644 --- a/src/tests/roc_audio/test_depacketizer.cpp +++ b/src/tests/roc_audio/test_depacketizer.cpp @@ -208,7 +208,7 @@ TEST(depacketizer, one_packet_one_read) { PcmDecoder decoder(packet_spec); packet::FifoQueue queue; - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); write_packet(queue, new_packet(encoder, 0, 0.11f, Now)); @@ -221,7 +221,7 @@ TEST(depacketizer, one_packet_multiple_reads) { PcmDecoder decoder(packet_spec); packet::FifoQueue queue; - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); write_packet(queue, new_packet(encoder, 0, 0.11f, Now)); @@ -240,7 +240,7 @@ TEST(depacketizer, multiple_packets_one_read) { PcmDecoder decoder(packet_spec); packet::FifoQueue queue; - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); core::nanoseconds_t ts = Now; @@ -261,7 +261,7 @@ TEST(depacketizer, multiple_packets_multiple_reads) { PcmDecoder decoder(packet_spec); packet::FifoQueue queue; - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); // Start with a packet with zero capture timestamp. @@ -300,7 +300,7 @@ TEST(depacketizer, timestamp_overflow) { PcmDecoder decoder(packet_spec); packet::FifoQueue queue; - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); const packet::stream_timestamp_t ts2 = 0; @@ -327,7 +327,7 @@ TEST(depacketizer, drop_late_packets) { PcmDecoder decoder(packet_spec); packet::FifoQueue queue; - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); const packet::stream_timestamp_t ts1 = SamplesPerPacket * 2; @@ -350,7 +350,7 @@ TEST(depacketizer, drop_late_packets_timestamp_overflow) { PcmDecoder decoder(packet_spec); packet::FifoQueue queue; - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); const packet::stream_timestamp_t ts1 = 0; @@ -373,7 +373,7 @@ TEST(depacketizer, zeros_no_packets) { PcmDecoder decoder(packet_spec); packet::FifoQueue queue; - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); expect_output(dp, SamplesPerPacket, 0.00f, 0); @@ -384,7 +384,7 @@ TEST(depacketizer, zeros_no_next_packet) { PcmDecoder decoder(packet_spec); packet::FifoQueue queue; - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); write_packet(queue, new_packet(encoder, 0, 0.11f, 0)); @@ -398,7 +398,7 @@ TEST(depacketizer, zeros_between_packets) { PcmDecoder decoder(packet_spec); packet::FifoQueue queue; - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); const core::nanoseconds_t capt_ts1 = Now; @@ -417,7 +417,7 @@ TEST(depacketizer, zeros_between_packets_timestamp_overflow) { PcmDecoder decoder(packet_spec); packet::FifoQueue queue; - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); const packet::stream_timestamp_t ts2 = 0; @@ -442,29 +442,28 @@ TEST(depacketizer, zeros_after_packet) { CHECK(SamplesPerPacket % 2 == 0); packet::FifoQueue queue; - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); write_packet(queue, new_packet(encoder, 0, 0.11f, Now)); const size_t frame_ch = frame_spec.num_channels(); - const size_t sz1 = SamplesPerPacket / 2; - const size_t sz2 = SamplesPerPacket; - FramePtr f1 = frame_factory.allocate_frame_no_buffer(); FramePtr f2 = frame_factory.allocate_frame_no_buffer(); + FramePtr f3 = frame_factory.allocate_frame_no_buffer(); - LONGS_EQUAL(status::StatusOK, dp.read(*f1, sz1, ModeHard)); - LONGS_EQUAL(status::StatusOK, dp.read(*f2, sz2, ModeHard)); + LONGS_EQUAL(status::StatusOK, dp.read(*f1, SamplesPerPacket / 2, ModeHard)); + LONGS_EQUAL(status::StatusPart, dp.read(*f2, SamplesPerPacket, ModeHard)); + LONGS_EQUAL(status::StatusOK, dp.read(*f3, SamplesPerPacket, ModeHard)); - UNSIGNED_LONGS_EQUAL(sz1 * frame_ch, f1->num_raw_samples()); - UNSIGNED_LONGS_EQUAL(sz2 * frame_ch, f2->num_raw_samples()); + UNSIGNED_LONGS_EQUAL(SamplesPerPacket / 2 * frame_ch, f1->num_raw_samples()); + UNSIGNED_LONGS_EQUAL(SamplesPerPacket / 2 * frame_ch, f2->num_raw_samples()); + UNSIGNED_LONGS_EQUAL(SamplesPerPacket * frame_ch, f3->num_raw_samples()); expect_values(f1->raw_samples(), SamplesPerPacket / 2 * frame_ch, 0.11f); expect_values(f2->raw_samples(), SamplesPerPacket / 2 * frame_ch, 0.11f); - expect_values(f2->raw_samples() + SamplesPerPacket / 2 * frame_ch, - SamplesPerPacket / 2 * frame_ch, 0.00f); + expect_values(f3->raw_samples(), SamplesPerPacket * frame_ch, 0.00f); } TEST(depacketizer, packet_after_zeros) { @@ -472,7 +471,7 @@ TEST(depacketizer, packet_after_zeros) { PcmDecoder decoder(packet_spec); packet::FifoQueue queue; - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); expect_output(dp, SamplesPerPacket, 0.00f, 0); @@ -489,7 +488,7 @@ TEST(depacketizer, overlapping_packets) { PcmDecoder decoder(packet_spec); packet::FifoQueue queue; - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); const packet::stream_timestamp_t ts1 = 0; @@ -509,7 +508,7 @@ TEST(depacketizer, overlapping_packets) { expect_output(dp, SamplesPerPacket / 2, 0.33f, Now + NsPerPacket * 3 / 2); } -TEST(depacketizer, frame_flags_incompltete_blank) { +IGNORE_TEST(depacketizer, frame_flags_incompltete_blank) { enum { PacketsPerFrame = 3 }; PcmEncoder encoder(packet_spec); @@ -578,7 +577,7 @@ TEST(depacketizer, frame_flags_incompltete_blank) { for (size_t n = 0; n < ROC_ARRAY_SIZE(packets); n++) { PcmDecoder decoder(packet_spec); - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); for (size_t p = 0; p < PacketsPerFrame; p++) { @@ -596,7 +595,7 @@ TEST(depacketizer, frame_flags_drops) { PcmDecoder decoder(packet_spec); packet::FifoQueue queue; - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); packet::PacketPtr packets[] = { @@ -640,7 +639,7 @@ TEST(depacketizer, timestamp) { PcmDecoder decoder(packet_spec); packet::FifoQueue queue; - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); core::nanoseconds_t capt_ts = 0; @@ -695,7 +694,7 @@ TEST(depacketizer, timestamp_fract_frame_per_packet) { PcmDecoder decoder(packet_spec); packet::FifoQueue queue; - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); core::nanoseconds_t capt_ts = @@ -719,7 +718,7 @@ TEST(depacketizer, timestamp_small_non_zero_cts) { PcmDecoder decoder(packet_spec); packet::FifoQueue queue; - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); // 1st packet in frame has 0 capture ts @@ -771,7 +770,7 @@ TEST(depacketizer, partial_on_big_read) { PcmDecoder decoder(packet_spec); packet::FifoQueue queue; - Depacketizer dp(queue, decoder, frame_factory, frame_spec, false); + Depacketizer dp(queue, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); core::nanoseconds_t pkt_cts = Now; @@ -794,7 +793,7 @@ TEST(depacketizer, forward_error) { packet::FifoQueue queue; StatusReader reader(queue); - Depacketizer dp(reader, decoder, frame_factory, frame_spec, false); + Depacketizer dp(reader, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); // push one packet @@ -834,7 +833,7 @@ TEST(depacketizer, preallocated_buffer) { packet::FifoQueue queue; StatusReader reader(queue); - Depacketizer dp(reader, decoder, frame_factory, frame_spec, false); + Depacketizer dp(reader, decoder, frame_factory, frame_spec); LONGS_EQUAL(status::StatusOK, dp.init_status()); FrameFactory mock_factory(arena, orig_buf_sz * sizeof(sample_t)); diff --git a/src/tools/roc_recv/cmdline.ggo b/src/tools/roc_recv/cmdline.ggo index dc818a26b..bb07b9c1b 100644 --- a/src/tools/roc_recv/cmdline.ggo +++ b/src/tools/roc_recv/cmdline.ggo @@ -73,8 +73,6 @@ section "Options" option "profiling" - "Enable self-profiling" flag off - option "beep" - "Enable beeping on packet loss" flag off - option "color" - "Set colored logging mode for stderr output" values="auto","always","never" default="auto" enum optional diff --git a/src/tools/roc_recv/main.cpp b/src/tools/roc_recv/main.cpp index ef07333be..f88621afc 100644 --- a/src/tools/roc_recv/main.cpp +++ b/src/tools/roc_recv/main.cpp @@ -223,7 +223,6 @@ int main(int argc, char** argv) { break; } - receiver_config.session_defaults.enable_beeping = args.beep_flag; receiver_config.common.enable_profiling = args.profiling_flag; node::ContextConfig context_config;