2013-01-29 12:09:21 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* Use of this source code is governed by a BSD-style license
|
|
|
|
|
* that can be found in the LICENSE file in the root of the source
|
|
|
|
|
* tree. An additional intellectual property rights grant can be found
|
|
|
|
|
* in the file PATENTS. All contributing project authors may
|
|
|
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
|
|
|
*/
|
|
|
|
|
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "modules/audio_coding/neteq/neteq_impl.h"
|
2013-01-29 12:09:21 +00:00
|
|
|
|
|
|
|
|
#include <algorithm>
|
2018-10-23 12:03:01 +02:00
|
|
|
#include <cstdint>
|
|
|
|
|
#include <cstring>
|
|
|
|
|
#include <list>
|
Reland "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
This reverts commit fab3460a821abe336ab610c6d6dfc0d392dac263.
Reason for revert: fix downstream instead
Original change's description:
> Revert "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
>
> This reverts commit 9973933d2e606d64fcdc753acb9ba3afd6e30569.
>
> Reason for revert: breaking downstream projects and not reviewed by direct owners
>
> Original change's description:
> > Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> >
> > This reverts commit 24192c267a40eb7d6b1850489ccdbf7a84f8ff0f.
> >
> > Reason for revert: Analyzed the performance regression in more detail.
> >
> > Most of the regression comes from the extra RtpPacketInfos-related memory allocations in every `NetEq::GetAudio()` call. Commit 1796a820f60cb9429bf4bcf13a40a41794ac8fb0 has removed roughly 2/3rds of the extra allocations from the impacted perf tests. Remaining perf impact is expected to be about "8 microseconds of CPU time per second" on the Linux benchmarking machines and "15 us per second" on Windows/Mac.
> >
> > There are options to optimize further but they are unlikely worth doing. Note for example that `NetEqPerformanceTest` uses the PCM codec while the real-world use cases would likely use the much heavier Opus codec. The numbers from `OpusSpeedTest` and `NetEqPerformanceTest` suggest that Opus decoding is about 10x as expensive as NetEq overall.
> >
> > Original change's description:
> > > Revert "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> > >
> > > This reverts commit 3e8ef940fe86cf6285afb80e68d2a0bedc631b9f.
> > >
> > > Reason for revert: This CL causes a performance regression in NetEq, see https://bugs.chromium.org/p/chromium/issues/detail?id=982260.
> > >
> > > Original change's description:
> > > > Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.
> > > >
> > > > This change adds the plumbing of RtpPacketInfo from ChannelReceive::OnRtpPacket() to ChannelReceive::GetAudioFrameWithInfo() for audio. It is a step towards replacing the non-spec compliant ContributingSources that updates itself at packet-receive time, with the spec-compliant SourceTracker that will update itself at frame-delivery-to-track time.
> > > >
> > > > Bug: webrtc:10668
> > > > Change-Id: I03385d6865bbc7bfbef7634f88de820a934f787a
> > > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/139890
> > > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > > Reviewed-by: Minyue Li <minyue@webrtc.org>
> > > > Commit-Queue: Chen Xing <chxg@google.com>
> > > > Cr-Commit-Position: refs/heads/master@{#28434}
> > >
> > > TBR=kwiberg@webrtc.org,stefan@webrtc.org,minyue@webrtc.org,chxg@google.com
> > >
> > > Bug: webrtc:10668, chromium:982260
> > > Change-Id: I5e2cfde78c59d1123e21869564d76ed3f6193a5c
> > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/145339
> > > Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
> > > Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#28561}
> >
> > TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
> >
> > # Not skipping CQ checks because original CL landed > 1 day ago.
> >
> > Bug: webrtc:10668, chromium:982260
> > Change-Id: Ie375a0b327ee368317bf3a04b2f1415c3a974470
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146707
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Chen Xing <chxg@google.com>
> > Cr-Commit-Position: refs/heads/master@{#28664}
>
> TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
>
> Change-Id: I652cb0814d83b514d3bee34e65ca3bb693099b22
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: webrtc:10668, chromium:982260
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146712
> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
> Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#28671}
TBR=alessiob@webrtc.org,kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
Change-Id: Id43b7b3da79b4f48004b41767482bae1c1fa1e16
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:10668, chromium:982260
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146713
Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28672}
2019-07-24 16:47:02 +00:00
|
|
|
#include <map>
|
2021-09-14 15:17:23 +00:00
|
|
|
#include <memory>
|
2016-09-20 01:38:00 -07:00
|
|
|
#include <utility>
|
2016-04-25 07:55:58 -07:00
|
|
|
#include <vector>
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "api/audio_codecs/audio_decoder.h"
|
2024-02-05 11:30:21 +01:00
|
|
|
#include "api/neteq/neteq_controller.h"
|
2019-10-31 14:38:11 +01:00
|
|
|
#include "api/neteq/tick_timer.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "common_audio/signal_processing/include/signal_processing_library.h"
|
2018-10-23 12:03:01 +02:00
|
|
|
#include "modules/audio_coding/codecs/cng/webrtc_cng.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "modules/audio_coding/neteq/accelerate.h"
|
|
|
|
|
#include "modules/audio_coding/neteq/background_noise.h"
|
|
|
|
|
#include "modules/audio_coding/neteq/comfort_noise.h"
|
|
|
|
|
#include "modules/audio_coding/neteq/decision_logic.h"
|
|
|
|
|
#include "modules/audio_coding/neteq/decoder_database.h"
|
|
|
|
|
#include "modules/audio_coding/neteq/dtmf_buffer.h"
|
|
|
|
|
#include "modules/audio_coding/neteq/dtmf_tone_generator.h"
|
|
|
|
|
#include "modules/audio_coding/neteq/expand.h"
|
|
|
|
|
#include "modules/audio_coding/neteq/merge.h"
|
|
|
|
|
#include "modules/audio_coding/neteq/nack_tracker.h"
|
|
|
|
|
#include "modules/audio_coding/neteq/normal.h"
|
|
|
|
|
#include "modules/audio_coding/neteq/packet.h"
|
|
|
|
|
#include "modules/audio_coding/neteq/packet_buffer.h"
|
|
|
|
|
#include "modules/audio_coding/neteq/preemptive_expand.h"
|
|
|
|
|
#include "modules/audio_coding/neteq/red_payload_splitter.h"
|
2019-03-05 16:59:03 +01:00
|
|
|
#include "modules/audio_coding/neteq/statistics_calculator.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "modules/audio_coding/neteq/sync_buffer.h"
|
2018-10-23 12:03:01 +02:00
|
|
|
#include "modules/audio_coding/neteq/time_stretch.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "modules/audio_coding/neteq/timestamp_scaler.h"
|
|
|
|
|
#include "rtc_base/checks.h"
|
|
|
|
|
#include "rtc_base/logging.h"
|
2017-11-22 10:42:26 +01:00
|
|
|
#include "rtc_base/numerics/safe_conversions.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "rtc_base/sanitizer.h"
|
2018-04-03 13:40:05 +02:00
|
|
|
#include "rtc_base/strings/audio_format_to_string.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "rtc_base/trace_event.h"
|
Reland "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
This reverts commit fab3460a821abe336ab610c6d6dfc0d392dac263.
Reason for revert: fix downstream instead
Original change's description:
> Revert "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
>
> This reverts commit 9973933d2e606d64fcdc753acb9ba3afd6e30569.
>
> Reason for revert: breaking downstream projects and not reviewed by direct owners
>
> Original change's description:
> > Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> >
> > This reverts commit 24192c267a40eb7d6b1850489ccdbf7a84f8ff0f.
> >
> > Reason for revert: Analyzed the performance regression in more detail.
> >
> > Most of the regression comes from the extra RtpPacketInfos-related memory allocations in every `NetEq::GetAudio()` call. Commit 1796a820f60cb9429bf4bcf13a40a41794ac8fb0 has removed roughly 2/3rds of the extra allocations from the impacted perf tests. Remaining perf impact is expected to be about "8 microseconds of CPU time per second" on the Linux benchmarking machines and "15 us per second" on Windows/Mac.
> >
> > There are options to optimize further but they are unlikely worth doing. Note for example that `NetEqPerformanceTest` uses the PCM codec while the real-world use cases would likely use the much heavier Opus codec. The numbers from `OpusSpeedTest` and `NetEqPerformanceTest` suggest that Opus decoding is about 10x as expensive as NetEq overall.
> >
> > Original change's description:
> > > Revert "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> > >
> > > This reverts commit 3e8ef940fe86cf6285afb80e68d2a0bedc631b9f.
> > >
> > > Reason for revert: This CL causes a performance regression in NetEq, see https://bugs.chromium.org/p/chromium/issues/detail?id=982260.
> > >
> > > Original change's description:
> > > > Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.
> > > >
> > > > This change adds the plumbing of RtpPacketInfo from ChannelReceive::OnRtpPacket() to ChannelReceive::GetAudioFrameWithInfo() for audio. It is a step towards replacing the non-spec compliant ContributingSources that updates itself at packet-receive time, with the spec-compliant SourceTracker that will update itself at frame-delivery-to-track time.
> > > >
> > > > Bug: webrtc:10668
> > > > Change-Id: I03385d6865bbc7bfbef7634f88de820a934f787a
> > > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/139890
> > > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > > Reviewed-by: Minyue Li <minyue@webrtc.org>
> > > > Commit-Queue: Chen Xing <chxg@google.com>
> > > > Cr-Commit-Position: refs/heads/master@{#28434}
> > >
> > > TBR=kwiberg@webrtc.org,stefan@webrtc.org,minyue@webrtc.org,chxg@google.com
> > >
> > > Bug: webrtc:10668, chromium:982260
> > > Change-Id: I5e2cfde78c59d1123e21869564d76ed3f6193a5c
> > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/145339
> > > Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
> > > Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#28561}
> >
> > TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
> >
> > # Not skipping CQ checks because original CL landed > 1 day ago.
> >
> > Bug: webrtc:10668, chromium:982260
> > Change-Id: Ie375a0b327ee368317bf3a04b2f1415c3a974470
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146707
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Chen Xing <chxg@google.com>
> > Cr-Commit-Position: refs/heads/master@{#28664}
>
> TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
>
> Change-Id: I652cb0814d83b514d3bee34e65ca3bb693099b22
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: webrtc:10668, chromium:982260
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146712
> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
> Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#28671}
TBR=alessiob@webrtc.org,kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
Change-Id: Id43b7b3da79b4f48004b41767482bae1c1fa1e16
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:10668, chromium:982260
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146713
Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28672}
2019-07-24 16:47:02 +00:00
|
|
|
#include "system_wrappers/include/clock.h"
|
2024-02-05 11:30:21 +01:00
|
|
|
#include "system_wrappers/include/field_trial.h"
|
2013-01-29 12:09:21 +00:00
|
|
|
|
|
|
|
|
namespace webrtc {
|
2019-10-24 15:20:39 +02:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<NetEqController> CreateNetEqController(
|
2019-10-31 14:38:11 +01:00
|
|
|
const NetEqControllerFactory& controller_factory,
|
2019-10-24 15:20:39 +02:00
|
|
|
int base_min_delay,
|
|
|
|
|
int max_packets_in_buffer,
|
|
|
|
|
bool allow_time_stretching,
|
2020-01-24 11:04:56 +01:00
|
|
|
TickTimer* tick_timer,
|
|
|
|
|
webrtc::Clock* clock) {
|
2019-10-24 15:20:39 +02:00
|
|
|
NetEqController::Config config;
|
|
|
|
|
config.base_min_delay_ms = base_min_delay;
|
|
|
|
|
config.max_packets_in_buffer = max_packets_in_buffer;
|
|
|
|
|
config.allow_time_stretching = allow_time_stretching;
|
|
|
|
|
config.tick_timer = tick_timer;
|
2020-01-24 11:04:56 +01:00
|
|
|
config.clock = clock;
|
2019-10-31 14:38:11 +01:00
|
|
|
return controller_factory.CreateNetEqController(config);
|
2019-10-24 15:20:39 +02:00
|
|
|
}
|
|
|
|
|
|
2024-02-07 15:17:39 +00:00
|
|
|
AudioFrame::SpeechType ToSpeechType(NetEqImpl::OutputType type) {
|
2023-11-27 13:20:27 +01:00
|
|
|
switch (type) {
|
|
|
|
|
case NetEqImpl::OutputType::kNormalSpeech: {
|
2024-02-07 15:17:39 +00:00
|
|
|
return AudioFrame::kNormalSpeech;
|
2023-11-27 13:20:27 +01:00
|
|
|
}
|
|
|
|
|
case NetEqImpl::OutputType::kCNG: {
|
2024-02-07 15:17:39 +00:00
|
|
|
return AudioFrame::kCNG;
|
2023-11-27 13:20:27 +01:00
|
|
|
}
|
|
|
|
|
case NetEqImpl::OutputType::kPLC: {
|
2024-02-07 15:17:39 +00:00
|
|
|
return AudioFrame::kPLC;
|
2023-11-27 13:20:27 +01:00
|
|
|
}
|
|
|
|
|
case NetEqImpl::OutputType::kPLCCNG: {
|
2024-02-07 15:17:39 +00:00
|
|
|
return AudioFrame::kPLCCNG;
|
2023-11-27 13:20:27 +01:00
|
|
|
}
|
|
|
|
|
case NetEqImpl::OutputType::kCodecPLC: {
|
2024-02-07 15:17:39 +00:00
|
|
|
return AudioFrame::kCodecPLC;
|
2023-11-27 13:20:27 +01:00
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
RTC_DCHECK_NOTREACHED();
|
2024-02-07 15:17:39 +00:00
|
|
|
return AudioFrame::kUndefined;
|
2023-11-27 13:20:27 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Returns true if both payload types are known to the decoder database, and
|
|
|
|
|
// have the same sample rate.
|
|
|
|
|
bool EqualSampleRates(uint8_t pt1,
|
|
|
|
|
uint8_t pt2,
|
|
|
|
|
const DecoderDatabase& decoder_database) {
|
|
|
|
|
auto* di1 = decoder_database.GetDecoderInfo(pt1);
|
|
|
|
|
auto* di2 = decoder_database.GetDecoderInfo(pt2);
|
|
|
|
|
return di1 && di2 && di1->SampleRateHz() == di2->SampleRateHz();
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-24 15:20:39 +02:00
|
|
|
} // namespace
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2016-05-25 07:37:43 -07:00
|
|
|
NetEqImpl::Dependencies::Dependencies(
|
|
|
|
|
const NetEq::Config& config,
|
Reland "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
This reverts commit fab3460a821abe336ab610c6d6dfc0d392dac263.
Reason for revert: fix downstream instead
Original change's description:
> Revert "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
>
> This reverts commit 9973933d2e606d64fcdc753acb9ba3afd6e30569.
>
> Reason for revert: breaking downstream projects and not reviewed by direct owners
>
> Original change's description:
> > Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> >
> > This reverts commit 24192c267a40eb7d6b1850489ccdbf7a84f8ff0f.
> >
> > Reason for revert: Analyzed the performance regression in more detail.
> >
> > Most of the regression comes from the extra RtpPacketInfos-related memory allocations in every `NetEq::GetAudio()` call. Commit 1796a820f60cb9429bf4bcf13a40a41794ac8fb0 has removed roughly 2/3rds of the extra allocations from the impacted perf tests. Remaining perf impact is expected to be about "8 microseconds of CPU time per second" on the Linux benchmarking machines and "15 us per second" on Windows/Mac.
> >
> > There are options to optimize further but they are unlikely worth doing. Note for example that `NetEqPerformanceTest` uses the PCM codec while the real-world use cases would likely use the much heavier Opus codec. The numbers from `OpusSpeedTest` and `NetEqPerformanceTest` suggest that Opus decoding is about 10x as expensive as NetEq overall.
> >
> > Original change's description:
> > > Revert "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> > >
> > > This reverts commit 3e8ef940fe86cf6285afb80e68d2a0bedc631b9f.
> > >
> > > Reason for revert: This CL causes a performance regression in NetEq, see https://bugs.chromium.org/p/chromium/issues/detail?id=982260.
> > >
> > > Original change's description:
> > > > Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.
> > > >
> > > > This change adds the plumbing of RtpPacketInfo from ChannelReceive::OnRtpPacket() to ChannelReceive::GetAudioFrameWithInfo() for audio. It is a step towards replacing the non-spec compliant ContributingSources that updates itself at packet-receive time, with the spec-compliant SourceTracker that will update itself at frame-delivery-to-track time.
> > > >
> > > > Bug: webrtc:10668
> > > > Change-Id: I03385d6865bbc7bfbef7634f88de820a934f787a
> > > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/139890
> > > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > > Reviewed-by: Minyue Li <minyue@webrtc.org>
> > > > Commit-Queue: Chen Xing <chxg@google.com>
> > > > Cr-Commit-Position: refs/heads/master@{#28434}
> > >
> > > TBR=kwiberg@webrtc.org,stefan@webrtc.org,minyue@webrtc.org,chxg@google.com
> > >
> > > Bug: webrtc:10668, chromium:982260
> > > Change-Id: I5e2cfde78c59d1123e21869564d76ed3f6193a5c
> > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/145339
> > > Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
> > > Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#28561}
> >
> > TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
> >
> > # Not skipping CQ checks because original CL landed > 1 day ago.
> >
> > Bug: webrtc:10668, chromium:982260
> > Change-Id: Ie375a0b327ee368317bf3a04b2f1415c3a974470
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146707
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Chen Xing <chxg@google.com>
> > Cr-Commit-Position: refs/heads/master@{#28664}
>
> TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
>
> Change-Id: I652cb0814d83b514d3bee34e65ca3bb693099b22
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: webrtc:10668, chromium:982260
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146712
> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
> Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#28671}
TBR=alessiob@webrtc.org,kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
Change-Id: Id43b7b3da79b4f48004b41767482bae1c1fa1e16
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:10668, chromium:982260
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146713
Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28672}
2019-07-24 16:47:02 +00:00
|
|
|
Clock* clock,
|
2019-10-31 14:38:11 +01:00
|
|
|
const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory,
|
|
|
|
|
const NetEqControllerFactory& controller_factory)
|
Reland "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
This reverts commit fab3460a821abe336ab610c6d6dfc0d392dac263.
Reason for revert: fix downstream instead
Original change's description:
> Revert "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
>
> This reverts commit 9973933d2e606d64fcdc753acb9ba3afd6e30569.
>
> Reason for revert: breaking downstream projects and not reviewed by direct owners
>
> Original change's description:
> > Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> >
> > This reverts commit 24192c267a40eb7d6b1850489ccdbf7a84f8ff0f.
> >
> > Reason for revert: Analyzed the performance regression in more detail.
> >
> > Most of the regression comes from the extra RtpPacketInfos-related memory allocations in every `NetEq::GetAudio()` call. Commit 1796a820f60cb9429bf4bcf13a40a41794ac8fb0 has removed roughly 2/3rds of the extra allocations from the impacted perf tests. Remaining perf impact is expected to be about "8 microseconds of CPU time per second" on the Linux benchmarking machines and "15 us per second" on Windows/Mac.
> >
> > There are options to optimize further but they are unlikely worth doing. Note for example that `NetEqPerformanceTest` uses the PCM codec while the real-world use cases would likely use the much heavier Opus codec. The numbers from `OpusSpeedTest` and `NetEqPerformanceTest` suggest that Opus decoding is about 10x as expensive as NetEq overall.
> >
> > Original change's description:
> > > Revert "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> > >
> > > This reverts commit 3e8ef940fe86cf6285afb80e68d2a0bedc631b9f.
> > >
> > > Reason for revert: This CL causes a performance regression in NetEq, see https://bugs.chromium.org/p/chromium/issues/detail?id=982260.
> > >
> > > Original change's description:
> > > > Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.
> > > >
> > > > This change adds the plumbing of RtpPacketInfo from ChannelReceive::OnRtpPacket() to ChannelReceive::GetAudioFrameWithInfo() for audio. It is a step towards replacing the non-spec compliant ContributingSources that updates itself at packet-receive time, with the spec-compliant SourceTracker that will update itself at frame-delivery-to-track time.
> > > >
> > > > Bug: webrtc:10668
> > > > Change-Id: I03385d6865bbc7bfbef7634f88de820a934f787a
> > > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/139890
> > > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > > Reviewed-by: Minyue Li <minyue@webrtc.org>
> > > > Commit-Queue: Chen Xing <chxg@google.com>
> > > > Cr-Commit-Position: refs/heads/master@{#28434}
> > >
> > > TBR=kwiberg@webrtc.org,stefan@webrtc.org,minyue@webrtc.org,chxg@google.com
> > >
> > > Bug: webrtc:10668, chromium:982260
> > > Change-Id: I5e2cfde78c59d1123e21869564d76ed3f6193a5c
> > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/145339
> > > Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
> > > Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#28561}
> >
> > TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
> >
> > # Not skipping CQ checks because original CL landed > 1 day ago.
> >
> > Bug: webrtc:10668, chromium:982260
> > Change-Id: Ie375a0b327ee368317bf3a04b2f1415c3a974470
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146707
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Chen Xing <chxg@google.com>
> > Cr-Commit-Position: refs/heads/master@{#28664}
>
> TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
>
> Change-Id: I652cb0814d83b514d3bee34e65ca3bb693099b22
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: webrtc:10668, chromium:982260
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146712
> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
> Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#28671}
TBR=alessiob@webrtc.org,kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
Change-Id: Id43b7b3da79b4f48004b41767482bae1c1fa1e16
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:10668, chromium:982260
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146713
Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28672}
2019-07-24 16:47:02 +00:00
|
|
|
: clock(clock),
|
|
|
|
|
tick_timer(new TickTimer),
|
2019-03-05 16:59:03 +01:00
|
|
|
stats(new StatisticsCalculator),
|
2018-03-20 19:18:55 +01:00
|
|
|
decoder_database(
|
|
|
|
|
new DecoderDatabase(decoder_factory, config.codec_pair_id)),
|
2016-04-26 12:19:34 -07:00
|
|
|
dtmf_buffer(new DtmfBuffer(config.sample_rate_hz)),
|
|
|
|
|
dtmf_tone_generator(new DtmfToneGenerator),
|
2023-11-07 10:10:47 +01:00
|
|
|
packet_buffer(new PacketBuffer(config.max_packets_in_buffer,
|
|
|
|
|
tick_timer.get(),
|
|
|
|
|
stats.get())),
|
2019-10-24 15:20:39 +02:00
|
|
|
neteq_controller(
|
2019-10-31 14:38:11 +01:00
|
|
|
CreateNetEqController(controller_factory,
|
|
|
|
|
config.min_delay_ms,
|
2019-10-24 15:20:39 +02:00
|
|
|
config.max_packets_in_buffer,
|
|
|
|
|
!config.for_test_no_time_stretching,
|
2020-01-24 11:04:56 +01:00
|
|
|
tick_timer.get(),
|
|
|
|
|
clock)),
|
2016-09-22 02:06:28 -07:00
|
|
|
red_payload_splitter(new RedPayloadSplitter),
|
2016-04-26 12:19:34 -07:00
|
|
|
timestamp_scaler(new TimestampScaler(*decoder_database)),
|
|
|
|
|
accelerate_factory(new AccelerateFactory),
|
|
|
|
|
expand_factory(new ExpandFactory),
|
|
|
|
|
preemptive_expand_factory(new PreemptiveExpandFactory) {}
|
|
|
|
|
|
|
|
|
|
NetEqImpl::Dependencies::~Dependencies() = default;
|
|
|
|
|
|
2014-08-07 12:27:37 +00:00
|
|
|
NetEqImpl::NetEqImpl(const NetEq::Config& config,
|
2016-04-26 12:19:34 -07:00
|
|
|
Dependencies&& deps,
|
2014-04-11 18:47:55 +00:00
|
|
|
bool create_components)
|
Reland "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
This reverts commit fab3460a821abe336ab610c6d6dfc0d392dac263.
Reason for revert: fix downstream instead
Original change's description:
> Revert "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
>
> This reverts commit 9973933d2e606d64fcdc753acb9ba3afd6e30569.
>
> Reason for revert: breaking downstream projects and not reviewed by direct owners
>
> Original change's description:
> > Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> >
> > This reverts commit 24192c267a40eb7d6b1850489ccdbf7a84f8ff0f.
> >
> > Reason for revert: Analyzed the performance regression in more detail.
> >
> > Most of the regression comes from the extra RtpPacketInfos-related memory allocations in every `NetEq::GetAudio()` call. Commit 1796a820f60cb9429bf4bcf13a40a41794ac8fb0 has removed roughly 2/3rds of the extra allocations from the impacted perf tests. Remaining perf impact is expected to be about "8 microseconds of CPU time per second" on the Linux benchmarking machines and "15 us per second" on Windows/Mac.
> >
> > There are options to optimize further but they are unlikely worth doing. Note for example that `NetEqPerformanceTest` uses the PCM codec while the real-world use cases would likely use the much heavier Opus codec. The numbers from `OpusSpeedTest` and `NetEqPerformanceTest` suggest that Opus decoding is about 10x as expensive as NetEq overall.
> >
> > Original change's description:
> > > Revert "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> > >
> > > This reverts commit 3e8ef940fe86cf6285afb80e68d2a0bedc631b9f.
> > >
> > > Reason for revert: This CL causes a performance regression in NetEq, see https://bugs.chromium.org/p/chromium/issues/detail?id=982260.
> > >
> > > Original change's description:
> > > > Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.
> > > >
> > > > This change adds the plumbing of RtpPacketInfo from ChannelReceive::OnRtpPacket() to ChannelReceive::GetAudioFrameWithInfo() for audio. It is a step towards replacing the non-spec compliant ContributingSources that updates itself at packet-receive time, with the spec-compliant SourceTracker that will update itself at frame-delivery-to-track time.
> > > >
> > > > Bug: webrtc:10668
> > > > Change-Id: I03385d6865bbc7bfbef7634f88de820a934f787a
> > > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/139890
> > > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > > Reviewed-by: Minyue Li <minyue@webrtc.org>
> > > > Commit-Queue: Chen Xing <chxg@google.com>
> > > > Cr-Commit-Position: refs/heads/master@{#28434}
> > >
> > > TBR=kwiberg@webrtc.org,stefan@webrtc.org,minyue@webrtc.org,chxg@google.com
> > >
> > > Bug: webrtc:10668, chromium:982260
> > > Change-Id: I5e2cfde78c59d1123e21869564d76ed3f6193a5c
> > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/145339
> > > Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
> > > Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#28561}
> >
> > TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
> >
> > # Not skipping CQ checks because original CL landed > 1 day ago.
> >
> > Bug: webrtc:10668, chromium:982260
> > Change-Id: Ie375a0b327ee368317bf3a04b2f1415c3a974470
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146707
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Chen Xing <chxg@google.com>
> > Cr-Commit-Position: refs/heads/master@{#28664}
>
> TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
>
> Change-Id: I652cb0814d83b514d3bee34e65ca3bb693099b22
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: webrtc:10668, chromium:982260
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146712
> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
> Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#28671}
TBR=alessiob@webrtc.org,kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
Change-Id: Id43b7b3da79b4f48004b41767482bae1c1fa1e16
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:10668, chromium:982260
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146713
Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28672}
2019-07-24 16:47:02 +00:00
|
|
|
: clock_(deps.clock),
|
|
|
|
|
tick_timer_(std::move(deps.tick_timer)),
|
2016-04-26 12:19:34 -07:00
|
|
|
decoder_database_(std::move(deps.decoder_database)),
|
|
|
|
|
dtmf_buffer_(std::move(deps.dtmf_buffer)),
|
|
|
|
|
dtmf_tone_generator_(std::move(deps.dtmf_tone_generator)),
|
|
|
|
|
packet_buffer_(std::move(deps.packet_buffer)),
|
2016-09-22 02:06:28 -07:00
|
|
|
red_payload_splitter_(std::move(deps.red_payload_splitter)),
|
2016-04-26 12:19:34 -07:00
|
|
|
timestamp_scaler_(std::move(deps.timestamp_scaler)),
|
|
|
|
|
expand_factory_(std::move(deps.expand_factory)),
|
|
|
|
|
accelerate_factory_(std::move(deps.accelerate_factory)),
|
|
|
|
|
preemptive_expand_factory_(std::move(deps.preemptive_expand_factory)),
|
2019-03-05 16:59:03 +01:00
|
|
|
stats_(std::move(deps.stats)),
|
2024-02-05 11:30:21 +01:00
|
|
|
enable_fec_delay_adaptation_(
|
|
|
|
|
!field_trial::IsDisabled("WebRTC-Audio-NetEqFecDelayAdaptation")),
|
2019-10-24 15:20:39 +02:00
|
|
|
controller_(std::move(deps.neteq_controller)),
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_(Mode::kNormal),
|
2013-01-29 12:09:21 +00:00
|
|
|
decoded_buffer_length_(kMaxFrameSize),
|
|
|
|
|
decoded_buffer_(new int16_t[decoded_buffer_length_]),
|
|
|
|
|
playout_timestamp_(0),
|
|
|
|
|
new_codec_(false),
|
|
|
|
|
timestamp_(0),
|
|
|
|
|
reset_decoder_(false),
|
|
|
|
|
first_packet_(true),
|
2015-05-27 14:33:29 +02:00
|
|
|
enable_fast_accelerate_(config.enable_fast_accelerate),
|
2016-05-12 13:51:28 -07:00
|
|
|
nack_enabled_(false),
|
2018-04-10 15:10:26 +02:00
|
|
|
enable_muted_state_(config.enable_muted_state),
|
|
|
|
|
expand_uma_logger_("WebRTC.Audio.ExpandRatePercent",
|
|
|
|
|
10, // Report once every 10 s.
|
|
|
|
|
tick_timer_.get()),
|
|
|
|
|
speech_expand_uma_logger_("WebRTC.Audio.SpeechExpandRatePercent",
|
|
|
|
|
10, // Report once every 10 s.
|
2018-07-02 10:14:46 +02:00
|
|
|
tick_timer_.get()),
|
2021-11-08 17:22:51 +01:00
|
|
|
no_time_stretching_(config.for_test_no_time_stretching) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_INFO) << "NetEq config: " << config.ToString();
|
2014-08-07 12:27:37 +00:00
|
|
|
int fs = config.sample_rate_hz;
|
2013-01-29 12:09:21 +00:00
|
|
|
if (fs != 8000 && fs != 16000 && fs != 32000 && fs != 48000) {
|
2020-01-14 12:11:31 +01:00
|
|
|
RTC_LOG(LS_ERROR) << "Sample rate " << fs
|
|
|
|
|
<< " Hz not supported. "
|
|
|
|
|
"Changing to 8000 Hz.";
|
2013-01-29 12:09:21 +00:00
|
|
|
fs = 8000;
|
|
|
|
|
}
|
2019-10-24 15:20:39 +02:00
|
|
|
controller_->SetMaximumDelay(config.max_delay_ms);
|
2013-01-29 12:09:21 +00:00
|
|
|
fs_hz_ = fs;
|
|
|
|
|
fs_mult_ = fs / 8000;
|
2015-11-23 06:49:25 -08:00
|
|
|
last_output_sample_rate_hz_ = fs;
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
output_size_samples_ = static_cast<size_t>(kOutputSizeMs * 8 * fs_mult_);
|
2019-10-24 15:20:39 +02:00
|
|
|
controller_->SetSampleRate(fs_hz_, output_size_samples_);
|
2019-11-29 13:32:12 +01:00
|
|
|
decoder_frame_length_ = 2 * output_size_samples_; // 20 ms.
|
2014-04-11 18:47:55 +00:00
|
|
|
if (create_components) {
|
|
|
|
|
SetSampleRateAndChannels(fs, 1); // Default is 1 channel.
|
|
|
|
|
}
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
Switch to base/logging.h in neteq_impl.cc
This change includes base/logging.h instead of the old and deprecated
system_wrappers/interface/logging.h. This requires some changes of the
actual logging invocations.
For reference the following regexps where used (in Eclipse) for a few
of the replacements:
find: LOG_FERR1\(\s*([^,]*),\s*([^,]*),\s*(.*)\);
replace: LOG($1) << "$2 " << $3;
find: LOG_FERR2\(\s*([^,]*),\s*([^,]*),\s*([^,]*),\s*(.*)\);
replace: LOG($1) << "$2 " << $3 << " " << $4;
BUG=4735
R=minyue@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/50229004 .
Cr-Commit-Position: refs/heads/master@{#9669}
2015-08-03 12:54:37 +02:00
|
|
|
NetEqImpl::~NetEqImpl() = default;
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2017-04-24 15:56:56 +02:00
|
|
|
int NetEqImpl::InsertPacket(const RTPHeader& rtp_header,
|
2019-10-10 14:23:00 +02:00
|
|
|
rtc::ArrayView<const uint8_t> payload) {
|
2016-09-02 00:39:33 -07:00
|
|
|
rtc::MsanCheckInitialized(payload);
|
2015-12-17 03:50:05 -08:00
|
|
|
TRACE_EVENT0("webrtc", "NetEqImpl::InsertPacket");
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2019-10-10 14:23:00 +02:00
|
|
|
if (InsertPacketInternal(rtp_header, payload) != 0) {
|
2014-01-09 14:01:55 +00:00
|
|
|
return kFail;
|
|
|
|
|
}
|
|
|
|
|
return kOK;
|
2013-09-26 00:27:56 +00:00
|
|
|
}
|
|
|
|
|
|
2021-09-09 10:09:28 +02:00
|
|
|
void NetEqImpl::InsertEmptyPacket(const RTPHeader& rtp_header) {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2021-09-09 10:09:28 +02:00
|
|
|
if (nack_enabled_) {
|
|
|
|
|
nack_->UpdateLastReceivedPacket(rtp_header.sequenceNumber,
|
|
|
|
|
rtp_header.timestamp);
|
|
|
|
|
}
|
2019-10-24 15:20:39 +02:00
|
|
|
controller_->RegisterEmptyPacket();
|
Handle padded audio packets correctly
RTP packets can be padded with extra data at the end of the payload. The usable
payload length of the packet should then be reduced with the padding length,
since the padding must be discarded. This was not the case; instead, the entire
payload, including padding data, was forwarded to the audio channel and in the
end to the decoder.
A special case of padding is packets which are empty except for the padding.
That is, they carry no usable payload. These packets are sometimes used for
probing the network and were discarded in
RTPReceiverAudio::ParseAudioCodecSpecific. The result is that NetEq never sees
those empty packets, just the holes in the sequence number series; this can
throw off the target buffer calculations.
With this change, the empty (after removing the padding) packets are let through,
all the way down to NetEq, to a new method called NetEq::InsertEmptyPacket. This
method notifies the DelayManager that an empty packet was received.
BUG=webrtc:7610, webrtc:7625
Review-Url: https://codereview.webrtc.org/2870043003
Cr-Commit-Position: refs/heads/master@{#18083}
2017-05-10 07:38:01 -07:00
|
|
|
}
|
|
|
|
|
|
2018-09-03 11:49:27 +02:00
|
|
|
int NetEqImpl::GetAudio(AudioFrame* audio_frame,
|
|
|
|
|
bool* muted,
|
2021-06-09 19:30:41 +02:00
|
|
|
int* current_sample_rate_hz,
|
2019-10-31 14:38:11 +01:00
|
|
|
absl::optional<Operation> action_override) {
|
2016-01-08 03:50:08 -08:00
|
|
|
TRACE_EVENT0("webrtc", "NetEqImpl::GetAudio");
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2018-09-03 11:49:27 +02:00
|
|
|
if (GetAudioInternal(audio_frame, muted, action_override) != 0) {
|
2013-01-29 12:09:21 +00:00
|
|
|
return kFail;
|
|
|
|
|
}
|
2016-08-24 11:18:49 -07:00
|
|
|
RTC_DCHECK_EQ(
|
|
|
|
|
audio_frame->sample_rate_hz_,
|
2017-03-01 18:52:48 -08:00
|
|
|
rtc::dchecked_cast<int>(audio_frame->samples_per_channel_ * 100));
|
2017-07-06 05:23:53 -07:00
|
|
|
RTC_DCHECK_EQ(*muted, audio_frame->muted());
|
2024-02-07 15:17:39 +00:00
|
|
|
audio_frame->speech_type_ = ToSpeechType(LastOutputType());
|
2016-03-04 10:34:21 -08:00
|
|
|
last_output_sample_rate_hz_ = audio_frame->sample_rate_hz_;
|
2015-11-23 06:49:25 -08:00
|
|
|
RTC_DCHECK(last_output_sample_rate_hz_ == 8000 ||
|
|
|
|
|
last_output_sample_rate_hz_ == 16000 ||
|
|
|
|
|
last_output_sample_rate_hz_ == 32000 ||
|
|
|
|
|
last_output_sample_rate_hz_ == 48000)
|
|
|
|
|
<< "Unexpected sample rate " << last_output_sample_rate_hz_;
|
2020-05-25 11:26:15 +02:00
|
|
|
|
2021-06-09 19:30:41 +02:00
|
|
|
if (current_sample_rate_hz) {
|
2021-11-08 17:22:51 +01:00
|
|
|
*current_sample_rate_hz = last_output_sample_rate_hz_;
|
2021-06-09 19:30:41 +02:00
|
|
|
}
|
|
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
return kOK;
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-27 07:15:49 -07:00
|
|
|
void NetEqImpl::SetCodecs(const std::map<int, SdpAudioFormat>& codecs) {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2017-03-27 07:15:49 -07:00
|
|
|
const std::vector<int> changed_payload_types =
|
|
|
|
|
decoder_database_->SetCodecs(codecs);
|
|
|
|
|
for (const int pt : changed_payload_types) {
|
2023-11-07 10:10:47 +01:00
|
|
|
packet_buffer_->DiscardPacketsWithPayloadType(pt);
|
2017-03-27 07:15:49 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-04 09:33:27 -07:00
|
|
|
bool NetEqImpl::RegisterPayloadType(int rtp_payload_type,
|
|
|
|
|
const SdpAudioFormat& audio_format) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_VERBOSE) << "NetEqImpl::RegisterPayloadType: payload type "
|
2018-04-03 13:40:05 +02:00
|
|
|
<< rtp_payload_type << ", codec "
|
|
|
|
|
<< rtc::ToString(audio_format);
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2017-06-14 12:29:03 +02:00
|
|
|
return decoder_database_->RegisterPayload(rtp_payload_type, audio_format) ==
|
|
|
|
|
DecoderDatabase::kOK;
|
2016-10-04 09:33:27 -07:00
|
|
|
}
|
|
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
int NetEqImpl::RemovePayloadType(uint8_t rtp_payload_type) {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2013-01-29 12:09:21 +00:00
|
|
|
int ret = decoder_database_->Remove(rtp_payload_type);
|
2017-06-14 12:29:03 +02:00
|
|
|
if (ret == DecoderDatabase::kOK || ret == DecoderDatabase::kDecoderNotFound) {
|
2023-11-07 10:10:47 +01:00
|
|
|
packet_buffer_->DiscardPacketsWithPayloadType(rtp_payload_type);
|
2013-01-29 12:09:21 +00:00
|
|
|
return kOK;
|
|
|
|
|
}
|
|
|
|
|
return kFail;
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-20 04:02:25 -07:00
|
|
|
void NetEqImpl::RemoveAllPayloadTypes() {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2016-09-20 04:02:25 -07:00
|
|
|
decoder_database_->RemoveAll();
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-16 23:44:24 +00:00
|
|
|
bool NetEqImpl::SetMinimumDelay(int delay_ms) {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2017-09-15 13:59:52 +02:00
|
|
|
if (delay_ms >= 0 && delay_ms <= 10000) {
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(controller_.get());
|
2021-11-08 17:22:51 +01:00
|
|
|
return controller_->SetMinimumDelay(delay_ms);
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-16 23:44:24 +00:00
|
|
|
bool NetEqImpl::SetMaximumDelay(int delay_ms) {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2017-09-15 13:59:52 +02:00
|
|
|
if (delay_ms >= 0 && delay_ms <= 10000) {
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(controller_.get());
|
2021-11-08 17:22:51 +01:00
|
|
|
return controller_->SetMaximumDelay(delay_ms);
|
2013-08-16 23:44:24 +00:00
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-05 13:49:26 +01:00
|
|
|
bool NetEqImpl::SetBaseMinimumDelayMs(int delay_ms) {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2019-02-05 13:49:26 +01:00
|
|
|
if (delay_ms >= 0 && delay_ms <= 10000) {
|
2019-10-24 15:20:39 +02:00
|
|
|
return controller_->SetBaseMinimumDelay(delay_ms);
|
2019-02-05 13:49:26 +01:00
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int NetEqImpl::GetBaseMinimumDelayMs() const {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2019-10-24 15:20:39 +02:00
|
|
|
return controller_->GetBaseMinimumDelay();
|
2019-02-05 13:49:26 +01:00
|
|
|
}
|
|
|
|
|
|
2017-11-29 09:14:04 +01:00
|
|
|
int NetEqImpl::TargetDelayMs() const {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2019-10-24 15:20:39 +02:00
|
|
|
RTC_DCHECK(controller_.get());
|
2021-11-08 17:22:51 +01:00
|
|
|
return controller_->TargetLevelMs();
|
2015-04-09 15:44:22 +02:00
|
|
|
}
|
|
|
|
|
|
2016-08-22 15:39:53 -07:00
|
|
|
int NetEqImpl::FilteredCurrentDelayMs() const {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2019-06-20 12:09:11 +00:00
|
|
|
// Sum up the filtered packet buffer level with the future length of the sync
|
2019-06-27 10:12:02 +02:00
|
|
|
// buffer.
|
2019-10-24 15:20:39 +02:00
|
|
|
const int delay_samples =
|
|
|
|
|
controller_->GetFilteredBufferLevel() + sync_buffer_->FutureLength();
|
2016-08-22 15:39:53 -07:00
|
|
|
// The division below will truncate. The return value is in ms.
|
2021-11-08 17:22:51 +01:00
|
|
|
return delay_samples / rtc::CheckedDivExact(fs_hz_, 1000);
|
2016-08-22 15:39:53 -07:00
|
|
|
}
|
|
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
int NetEqImpl::NetworkStatistics(NetEqNetworkStatistics* stats) {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(decoder_database_.get());
|
2020-09-14 10:47:50 +02:00
|
|
|
*stats = CurrentNetworkStatisticsInternal();
|
|
|
|
|
stats_->GetNetworkStatistics(decoder_frame_length_, stats);
|
2013-01-29 12:09:21 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-14 10:47:50 +02:00
|
|
|
NetEqNetworkStatistics NetEqImpl::CurrentNetworkStatistics() const {
|
|
|
|
|
MutexLock lock(&mutex_);
|
|
|
|
|
return CurrentNetworkStatisticsInternal();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NetEqNetworkStatistics NetEqImpl::CurrentNetworkStatisticsInternal() const {
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(decoder_database_.get());
|
2020-09-14 10:47:50 +02:00
|
|
|
NetEqNetworkStatistics stats;
|
|
|
|
|
const size_t total_samples_in_buffers =
|
|
|
|
|
packet_buffer_->NumSamplesInBuffer(decoder_frame_length_) +
|
|
|
|
|
sync_buffer_->FutureLength();
|
|
|
|
|
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(controller_.get());
|
2020-09-14 10:47:50 +02:00
|
|
|
stats.preferred_buffer_size_ms = controller_->TargetLevelMs();
|
|
|
|
|
stats.jitter_peaks_found = controller_->PeakFound();
|
|
|
|
|
RTC_DCHECK_GT(fs_hz_, 0);
|
|
|
|
|
stats.current_buffer_size_ms =
|
|
|
|
|
static_cast<uint16_t>(total_samples_in_buffers * 1000 / fs_hz_);
|
|
|
|
|
return stats;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-24 17:15:13 -07:00
|
|
|
NetEqLifetimeStatistics NetEqImpl::GetLifetimeStatistics() const {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2019-03-05 16:59:03 +01:00
|
|
|
return stats_->GetLifetimeStatistics();
|
2017-08-24 17:15:13 -07:00
|
|
|
}
|
|
|
|
|
|
2018-09-13 14:39:55 +02:00
|
|
|
NetEqOperationsAndState NetEqImpl::GetOperationsAndState() const {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2019-03-05 16:59:03 +01:00
|
|
|
auto result = stats_->GetOperationsAndState();
|
2018-09-13 14:39:55 +02:00
|
|
|
result.current_buffer_size_ms =
|
|
|
|
|
(packet_buffer_->NumSamplesInBuffer(decoder_frame_length_) +
|
|
|
|
|
sync_buffer_->FutureLength()) *
|
|
|
|
|
1000 / fs_hz_;
|
2018-09-27 11:43:42 +02:00
|
|
|
result.current_frame_size_ms = decoder_frame_length_ * 1000 / fs_hz_;
|
|
|
|
|
result.next_packet_available = packet_buffer_->PeekNextPacket() &&
|
|
|
|
|
packet_buffer_->PeekNextPacket()->timestamp ==
|
|
|
|
|
sync_buffer_->end_timestamp();
|
2018-09-13 14:39:55 +02:00
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-19 13:26:36 +02:00
|
|
|
absl::optional<uint32_t> NetEqImpl::GetPlayoutTimestamp() const {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2019-10-31 14:38:11 +01:00
|
|
|
if (first_packet_ || last_mode_ == Mode::kRfc3389Cng ||
|
|
|
|
|
last_mode_ == Mode::kCodecInternalCng) {
|
2014-06-05 20:34:08 +00:00
|
|
|
// We don't have a valid RTP timestamp until we have decoded our first
|
2016-04-06 12:28:26 -07:00
|
|
|
// RTP packet. Also, the RTP timestamp is not accurate while playing CNG,
|
|
|
|
|
// which is indicated by returning an empty value.
|
2018-06-19 13:26:36 +02:00
|
|
|
return absl::nullopt;
|
2014-06-05 20:34:08 +00:00
|
|
|
}
|
2021-11-08 17:22:51 +01:00
|
|
|
return timestamp_scaler_->ToExternal(playout_timestamp_);
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
2015-11-23 06:49:25 -08:00
|
|
|
int NetEqImpl::last_output_sample_rate_hz() const {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2021-11-08 17:22:51 +01:00
|
|
|
return last_output_sample_rate_hz_;
|
2015-11-23 06:49:25 -08:00
|
|
|
}
|
|
|
|
|
|
2019-10-11 09:37:42 +02:00
|
|
|
absl::optional<NetEq::DecoderFormat> NetEqImpl::GetDecoderFormat(
|
2016-09-23 02:19:43 -07:00
|
|
|
int payload_type) const {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2016-09-21 10:55:15 -07:00
|
|
|
const DecoderDatabase::DecoderInfo* const di =
|
|
|
|
|
decoder_database_->GetDecoderInfo(payload_type);
|
2019-10-11 09:37:42 +02:00
|
|
|
if (di) {
|
|
|
|
|
const AudioDecoder* const decoder = di->GetDecoder();
|
|
|
|
|
// TODO(kwiberg): Why the special case for RED?
|
|
|
|
|
return DecoderFormat{
|
|
|
|
|
/*sample_rate_hz=*/di->IsRed() ? 8000 : di->SampleRateHz(),
|
|
|
|
|
/*num_channels=*/
|
|
|
|
|
decoder ? rtc::dchecked_cast<int>(decoder->Channels()) : 1,
|
|
|
|
|
/*sdp_format=*/di->GetFormat()};
|
|
|
|
|
} else {
|
|
|
|
|
// Payload type not registered.
|
|
|
|
|
return absl::nullopt;
|
2016-09-21 10:55:15 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
void NetEqImpl::FlushBuffers() {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_VERBOSE) << "FlushBuffers";
|
2023-11-07 10:10:47 +01:00
|
|
|
packet_buffer_->Flush();
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(sync_buffer_.get());
|
|
|
|
|
RTC_DCHECK(expand_.get());
|
2013-01-29 12:09:21 +00:00
|
|
|
sync_buffer_->Flush();
|
|
|
|
|
sync_buffer_->set_next_index(sync_buffer_->next_index() -
|
|
|
|
|
expand_->overlap_length());
|
|
|
|
|
// Set to wait for new codec.
|
|
|
|
|
first_packet_ = true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-29 05:36:24 -07:00
|
|
|
void NetEqImpl::EnableNack(size_t max_nack_list_size) {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2015-10-29 05:36:24 -07:00
|
|
|
if (!nack_enabled_) {
|
2021-09-14 15:17:23 +00:00
|
|
|
nack_ = std::make_unique<NackTracker>();
|
2015-10-29 05:36:24 -07:00
|
|
|
nack_enabled_ = true;
|
|
|
|
|
nack_->UpdateSampleRate(fs_hz_);
|
|
|
|
|
}
|
|
|
|
|
nack_->SetMaxNackListSize(max_nack_list_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void NetEqImpl::DisableNack() {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2015-10-29 05:36:24 -07:00
|
|
|
nack_.reset();
|
|
|
|
|
nack_enabled_ = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<uint16_t> NetEqImpl::GetNackList(int64_t round_trip_time_ms) const {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2015-10-29 05:36:24 -07:00
|
|
|
if (!nack_enabled_) {
|
|
|
|
|
return std::vector<uint16_t>();
|
|
|
|
|
}
|
|
|
|
|
RTC_DCHECK(nack_.get());
|
|
|
|
|
return nack_->GetNackList(round_trip_time_ms);
|
2013-08-29 00:58:14 +00:00
|
|
|
}
|
|
|
|
|
|
2017-04-26 07:47:32 -07:00
|
|
|
int NetEqImpl::SyncBufferSizeMs() const {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2017-04-26 07:47:32 -07:00
|
|
|
return rtc::dchecked_cast<int>(sync_buffer_->FutureLength() /
|
|
|
|
|
rtc::CheckedDivExact(fs_hz_, 1000));
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-07 21:21:45 +00:00
|
|
|
const SyncBuffer* NetEqImpl::sync_buffer_for_test() const {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2014-04-07 21:21:45 +00:00
|
|
|
return sync_buffer_.get();
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-31 14:38:11 +01:00
|
|
|
NetEq::Operation NetEqImpl::last_operation_for_test() const {
|
2020-07-07 15:53:34 +02:00
|
|
|
MutexLock lock(&mutex_);
|
2016-05-02 04:46:11 -07:00
|
|
|
return last_operation_;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
// Methods below this line are private.
|
|
|
|
|
|
2017-04-24 15:56:56 +02:00
|
|
|
int NetEqImpl::InsertPacketInternal(const RTPHeader& rtp_header,
|
2019-10-10 14:23:00 +02:00
|
|
|
rtc::ArrayView<const uint8_t> payload) {
|
2015-11-11 10:34:00 -08:00
|
|
|
if (payload.empty()) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG_F(LS_ERROR) << "payload is empty";
|
2013-01-29 12:09:21 +00:00
|
|
|
return kInvalidPointer;
|
|
|
|
|
}
|
Reland "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
This reverts commit fab3460a821abe336ab610c6d6dfc0d392dac263.
Reason for revert: fix downstream instead
Original change's description:
> Revert "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
>
> This reverts commit 9973933d2e606d64fcdc753acb9ba3afd6e30569.
>
> Reason for revert: breaking downstream projects and not reviewed by direct owners
>
> Original change's description:
> > Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> >
> > This reverts commit 24192c267a40eb7d6b1850489ccdbf7a84f8ff0f.
> >
> > Reason for revert: Analyzed the performance regression in more detail.
> >
> > Most of the regression comes from the extra RtpPacketInfos-related memory allocations in every `NetEq::GetAudio()` call. Commit 1796a820f60cb9429bf4bcf13a40a41794ac8fb0 has removed roughly 2/3rds of the extra allocations from the impacted perf tests. Remaining perf impact is expected to be about "8 microseconds of CPU time per second" on the Linux benchmarking machines and "15 us per second" on Windows/Mac.
> >
> > There are options to optimize further but they are unlikely worth doing. Note for example that `NetEqPerformanceTest` uses the PCM codec while the real-world use cases would likely use the much heavier Opus codec. The numbers from `OpusSpeedTest` and `NetEqPerformanceTest` suggest that Opus decoding is about 10x as expensive as NetEq overall.
> >
> > Original change's description:
> > > Revert "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> > >
> > > This reverts commit 3e8ef940fe86cf6285afb80e68d2a0bedc631b9f.
> > >
> > > Reason for revert: This CL causes a performance regression in NetEq, see https://bugs.chromium.org/p/chromium/issues/detail?id=982260.
> > >
> > > Original change's description:
> > > > Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.
> > > >
> > > > This change adds the plumbing of RtpPacketInfo from ChannelReceive::OnRtpPacket() to ChannelReceive::GetAudioFrameWithInfo() for audio. It is a step towards replacing the non-spec compliant ContributingSources that updates itself at packet-receive time, with the spec-compliant SourceTracker that will update itself at frame-delivery-to-track time.
> > > >
> > > > Bug: webrtc:10668
> > > > Change-Id: I03385d6865bbc7bfbef7634f88de820a934f787a
> > > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/139890
> > > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > > Reviewed-by: Minyue Li <minyue@webrtc.org>
> > > > Commit-Queue: Chen Xing <chxg@google.com>
> > > > Cr-Commit-Position: refs/heads/master@{#28434}
> > >
> > > TBR=kwiberg@webrtc.org,stefan@webrtc.org,minyue@webrtc.org,chxg@google.com
> > >
> > > Bug: webrtc:10668, chromium:982260
> > > Change-Id: I5e2cfde78c59d1123e21869564d76ed3f6193a5c
> > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/145339
> > > Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
> > > Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#28561}
> >
> > TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
> >
> > # Not skipping CQ checks because original CL landed > 1 day ago.
> >
> > Bug: webrtc:10668, chromium:982260
> > Change-Id: Ie375a0b327ee368317bf3a04b2f1415c3a974470
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146707
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Chen Xing <chxg@google.com>
> > Cr-Commit-Position: refs/heads/master@{#28664}
>
> TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
>
> Change-Id: I652cb0814d83b514d3bee34e65ca3bb693099b22
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: webrtc:10668, chromium:982260
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146712
> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
> Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#28671}
TBR=alessiob@webrtc.org,kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
Change-Id: Id43b7b3da79b4f48004b41767482bae1c1fa1e16
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:10668, chromium:982260
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146713
Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28672}
2019-07-24 16:47:02 +00:00
|
|
|
|
2021-04-30 13:10:56 +02:00
|
|
|
Timestamp receive_time = clock_->CurrentTime();
|
2019-03-05 16:59:03 +01:00
|
|
|
stats_->ReceivedPacket();
|
2016-09-08 04:52:55 -07:00
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
PacketList packet_list;
|
2016-10-24 08:25:28 -07:00
|
|
|
// Insert packet in a packet list.
|
2023-06-07 19:18:18 +02:00
|
|
|
packet_list.push_back([&rtp_header, &payload] {
|
2013-01-30 07:37:20 +00:00
|
|
|
// Convert to Packet.
|
2016-10-24 08:25:28 -07:00
|
|
|
Packet packet;
|
2017-04-24 15:56:56 +02:00
|
|
|
packet.payload_type = rtp_header.payloadType;
|
|
|
|
|
packet.sequence_number = rtp_header.sequenceNumber;
|
|
|
|
|
packet.timestamp = rtp_header.timestamp;
|
2016-10-24 08:25:28 -07:00
|
|
|
packet.payload.SetData(payload.data(), payload.size());
|
2016-04-26 07:45:16 -07:00
|
|
|
// Waiting time will be set upon inserting the packet in the buffer.
|
2016-10-24 08:25:28 -07:00
|
|
|
RTC_DCHECK(!packet.waiting_time);
|
|
|
|
|
return packet;
|
|
|
|
|
}());
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2018-11-21 16:07:10 +01:00
|
|
|
bool update_sample_rate_and_channels = first_packet_;
|
2017-03-14 10:00:27 -07:00
|
|
|
|
|
|
|
|
if (update_sample_rate_and_channels) {
|
|
|
|
|
// Reset timestamp scaling.
|
|
|
|
|
timestamp_scaler_->Reset();
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-24 15:56:56 +02:00
|
|
|
if (!decoder_database_->IsRed(rtp_header.payloadType)) {
|
2017-03-14 10:00:27 -07:00
|
|
|
// Scale timestamp to internal domain (only for some codecs).
|
|
|
|
|
timestamp_scaler_->ToInternal(&packet_list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Store these for later use, since the first packet may very well disappear
|
|
|
|
|
// before we need these values.
|
|
|
|
|
uint32_t main_timestamp = packet_list.front().timestamp;
|
|
|
|
|
uint8_t main_payload_type = packet_list.front().payload_type;
|
|
|
|
|
uint16_t main_sequence_number = packet_list.front().sequence_number;
|
|
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
// Reinitialize NetEq if it's needed (changed SSRC or first call).
|
2017-03-14 10:00:27 -07:00
|
|
|
if (update_sample_rate_and_channels) {
|
2021-07-28 20:00:17 +02:00
|
|
|
// Note: `first_packet_` will be cleared further down in this method, once
|
2014-11-20 14:14:49 +00:00
|
|
|
// the packet has been successfully inserted into the packet buffer.
|
|
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
// Flush the packet buffer and DTMF buffer.
|
2023-11-07 10:10:47 +01:00
|
|
|
packet_buffer_->Flush();
|
2013-01-29 12:09:21 +00:00
|
|
|
dtmf_buffer_->Flush();
|
|
|
|
|
|
2013-03-27 18:31:42 +00:00
|
|
|
// Update audio buffer timestamp.
|
2017-03-14 10:00:27 -07:00
|
|
|
sync_buffer_->IncreaseEndTimestamp(main_timestamp - timestamp_);
|
2013-03-27 18:31:42 +00:00
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
// Update codecs.
|
2017-03-14 10:00:27 -07:00
|
|
|
timestamp_ = main_timestamp;
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
2016-10-18 04:06:13 -07:00
|
|
|
if (nack_enabled_) {
|
|
|
|
|
RTC_DCHECK(nack_);
|
|
|
|
|
if (update_sample_rate_and_channels) {
|
|
|
|
|
nack_->Reset();
|
|
|
|
|
}
|
2021-06-18 10:45:16 -07:00
|
|
|
nack_->UpdateLastReceivedPacket(main_sequence_number, main_timestamp);
|
2016-10-18 04:06:13 -07:00
|
|
|
}
|
2013-01-29 12:09:21 +00:00
|
|
|
|
|
|
|
|
// Check for RED payload type, and separate payloads into several packets.
|
2017-04-24 15:56:56 +02:00
|
|
|
if (decoder_database_->IsRed(rtp_header.payloadType)) {
|
2016-09-22 02:06:28 -07:00
|
|
|
if (!red_payload_splitter_->SplitRed(&packet_list)) {
|
2013-01-29 12:09:21 +00:00
|
|
|
return kRedundancySplitError;
|
|
|
|
|
}
|
|
|
|
|
// Only accept a few RED payloads of the same type as the main data,
|
|
|
|
|
// DTMF events and CNG.
|
2016-09-22 02:06:28 -07:00
|
|
|
red_payload_splitter_->CheckRedPayloads(&packet_list, *decoder_database_);
|
2018-07-03 13:07:30 +02:00
|
|
|
if (packet_list.empty()) {
|
|
|
|
|
return kRedundancySplitError;
|
|
|
|
|
}
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check payload types.
|
|
|
|
|
if (decoder_database_->CheckPayloadTypes(packet_list) ==
|
|
|
|
|
DecoderDatabase::kDecoderNotFound) {
|
|
|
|
|
return kUnknownRtpPayloadType;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-18 04:06:13 -07:00
|
|
|
RTC_DCHECK(!packet_list.empty());
|
|
|
|
|
|
2017-03-14 10:00:27 -07:00
|
|
|
// Update main_timestamp, if new packets appear in the list
|
|
|
|
|
// after RED splitting.
|
2017-04-24 15:56:56 +02:00
|
|
|
if (decoder_database_->IsRed(rtp_header.payloadType)) {
|
2017-03-14 10:00:27 -07:00
|
|
|
timestamp_scaler_->ToInternal(&packet_list);
|
|
|
|
|
main_timestamp = packet_list.front().timestamp;
|
|
|
|
|
main_payload_type = packet_list.front().payload_type;
|
|
|
|
|
main_sequence_number = packet_list.front().sequence_number;
|
|
|
|
|
}
|
2013-01-29 12:09:21 +00:00
|
|
|
|
|
|
|
|
// Process DTMF payloads. Cycle through the list of packets, and pick out any
|
|
|
|
|
// DTMF payloads found.
|
|
|
|
|
PacketList::iterator it = packet_list.begin();
|
|
|
|
|
while (it != packet_list.end()) {
|
2016-10-24 08:25:28 -07:00
|
|
|
const Packet& current_packet = (*it);
|
|
|
|
|
RTC_DCHECK(!current_packet.payload.empty());
|
|
|
|
|
if (decoder_database_->IsDtmf(current_packet.payload_type)) {
|
2013-08-06 05:36:26 +00:00
|
|
|
DtmfEvent event;
|
2016-10-24 08:25:28 -07:00
|
|
|
int ret = DtmfBuffer::ParseEvent(current_packet.timestamp,
|
|
|
|
|
current_packet.payload.data(),
|
|
|
|
|
current_packet.payload.size(), &event);
|
2013-08-06 05:36:26 +00:00
|
|
|
if (ret != DtmfBuffer::kOK) {
|
|
|
|
|
return kDtmfParsingError;
|
|
|
|
|
}
|
|
|
|
|
if (dtmf_buffer_->InsertEvent(event) != DtmfBuffer::kOK) {
|
|
|
|
|
return kDtmfInsertError;
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
it = packet_list.erase(it);
|
|
|
|
|
} else {
|
|
|
|
|
++it;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-20 01:38:00 -07:00
|
|
|
PacketList parsed_packet_list;
|
2020-10-14 17:54:22 +02:00
|
|
|
bool is_dtx = false;
|
2016-09-20 01:38:00 -07:00
|
|
|
while (!packet_list.empty()) {
|
2016-10-24 08:25:28 -07:00
|
|
|
Packet& packet = packet_list.front();
|
2016-09-20 01:38:00 -07:00
|
|
|
const DecoderDatabase::DecoderInfo* info =
|
2016-10-24 08:25:28 -07:00
|
|
|
decoder_database_->GetDecoderInfo(packet.payload_type);
|
2016-09-20 01:38:00 -07:00
|
|
|
if (!info) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_WARNING) << "SplitAudio unknown payload type";
|
2016-09-20 01:38:00 -07:00
|
|
|
return kUnknownRtpPayloadType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (info->IsComfortNoise()) {
|
|
|
|
|
// Carry comfort noise packets along.
|
2016-10-24 08:25:28 -07:00
|
|
|
parsed_packet_list.splice(parsed_packet_list.end(), packet_list,
|
|
|
|
|
packet_list.begin());
|
2016-09-20 01:38:00 -07:00
|
|
|
} else {
|
2023-06-07 19:18:18 +02:00
|
|
|
const uint16_t sequence_number = packet.sequence_number;
|
|
|
|
|
const uint8_t payload_type = packet.payload_type;
|
2016-10-24 08:25:28 -07:00
|
|
|
const Packet::Priority original_priority = packet.priority;
|
2018-06-19 15:03:05 +02:00
|
|
|
auto packet_from_result = [&](AudioDecoder::ParseResult& result) {
|
2016-10-24 08:25:28 -07:00
|
|
|
Packet new_packet;
|
|
|
|
|
new_packet.sequence_number = sequence_number;
|
|
|
|
|
new_packet.payload_type = payload_type;
|
|
|
|
|
new_packet.timestamp = result.timestamp;
|
|
|
|
|
new_packet.priority.codec_level = result.priority;
|
|
|
|
|
new_packet.priority.red_level = original_priority.red_level;
|
2023-06-07 19:18:18 +02:00
|
|
|
// Only associate the header information with the primary packet.
|
|
|
|
|
if (new_packet.timestamp == rtp_header.timestamp) {
|
|
|
|
|
new_packet.packet_info = RtpPacketInfo(rtp_header, receive_time);
|
|
|
|
|
}
|
2016-10-24 08:25:28 -07:00
|
|
|
new_packet.frame = std::move(result.frame);
|
|
|
|
|
return new_packet;
|
|
|
|
|
};
|
|
|
|
|
|
2016-09-20 01:38:00 -07:00
|
|
|
std::vector<AudioDecoder::ParseResult> results =
|
2016-10-24 08:25:28 -07:00
|
|
|
info->GetDecoder()->ParsePayload(std::move(packet.payload),
|
|
|
|
|
packet.timestamp);
|
|
|
|
|
if (results.empty()) {
|
|
|
|
|
packet_list.pop_front();
|
|
|
|
|
} else {
|
|
|
|
|
bool first = true;
|
|
|
|
|
for (auto& result : results) {
|
|
|
|
|
RTC_DCHECK(result.frame);
|
|
|
|
|
RTC_DCHECK_GE(result.priority, 0);
|
2020-10-14 17:54:22 +02:00
|
|
|
is_dtx = is_dtx || result.frame->IsDtxPacket();
|
2016-10-24 08:25:28 -07:00
|
|
|
if (first) {
|
|
|
|
|
// Re-use the node and move it to parsed_packet_list.
|
|
|
|
|
packet_list.front() = packet_from_result(result);
|
|
|
|
|
parsed_packet_list.splice(parsed_packet_list.end(), packet_list,
|
|
|
|
|
packet_list.begin());
|
|
|
|
|
first = false;
|
|
|
|
|
} else {
|
|
|
|
|
parsed_packet_list.push_back(packet_from_result(result));
|
|
|
|
|
}
|
2016-09-20 01:38:00 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-20 12:35:04 +02:00
|
|
|
// Calculate the number of primary (non-FEC/RED) packets.
|
2019-04-24 14:06:24 +02:00
|
|
|
const size_t number_of_primary_packets = std::count_if(
|
2017-10-20 12:35:04 +02:00
|
|
|
parsed_packet_list.begin(), parsed_packet_list.end(),
|
|
|
|
|
[](const Packet& in) { return in.priority.codec_level == 0; });
|
2019-04-24 14:06:24 +02:00
|
|
|
if (number_of_primary_packets < parsed_packet_list.size()) {
|
|
|
|
|
stats_->SecondaryPacketsReceived(parsed_packet_list.size() -
|
|
|
|
|
number_of_primary_packets);
|
|
|
|
|
}
|
2017-10-20 12:35:04 +02:00
|
|
|
|
2020-11-25 11:32:40 +01:00
|
|
|
bool buffer_flush_occured = false;
|
2023-11-27 13:20:27 +01:00
|
|
|
for (Packet& packet : parsed_packet_list) {
|
|
|
|
|
if (MaybeChangePayloadType(packet.payload_type)) {
|
|
|
|
|
packet_buffer_->Flush();
|
|
|
|
|
buffer_flush_occured = true;
|
|
|
|
|
}
|
2024-02-05 11:30:21 +01:00
|
|
|
NetEqController::PacketArrivedInfo info = ToPacketArrivedInfo(packet);
|
2023-11-27 13:20:27 +01:00
|
|
|
int return_val = packet_buffer_->InsertPacket(std::move(packet));
|
|
|
|
|
if (return_val == PacketBuffer::kFlushed) {
|
|
|
|
|
buffer_flush_occured = true;
|
|
|
|
|
} else if (return_val != PacketBuffer::kOK) {
|
|
|
|
|
// An error occurred.
|
|
|
|
|
return kOtherError;
|
|
|
|
|
}
|
2024-02-05 11:30:21 +01:00
|
|
|
if (enable_fec_delay_adaptation_) {
|
|
|
|
|
info.buffer_flush = buffer_flush_occured;
|
|
|
|
|
const bool should_update_stats = !new_codec_ && !buffer_flush_occured;
|
|
|
|
|
auto relative_delay =
|
|
|
|
|
controller_->PacketArrived(fs_hz_, should_update_stats, info);
|
|
|
|
|
if (relative_delay) {
|
|
|
|
|
stats_->RelativePacketArrivalDelay(relative_delay.value());
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-27 13:20:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (buffer_flush_occured) {
|
2013-01-29 12:09:21 +00:00
|
|
|
// Reset DSP timestamp etc. if packet buffer flushed.
|
|
|
|
|
new_codec_ = true;
|
2013-10-01 22:01:09 +00:00
|
|
|
update_sample_rate_and_channels = true;
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
2014-11-20 14:14:49 +00:00
|
|
|
|
|
|
|
|
if (first_packet_) {
|
|
|
|
|
first_packet_ = false;
|
|
|
|
|
// Update the codec on the next GetAudio call.
|
|
|
|
|
new_codec_ = true;
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-31 03:14:11 -07:00
|
|
|
if (current_rtp_payload_type_) {
|
|
|
|
|
RTC_DCHECK(decoder_database_->GetDecoderInfo(*current_rtp_payload_type_))
|
|
|
|
|
<< "Payload type " << static_cast<int>(*current_rtp_payload_type_)
|
|
|
|
|
<< " is unknown where it shouldn't be";
|
|
|
|
|
}
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2013-10-01 22:01:09 +00:00
|
|
|
if (update_sample_rate_and_channels && !packet_buffer_->Empty()) {
|
2021-07-28 20:00:17 +02:00
|
|
|
// We do not use `current_rtp_payload_type_` to |set payload_type|, but
|
|
|
|
|
// get the next RTP header from `packet_buffer_` to obtain the payload type.
|
2013-10-01 22:01:09 +00:00
|
|
|
// The reason for it is the following corner case. If NetEq receives a
|
|
|
|
|
// CNG packet with a sample rate different than the current CNG then it
|
|
|
|
|
// flushes its buffer, assuming send codec must have been changed. However,
|
|
|
|
|
// payload type of the hypothetically new send codec is not known.
|
2016-10-18 04:06:13 -07:00
|
|
|
const Packet* next_packet = packet_buffer_->PeekNextPacket();
|
|
|
|
|
RTC_DCHECK(next_packet);
|
|
|
|
|
const int payload_type = next_packet->payload_type;
|
2016-04-25 07:55:58 -07:00
|
|
|
size_t channels = 1;
|
|
|
|
|
if (!decoder_database_->IsComfortNoise(payload_type)) {
|
|
|
|
|
AudioDecoder* decoder = decoder_database_->GetDecoder(payload_type);
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(decoder); // Payloads are already checked to be valid.
|
2016-04-25 07:55:58 -07:00
|
|
|
channels = decoder->Channels();
|
|
|
|
|
}
|
2013-10-01 22:01:09 +00:00
|
|
|
const DecoderDatabase::DecoderInfo* decoder_info =
|
|
|
|
|
decoder_database_->GetDecoderInfo(payload_type);
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(decoder_info);
|
2016-05-31 06:28:03 -07:00
|
|
|
if (decoder_info->SampleRateHz() != fs_hz_ ||
|
2016-04-25 07:55:58 -07:00
|
|
|
channels != algorithm_buffer_->Channels()) {
|
2018-06-19 15:03:05 +02:00
|
|
|
SetSampleRateAndChannels(decoder_info->SampleRateHz(), channels);
|
2015-10-29 05:36:24 -07:00
|
|
|
}
|
|
|
|
|
if (nack_enabled_) {
|
|
|
|
|
RTC_DCHECK(nack_);
|
|
|
|
|
// Update the sample rate even if the rate is not new, because of Reset().
|
|
|
|
|
nack_->UpdateSampleRate(fs_hz_);
|
|
|
|
|
}
|
2013-10-01 22:01:09 +00:00
|
|
|
}
|
|
|
|
|
|
2024-02-05 11:30:21 +01:00
|
|
|
if (!enable_fec_delay_adaptation_) {
|
|
|
|
|
const DecoderDatabase::DecoderInfo* dec_info =
|
|
|
|
|
decoder_database_->GetDecoderInfo(main_payload_type);
|
|
|
|
|
RTC_DCHECK(dec_info); // Already checked that the payload type is known.
|
|
|
|
|
|
|
|
|
|
NetEqController::PacketArrivedInfo info;
|
|
|
|
|
info.is_cng_or_dtmf = dec_info->IsComfortNoise() || dec_info->IsDtmf();
|
|
|
|
|
info.packet_length_samples =
|
|
|
|
|
number_of_primary_packets * decoder_frame_length_;
|
|
|
|
|
info.main_timestamp = main_timestamp;
|
|
|
|
|
info.main_sequence_number = main_sequence_number;
|
|
|
|
|
info.is_dtx = is_dtx;
|
|
|
|
|
info.buffer_flush = buffer_flush_occured;
|
|
|
|
|
|
|
|
|
|
const bool should_update_stats = !new_codec_;
|
|
|
|
|
auto relative_delay =
|
|
|
|
|
controller_->PacketArrived(fs_hz_, should_update_stats, info);
|
|
|
|
|
if (relative_delay) {
|
|
|
|
|
stats_->RelativePacketArrivalDelay(relative_delay.value());
|
|
|
|
|
}
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-27 13:20:27 +01:00
|
|
|
bool NetEqImpl::MaybeChangePayloadType(uint8_t payload_type) {
|
|
|
|
|
bool changed = false;
|
|
|
|
|
if (decoder_database_->IsComfortNoise(payload_type)) {
|
|
|
|
|
if (current_cng_rtp_payload_type_ &&
|
|
|
|
|
*current_cng_rtp_payload_type_ != payload_type) {
|
|
|
|
|
// New CNG payload type implies new codec type.
|
|
|
|
|
current_rtp_payload_type_ = absl::nullopt;
|
|
|
|
|
changed = true;
|
|
|
|
|
}
|
|
|
|
|
current_cng_rtp_payload_type_ = payload_type;
|
|
|
|
|
} else if (!decoder_database_->IsDtmf(payload_type)) {
|
|
|
|
|
// This must be speech.
|
|
|
|
|
if ((current_rtp_payload_type_ &&
|
|
|
|
|
*current_rtp_payload_type_ != payload_type) ||
|
|
|
|
|
(current_cng_rtp_payload_type_ &&
|
|
|
|
|
!EqualSampleRates(payload_type, *current_cng_rtp_payload_type_,
|
|
|
|
|
*decoder_database_))) {
|
|
|
|
|
current_cng_rtp_payload_type_ = absl::nullopt;
|
|
|
|
|
changed = true;
|
|
|
|
|
}
|
|
|
|
|
current_rtp_payload_type_ = payload_type;
|
|
|
|
|
}
|
|
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-03 11:49:27 +02:00
|
|
|
int NetEqImpl::GetAudioInternal(AudioFrame* audio_frame,
|
|
|
|
|
bool* muted,
|
2019-10-31 14:38:11 +01:00
|
|
|
absl::optional<Operation> action_override) {
|
2013-01-29 12:09:21 +00:00
|
|
|
PacketList packet_list;
|
|
|
|
|
DtmfEvent dtmf_event;
|
2019-10-31 14:38:11 +01:00
|
|
|
Operation operation;
|
2013-01-29 12:09:21 +00:00
|
|
|
bool play_dtmf;
|
2016-05-12 13:51:28 -07:00
|
|
|
*muted = false;
|
Reland "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
This reverts commit fab3460a821abe336ab610c6d6dfc0d392dac263.
Reason for revert: fix downstream instead
Original change's description:
> Revert "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
>
> This reverts commit 9973933d2e606d64fcdc753acb9ba3afd6e30569.
>
> Reason for revert: breaking downstream projects and not reviewed by direct owners
>
> Original change's description:
> > Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> >
> > This reverts commit 24192c267a40eb7d6b1850489ccdbf7a84f8ff0f.
> >
> > Reason for revert: Analyzed the performance regression in more detail.
> >
> > Most of the regression comes from the extra RtpPacketInfos-related memory allocations in every `NetEq::GetAudio()` call. Commit 1796a820f60cb9429bf4bcf13a40a41794ac8fb0 has removed roughly 2/3rds of the extra allocations from the impacted perf tests. Remaining perf impact is expected to be about "8 microseconds of CPU time per second" on the Linux benchmarking machines and "15 us per second" on Windows/Mac.
> >
> > There are options to optimize further but they are unlikely worth doing. Note for example that `NetEqPerformanceTest` uses the PCM codec while the real-world use cases would likely use the much heavier Opus codec. The numbers from `OpusSpeedTest` and `NetEqPerformanceTest` suggest that Opus decoding is about 10x as expensive as NetEq overall.
> >
> > Original change's description:
> > > Revert "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> > >
> > > This reverts commit 3e8ef940fe86cf6285afb80e68d2a0bedc631b9f.
> > >
> > > Reason for revert: This CL causes a performance regression in NetEq, see https://bugs.chromium.org/p/chromium/issues/detail?id=982260.
> > >
> > > Original change's description:
> > > > Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.
> > > >
> > > > This change adds the plumbing of RtpPacketInfo from ChannelReceive::OnRtpPacket() to ChannelReceive::GetAudioFrameWithInfo() for audio. It is a step towards replacing the non-spec compliant ContributingSources that updates itself at packet-receive time, with the spec-compliant SourceTracker that will update itself at frame-delivery-to-track time.
> > > >
> > > > Bug: webrtc:10668
> > > > Change-Id: I03385d6865bbc7bfbef7634f88de820a934f787a
> > > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/139890
> > > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > > Reviewed-by: Minyue Li <minyue@webrtc.org>
> > > > Commit-Queue: Chen Xing <chxg@google.com>
> > > > Cr-Commit-Position: refs/heads/master@{#28434}
> > >
> > > TBR=kwiberg@webrtc.org,stefan@webrtc.org,minyue@webrtc.org,chxg@google.com
> > >
> > > Bug: webrtc:10668, chromium:982260
> > > Change-Id: I5e2cfde78c59d1123e21869564d76ed3f6193a5c
> > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/145339
> > > Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
> > > Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#28561}
> >
> > TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
> >
> > # Not skipping CQ checks because original CL landed > 1 day ago.
> >
> > Bug: webrtc:10668, chromium:982260
> > Change-Id: Ie375a0b327ee368317bf3a04b2f1415c3a974470
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146707
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Chen Xing <chxg@google.com>
> > Cr-Commit-Position: refs/heads/master@{#28664}
>
> TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
>
> Change-Id: I652cb0814d83b514d3bee34e65ca3bb693099b22
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: webrtc:10668, chromium:982260
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146712
> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
> Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#28671}
TBR=alessiob@webrtc.org,kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
Change-Id: Id43b7b3da79b4f48004b41767482bae1c1fa1e16
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:10668, chromium:982260
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146713
Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28672}
2019-07-24 16:47:02 +00:00
|
|
|
last_decoded_packet_infos_.clear();
|
2016-04-25 10:11:38 -07:00
|
|
|
tick_timer_->Increment();
|
2019-03-05 16:59:03 +01:00
|
|
|
stats_->IncreaseCounter(output_size_samples_, fs_hz_);
|
|
|
|
|
const auto lifetime_stats = stats_->GetLifetimeStatistics();
|
2018-04-10 15:10:26 +02:00
|
|
|
expand_uma_logger_.UpdateSampleCounter(lifetime_stats.concealed_samples,
|
|
|
|
|
fs_hz_);
|
|
|
|
|
speech_expand_uma_logger_.UpdateSampleCounter(
|
2019-04-24 14:06:24 +02:00
|
|
|
lifetime_stats.concealed_samples -
|
|
|
|
|
lifetime_stats.silent_concealed_samples,
|
|
|
|
|
fs_hz_);
|
2016-05-12 13:51:28 -07:00
|
|
|
|
|
|
|
|
// Check for muted state.
|
|
|
|
|
if (enable_muted_state_ && expand_->Muted() && packet_buffer_->Empty()) {
|
2019-10-31 14:38:11 +01:00
|
|
|
RTC_DCHECK_EQ(last_mode_, Mode::kExpand);
|
2017-07-06 05:23:53 -07:00
|
|
|
audio_frame->Reset();
|
|
|
|
|
RTC_DCHECK(audio_frame->muted()); // Reset() should mute the frame.
|
2016-05-12 13:51:28 -07:00
|
|
|
playout_timestamp_ += static_cast<uint32_t>(output_size_samples_);
|
|
|
|
|
audio_frame->sample_rate_hz_ = fs_hz_;
|
2021-11-24 12:32:07 +00:00
|
|
|
// Make sure the total number of samples fits in the AudioFrame.
|
|
|
|
|
if (output_size_samples_ * sync_buffer_->Channels() >
|
|
|
|
|
AudioFrame::kMaxDataSizeSamples) {
|
|
|
|
|
return kSampleUnderrun;
|
|
|
|
|
}
|
2021-11-23 17:00:51 +00:00
|
|
|
audio_frame->samples_per_channel_ = output_size_samples_;
|
2016-05-12 13:51:28 -07:00
|
|
|
audio_frame->timestamp_ =
|
|
|
|
|
first_packet_
|
|
|
|
|
? 0
|
|
|
|
|
: timestamp_scaler_->ToExternal(playout_timestamp_) -
|
|
|
|
|
static_cast<uint32_t>(audio_frame->samples_per_channel_);
|
|
|
|
|
audio_frame->num_channels_ = sync_buffer_->Channels();
|
2019-03-05 16:59:03 +01:00
|
|
|
stats_->ExpandedNoiseSamples(output_size_samples_, false);
|
2020-10-06 17:29:09 +02:00
|
|
|
controller_->NotifyMutedState();
|
2016-05-12 13:51:28 -07:00
|
|
|
*muted = true;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2018-09-03 11:49:27 +02:00
|
|
|
int return_value = GetDecision(&operation, &packet_list, &dtmf_event,
|
|
|
|
|
&play_dtmf, action_override);
|
2013-01-29 12:09:21 +00:00
|
|
|
if (return_value != 0) {
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kError;
|
2013-01-29 12:09:21 +00:00
|
|
|
return return_value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AudioDecoder::SpeechType speech_type;
|
|
|
|
|
int length = 0;
|
2017-11-02 12:09:06 +01:00
|
|
|
const size_t start_num_packets = packet_list.size();
|
2018-06-19 15:03:05 +02:00
|
|
|
int decode_return_value =
|
|
|
|
|
Decode(&packet_list, &operation, &length, &speech_type);
|
2023-03-29 15:42:19 +02:00
|
|
|
if (length > 0) {
|
|
|
|
|
last_decoded_type_ = speech_type;
|
|
|
|
|
}
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2019-10-31 14:38:11 +01:00
|
|
|
bool sid_frame_available =
|
|
|
|
|
(operation == Operation::kRfc3389Cng && !packet_list.empty());
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2017-11-02 12:09:06 +01:00
|
|
|
// This is the criterion that we did decode some data through the speech
|
|
|
|
|
// decoder, and the operation resulted in comfort noise.
|
|
|
|
|
const bool codec_internal_sid_frame =
|
2018-01-26 17:32:56 +01:00
|
|
|
(speech_type == AudioDecoder::kComfortNoise &&
|
|
|
|
|
start_num_packets > packet_list.size());
|
2017-11-02 12:09:06 +01:00
|
|
|
|
|
|
|
|
if (sid_frame_available || codec_internal_sid_frame) {
|
2016-05-03 08:18:47 -07:00
|
|
|
// Start a new stopwatch since we are decoding a new CNG packet.
|
|
|
|
|
generated_noise_stopwatch_ = tick_timer_->GetNewStopwatch();
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-02 07:59:30 +00:00
|
|
|
algorithm_buffer_->Clear();
|
2013-01-29 12:09:21 +00:00
|
|
|
switch (operation) {
|
2019-10-31 14:38:11 +01:00
|
|
|
case Operation::kNormal: {
|
2013-09-02 07:59:30 +00:00
|
|
|
DoNormal(decoded_buffer_.get(), length, speech_type, play_dtmf);
|
2019-04-26 09:47:07 +02:00
|
|
|
if (length > 0) {
|
|
|
|
|
stats_->DecodedOutputPlayed();
|
|
|
|
|
}
|
2013-01-29 12:09:21 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2019-10-31 14:38:11 +01:00
|
|
|
case Operation::kMerge: {
|
2013-09-02 07:59:30 +00:00
|
|
|
DoMerge(decoded_buffer_.get(), length, speech_type, play_dtmf);
|
2013-01-29 12:09:21 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2019-10-31 14:38:11 +01:00
|
|
|
case Operation::kExpand: {
|
2018-09-05 18:14:52 +02:00
|
|
|
RTC_DCHECK_EQ(return_value, 0);
|
|
|
|
|
if (!current_rtp_payload_type_ || !DoCodecPlc()) {
|
|
|
|
|
return_value = DoExpand(play_dtmf);
|
|
|
|
|
}
|
|
|
|
|
RTC_DCHECK_GE(sync_buffer_->FutureLength() - expand_->overlap_length(),
|
|
|
|
|
output_size_samples_);
|
2013-01-29 12:09:21 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2019-10-31 14:38:11 +01:00
|
|
|
case Operation::kAccelerate:
|
|
|
|
|
case Operation::kFastAccelerate: {
|
2015-05-27 14:33:29 +02:00
|
|
|
const bool fast_accelerate =
|
2019-10-31 14:38:11 +01:00
|
|
|
enable_fast_accelerate_ && (operation == Operation::kFastAccelerate);
|
2013-01-29 12:09:21 +00:00
|
|
|
return_value = DoAccelerate(decoded_buffer_.get(), length, speech_type,
|
2015-05-27 14:33:29 +02:00
|
|
|
play_dtmf, fast_accelerate);
|
2013-01-29 12:09:21 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2019-10-31 14:38:11 +01:00
|
|
|
case Operation::kPreemptiveExpand: {
|
2013-01-29 12:09:21 +00:00
|
|
|
return_value = DoPreemptiveExpand(decoded_buffer_.get(), length,
|
2013-09-02 07:59:30 +00:00
|
|
|
speech_type, play_dtmf);
|
2013-01-29 12:09:21 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2019-10-31 14:38:11 +01:00
|
|
|
case Operation::kRfc3389Cng:
|
|
|
|
|
case Operation::kRfc3389CngNoPacket: {
|
2013-09-02 07:59:30 +00:00
|
|
|
return_value = DoRfc3389Cng(&packet_list, play_dtmf);
|
2013-01-29 12:09:21 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2019-10-31 14:38:11 +01:00
|
|
|
case Operation::kCodecInternalCng: {
|
2013-01-29 12:09:21 +00:00
|
|
|
// This handles the case when there is no transmission and the decoder
|
|
|
|
|
// should produce internal comfort noise.
|
|
|
|
|
// TODO(hlundin): Write test for codec-internal CNG.
|
2015-09-23 15:20:39 +02:00
|
|
|
DoCodecInternalCng(decoded_buffer_.get(), length);
|
2013-01-29 12:09:21 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2019-10-31 14:38:11 +01:00
|
|
|
case Operation::kDtmf: {
|
2013-01-29 12:09:21 +00:00
|
|
|
// TODO(hlundin): Write test for this.
|
2013-09-02 07:59:30 +00:00
|
|
|
return_value = DoDtmf(dtmf_event, &play_dtmf);
|
2013-01-29 12:09:21 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2019-10-31 14:38:11 +01:00
|
|
|
case Operation::kUndefined: {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_ERROR) << "Invalid operation kUndefined.";
|
2021-11-15 16:57:07 +01:00
|
|
|
RTC_DCHECK_NOTREACHED(); // This should not happen.
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kError;
|
2013-01-29 12:09:21 +00:00
|
|
|
return kInvalidOperation;
|
|
|
|
|
}
|
|
|
|
|
} // End of switch.
|
2016-05-02 04:46:11 -07:00
|
|
|
last_operation_ = operation;
|
2013-01-29 12:09:21 +00:00
|
|
|
if (return_value < 0) {
|
|
|
|
|
return return_value;
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-31 14:38:11 +01:00
|
|
|
if (last_mode_ != Mode::kRfc3389Cng) {
|
2013-01-29 12:09:21 +00:00
|
|
|
comfort_noise_->Reset();
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-28 20:00:17 +02:00
|
|
|
// We treat it as if all packets referenced to by `last_decoded_packet_infos_`
|
|
|
|
|
// were mashed together when creating the samples in `algorithm_buffer_`.
|
2019-08-09 13:20:03 +02:00
|
|
|
RtpPacketInfos packet_infos(last_decoded_packet_infos_);
|
Reland "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
This reverts commit fab3460a821abe336ab610c6d6dfc0d392dac263.
Reason for revert: fix downstream instead
Original change's description:
> Revert "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
>
> This reverts commit 9973933d2e606d64fcdc753acb9ba3afd6e30569.
>
> Reason for revert: breaking downstream projects and not reviewed by direct owners
>
> Original change's description:
> > Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> >
> > This reverts commit 24192c267a40eb7d6b1850489ccdbf7a84f8ff0f.
> >
> > Reason for revert: Analyzed the performance regression in more detail.
> >
> > Most of the regression comes from the extra RtpPacketInfos-related memory allocations in every `NetEq::GetAudio()` call. Commit 1796a820f60cb9429bf4bcf13a40a41794ac8fb0 has removed roughly 2/3rds of the extra allocations from the impacted perf tests. Remaining perf impact is expected to be about "8 microseconds of CPU time per second" on the Linux benchmarking machines and "15 us per second" on Windows/Mac.
> >
> > There are options to optimize further but they are unlikely worth doing. Note for example that `NetEqPerformanceTest` uses the PCM codec while the real-world use cases would likely use the much heavier Opus codec. The numbers from `OpusSpeedTest` and `NetEqPerformanceTest` suggest that Opus decoding is about 10x as expensive as NetEq overall.
> >
> > Original change's description:
> > > Revert "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> > >
> > > This reverts commit 3e8ef940fe86cf6285afb80e68d2a0bedc631b9f.
> > >
> > > Reason for revert: This CL causes a performance regression in NetEq, see https://bugs.chromium.org/p/chromium/issues/detail?id=982260.
> > >
> > > Original change's description:
> > > > Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.
> > > >
> > > > This change adds the plumbing of RtpPacketInfo from ChannelReceive::OnRtpPacket() to ChannelReceive::GetAudioFrameWithInfo() for audio. It is a step towards replacing the non-spec compliant ContributingSources that updates itself at packet-receive time, with the spec-compliant SourceTracker that will update itself at frame-delivery-to-track time.
> > > >
> > > > Bug: webrtc:10668
> > > > Change-Id: I03385d6865bbc7bfbef7634f88de820a934f787a
> > > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/139890
> > > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > > Reviewed-by: Minyue Li <minyue@webrtc.org>
> > > > Commit-Queue: Chen Xing <chxg@google.com>
> > > > Cr-Commit-Position: refs/heads/master@{#28434}
> > >
> > > TBR=kwiberg@webrtc.org,stefan@webrtc.org,minyue@webrtc.org,chxg@google.com
> > >
> > > Bug: webrtc:10668, chromium:982260
> > > Change-Id: I5e2cfde78c59d1123e21869564d76ed3f6193a5c
> > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/145339
> > > Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
> > > Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#28561}
> >
> > TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
> >
> > # Not skipping CQ checks because original CL landed > 1 day ago.
> >
> > Bug: webrtc:10668, chromium:982260
> > Change-Id: Ie375a0b327ee368317bf3a04b2f1415c3a974470
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146707
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Chen Xing <chxg@google.com>
> > Cr-Commit-Position: refs/heads/master@{#28664}
>
> TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
>
> Change-Id: I652cb0814d83b514d3bee34e65ca3bb693099b22
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: webrtc:10668, chromium:982260
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146712
> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
> Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#28671}
TBR=alessiob@webrtc.org,kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
Change-Id: Id43b7b3da79b4f48004b41767482bae1c1fa1e16
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:10668, chromium:982260
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146713
Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28672}
2019-07-24 16:47:02 +00:00
|
|
|
|
2021-07-28 20:00:17 +02:00
|
|
|
// Copy samples from `algorithm_buffer_` to `sync_buffer_`.
|
Reland "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
This reverts commit fab3460a821abe336ab610c6d6dfc0d392dac263.
Reason for revert: fix downstream instead
Original change's description:
> Revert "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
>
> This reverts commit 9973933d2e606d64fcdc753acb9ba3afd6e30569.
>
> Reason for revert: breaking downstream projects and not reviewed by direct owners
>
> Original change's description:
> > Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> >
> > This reverts commit 24192c267a40eb7d6b1850489ccdbf7a84f8ff0f.
> >
> > Reason for revert: Analyzed the performance regression in more detail.
> >
> > Most of the regression comes from the extra RtpPacketInfos-related memory allocations in every `NetEq::GetAudio()` call. Commit 1796a820f60cb9429bf4bcf13a40a41794ac8fb0 has removed roughly 2/3rds of the extra allocations from the impacted perf tests. Remaining perf impact is expected to be about "8 microseconds of CPU time per second" on the Linux benchmarking machines and "15 us per second" on Windows/Mac.
> >
> > There are options to optimize further but they are unlikely worth doing. Note for example that `NetEqPerformanceTest` uses the PCM codec while the real-world use cases would likely use the much heavier Opus codec. The numbers from `OpusSpeedTest` and `NetEqPerformanceTest` suggest that Opus decoding is about 10x as expensive as NetEq overall.
> >
> > Original change's description:
> > > Revert "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> > >
> > > This reverts commit 3e8ef940fe86cf6285afb80e68d2a0bedc631b9f.
> > >
> > > Reason for revert: This CL causes a performance regression in NetEq, see https://bugs.chromium.org/p/chromium/issues/detail?id=982260.
> > >
> > > Original change's description:
> > > > Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.
> > > >
> > > > This change adds the plumbing of RtpPacketInfo from ChannelReceive::OnRtpPacket() to ChannelReceive::GetAudioFrameWithInfo() for audio. It is a step towards replacing the non-spec compliant ContributingSources that updates itself at packet-receive time, with the spec-compliant SourceTracker that will update itself at frame-delivery-to-track time.
> > > >
> > > > Bug: webrtc:10668
> > > > Change-Id: I03385d6865bbc7bfbef7634f88de820a934f787a
> > > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/139890
> > > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > > Reviewed-by: Minyue Li <minyue@webrtc.org>
> > > > Commit-Queue: Chen Xing <chxg@google.com>
> > > > Cr-Commit-Position: refs/heads/master@{#28434}
> > >
> > > TBR=kwiberg@webrtc.org,stefan@webrtc.org,minyue@webrtc.org,chxg@google.com
> > >
> > > Bug: webrtc:10668, chromium:982260
> > > Change-Id: I5e2cfde78c59d1123e21869564d76ed3f6193a5c
> > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/145339
> > > Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
> > > Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#28561}
> >
> > TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
> >
> > # Not skipping CQ checks because original CL landed > 1 day ago.
> >
> > Bug: webrtc:10668, chromium:982260
> > Change-Id: Ie375a0b327ee368317bf3a04b2f1415c3a974470
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146707
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Chen Xing <chxg@google.com>
> > Cr-Commit-Position: refs/heads/master@{#28664}
>
> TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
>
> Change-Id: I652cb0814d83b514d3bee34e65ca3bb693099b22
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: webrtc:10668, chromium:982260
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146712
> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
> Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#28671}
TBR=alessiob@webrtc.org,kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
Change-Id: Id43b7b3da79b4f48004b41767482bae1c1fa1e16
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:10668, chromium:982260
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146713
Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28672}
2019-07-24 16:47:02 +00:00
|
|
|
//
|
|
|
|
|
// TODO(bugs.webrtc.org/10757):
|
2021-07-28 20:00:17 +02:00
|
|
|
// We would in the future also like to pass `packet_infos` so that we can do
|
|
|
|
|
// sample-perfect tracking of that information across `sync_buffer_`.
|
2013-09-02 07:59:30 +00:00
|
|
|
sync_buffer_->PushBack(*algorithm_buffer_);
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2021-07-28 20:00:17 +02:00
|
|
|
// Extract data from `sync_buffer_` to `output`.
|
2013-09-20 16:25:28 +00:00
|
|
|
size_t num_output_samples_per_channel = output_size_samples_;
|
|
|
|
|
size_t num_output_samples = output_size_samples_ * sync_buffer_->Channels();
|
2016-03-04 10:34:21 -08:00
|
|
|
if (num_output_samples > AudioFrame::kMaxDataSizeSamples) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_WARNING) << "Output array is too short. "
|
|
|
|
|
<< AudioFrame::kMaxDataSizeSamples << " < "
|
|
|
|
|
<< output_size_samples_ << " * "
|
|
|
|
|
<< sync_buffer_->Channels();
|
2016-03-04 10:34:21 -08:00
|
|
|
num_output_samples = AudioFrame::kMaxDataSizeSamples;
|
|
|
|
|
num_output_samples_per_channel =
|
|
|
|
|
AudioFrame::kMaxDataSizeSamples / sync_buffer_->Channels();
|
|
|
|
|
}
|
|
|
|
|
sync_buffer_->GetNextAudioInterleaved(num_output_samples_per_channel,
|
|
|
|
|
audio_frame);
|
|
|
|
|
audio_frame->sample_rate_hz_ = fs_hz_;
|
Reland "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
This reverts commit fab3460a821abe336ab610c6d6dfc0d392dac263.
Reason for revert: fix downstream instead
Original change's description:
> Revert "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
>
> This reverts commit 9973933d2e606d64fcdc753acb9ba3afd6e30569.
>
> Reason for revert: breaking downstream projects and not reviewed by direct owners
>
> Original change's description:
> > Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> >
> > This reverts commit 24192c267a40eb7d6b1850489ccdbf7a84f8ff0f.
> >
> > Reason for revert: Analyzed the performance regression in more detail.
> >
> > Most of the regression comes from the extra RtpPacketInfos-related memory allocations in every `NetEq::GetAudio()` call. Commit 1796a820f60cb9429bf4bcf13a40a41794ac8fb0 has removed roughly 2/3rds of the extra allocations from the impacted perf tests. Remaining perf impact is expected to be about "8 microseconds of CPU time per second" on the Linux benchmarking machines and "15 us per second" on Windows/Mac.
> >
> > There are options to optimize further but they are unlikely worth doing. Note for example that `NetEqPerformanceTest` uses the PCM codec while the real-world use cases would likely use the much heavier Opus codec. The numbers from `OpusSpeedTest` and `NetEqPerformanceTest` suggest that Opus decoding is about 10x as expensive as NetEq overall.
> >
> > Original change's description:
> > > Revert "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> > >
> > > This reverts commit 3e8ef940fe86cf6285afb80e68d2a0bedc631b9f.
> > >
> > > Reason for revert: This CL causes a performance regression in NetEq, see https://bugs.chromium.org/p/chromium/issues/detail?id=982260.
> > >
> > > Original change's description:
> > > > Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.
> > > >
> > > > This change adds the plumbing of RtpPacketInfo from ChannelReceive::OnRtpPacket() to ChannelReceive::GetAudioFrameWithInfo() for audio. It is a step towards replacing the non-spec compliant ContributingSources that updates itself at packet-receive time, with the spec-compliant SourceTracker that will update itself at frame-delivery-to-track time.
> > > >
> > > > Bug: webrtc:10668
> > > > Change-Id: I03385d6865bbc7bfbef7634f88de820a934f787a
> > > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/139890
> > > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > > Reviewed-by: Minyue Li <minyue@webrtc.org>
> > > > Commit-Queue: Chen Xing <chxg@google.com>
> > > > Cr-Commit-Position: refs/heads/master@{#28434}
> > >
> > > TBR=kwiberg@webrtc.org,stefan@webrtc.org,minyue@webrtc.org,chxg@google.com
> > >
> > > Bug: webrtc:10668, chromium:982260
> > > Change-Id: I5e2cfde78c59d1123e21869564d76ed3f6193a5c
> > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/145339
> > > Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
> > > Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#28561}
> >
> > TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
> >
> > # Not skipping CQ checks because original CL landed > 1 day ago.
> >
> > Bug: webrtc:10668, chromium:982260
> > Change-Id: Ie375a0b327ee368317bf3a04b2f1415c3a974470
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146707
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Chen Xing <chxg@google.com>
> > Cr-Commit-Position: refs/heads/master@{#28664}
>
> TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
>
> Change-Id: I652cb0814d83b514d3bee34e65ca3bb693099b22
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: webrtc:10668, chromium:982260
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146712
> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
> Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#28671}
TBR=alessiob@webrtc.org,kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
Change-Id: Id43b7b3da79b4f48004b41767482bae1c1fa1e16
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:10668, chromium:982260
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146713
Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28672}
2019-07-24 16:47:02 +00:00
|
|
|
// TODO(bugs.webrtc.org/10757):
|
|
|
|
|
// We don't have the ability to properly track individual packets once their
|
2021-07-28 20:00:17 +02:00
|
|
|
// audio samples have entered `sync_buffer_`. So for now, treat it as if
|
|
|
|
|
// `packet_infos` from packets decoded by the current `GetAudioInternal()`
|
Reland "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
This reverts commit fab3460a821abe336ab610c6d6dfc0d392dac263.
Reason for revert: fix downstream instead
Original change's description:
> Revert "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
>
> This reverts commit 9973933d2e606d64fcdc753acb9ba3afd6e30569.
>
> Reason for revert: breaking downstream projects and not reviewed by direct owners
>
> Original change's description:
> > Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> >
> > This reverts commit 24192c267a40eb7d6b1850489ccdbf7a84f8ff0f.
> >
> > Reason for revert: Analyzed the performance regression in more detail.
> >
> > Most of the regression comes from the extra RtpPacketInfos-related memory allocations in every `NetEq::GetAudio()` call. Commit 1796a820f60cb9429bf4bcf13a40a41794ac8fb0 has removed roughly 2/3rds of the extra allocations from the impacted perf tests. Remaining perf impact is expected to be about "8 microseconds of CPU time per second" on the Linux benchmarking machines and "15 us per second" on Windows/Mac.
> >
> > There are options to optimize further but they are unlikely worth doing. Note for example that `NetEqPerformanceTest` uses the PCM codec while the real-world use cases would likely use the much heavier Opus codec. The numbers from `OpusSpeedTest` and `NetEqPerformanceTest` suggest that Opus decoding is about 10x as expensive as NetEq overall.
> >
> > Original change's description:
> > > Revert "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> > >
> > > This reverts commit 3e8ef940fe86cf6285afb80e68d2a0bedc631b9f.
> > >
> > > Reason for revert: This CL causes a performance regression in NetEq, see https://bugs.chromium.org/p/chromium/issues/detail?id=982260.
> > >
> > > Original change's description:
> > > > Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.
> > > >
> > > > This change adds the plumbing of RtpPacketInfo from ChannelReceive::OnRtpPacket() to ChannelReceive::GetAudioFrameWithInfo() for audio. It is a step towards replacing the non-spec compliant ContributingSources that updates itself at packet-receive time, with the spec-compliant SourceTracker that will update itself at frame-delivery-to-track time.
> > > >
> > > > Bug: webrtc:10668
> > > > Change-Id: I03385d6865bbc7bfbef7634f88de820a934f787a
> > > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/139890
> > > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > > Reviewed-by: Minyue Li <minyue@webrtc.org>
> > > > Commit-Queue: Chen Xing <chxg@google.com>
> > > > Cr-Commit-Position: refs/heads/master@{#28434}
> > >
> > > TBR=kwiberg@webrtc.org,stefan@webrtc.org,minyue@webrtc.org,chxg@google.com
> > >
> > > Bug: webrtc:10668, chromium:982260
> > > Change-Id: I5e2cfde78c59d1123e21869564d76ed3f6193a5c
> > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/145339
> > > Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
> > > Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#28561}
> >
> > TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
> >
> > # Not skipping CQ checks because original CL landed > 1 day ago.
> >
> > Bug: webrtc:10668, chromium:982260
> > Change-Id: Ie375a0b327ee368317bf3a04b2f1415c3a974470
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146707
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Chen Xing <chxg@google.com>
> > Cr-Commit-Position: refs/heads/master@{#28664}
>
> TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
>
> Change-Id: I652cb0814d83b514d3bee34e65ca3bb693099b22
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: webrtc:10668, chromium:982260
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146712
> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
> Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#28671}
TBR=alessiob@webrtc.org,kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
Change-Id: Id43b7b3da79b4f48004b41767482bae1c1fa1e16
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:10668, chromium:982260
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146713
Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28672}
2019-07-24 16:47:02 +00:00
|
|
|
// call were all consumed assembling the current audio frame and the current
|
|
|
|
|
// audio frame only.
|
|
|
|
|
audio_frame->packet_infos_ = std::move(packet_infos);
|
2015-09-01 11:51:58 +02:00
|
|
|
if (sync_buffer_->FutureLength() < expand_->overlap_length()) {
|
2021-07-28 20:00:17 +02:00
|
|
|
// The sync buffer should always contain `overlap_length` samples, but now
|
|
|
|
|
// too many samples have been extracted. Reinstall the `overlap_length`
|
2015-09-01 11:51:58 +02:00
|
|
|
// lookahead by moving the index.
|
|
|
|
|
const size_t missing_lookahead_samples =
|
|
|
|
|
expand_->overlap_length() - sync_buffer_->FutureLength();
|
2015-09-17 00:24:34 -07:00
|
|
|
RTC_DCHECK_GE(sync_buffer_->next_index(), missing_lookahead_samples);
|
2015-09-01 11:51:58 +02:00
|
|
|
sync_buffer_->set_next_index(sync_buffer_->next_index() -
|
|
|
|
|
missing_lookahead_samples);
|
|
|
|
|
}
|
2016-03-04 10:34:21 -08:00
|
|
|
if (audio_frame->samples_per_channel_ != output_size_samples_) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_ERROR) << "audio_frame->samples_per_channel_ ("
|
|
|
|
|
<< audio_frame->samples_per_channel_
|
|
|
|
|
<< ") != output_size_samples_ (" << output_size_samples_
|
|
|
|
|
<< ")";
|
2013-08-13 01:39:21 +00:00
|
|
|
// TODO(minyue): treatment of under-run, filling zeros
|
2017-06-12 12:45:32 -07:00
|
|
|
audio_frame->Mute();
|
2013-01-29 12:09:21 +00:00
|
|
|
return kSampleUnderrun;
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-28 20:00:17 +02:00
|
|
|
// Should always have overlap samples left in the `sync_buffer_`.
|
2015-09-17 00:24:34 -07:00
|
|
|
RTC_DCHECK_GE(sync_buffer_->FutureLength(), expand_->overlap_length());
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2017-06-12 12:45:32 -07:00
|
|
|
// TODO(yujo): For muted frames, this can be a copy rather than an addition.
|
2013-01-29 12:09:21 +00:00
|
|
|
if (play_dtmf) {
|
2017-06-12 12:45:32 -07:00
|
|
|
return_value = DtmfOverdub(dtmf_event, sync_buffer_->Channels(),
|
|
|
|
|
audio_frame->mutable_data());
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update the background noise parameters if last operation wrote data
|
2021-07-28 20:00:17 +02:00
|
|
|
// straight from the decoder to the `sync_buffer_`. That is, none of the
|
2013-01-29 12:09:21 +00:00
|
|
|
// operations that modify the signal can be followed by a parameter update.
|
2019-10-31 14:38:11 +01:00
|
|
|
if ((last_mode_ == Mode::kNormal) || (last_mode_ == Mode::kAccelerateFail) ||
|
|
|
|
|
(last_mode_ == Mode::kPreemptiveExpandFail) ||
|
|
|
|
|
(last_mode_ == Mode::kRfc3389Cng) ||
|
|
|
|
|
(last_mode_ == Mode::kCodecInternalCng)) {
|
2024-02-07 15:17:39 +00:00
|
|
|
background_noise_->Update(*sync_buffer_);
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
2019-10-31 14:38:11 +01:00
|
|
|
if (operation == Operation::kDtmf) {
|
2021-07-28 20:00:17 +02:00
|
|
|
// DTMF data was written the end of `sync_buffer_`.
|
|
|
|
|
// Update index to end of DTMF data in `sync_buffer_`.
|
2013-01-29 12:09:21 +00:00
|
|
|
sync_buffer_->set_dtmf_index(sync_buffer_->Size());
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-31 14:38:11 +01:00
|
|
|
if (last_mode_ != Mode::kExpand && last_mode_ != Mode::kCodecPlc) {
|
2021-07-28 20:00:17 +02:00
|
|
|
// If last operation was not expand, calculate the `playout_timestamp_` from
|
|
|
|
|
// the `sync_buffer_`. However, do not update the `playout_timestamp_` if it
|
2014-03-06 10:28:07 +00:00
|
|
|
// would be moved "backwards".
|
2018-06-19 15:03:05 +02:00
|
|
|
uint32_t temp_timestamp =
|
|
|
|
|
sync_buffer_->end_timestamp() -
|
2013-09-20 16:25:28 +00:00
|
|
|
static_cast<uint32_t>(sync_buffer_->FutureLength());
|
2013-01-29 12:09:21 +00:00
|
|
|
if (static_cast<int32_t>(temp_timestamp - playout_timestamp_) > 0) {
|
|
|
|
|
playout_timestamp_ = temp_timestamp;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2021-07-28 20:00:17 +02:00
|
|
|
// Use dead reckoning to estimate the `playout_timestamp_`.
|
Match existing type usage better.
This makes a variety of small changes to synchronize bits of code using different types, remove useless code or casts, and add explicit casts in some places previously doing implicit ones. For example:
* Change a few type declarations to better match how the majority of code uses those objects.
* Eliminate "< 0" check for unsigned values.
* Replace "(float)sin(x)", where |x| is also a float, with "sinf(x)", and similar.
* Add casts to uint32_t in many places timestamps were used and the existing code stored signed values into the unsigned objects.
* Remove downcasts when the results would be passed to a larger type, e.g. calling "foo((int16_t)x)" with an int |x| when foo() takes an int instead of an int16_t.
* Similarly, add casts when passing a larger type to a function taking a smaller one.
* Add casts to int16_t when doing something like "int16_t = int16_t + int16_t" as the "+" operation would implicitly upconvert to int, and similar.
* Use "false" instead of "0" for setting a bool.
* Shift a few temp types when doing a multi-stage calculation involving typecasts, so as to put the most logical/semantically correct type possible into the temps. For example, when doing "int foo = int + int; size_t bar = (size_t)foo + size_t;", we might change |foo| to a size_t and move the cast if it makes more sense for |foo| to be represented as a size_t.
BUG=none
R=andrew@webrtc.org, asapersson@webrtc.org, henrika@webrtc.org, juberti@webrtc.org, kwiberg@webrtc.org
TBR=andrew, asapersson, henrika
Review URL: https://codereview.webrtc.org/1168753002
Cr-Commit-Position: refs/heads/master@{#9419}
2015-06-11 12:55:50 -07:00
|
|
|
playout_timestamp_ += static_cast<uint32_t>(output_size_samples_);
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
2016-04-06 08:38:56 -07:00
|
|
|
// Set the timestamp in the audio frame to zero before the first packet has
|
|
|
|
|
// been inserted. Otherwise, subtract the frame size in samples to get the
|
|
|
|
|
// timestamp of the first sample in the frame (playout_timestamp_ is the
|
|
|
|
|
// last + 1).
|
|
|
|
|
audio_frame->timestamp_ =
|
|
|
|
|
first_packet_
|
|
|
|
|
? 0
|
|
|
|
|
: timestamp_scaler_->ToExternal(playout_timestamp_) -
|
|
|
|
|
static_cast<uint32_t>(audio_frame->samples_per_channel_);
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2019-10-31 14:38:11 +01:00
|
|
|
if (!(last_mode_ == Mode::kRfc3389Cng ||
|
|
|
|
|
last_mode_ == Mode::kCodecInternalCng || last_mode_ == Mode::kExpand ||
|
|
|
|
|
last_mode_ == Mode::kCodecPlc)) {
|
2016-05-03 08:18:47 -07:00
|
|
|
generated_noise_stopwatch_.reset();
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
if (decode_return_value)
|
|
|
|
|
return decode_return_value;
|
2013-01-29 12:09:21 +00:00
|
|
|
return return_value;
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-31 14:38:11 +01:00
|
|
|
int NetEqImpl::GetDecision(Operation* operation,
|
2013-01-29 12:09:21 +00:00
|
|
|
PacketList* packet_list,
|
|
|
|
|
DtmfEvent* dtmf_event,
|
2018-09-03 11:49:27 +02:00
|
|
|
bool* play_dtmf,
|
2019-10-31 14:38:11 +01:00
|
|
|
absl::optional<Operation> action_override) {
|
2013-01-29 12:09:21 +00:00
|
|
|
// Initialize output variables.
|
|
|
|
|
*play_dtmf = false;
|
2019-10-31 14:38:11 +01:00
|
|
|
*operation = Operation::kUndefined;
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(sync_buffer_.get());
|
2013-01-29 12:09:21 +00:00
|
|
|
uint32_t end_timestamp = sync_buffer_->end_timestamp();
|
2014-11-04 14:03:58 +00:00
|
|
|
if (!new_codec_) {
|
|
|
|
|
const uint32_t five_seconds_samples = 5 * fs_hz_;
|
2023-11-07 10:10:47 +01:00
|
|
|
packet_buffer_->DiscardOldPackets(end_timestamp, five_seconds_samples);
|
2014-11-04 14:03:58 +00:00
|
|
|
}
|
2016-10-18 04:06:13 -07:00
|
|
|
const Packet* packet = packet_buffer_->PeekNextPacket();
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2016-05-03 08:18:47 -07:00
|
|
|
RTC_DCHECK(!generated_noise_stopwatch_ ||
|
|
|
|
|
generated_noise_stopwatch_->ElapsedTicks() >= 1);
|
|
|
|
|
uint64_t generated_noise_samples =
|
2018-06-19 15:03:05 +02:00
|
|
|
generated_noise_stopwatch_ ? (generated_noise_stopwatch_->ElapsedTicks() -
|
|
|
|
|
1) * output_size_samples_ +
|
2019-10-24 15:20:39 +02:00
|
|
|
controller_->noise_fast_forward()
|
2018-06-19 15:03:05 +02:00
|
|
|
: 0;
|
2016-05-03 08:18:47 -07:00
|
|
|
|
2023-03-16 22:09:39 +01:00
|
|
|
if (last_mode_ == Mode::kRfc3389Cng) {
|
2013-01-29 12:09:21 +00:00
|
|
|
// Because of timestamp peculiarities, we have to "manually" disallow using
|
|
|
|
|
// a CNG packet with the same timestamp as the one that was last played.
|
|
|
|
|
// This can happen when using redundancy and will cause the timing to shift.
|
2016-10-18 04:06:13 -07:00
|
|
|
while (packet && decoder_database_->IsComfortNoise(packet->payload_type) &&
|
|
|
|
|
(end_timestamp >= packet->timestamp ||
|
|
|
|
|
end_timestamp + generated_noise_samples > packet->timestamp)) {
|
2013-01-29 12:09:21 +00:00
|
|
|
// Don't use this packet, discard it.
|
2023-11-07 10:10:47 +01:00
|
|
|
if (packet_buffer_->DiscardNextPacket() != PacketBuffer::kOK) {
|
2021-11-15 16:57:07 +01:00
|
|
|
RTC_DCHECK_NOTREACHED(); // Must be ok by design.
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
// Check buffer again.
|
|
|
|
|
if (!new_codec_) {
|
2023-11-07 10:10:47 +01:00
|
|
|
packet_buffer_->DiscardOldPackets(end_timestamp, 5 * fs_hz_);
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
2016-10-18 04:06:13 -07:00
|
|
|
packet = packet_buffer_->PeekNextPacket();
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(expand_.get());
|
2013-09-20 16:25:28 +00:00
|
|
|
const int samples_left = static_cast<int>(sync_buffer_->FutureLength() -
|
2018-06-19 15:03:05 +02:00
|
|
|
expand_->overlap_length());
|
2019-10-31 14:38:11 +01:00
|
|
|
if (last_mode_ == Mode::kAccelerateSuccess ||
|
|
|
|
|
last_mode_ == Mode::kAccelerateLowEnergy ||
|
|
|
|
|
last_mode_ == Mode::kPreemptiveExpandSuccess ||
|
|
|
|
|
last_mode_ == Mode::kPreemptiveExpandLowEnergy) {
|
2013-01-29 12:09:21 +00:00
|
|
|
// Subtract (samples_left + output_size_samples_) from sampleMemory.
|
2019-10-24 15:20:39 +02:00
|
|
|
controller_->AddSampleMemory(
|
2017-03-01 18:52:48 -08:00
|
|
|
-(samples_left + rtc::dchecked_cast<int>(output_size_samples_)));
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check if it is time to play a DTMF event.
|
Match existing type usage better.
This makes a variety of small changes to synchronize bits of code using different types, remove useless code or casts, and add explicit casts in some places previously doing implicit ones. For example:
* Change a few type declarations to better match how the majority of code uses those objects.
* Eliminate "< 0" check for unsigned values.
* Replace "(float)sin(x)", where |x| is also a float, with "sinf(x)", and similar.
* Add casts to uint32_t in many places timestamps were used and the existing code stored signed values into the unsigned objects.
* Remove downcasts when the results would be passed to a larger type, e.g. calling "foo((int16_t)x)" with an int |x| when foo() takes an int instead of an int16_t.
* Similarly, add casts when passing a larger type to a function taking a smaller one.
* Add casts to int16_t when doing something like "int16_t = int16_t + int16_t" as the "+" operation would implicitly upconvert to int, and similar.
* Use "false" instead of "0" for setting a bool.
* Shift a few temp types when doing a multi-stage calculation involving typecasts, so as to put the most logical/semantically correct type possible into the temps. For example, when doing "int foo = int + int; size_t bar = (size_t)foo + size_t;", we might change |foo| to a size_t and move the cast if it makes more sense for |foo| to be represented as a size_t.
BUG=none
R=andrew@webrtc.org, asapersson@webrtc.org, henrika@webrtc.org, juberti@webrtc.org, kwiberg@webrtc.org
TBR=andrew, asapersson, henrika
Review URL: https://codereview.webrtc.org/1168753002
Cr-Commit-Position: refs/heads/master@{#9419}
2015-06-11 12:55:50 -07:00
|
|
|
if (dtmf_buffer_->GetEvent(
|
2018-06-19 15:03:05 +02:00
|
|
|
static_cast<uint32_t>(end_timestamp + generated_noise_samples),
|
|
|
|
|
dtmf_event)) {
|
2013-01-29 12:09:21 +00:00
|
|
|
*play_dtmf = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get instruction.
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(sync_buffer_.get());
|
|
|
|
|
RTC_DCHECK(expand_.get());
|
2016-05-03 08:18:47 -07:00
|
|
|
generated_noise_samples =
|
|
|
|
|
generated_noise_stopwatch_
|
|
|
|
|
? generated_noise_stopwatch_->ElapsedTicks() * output_size_samples_ +
|
2019-10-24 15:20:39 +02:00
|
|
|
controller_->noise_fast_forward()
|
2016-05-03 08:18:47 -07:00
|
|
|
: 0;
|
2019-10-24 15:20:39 +02:00
|
|
|
NetEqController::NetEqStatus status;
|
|
|
|
|
status.packet_buffer_info.dtx_or_cng =
|
|
|
|
|
packet_buffer_->ContainsDtxOrCngPacket(decoder_database_.get());
|
|
|
|
|
status.packet_buffer_info.num_samples =
|
|
|
|
|
packet_buffer_->NumSamplesInBuffer(decoder_frame_length_);
|
|
|
|
|
status.packet_buffer_info.span_samples = packet_buffer_->GetSpanSamples(
|
2023-03-23 21:51:27 +01:00
|
|
|
decoder_frame_length_, last_output_sample_rate_hz_, false);
|
|
|
|
|
status.packet_buffer_info.span_samples_wait_time =
|
2019-10-24 15:20:39 +02:00
|
|
|
packet_buffer_->GetSpanSamples(decoder_frame_length_,
|
2023-03-23 21:51:27 +01:00
|
|
|
last_output_sample_rate_hz_, true);
|
2019-10-24 15:20:39 +02:00
|
|
|
status.packet_buffer_info.num_packets = packet_buffer_->NumPacketsInBuffer();
|
|
|
|
|
status.target_timestamp = sync_buffer_->end_timestamp();
|
|
|
|
|
status.expand_mutefactor = expand_->MuteFactor(0);
|
|
|
|
|
status.last_packet_samples = decoder_frame_length_;
|
|
|
|
|
status.last_mode = last_mode_;
|
|
|
|
|
status.play_dtmf = *play_dtmf;
|
|
|
|
|
status.generated_noise_samples = generated_noise_samples;
|
2020-01-24 11:04:56 +01:00
|
|
|
status.sync_buffer_samples = sync_buffer_->FutureLength();
|
2019-10-24 15:20:39 +02:00
|
|
|
if (packet) {
|
|
|
|
|
status.next_packet = {
|
|
|
|
|
packet->timestamp, packet->frame && packet->frame->IsDtxPacket(),
|
|
|
|
|
decoder_database_->IsComfortNoise(packet->payload_type)};
|
|
|
|
|
}
|
|
|
|
|
*operation = controller_->GetDecision(status, &reset_decoder_);
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2019-04-15 14:29:27 +02:00
|
|
|
// Disallow time stretching if this packet is DTX, because such a decision may
|
|
|
|
|
// be based on earlier buffer level estimate, as we do not update buffer level
|
|
|
|
|
// during DTX. When we have a better way to update buffer level during DTX,
|
|
|
|
|
// this can be discarded.
|
|
|
|
|
if (packet && packet->frame && packet->frame->IsDtxPacket() &&
|
2019-10-31 14:38:11 +01:00
|
|
|
(*operation == Operation::kMerge ||
|
|
|
|
|
*operation == Operation::kAccelerate ||
|
|
|
|
|
*operation == Operation::kFastAccelerate ||
|
|
|
|
|
*operation == Operation::kPreemptiveExpand)) {
|
|
|
|
|
*operation = Operation::kNormal;
|
2019-04-15 14:29:27 +02:00
|
|
|
}
|
|
|
|
|
|
2018-09-03 11:49:27 +02:00
|
|
|
if (action_override) {
|
|
|
|
|
// Use the provided action instead of the decision NetEq decided on.
|
|
|
|
|
*operation = *action_override;
|
|
|
|
|
}
|
2021-07-28 20:00:17 +02:00
|
|
|
// Check if we already have enough samples in the `sync_buffer_`. If so,
|
2013-01-29 12:09:21 +00:00
|
|
|
// change decision to normal, unless the decision was merge, accelerate, or
|
|
|
|
|
// preemptive expand.
|
2017-03-01 18:52:48 -08:00
|
|
|
if (samples_left >= rtc::dchecked_cast<int>(output_size_samples_) &&
|
2019-10-31 14:38:11 +01:00
|
|
|
*operation != Operation::kMerge && *operation != Operation::kAccelerate &&
|
|
|
|
|
*operation != Operation::kFastAccelerate &&
|
|
|
|
|
*operation != Operation::kPreemptiveExpand) {
|
|
|
|
|
*operation = Operation::kNormal;
|
2013-01-29 12:09:21 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-24 15:20:39 +02:00
|
|
|
controller_->ExpandDecision(*operation);
|
2021-02-10 10:38:50 +01:00
|
|
|
if ((last_mode_ == Mode::kCodecPlc) && (*operation != Operation::kExpand)) {
|
|
|
|
|
// Getting out of the PLC expand mode, reporting interruptions.
|
|
|
|
|
// NetEq PLC reports this metrics in expand.cc
|
|
|
|
|
stats_->EndExpandEvent(fs_hz_);
|
|
|
|
|
}
|
2013-01-29 12:09:21 +00:00
|
|
|
|
|
|
|
|
// Check conditions for reset.
|
2019-10-31 14:38:11 +01:00
|
|
|
if (new_codec_ || *operation == Operation::kUndefined) {
|
2013-01-29 12:09:21 +00:00
|
|
|
// The only valid reason to get kUndefined is that new_codec_ is set.
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(new_codec_);
|
2016-10-18 04:06:13 -07:00
|
|
|
if (*play_dtmf && !packet) {
|
2013-03-27 18:31:42 +00:00
|
|
|
timestamp_ = dtmf_event->timestamp;
|
|
|
|
|
} else {
|
2016-10-18 04:06:13 -07:00
|
|
|
if (!packet) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_ERROR) << "Packet missing where it shouldn't.";
|
2013-03-27 18:31:42 +00:00
|
|
|
return -1;
|
|
|
|
|
}
|
2016-10-18 04:06:13 -07:00
|
|
|
timestamp_ = packet->timestamp;
|
2019-10-31 14:38:11 +01:00
|
|
|
if (*operation == Operation::kRfc3389CngNoPacket &&
|
2016-10-18 04:06:13 -07:00
|
|
|
decoder_database_->IsComfortNoise(packet->payload_type)) {
|
2013-03-27 18:31:42 +00:00
|
|
|
// Change decision to CNG packet, since we do have a CNG packet, but it
|
|
|
|
|
// was considered too early to use. Now, use it anyway.
|
2019-10-31 14:38:11 +01:00
|
|
|
*operation = Operation::kRfc3389Cng;
|
|
|
|
|
} else if (*operation != Operation::kRfc3389Cng) {
|
|
|
|
|
*operation = Operation::kNormal;
|
2013-03-27 18:31:42 +00:00
|
|
|
}
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
2021-07-28 20:00:17 +02:00
|
|
|
// Adjust `sync_buffer_` timestamp before setting `end_timestamp` to the
|
2013-01-29 12:09:21 +00:00
|
|
|
// new value.
|
|
|
|
|
sync_buffer_->IncreaseEndTimestamp(timestamp_ - end_timestamp);
|
2013-03-27 18:31:42 +00:00
|
|
|
end_timestamp = timestamp_;
|
2013-01-29 12:09:21 +00:00
|
|
|
new_codec_ = false;
|
2019-10-24 15:20:39 +02:00
|
|
|
controller_->SoftReset();
|
2019-03-05 16:59:03 +01:00
|
|
|
stats_->ResetMcu();
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
size_t required_samples = output_size_samples_;
|
|
|
|
|
const size_t samples_10_ms = static_cast<size_t>(80 * fs_mult_);
|
|
|
|
|
const size_t samples_20_ms = 2 * samples_10_ms;
|
|
|
|
|
const size_t samples_30_ms = 3 * samples_10_ms;
|
2013-01-29 12:09:21 +00:00
|
|
|
|
|
|
|
|
switch (*operation) {
|
2019-10-31 14:38:11 +01:00
|
|
|
case Operation::kExpand: {
|
2013-01-29 12:09:21 +00:00
|
|
|
timestamp_ = end_timestamp;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2019-10-31 14:38:11 +01:00
|
|
|
case Operation::kRfc3389CngNoPacket:
|
|
|
|
|
case Operation::kCodecInternalCng: {
|
2013-01-29 12:09:21 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
2019-10-31 14:38:11 +01:00
|
|
|
case Operation::kDtmf: {
|
2013-01-29 12:09:21 +00:00
|
|
|
// TODO(hlundin): Write test for this.
|
|
|
|
|
// Update timestamp.
|
|
|
|
|
timestamp_ = end_timestamp;
|
2016-05-03 08:18:47 -07:00
|
|
|
const uint64_t generated_noise_samples =
|
|
|
|
|
generated_noise_stopwatch_
|
|
|
|
|
? generated_noise_stopwatch_->ElapsedTicks() *
|
|
|
|
|
output_size_samples_ +
|
2019-10-24 15:20:39 +02:00
|
|
|
controller_->noise_fast_forward()
|
2016-05-03 08:18:47 -07:00
|
|
|
: 0;
|
2019-10-31 14:38:11 +01:00
|
|
|
if (generated_noise_samples > 0 && last_mode_ != Mode::kDtmf) {
|
2013-01-29 12:09:21 +00:00
|
|
|
// Make a jump in timestamp due to the recently played comfort noise.
|
Match existing type usage better.
This makes a variety of small changes to synchronize bits of code using different types, remove useless code or casts, and add explicit casts in some places previously doing implicit ones. For example:
* Change a few type declarations to better match how the majority of code uses those objects.
* Eliminate "< 0" check for unsigned values.
* Replace "(float)sin(x)", where |x| is also a float, with "sinf(x)", and similar.
* Add casts to uint32_t in many places timestamps were used and the existing code stored signed values into the unsigned objects.
* Remove downcasts when the results would be passed to a larger type, e.g. calling "foo((int16_t)x)" with an int |x| when foo() takes an int instead of an int16_t.
* Similarly, add casts when passing a larger type to a function taking a smaller one.
* Add casts to int16_t when doing something like "int16_t = int16_t + int16_t" as the "+" operation would implicitly upconvert to int, and similar.
* Use "false" instead of "0" for setting a bool.
* Shift a few temp types when doing a multi-stage calculation involving typecasts, so as to put the most logical/semantically correct type possible into the temps. For example, when doing "int foo = int + int; size_t bar = (size_t)foo + size_t;", we might change |foo| to a size_t and move the cast if it makes more sense for |foo| to be represented as a size_t.
BUG=none
R=andrew@webrtc.org, asapersson@webrtc.org, henrika@webrtc.org, juberti@webrtc.org, kwiberg@webrtc.org
TBR=andrew, asapersson, henrika
Review URL: https://codereview.webrtc.org/1168753002
Cr-Commit-Position: refs/heads/master@{#9419}
2015-06-11 12:55:50 -07:00
|
|
|
uint32_t timestamp_jump =
|
2016-05-03 08:18:47 -07:00
|
|
|
static_cast<uint32_t>(generated_noise_samples);
|
2013-01-29 12:09:21 +00:00
|
|
|
sync_buffer_->IncreaseEndTimestamp(timestamp_jump);
|
|
|
|
|
timestamp_ += timestamp_jump;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2019-10-31 14:38:11 +01:00
|
|
|
case Operation::kAccelerate:
|
|
|
|
|
case Operation::kFastAccelerate: {
|
2015-05-27 14:33:29 +02:00
|
|
|
// In order to do an accelerate we need at least 30 ms of audio data.
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
if (samples_left >= static_cast<int>(samples_30_ms)) {
|
2013-01-29 12:09:21 +00:00
|
|
|
// Already have enough data, so we do not need to extract any more.
|
2019-10-24 15:20:39 +02:00
|
|
|
controller_->set_sample_memory(samples_left);
|
|
|
|
|
controller_->set_prev_time_scale(true);
|
2013-01-29 12:09:21 +00:00
|
|
|
return 0;
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
} else if (samples_left >= static_cast<int>(samples_10_ms) &&
|
2018-06-19 15:03:05 +02:00
|
|
|
decoder_frame_length_ >= samples_30_ms) {
|
2013-01-29 12:09:21 +00:00
|
|
|
// Avoid decoding more data as it might overflow the playout buffer.
|
2019-10-31 14:38:11 +01:00
|
|
|
*operation = Operation::kNormal;
|
2013-01-29 12:09:21 +00:00
|
|
|
return 0;
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
} else if (samples_left < static_cast<int>(samples_20_ms) &&
|
2018-06-19 15:03:05 +02:00
|
|
|
decoder_frame_length_ < samples_30_ms) {
|
2013-01-29 12:09:21 +00:00
|
|
|
// Build up decoded data by decoding at least 20 ms of audio data. Do
|
|
|
|
|
// not perform accelerate yet, but wait until we only need to do one
|
|
|
|
|
// decoding.
|
|
|
|
|
required_samples = 2 * output_size_samples_;
|
2019-10-31 14:38:11 +01:00
|
|
|
*operation = Operation::kNormal;
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
// If none of the above is true, we have one of two possible situations:
|
|
|
|
|
// (1) 20 ms <= samples_left < 30 ms and decoder_frame_length_ < 30 ms; or
|
|
|
|
|
// (2) samples_left < 10 ms and decoder_frame_length_ >= 30 ms.
|
|
|
|
|
// In either case, we move on with the accelerate decision, and decode one
|
|
|
|
|
// frame now.
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-10-31 14:38:11 +01:00
|
|
|
case Operation::kPreemptiveExpand: {
|
2013-01-29 12:09:21 +00:00
|
|
|
// In order to do a preemptive expand we need at least 30 ms of decoded
|
|
|
|
|
// audio data.
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
if ((samples_left >= static_cast<int>(samples_30_ms)) ||
|
|
|
|
|
(samples_left >= static_cast<int>(samples_10_ms) &&
|
2018-06-19 15:03:05 +02:00
|
|
|
decoder_frame_length_ >= samples_30_ms)) {
|
2013-01-29 12:09:21 +00:00
|
|
|
// Already have enough data, so we do not need to extract any more.
|
|
|
|
|
// Or, avoid decoding more data as it might overflow the playout buffer.
|
|
|
|
|
// Still try preemptive expand, though.
|
2019-10-24 15:20:39 +02:00
|
|
|
controller_->set_sample_memory(samples_left);
|
|
|
|
|
controller_->set_prev_time_scale(true);
|
2013-01-29 12:09:21 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
if (samples_left < static_cast<int>(samples_20_ms) &&
|
2013-01-29 12:09:21 +00:00
|
|
|
decoder_frame_length_ < samples_30_ms) {
|
|
|
|
|
// Build up decoded data by decoding at least 20 ms of audio data.
|
|
|
|
|
// Still try to perform preemptive expand.
|
|
|
|
|
required_samples = 2 * output_size_samples_;
|
|
|
|
|
}
|
|
|
|
|
// Move on with the preemptive expand decision.
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-10-31 14:38:11 +01:00
|
|
|
case Operation::kMerge: {
|
2014-04-11 18:47:55 +00:00
|
|
|
required_samples =
|
|
|
|
|
std::max(merge_->RequiredFutureSamples(), required_samples);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2013-01-29 12:09:21 +00:00
|
|
|
default: {
|
|
|
|
|
// Do nothing.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get packets from buffer.
|
|
|
|
|
int extracted_samples = 0;
|
2018-07-02 10:14:46 +02:00
|
|
|
if (packet) {
|
2016-10-18 04:06:13 -07:00
|
|
|
sync_buffer_->IncreaseEndTimestamp(packet->timestamp - end_timestamp);
|
2013-01-29 12:09:21 +00:00
|
|
|
extracted_samples = ExtractPackets(required_samples, packet_list);
|
|
|
|
|
if (extracted_samples < 0) {
|
|
|
|
|
return kPacketBufferCorruption;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-31 14:38:11 +01:00
|
|
|
if (*operation == Operation::kAccelerate ||
|
|
|
|
|
*operation == Operation::kFastAccelerate ||
|
|
|
|
|
*operation == Operation::kPreemptiveExpand) {
|
2019-10-24 15:20:39 +02:00
|
|
|
controller_->set_sample_memory(samples_left + extracted_samples);
|
|
|
|
|
controller_->set_prev_time_scale(true);
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
2019-10-31 14:38:11 +01:00
|
|
|
if (*operation == Operation::kAccelerate ||
|
|
|
|
|
*operation == Operation::kFastAccelerate) {
|
2013-01-29 12:09:21 +00:00
|
|
|
// Check that we have enough data (30ms) to do accelerate.
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
if (extracted_samples + samples_left < static_cast<int>(samples_30_ms)) {
|
2013-01-29 12:09:21 +00:00
|
|
|
// TODO(hlundin): Write test for this.
|
|
|
|
|
// Not enough, do normal operation instead.
|
2019-10-31 14:38:11 +01:00
|
|
|
*operation = Operation::kNormal;
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-09 12:58:45 +01:00
|
|
|
timestamp_ = sync_buffer_->end_timestamp();
|
2013-01-29 12:09:21 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
int NetEqImpl::Decode(PacketList* packet_list,
|
2019-10-31 14:38:11 +01:00
|
|
|
Operation* operation,
|
2013-01-29 12:09:21 +00:00
|
|
|
int* decoded_length,
|
|
|
|
|
AudioDecoder::SpeechType* speech_type) {
|
|
|
|
|
*speech_type = AudioDecoder::kSpeech;
|
2015-09-23 15:20:39 +02:00
|
|
|
|
|
|
|
|
// When packet_list is empty, we may be in kCodecInternalCng mode, and for
|
|
|
|
|
// that we use current active decoder.
|
|
|
|
|
AudioDecoder* decoder = decoder_database_->GetActiveDecoder();
|
|
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
if (!packet_list->empty()) {
|
2016-10-24 08:25:28 -07:00
|
|
|
const Packet& packet = packet_list->front();
|
|
|
|
|
uint8_t payload_type = packet.payload_type;
|
2013-01-29 12:09:21 +00:00
|
|
|
if (!decoder_database_->IsComfortNoise(payload_type)) {
|
|
|
|
|
decoder = decoder_database_->GetDecoder(payload_type);
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(decoder);
|
2013-01-29 12:09:21 +00:00
|
|
|
if (!decoder) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_WARNING)
|
|
|
|
|
<< "Unknown payload type " << static_cast<int>(payload_type);
|
2016-10-24 08:25:28 -07:00
|
|
|
packet_list->clear();
|
2013-01-29 12:09:21 +00:00
|
|
|
return kDecoderNotFound;
|
|
|
|
|
}
|
|
|
|
|
bool decoder_changed;
|
|
|
|
|
decoder_database_->SetActiveDecoder(payload_type, &decoder_changed);
|
|
|
|
|
if (decoder_changed) {
|
|
|
|
|
// We have a new decoder. Re-init some values.
|
2018-06-19 15:03:05 +02:00
|
|
|
const DecoderDatabase::DecoderInfo* decoder_info =
|
|
|
|
|
decoder_database_->GetDecoderInfo(payload_type);
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(decoder_info);
|
2013-01-29 12:09:21 +00:00
|
|
|
if (!decoder_info) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_WARNING)
|
|
|
|
|
<< "Unknown payload type " << static_cast<int>(payload_type);
|
2016-10-24 08:25:28 -07:00
|
|
|
packet_list->clear();
|
2013-01-29 12:09:21 +00:00
|
|
|
return kDecoderNotFound;
|
|
|
|
|
}
|
2014-03-23 09:58:48 +00:00
|
|
|
// If sampling rate or number of channels has changed, we need to make
|
|
|
|
|
// a reset.
|
2016-05-31 06:28:03 -07:00
|
|
|
if (decoder_info->SampleRateHz() != fs_hz_ ||
|
2015-03-18 09:47:08 +00:00
|
|
|
decoder->Channels() != algorithm_buffer_->Channels()) {
|
2014-03-23 09:58:48 +00:00
|
|
|
// TODO(tlegrand): Add unittest to cover this event.
|
2016-05-31 06:28:03 -07:00
|
|
|
SetSampleRateAndChannels(decoder_info->SampleRateHz(),
|
|
|
|
|
decoder->Channels());
|
2013-10-01 22:01:09 +00:00
|
|
|
}
|
2013-01-29 12:09:21 +00:00
|
|
|
sync_buffer_->set_end_timestamp(timestamp_);
|
|
|
|
|
playout_timestamp_ = timestamp_;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (reset_decoder_) {
|
|
|
|
|
// TODO(hlundin): Write test for this.
|
2015-08-27 15:22:11 +02:00
|
|
|
if (decoder)
|
|
|
|
|
decoder->Reset();
|
|
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
// Reset comfort noise decoder.
|
2016-04-25 07:55:58 -07:00
|
|
|
ComfortNoiseDecoder* cng_decoder = decoder_database_->GetActiveCngDecoder();
|
2015-08-27 15:22:11 +02:00
|
|
|
if (cng_decoder)
|
|
|
|
|
cng_decoder->Reset();
|
|
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
reset_decoder_ = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*decoded_length = 0;
|
|
|
|
|
// Update codec-internal PLC state.
|
2019-10-31 14:38:11 +01:00
|
|
|
if ((*operation == Operation::kMerge) && decoder && decoder->HasDecodePlc()) {
|
2013-01-29 12:09:21 +00:00
|
|
|
decoder->DecodePlc(1, &decoded_buffer_[*decoded_length]);
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-23 15:20:39 +02:00
|
|
|
int return_value;
|
2019-10-31 14:38:11 +01:00
|
|
|
if (*operation == Operation::kCodecInternalCng) {
|
2015-09-23 15:20:39 +02:00
|
|
|
RTC_DCHECK(packet_list->empty());
|
|
|
|
|
return_value = DecodeCng(decoder, decoded_length, speech_type);
|
|
|
|
|
} else {
|
2018-06-19 15:03:05 +02:00
|
|
|
return_value = DecodeLoop(packet_list, *operation, decoder, decoded_length,
|
|
|
|
|
speech_type);
|
2015-09-23 15:20:39 +02:00
|
|
|
}
|
2013-01-29 12:09:21 +00:00
|
|
|
|
|
|
|
|
if (*decoded_length < 0) {
|
|
|
|
|
// Error returned from the decoder.
|
|
|
|
|
*decoded_length = 0;
|
Match existing type usage better.
This makes a variety of small changes to synchronize bits of code using different types, remove useless code or casts, and add explicit casts in some places previously doing implicit ones. For example:
* Change a few type declarations to better match how the majority of code uses those objects.
* Eliminate "< 0" check for unsigned values.
* Replace "(float)sin(x)", where |x| is also a float, with "sinf(x)", and similar.
* Add casts to uint32_t in many places timestamps were used and the existing code stored signed values into the unsigned objects.
* Remove downcasts when the results would be passed to a larger type, e.g. calling "foo((int16_t)x)" with an int |x| when foo() takes an int instead of an int16_t.
* Similarly, add casts when passing a larger type to a function taking a smaller one.
* Add casts to int16_t when doing something like "int16_t = int16_t + int16_t" as the "+" operation would implicitly upconvert to int, and similar.
* Use "false" instead of "0" for setting a bool.
* Shift a few temp types when doing a multi-stage calculation involving typecasts, so as to put the most logical/semantically correct type possible into the temps. For example, when doing "int foo = int + int; size_t bar = (size_t)foo + size_t;", we might change |foo| to a size_t and move the cast if it makes more sense for |foo| to be represented as a size_t.
BUG=none
R=andrew@webrtc.org, asapersson@webrtc.org, henrika@webrtc.org, juberti@webrtc.org, kwiberg@webrtc.org
TBR=andrew, asapersson, henrika
Review URL: https://codereview.webrtc.org/1168753002
Cr-Commit-Position: refs/heads/master@{#9419}
2015-06-11 12:55:50 -07:00
|
|
|
sync_buffer_->IncreaseEndTimestamp(
|
|
|
|
|
static_cast<uint32_t>(decoder_frame_length_));
|
2013-01-29 12:09:21 +00:00
|
|
|
int error_code = 0;
|
|
|
|
|
if (decoder)
|
|
|
|
|
error_code = decoder->ErrorCode();
|
|
|
|
|
if (error_code != 0) {
|
|
|
|
|
// Got some error code from the decoder.
|
|
|
|
|
return_value = kDecoderErrorCode;
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_WARNING) << "Decoder returned error code: " << error_code;
|
2013-01-29 12:09:21 +00:00
|
|
|
} else {
|
|
|
|
|
// Decoder does not implement error codes. Return generic error.
|
|
|
|
|
return_value = kOtherDecoderError;
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_WARNING) << "Decoder error (no error code)";
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
2019-10-31 14:38:11 +01:00
|
|
|
*operation = Operation::kExpand; // Do expansion to get data instead.
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
if (*speech_type != AudioDecoder::kComfortNoise) {
|
|
|
|
|
// Don't increment timestamp if codec returned CNG speech type
|
|
|
|
|
// since in this case, the we will increment the CNGplayedTS counter.
|
|
|
|
|
// Increase with number of samples per channel.
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(*decoded_length == 0 ||
|
|
|
|
|
(decoder && decoder->Channels() == sync_buffer_->Channels()));
|
2013-09-20 16:25:28 +00:00
|
|
|
sync_buffer_->IncreaseEndTimestamp(
|
|
|
|
|
*decoded_length / static_cast<int>(sync_buffer_->Channels()));
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
return return_value;
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
int NetEqImpl::DecodeCng(AudioDecoder* decoder,
|
|
|
|
|
int* decoded_length,
|
2015-09-23 15:20:39 +02:00
|
|
|
AudioDecoder::SpeechType* speech_type) {
|
|
|
|
|
if (!decoder) {
|
|
|
|
|
// This happens when active decoder is not defined.
|
|
|
|
|
*decoded_length = -1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-01 18:52:48 -08:00
|
|
|
while (*decoded_length < rtc::dchecked_cast<int>(output_size_samples_)) {
|
2015-09-23 15:20:39 +02:00
|
|
|
const int length = decoder->Decode(
|
2018-06-19 15:03:05 +02:00
|
|
|
nullptr, 0, fs_hz_,
|
|
|
|
|
(decoded_buffer_length_ - *decoded_length) * sizeof(int16_t),
|
|
|
|
|
&decoded_buffer_[*decoded_length], speech_type);
|
2015-09-23 15:20:39 +02:00
|
|
|
if (length > 0) {
|
|
|
|
|
*decoded_length += length;
|
|
|
|
|
} else {
|
|
|
|
|
// Error.
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_WARNING) << "Failed to decode CNG";
|
2015-09-23 15:20:39 +02:00
|
|
|
*decoded_length = -1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (*decoded_length > static_cast<int>(decoded_buffer_length_)) {
|
|
|
|
|
// Guard against overflow.
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_WARNING) << "Decoded too much CNG.";
|
2015-09-23 15:20:39 +02:00
|
|
|
return kDecodedTooMuch;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-04-18 20:31:51 +02:00
|
|
|
stats_->GeneratedNoiseSamples(*decoded_length);
|
2015-09-23 15:20:39 +02:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
int NetEqImpl::DecodeLoop(PacketList* packet_list,
|
2019-10-31 14:38:11 +01:00
|
|
|
const Operation& operation,
|
2018-06-19 15:03:05 +02:00
|
|
|
AudioDecoder* decoder,
|
|
|
|
|
int* decoded_length,
|
2013-01-29 12:09:21 +00:00
|
|
|
AudioDecoder::SpeechType* speech_type) {
|
Reland "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
This reverts commit fab3460a821abe336ab610c6d6dfc0d392dac263.
Reason for revert: fix downstream instead
Original change's description:
> Revert "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
>
> This reverts commit 9973933d2e606d64fcdc753acb9ba3afd6e30569.
>
> Reason for revert: breaking downstream projects and not reviewed by direct owners
>
> Original change's description:
> > Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> >
> > This reverts commit 24192c267a40eb7d6b1850489ccdbf7a84f8ff0f.
> >
> > Reason for revert: Analyzed the performance regression in more detail.
> >
> > Most of the regression comes from the extra RtpPacketInfos-related memory allocations in every `NetEq::GetAudio()` call. Commit 1796a820f60cb9429bf4bcf13a40a41794ac8fb0 has removed roughly 2/3rds of the extra allocations from the impacted perf tests. Remaining perf impact is expected to be about "8 microseconds of CPU time per second" on the Linux benchmarking machines and "15 us per second" on Windows/Mac.
> >
> > There are options to optimize further but they are unlikely worth doing. Note for example that `NetEqPerformanceTest` uses the PCM codec while the real-world use cases would likely use the much heavier Opus codec. The numbers from `OpusSpeedTest` and `NetEqPerformanceTest` suggest that Opus decoding is about 10x as expensive as NetEq overall.
> >
> > Original change's description:
> > > Revert "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> > >
> > > This reverts commit 3e8ef940fe86cf6285afb80e68d2a0bedc631b9f.
> > >
> > > Reason for revert: This CL causes a performance regression in NetEq, see https://bugs.chromium.org/p/chromium/issues/detail?id=982260.
> > >
> > > Original change's description:
> > > > Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.
> > > >
> > > > This change adds the plumbing of RtpPacketInfo from ChannelReceive::OnRtpPacket() to ChannelReceive::GetAudioFrameWithInfo() for audio. It is a step towards replacing the non-spec compliant ContributingSources that updates itself at packet-receive time, with the spec-compliant SourceTracker that will update itself at frame-delivery-to-track time.
> > > >
> > > > Bug: webrtc:10668
> > > > Change-Id: I03385d6865bbc7bfbef7634f88de820a934f787a
> > > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/139890
> > > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > > Reviewed-by: Minyue Li <minyue@webrtc.org>
> > > > Commit-Queue: Chen Xing <chxg@google.com>
> > > > Cr-Commit-Position: refs/heads/master@{#28434}
> > >
> > > TBR=kwiberg@webrtc.org,stefan@webrtc.org,minyue@webrtc.org,chxg@google.com
> > >
> > > Bug: webrtc:10668, chromium:982260
> > > Change-Id: I5e2cfde78c59d1123e21869564d76ed3f6193a5c
> > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/145339
> > > Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
> > > Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#28561}
> >
> > TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
> >
> > # Not skipping CQ checks because original CL landed > 1 day ago.
> >
> > Bug: webrtc:10668, chromium:982260
> > Change-Id: Ie375a0b327ee368317bf3a04b2f1415c3a974470
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146707
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Chen Xing <chxg@google.com>
> > Cr-Commit-Position: refs/heads/master@{#28664}
>
> TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
>
> Change-Id: I652cb0814d83b514d3bee34e65ca3bb693099b22
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: webrtc:10668, chromium:982260
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146712
> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
> Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#28671}
TBR=alessiob@webrtc.org,kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
Change-Id: Id43b7b3da79b4f48004b41767482bae1c1fa1e16
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:10668, chromium:982260
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146713
Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28672}
2019-07-24 16:47:02 +00:00
|
|
|
RTC_DCHECK(last_decoded_packet_infos_.empty());
|
2017-04-26 07:47:32 -07:00
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
// Do decoding.
|
2018-06-19 15:03:05 +02:00
|
|
|
while (!packet_list->empty() && !decoder_database_->IsComfortNoise(
|
|
|
|
|
packet_list->front().payload_type)) {
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(decoder); // At this point, we must have a decoder object.
|
2021-07-28 20:00:17 +02:00
|
|
|
// The number of channels in the `sync_buffer_` should be the same as the
|
2013-01-29 12:09:21 +00:00
|
|
|
// number decoder channels.
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK_EQ(sync_buffer_->Channels(), decoder->Channels());
|
|
|
|
|
RTC_DCHECK_GE(decoded_buffer_length_, kMaxFrameSize * decoder->Channels());
|
|
|
|
|
RTC_DCHECK(operation == Operation::kNormal ||
|
|
|
|
|
operation == Operation::kAccelerate ||
|
|
|
|
|
operation == Operation::kFastAccelerate ||
|
|
|
|
|
operation == Operation::kMerge ||
|
|
|
|
|
operation == Operation::kPreemptiveExpand);
|
2016-10-24 08:25:28 -07:00
|
|
|
|
|
|
|
|
auto opt_result = packet_list->front().frame->Decode(
|
2016-09-20 01:38:00 -07:00
|
|
|
rtc::ArrayView<int16_t>(&decoded_buffer_[*decoded_length],
|
|
|
|
|
decoded_buffer_length_ - *decoded_length));
|
2023-06-07 19:18:18 +02:00
|
|
|
if (packet_list->front().packet_info) {
|
|
|
|
|
last_decoded_packet_infos_.push_back(*packet_list->front().packet_info);
|
|
|
|
|
}
|
2016-10-24 08:25:28 -07:00
|
|
|
packet_list->pop_front();
|
2016-09-20 01:38:00 -07:00
|
|
|
if (opt_result) {
|
|
|
|
|
const auto& result = *opt_result;
|
|
|
|
|
*speech_type = result.speech_type;
|
|
|
|
|
if (result.num_decoded_samples > 0) {
|
2017-03-01 18:52:48 -08:00
|
|
|
*decoded_length += rtc::dchecked_cast<int>(result.num_decoded_samples);
|
2021-07-28 20:00:17 +02:00
|
|
|
// Update `decoder_frame_length_` with number of samples per channel.
|
2016-09-20 01:38:00 -07:00
|
|
|
decoder_frame_length_ =
|
|
|
|
|
result.num_decoded_samples / decoder->Channels();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2013-01-29 12:09:21 +00:00
|
|
|
// Error.
|
2016-09-20 01:38:00 -07:00
|
|
|
// TODO(ossu): What to put here?
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_WARNING) << "Decode error";
|
2013-01-29 12:09:21 +00:00
|
|
|
*decoded_length = -1;
|
Reland "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
This reverts commit fab3460a821abe336ab610c6d6dfc0d392dac263.
Reason for revert: fix downstream instead
Original change's description:
> Revert "Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.""
>
> This reverts commit 9973933d2e606d64fcdc753acb9ba3afd6e30569.
>
> Reason for revert: breaking downstream projects and not reviewed by direct owners
>
> Original change's description:
> > Reland "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> >
> > This reverts commit 24192c267a40eb7d6b1850489ccdbf7a84f8ff0f.
> >
> > Reason for revert: Analyzed the performance regression in more detail.
> >
> > Most of the regression comes from the extra RtpPacketInfos-related memory allocations in every `NetEq::GetAudio()` call. Commit 1796a820f60cb9429bf4bcf13a40a41794ac8fb0 has removed roughly 2/3rds of the extra allocations from the impacted perf tests. Remaining perf impact is expected to be about "8 microseconds of CPU time per second" on the Linux benchmarking machines and "15 us per second" on Windows/Mac.
> >
> > There are options to optimize further but they are unlikely worth doing. Note for example that `NetEqPerformanceTest` uses the PCM codec while the real-world use cases would likely use the much heavier Opus codec. The numbers from `OpusSpeedTest` and `NetEqPerformanceTest` suggest that Opus decoding is about 10x as expensive as NetEq overall.
> >
> > Original change's description:
> > > Revert "Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker."
> > >
> > > This reverts commit 3e8ef940fe86cf6285afb80e68d2a0bedc631b9f.
> > >
> > > Reason for revert: This CL causes a performance regression in NetEq, see https://bugs.chromium.org/p/chromium/issues/detail?id=982260.
> > >
> > > Original change's description:
> > > > Add plumbing of RtpPacketInfos to each AudioFrame as input for SourceTracker.
> > > >
> > > > This change adds the plumbing of RtpPacketInfo from ChannelReceive::OnRtpPacket() to ChannelReceive::GetAudioFrameWithInfo() for audio. It is a step towards replacing the non-spec compliant ContributingSources that updates itself at packet-receive time, with the spec-compliant SourceTracker that will update itself at frame-delivery-to-track time.
> > > >
> > > > Bug: webrtc:10668
> > > > Change-Id: I03385d6865bbc7bfbef7634f88de820a934f787a
> > > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/139890
> > > > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > > > Reviewed-by: Minyue Li <minyue@webrtc.org>
> > > > Commit-Queue: Chen Xing <chxg@google.com>
> > > > Cr-Commit-Position: refs/heads/master@{#28434}
> > >
> > > TBR=kwiberg@webrtc.org,stefan@webrtc.org,minyue@webrtc.org,chxg@google.com
> > >
> > > Bug: webrtc:10668, chromium:982260
> > > Change-Id: I5e2cfde78c59d1123e21869564d76ed3f6193a5c
> > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/145339
> > > Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
> > > Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
> > > Cr-Commit-Position: refs/heads/master@{#28561}
> >
> > TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
> >
> > # Not skipping CQ checks because original CL landed > 1 day ago.
> >
> > Bug: webrtc:10668, chromium:982260
> > Change-Id: Ie375a0b327ee368317bf3a04b2f1415c3a974470
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146707
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Chen Xing <chxg@google.com>
> > Cr-Commit-Position: refs/heads/master@{#28664}
>
> TBR=kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
>
> Change-Id: I652cb0814d83b514d3bee34e65ca3bb693099b22
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: webrtc:10668, chromium:982260
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146712
> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
> Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#28671}
TBR=alessiob@webrtc.org,kwiberg@webrtc.org,stefan@webrtc.org,ivoc@webrtc.org,minyue@webrtc.org,chxg@google.com
Change-Id: Id43b7b3da79b4f48004b41767482bae1c1fa1e16
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:10668, chromium:982260
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/146713
Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28672}
2019-07-24 16:47:02 +00:00
|
|
|
last_decoded_packet_infos_.clear();
|
2016-10-24 08:25:28 -07:00
|
|
|
packet_list->clear();
|
2013-01-29 12:09:21 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2017-03-01 18:52:48 -08:00
|
|
|
if (*decoded_length > rtc::dchecked_cast<int>(decoded_buffer_length_)) {
|
2013-01-29 12:09:21 +00:00
|
|
|
// Guard against overflow.
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_WARNING) << "Decoded too much.";
|
2016-10-24 08:25:28 -07:00
|
|
|
packet_list->clear();
|
2013-01-29 12:09:21 +00:00
|
|
|
return kDecodedTooMuch;
|
|
|
|
|
}
|
|
|
|
|
} // End of decode loop.
|
|
|
|
|
|
2013-10-31 15:15:55 +00:00
|
|
|
// If the list is not empty at this point, either a decoding error terminated
|
|
|
|
|
// the while-loop, or list must hold exactly one CNG packet.
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(
|
|
|
|
|
packet_list->empty() || *decoded_length < 0 ||
|
|
|
|
|
(packet_list->size() == 1 &&
|
|
|
|
|
decoder_database_->IsComfortNoise(packet_list->front().payload_type)));
|
2013-01-29 12:09:21 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
void NetEqImpl::DoNormal(const int16_t* decoded_buffer,
|
|
|
|
|
size_t decoded_length,
|
|
|
|
|
AudioDecoder::SpeechType speech_type,
|
|
|
|
|
bool play_dtmf) {
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(normal_.get());
|
2013-09-18 12:19:50 +00:00
|
|
|
normal_->Process(decoded_buffer, decoded_length, last_mode_,
|
2018-05-22 10:40:23 +02:00
|
|
|
algorithm_buffer_.get());
|
2013-01-29 12:09:21 +00:00
|
|
|
if (decoded_length != 0) {
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kNormal;
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If last packet was decoded as an inband CNG, set mode to CNG instead.
|
2018-06-19 15:03:05 +02:00
|
|
|
if ((speech_type == AudioDecoder::kComfortNoise) ||
|
2019-10-31 14:38:11 +01:00
|
|
|
((last_mode_ == Mode::kCodecInternalCng) && (decoded_length == 0))) {
|
2013-01-29 12:09:21 +00:00
|
|
|
// TODO(hlundin): Remove second part of || statement above.
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kCodecInternalCng;
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!play_dtmf) {
|
|
|
|
|
dtmf_tone_generator_->Reset();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
void NetEqImpl::DoMerge(int16_t* decoded_buffer,
|
|
|
|
|
size_t decoded_length,
|
|
|
|
|
AudioDecoder::SpeechType speech_type,
|
|
|
|
|
bool play_dtmf) {
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(merge_.get());
|
2018-06-19 15:03:05 +02:00
|
|
|
size_t new_length =
|
|
|
|
|
merge_->Process(decoded_buffer, decoded_length, algorithm_buffer_.get());
|
2017-05-05 05:04:16 -07:00
|
|
|
// Correction can be negative.
|
|
|
|
|
int expand_length_correction =
|
|
|
|
|
rtc::dchecked_cast<int>(new_length) -
|
|
|
|
|
rtc::dchecked_cast<int>(decoded_length / algorithm_buffer_->Channels());
|
2013-01-29 12:09:21 +00:00
|
|
|
|
|
|
|
|
// Update in-call and post-call statistics.
|
2023-03-29 15:42:19 +02:00
|
|
|
if (expand_->Muted() || last_decoded_type_ == AudioDecoder::kComfortNoise) {
|
2013-01-29 12:09:21 +00:00
|
|
|
// Expand generates only noise.
|
2019-03-05 16:59:03 +01:00
|
|
|
stats_->ExpandedNoiseSamplesCorrection(expand_length_correction);
|
2013-01-29 12:09:21 +00:00
|
|
|
} else {
|
|
|
|
|
// Expansion generates more than only noise.
|
2019-03-05 16:59:03 +01:00
|
|
|
stats_->ExpandedVoiceSamplesCorrection(expand_length_correction);
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kMerge;
|
2013-01-29 12:09:21 +00:00
|
|
|
// If last packet was decoded as an inband CNG, set mode to CNG instead.
|
|
|
|
|
if (speech_type == AudioDecoder::kComfortNoise) {
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kCodecInternalCng;
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
expand_->Reset();
|
|
|
|
|
if (!play_dtmf) {
|
|
|
|
|
dtmf_tone_generator_->Reset();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-05 18:14:52 +02:00
|
|
|
bool NetEqImpl::DoCodecPlc() {
|
|
|
|
|
AudioDecoder* decoder = decoder_database_->GetActiveDecoder();
|
|
|
|
|
if (!decoder) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
const size_t channels = algorithm_buffer_->Channels();
|
|
|
|
|
const size_t requested_samples_per_channel =
|
|
|
|
|
output_size_samples_ -
|
|
|
|
|
(sync_buffer_->FutureLength() - expand_->overlap_length());
|
|
|
|
|
concealment_audio_.Clear();
|
|
|
|
|
decoder->GeneratePlc(requested_samples_per_channel, &concealment_audio_);
|
|
|
|
|
if (concealment_audio_.empty()) {
|
|
|
|
|
// Nothing produced. Resort to regular expand.
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
RTC_CHECK_GE(concealment_audio_.size(),
|
|
|
|
|
requested_samples_per_channel * channels);
|
|
|
|
|
sync_buffer_->PushBackInterleaved(concealment_audio_);
|
|
|
|
|
RTC_DCHECK_NE(algorithm_buffer_->Channels(), 0);
|
|
|
|
|
const size_t concealed_samples_per_channel =
|
|
|
|
|
concealment_audio_.size() / channels;
|
|
|
|
|
|
|
|
|
|
// Update in-call and post-call statistics.
|
2019-10-31 14:38:11 +01:00
|
|
|
const bool is_new_concealment_event = (last_mode_ != Mode::kCodecPlc);
|
2018-09-05 18:14:52 +02:00
|
|
|
if (std::all_of(concealment_audio_.cbegin(), concealment_audio_.cend(),
|
|
|
|
|
[](int16_t i) { return i == 0; })) {
|
|
|
|
|
// Expand operation generates only noise.
|
2019-03-05 16:59:03 +01:00
|
|
|
stats_->ExpandedNoiseSamples(concealed_samples_per_channel,
|
|
|
|
|
is_new_concealment_event);
|
2018-09-05 18:14:52 +02:00
|
|
|
} else {
|
|
|
|
|
// Expand operation generates more than only noise.
|
2019-03-05 16:59:03 +01:00
|
|
|
stats_->ExpandedVoiceSamples(concealed_samples_per_channel,
|
|
|
|
|
is_new_concealment_event);
|
2018-09-05 18:14:52 +02:00
|
|
|
}
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kCodecPlc;
|
2018-09-05 18:14:52 +02:00
|
|
|
if (!generated_noise_stopwatch_) {
|
|
|
|
|
// Start a new stopwatch since we may be covering for a lost CNG packet.
|
|
|
|
|
generated_noise_stopwatch_ = tick_timer_->GetNewStopwatch();
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-02 07:59:30 +00:00
|
|
|
int NetEqImpl::DoExpand(bool play_dtmf) {
|
2013-01-29 12:09:21 +00:00
|
|
|
while ((sync_buffer_->FutureLength() - expand_->overlap_length()) <
|
2018-06-19 15:03:05 +02:00
|
|
|
output_size_samples_) {
|
2013-09-02 07:59:30 +00:00
|
|
|
algorithm_buffer_->Clear();
|
2013-09-18 21:12:38 +00:00
|
|
|
int return_value = expand_->Process(algorithm_buffer_.get());
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
size_t length = algorithm_buffer_->Size();
|
2019-10-31 14:38:11 +01:00
|
|
|
bool is_new_concealment_event = (last_mode_ != Mode::kExpand);
|
2013-01-29 12:09:21 +00:00
|
|
|
|
|
|
|
|
// Update in-call and post-call statistics.
|
2023-03-29 15:42:19 +02:00
|
|
|
if (expand_->Muted() || last_decoded_type_ == AudioDecoder::kComfortNoise) {
|
2013-01-29 12:09:21 +00:00
|
|
|
// Expand operation generates only noise.
|
2019-03-05 16:59:03 +01:00
|
|
|
stats_->ExpandedNoiseSamples(length, is_new_concealment_event);
|
2013-01-29 12:09:21 +00:00
|
|
|
} else {
|
|
|
|
|
// Expand operation generates more than only noise.
|
2019-03-05 16:59:03 +01:00
|
|
|
stats_->ExpandedVoiceSamples(length, is_new_concealment_event);
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kExpand;
|
2013-01-29 12:09:21 +00:00
|
|
|
|
|
|
|
|
if (return_value < 0) {
|
|
|
|
|
return return_value;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-02 07:59:30 +00:00
|
|
|
sync_buffer_->PushBack(*algorithm_buffer_);
|
|
|
|
|
algorithm_buffer_->Clear();
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
if (!play_dtmf) {
|
|
|
|
|
dtmf_tone_generator_->Reset();
|
|
|
|
|
}
|
2016-05-03 08:18:47 -07:00
|
|
|
|
|
|
|
|
if (!generated_noise_stopwatch_) {
|
|
|
|
|
// Start a new stopwatch since we may be covering for a lost CNG packet.
|
|
|
|
|
generated_noise_stopwatch_ = tick_timer_->GetNewStopwatch();
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-27 14:33:29 +02:00
|
|
|
int NetEqImpl::DoAccelerate(int16_t* decoded_buffer,
|
|
|
|
|
size_t decoded_length,
|
2013-01-29 12:09:21 +00:00
|
|
|
AudioDecoder::SpeechType speech_type,
|
2015-05-27 14:33:29 +02:00
|
|
|
bool play_dtmf,
|
|
|
|
|
bool fast_accelerate) {
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
const size_t required_samples =
|
|
|
|
|
static_cast<size_t>(240 * fs_mult_); // Must have 30 ms.
|
2013-09-20 16:25:28 +00:00
|
|
|
size_t borrowed_samples_per_channel = 0;
|
2013-09-02 07:59:30 +00:00
|
|
|
size_t num_channels = algorithm_buffer_->Channels();
|
2013-01-29 12:09:21 +00:00
|
|
|
size_t decoded_length_per_channel = decoded_length / num_channels;
|
|
|
|
|
if (decoded_length_per_channel < required_samples) {
|
2021-07-28 20:00:17 +02:00
|
|
|
// Must move data from the `sync_buffer_` in order to get 30 ms.
|
2018-06-19 15:03:05 +02:00
|
|
|
borrowed_samples_per_channel =
|
|
|
|
|
static_cast<int>(required_samples - decoded_length_per_channel);
|
2013-01-29 12:09:21 +00:00
|
|
|
memmove(&decoded_buffer[borrowed_samples_per_channel * num_channels],
|
2018-06-19 15:03:05 +02:00
|
|
|
decoded_buffer, sizeof(int16_t) * decoded_length);
|
2013-01-29 12:09:21 +00:00
|
|
|
sync_buffer_->ReadInterleavedFromEnd(borrowed_samples_per_channel,
|
|
|
|
|
decoded_buffer);
|
|
|
|
|
decoded_length = required_samples * num_channels;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-03 16:36:17 +01:00
|
|
|
size_t samples_removed = 0;
|
2015-05-27 14:33:29 +02:00
|
|
|
Accelerate::ReturnCodes return_code =
|
|
|
|
|
accelerate_->Process(decoded_buffer, decoded_length, fast_accelerate,
|
|
|
|
|
algorithm_buffer_.get(), &samples_removed);
|
2019-03-05 16:59:03 +01:00
|
|
|
stats_->AcceleratedSamples(samples_removed);
|
2013-01-29 12:09:21 +00:00
|
|
|
switch (return_code) {
|
|
|
|
|
case Accelerate::kSuccess:
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kAccelerateSuccess;
|
2013-01-29 12:09:21 +00:00
|
|
|
break;
|
|
|
|
|
case Accelerate::kSuccessLowEnergy:
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kAccelerateLowEnergy;
|
2013-01-29 12:09:21 +00:00
|
|
|
break;
|
|
|
|
|
case Accelerate::kNoStretch:
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kAccelerateFail;
|
2013-01-29 12:09:21 +00:00
|
|
|
break;
|
|
|
|
|
case Accelerate::kError:
|
2019-10-31 14:38:11 +01:00
|
|
|
// TODO(hlundin): Map to Modes::kError instead?
|
|
|
|
|
last_mode_ = Mode::kAccelerateFail;
|
2013-01-29 12:09:21 +00:00
|
|
|
return kAccelerateError;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (borrowed_samples_per_channel > 0) {
|
2021-07-28 20:00:17 +02:00
|
|
|
// Copy borrowed samples back to the `sync_buffer_`.
|
2013-09-20 16:25:28 +00:00
|
|
|
size_t length = algorithm_buffer_->Size();
|
2013-01-29 12:09:21 +00:00
|
|
|
if (length < borrowed_samples_per_channel) {
|
|
|
|
|
// This destroys the beginning of the buffer, but will not cause any
|
|
|
|
|
// problems.
|
2018-06-19 15:03:05 +02:00
|
|
|
sync_buffer_->ReplaceAtIndex(
|
|
|
|
|
*algorithm_buffer_,
|
|
|
|
|
sync_buffer_->Size() - borrowed_samples_per_channel);
|
2013-01-29 12:09:21 +00:00
|
|
|
sync_buffer_->PushFrontZeros(borrowed_samples_per_channel - length);
|
2013-09-02 07:59:30 +00:00
|
|
|
algorithm_buffer_->PopFront(length);
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(algorithm_buffer_->Empty());
|
2013-01-29 12:09:21 +00:00
|
|
|
} else {
|
2018-06-19 15:03:05 +02:00
|
|
|
sync_buffer_->ReplaceAtIndex(
|
|
|
|
|
*algorithm_buffer_, borrowed_samples_per_channel,
|
|
|
|
|
sync_buffer_->Size() - borrowed_samples_per_channel);
|
2013-09-02 07:59:30 +00:00
|
|
|
algorithm_buffer_->PopFront(borrowed_samples_per_channel);
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If last packet was decoded as an inband CNG, set mode to CNG instead.
|
|
|
|
|
if (speech_type == AudioDecoder::kComfortNoise) {
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kCodecInternalCng;
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
if (!play_dtmf) {
|
|
|
|
|
dtmf_tone_generator_->Reset();
|
|
|
|
|
}
|
|
|
|
|
expand_->Reset();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int NetEqImpl::DoPreemptiveExpand(int16_t* decoded_buffer,
|
|
|
|
|
size_t decoded_length,
|
|
|
|
|
AudioDecoder::SpeechType speech_type,
|
2013-09-02 07:59:30 +00:00
|
|
|
bool play_dtmf) {
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
const size_t required_samples =
|
|
|
|
|
static_cast<size_t>(240 * fs_mult_); // Must have 30 ms.
|
2013-09-02 07:59:30 +00:00
|
|
|
size_t num_channels = algorithm_buffer_->Channels();
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
size_t borrowed_samples_per_channel = 0;
|
|
|
|
|
size_t old_borrowed_samples_per_channel = 0;
|
2013-01-29 12:09:21 +00:00
|
|
|
size_t decoded_length_per_channel = decoded_length / num_channels;
|
|
|
|
|
if (decoded_length_per_channel < required_samples) {
|
2021-07-28 20:00:17 +02:00
|
|
|
// Must move data from the `sync_buffer_` in order to get 30 ms.
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
borrowed_samples_per_channel =
|
|
|
|
|
required_samples - decoded_length_per_channel;
|
2013-01-29 12:09:21 +00:00
|
|
|
// Calculate how many of these were already played out.
|
2015-06-10 21:15:38 -07:00
|
|
|
old_borrowed_samples_per_channel =
|
2018-06-19 15:03:05 +02:00
|
|
|
(borrowed_samples_per_channel > sync_buffer_->FutureLength())
|
|
|
|
|
? (borrowed_samples_per_channel - sync_buffer_->FutureLength())
|
|
|
|
|
: 0;
|
2013-01-29 12:09:21 +00:00
|
|
|
memmove(&decoded_buffer[borrowed_samples_per_channel * num_channels],
|
2018-06-19 15:03:05 +02:00
|
|
|
decoded_buffer, sizeof(int16_t) * decoded_length);
|
2013-01-29 12:09:21 +00:00
|
|
|
sync_buffer_->ReadInterleavedFromEnd(borrowed_samples_per_channel,
|
|
|
|
|
decoded_buffer);
|
|
|
|
|
decoded_length = required_samples * num_channels;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-03 16:36:17 +01:00
|
|
|
size_t samples_added = 0;
|
2013-09-18 12:19:50 +00:00
|
|
|
PreemptiveExpand::ReturnCodes return_code = preemptive_expand_->Process(
|
2018-06-19 15:03:05 +02:00
|
|
|
decoded_buffer, decoded_length, old_borrowed_samples_per_channel,
|
2013-09-18 21:12:38 +00:00
|
|
|
algorithm_buffer_.get(), &samples_added);
|
2019-03-05 16:59:03 +01:00
|
|
|
stats_->PreemptiveExpandedSamples(samples_added);
|
2013-01-29 12:09:21 +00:00
|
|
|
switch (return_code) {
|
|
|
|
|
case PreemptiveExpand::kSuccess:
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kPreemptiveExpandSuccess;
|
2013-01-29 12:09:21 +00:00
|
|
|
break;
|
|
|
|
|
case PreemptiveExpand::kSuccessLowEnergy:
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kPreemptiveExpandLowEnergy;
|
2013-01-29 12:09:21 +00:00
|
|
|
break;
|
|
|
|
|
case PreemptiveExpand::kNoStretch:
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kPreemptiveExpandFail;
|
2013-01-29 12:09:21 +00:00
|
|
|
break;
|
|
|
|
|
case PreemptiveExpand::kError:
|
2019-10-31 14:38:11 +01:00
|
|
|
// TODO(hlundin): Map to Modes::kError instead?
|
|
|
|
|
last_mode_ = Mode::kPreemptiveExpandFail;
|
2013-01-29 12:09:21 +00:00
|
|
|
return kPreemptiveExpandError;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (borrowed_samples_per_channel > 0) {
|
2021-07-28 20:00:17 +02:00
|
|
|
// Copy borrowed samples back to the `sync_buffer_`.
|
2013-01-29 12:09:21 +00:00
|
|
|
sync_buffer_->ReplaceAtIndex(
|
2013-09-02 07:59:30 +00:00
|
|
|
*algorithm_buffer_, borrowed_samples_per_channel,
|
2013-01-29 12:09:21 +00:00
|
|
|
sync_buffer_->Size() - borrowed_samples_per_channel);
|
2013-09-02 07:59:30 +00:00
|
|
|
algorithm_buffer_->PopFront(borrowed_samples_per_channel);
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If last packet was decoded as an inband CNG, set mode to CNG instead.
|
|
|
|
|
if (speech_type == AudioDecoder::kComfortNoise) {
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kCodecInternalCng;
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
if (!play_dtmf) {
|
|
|
|
|
dtmf_tone_generator_->Reset();
|
|
|
|
|
}
|
|
|
|
|
expand_->Reset();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-02 07:59:30 +00:00
|
|
|
int NetEqImpl::DoRfc3389Cng(PacketList* packet_list, bool play_dtmf) {
|
2013-01-29 12:09:21 +00:00
|
|
|
if (!packet_list->empty()) {
|
|
|
|
|
// Must have exactly one SID frame at this point.
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK_EQ(packet_list->size(), 1);
|
2016-10-24 08:25:28 -07:00
|
|
|
const Packet& packet = packet_list->front();
|
|
|
|
|
if (!decoder_database_->IsComfortNoise(packet.payload_type)) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_ERROR) << "Trying to decode non-CNG payload as CNG.";
|
2013-01-31 13:32:51 +00:00
|
|
|
return kOtherError;
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
if (comfort_noise_->UpdateParameters(packet) ==
|
|
|
|
|
ComfortNoise::kInternalError) {
|
2013-09-02 07:59:30 +00:00
|
|
|
algorithm_buffer_->Zeros(output_size_samples_);
|
2013-01-29 12:09:21 +00:00
|
|
|
return -comfort_noise_->internal_error_code();
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-19 15:03:05 +02:00
|
|
|
int cn_return =
|
|
|
|
|
comfort_noise_->Generate(output_size_samples_, algorithm_buffer_.get());
|
2013-01-29 12:09:21 +00:00
|
|
|
expand_->Reset();
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kRfc3389Cng;
|
2013-01-29 12:09:21 +00:00
|
|
|
if (!play_dtmf) {
|
|
|
|
|
dtmf_tone_generator_->Reset();
|
|
|
|
|
}
|
|
|
|
|
if (cn_return == ComfortNoise::kInternalError) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_WARNING) << "Comfort noise generator returned error code: "
|
|
|
|
|
<< comfort_noise_->internal_error_code();
|
2013-01-29 12:09:21 +00:00
|
|
|
return kComfortNoiseErrorCode;
|
|
|
|
|
} else if (cn_return == ComfortNoise::kUnknownPayloadType) {
|
|
|
|
|
return kUnknownRtpPayloadType;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-23 15:20:39 +02:00
|
|
|
void NetEqImpl::DoCodecInternalCng(const int16_t* decoded_buffer,
|
|
|
|
|
size_t decoded_length) {
|
|
|
|
|
RTC_DCHECK(normal_.get());
|
|
|
|
|
normal_->Process(decoded_buffer, decoded_length, last_mode_,
|
2018-05-22 10:40:23 +02:00
|
|
|
algorithm_buffer_.get());
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kCodecInternalCng;
|
2013-01-29 12:09:21 +00:00
|
|
|
expand_->Reset();
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-02 07:59:30 +00:00
|
|
|
int NetEqImpl::DoDtmf(const DtmfEvent& dtmf_event, bool* play_dtmf) {
|
2021-07-28 20:00:17 +02:00
|
|
|
// This block of the code and the block further down, handling `dtmf_switch`
|
2013-03-27 18:31:42 +00:00
|
|
|
// are commented out. Otherwise playing out-of-band DTMF would fail in VoE
|
|
|
|
|
// test, DtmfTest.ManualSuccessfullySendsOutOfBandTelephoneEvents. This is
|
2021-07-28 20:00:17 +02:00
|
|
|
// equivalent to `dtmf_switch` always be false.
|
2013-03-27 18:31:42 +00:00
|
|
|
//
|
|
|
|
|
// See http://webrtc-codereview.appspot.com/1195004/ for discussion
|
|
|
|
|
// On this issue. This change might cause some glitches at the point of
|
|
|
|
|
// switch from audio to DTMF. Issue 1545 is filed to track this.
|
|
|
|
|
//
|
|
|
|
|
// bool dtmf_switch = false;
|
2019-10-31 14:38:11 +01:00
|
|
|
// if ((last_mode_ != Modes::kDtmf) &&
|
|
|
|
|
// dtmf_tone_generator_->initialized()) {
|
2013-03-27 18:31:42 +00:00
|
|
|
// // Special case; see below.
|
2021-07-28 20:00:17 +02:00
|
|
|
// // We must catch this before calling Generate, since `initialized` is
|
2013-03-27 18:31:42 +00:00
|
|
|
// // modified in that call.
|
|
|
|
|
// dtmf_switch = true;
|
|
|
|
|
// }
|
2013-01-29 12:09:21 +00:00
|
|
|
|
|
|
|
|
int dtmf_return_value = 0;
|
|
|
|
|
if (!dtmf_tone_generator_->initialized()) {
|
|
|
|
|
// Initialize if not already done.
|
|
|
|
|
dtmf_return_value = dtmf_tone_generator_->Init(fs_hz_, dtmf_event.event_no,
|
|
|
|
|
dtmf_event.volume);
|
|
|
|
|
}
|
2013-03-27 18:31:42 +00:00
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
if (dtmf_return_value == 0) {
|
|
|
|
|
// Generate DTMF signal.
|
|
|
|
|
dtmf_return_value = dtmf_tone_generator_->Generate(output_size_samples_,
|
2013-09-18 21:12:38 +00:00
|
|
|
algorithm_buffer_.get());
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
2013-03-27 18:31:42 +00:00
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
if (dtmf_return_value < 0) {
|
2013-09-02 07:59:30 +00:00
|
|
|
algorithm_buffer_->Zeros(output_size_samples_);
|
2013-01-29 12:09:21 +00:00
|
|
|
return dtmf_return_value;
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-27 18:31:42 +00:00
|
|
|
// if (dtmf_switch) {
|
|
|
|
|
// // This is the special case where the previous operation was DTMF
|
|
|
|
|
// // overdub, but the current instruction is "regular" DTMF. We must make
|
|
|
|
|
// // sure that the DTMF does not have any discontinuities. The first DTMF
|
|
|
|
|
// // sample that we generate now must be played out immediately, therefore
|
|
|
|
|
// // it must be copied to the speech buffer.
|
|
|
|
|
// // TODO(hlundin): This code seems incorrect. (Legacy.) Write test and
|
|
|
|
|
// // verify correct operation.
|
2021-11-15 16:57:07 +01:00
|
|
|
// RTC_DCHECK_NOTREACHED();
|
2021-07-28 20:00:17 +02:00
|
|
|
// // Must generate enough data to replace all of the `sync_buffer_`
|
2013-03-27 18:31:42 +00:00
|
|
|
// // "future".
|
|
|
|
|
// int required_length = sync_buffer_->FutureLength();
|
2021-07-08 20:08:20 +02:00
|
|
|
// RTC_DCHECK(dtmf_tone_generator_->initialized());
|
2013-03-27 18:31:42 +00:00
|
|
|
// dtmf_return_value = dtmf_tone_generator_->Generate(required_length,
|
2013-09-02 07:59:30 +00:00
|
|
|
// algorithm_buffer_);
|
2021-07-08 20:08:20 +02:00
|
|
|
// RTC_DCHECK((size_t) required_length == algorithm_buffer_->Size());
|
2013-03-27 18:31:42 +00:00
|
|
|
// if (dtmf_return_value < 0) {
|
2013-09-02 07:59:30 +00:00
|
|
|
// algorithm_buffer_->Zeros(output_size_samples_);
|
2013-03-27 18:31:42 +00:00
|
|
|
// return dtmf_return_value;
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// // Overwrite the "future" part of the speech buffer with the new DTMF
|
|
|
|
|
// // data.
|
|
|
|
|
// // TODO(hlundin): It seems that this overwriting has gone lost.
|
|
|
|
|
// // Not adapted for multi-channel yet.
|
2021-07-08 20:08:20 +02:00
|
|
|
// RTC_DCHECK(algorithm_buffer_->Channels() == 1);
|
2013-09-02 07:59:30 +00:00
|
|
|
// if (algorithm_buffer_->Channels() != 1) {
|
2017-11-09 11:09:25 +01:00
|
|
|
// RTC_LOG(LS_WARNING) << "DTMF not supported for more than one channel";
|
2013-03-27 18:31:42 +00:00
|
|
|
// return kStereoNotSupported;
|
|
|
|
|
// }
|
|
|
|
|
// // Shuffle the remaining data to the beginning of algorithm buffer.
|
2013-09-02 07:59:30 +00:00
|
|
|
// algorithm_buffer_->PopFront(sync_buffer_->FutureLength());
|
2013-03-27 18:31:42 +00:00
|
|
|
// }
|
2013-01-29 12:09:21 +00:00
|
|
|
|
Match existing type usage better.
This makes a variety of small changes to synchronize bits of code using different types, remove useless code or casts, and add explicit casts in some places previously doing implicit ones. For example:
* Change a few type declarations to better match how the majority of code uses those objects.
* Eliminate "< 0" check for unsigned values.
* Replace "(float)sin(x)", where |x| is also a float, with "sinf(x)", and similar.
* Add casts to uint32_t in many places timestamps were used and the existing code stored signed values into the unsigned objects.
* Remove downcasts when the results would be passed to a larger type, e.g. calling "foo((int16_t)x)" with an int |x| when foo() takes an int instead of an int16_t.
* Similarly, add casts when passing a larger type to a function taking a smaller one.
* Add casts to int16_t when doing something like "int16_t = int16_t + int16_t" as the "+" operation would implicitly upconvert to int, and similar.
* Use "false" instead of "0" for setting a bool.
* Shift a few temp types when doing a multi-stage calculation involving typecasts, so as to put the most logical/semantically correct type possible into the temps. For example, when doing "int foo = int + int; size_t bar = (size_t)foo + size_t;", we might change |foo| to a size_t and move the cast if it makes more sense for |foo| to be represented as a size_t.
BUG=none
R=andrew@webrtc.org, asapersson@webrtc.org, henrika@webrtc.org, juberti@webrtc.org, kwiberg@webrtc.org
TBR=andrew, asapersson, henrika
Review URL: https://codereview.webrtc.org/1168753002
Cr-Commit-Position: refs/heads/master@{#9419}
2015-06-11 12:55:50 -07:00
|
|
|
sync_buffer_->IncreaseEndTimestamp(
|
|
|
|
|
static_cast<uint32_t>(output_size_samples_));
|
2013-01-29 12:09:21 +00:00
|
|
|
expand_->Reset();
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kDtmf;
|
2013-01-29 12:09:21 +00:00
|
|
|
|
|
|
|
|
// Set to false because the DTMF is already in the algorithm buffer.
|
|
|
|
|
*play_dtmf = false;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
int NetEqImpl::DtmfOverdub(const DtmfEvent& dtmf_event,
|
|
|
|
|
size_t num_channels,
|
2013-01-29 12:09:21 +00:00
|
|
|
int16_t* output) const {
|
|
|
|
|
size_t out_index = 0;
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
size_t overdub_length = output_size_samples_; // Default value.
|
2013-01-29 12:09:21 +00:00
|
|
|
|
|
|
|
|
if (sync_buffer_->dtmf_index() > sync_buffer_->next_index()) {
|
|
|
|
|
// Special operation for transition from "DTMF only" to "DTMF overdub".
|
2018-06-19 15:03:05 +02:00
|
|
|
out_index =
|
|
|
|
|
std::min(sync_buffer_->dtmf_index() - sync_buffer_->next_index(),
|
|
|
|
|
output_size_samples_);
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
overdub_length = output_size_samples_ - out_index;
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
2013-09-30 20:38:44 +00:00
|
|
|
AudioMultiVector dtmf_output(num_channels);
|
2013-01-29 12:09:21 +00:00
|
|
|
int dtmf_return_value = 0;
|
|
|
|
|
if (!dtmf_tone_generator_->initialized()) {
|
|
|
|
|
dtmf_return_value = dtmf_tone_generator_->Init(fs_hz_, dtmf_event.event_no,
|
|
|
|
|
dtmf_event.volume);
|
|
|
|
|
}
|
|
|
|
|
if (dtmf_return_value == 0) {
|
2018-06-19 15:03:05 +02:00
|
|
|
dtmf_return_value =
|
|
|
|
|
dtmf_tone_generator_->Generate(overdub_length, &dtmf_output);
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK_EQ(overdub_length, dtmf_output.Size());
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
dtmf_output.ReadInterleaved(overdub_length, &output[out_index]);
|
|
|
|
|
return dtmf_return_value < 0 ? dtmf_return_value : 0;
|
|
|
|
|
}
|
|
|
|
|
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
int NetEqImpl::ExtractPackets(size_t required_samples,
|
|
|
|
|
PacketList* packet_list) {
|
2013-01-29 12:09:21 +00:00
|
|
|
bool first_packet = true;
|
|
|
|
|
bool next_packet_available = false;
|
|
|
|
|
|
2016-10-18 04:06:13 -07:00
|
|
|
const Packet* next_packet = packet_buffer_->PeekNextPacket();
|
|
|
|
|
RTC_DCHECK(next_packet);
|
|
|
|
|
if (!next_packet) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_ERROR) << "Packet buffer unexpectedly empty.";
|
2013-01-29 12:09:21 +00:00
|
|
|
return -1;
|
|
|
|
|
}
|
2016-10-18 04:06:13 -07:00
|
|
|
uint32_t first_timestamp = next_packet->timestamp;
|
2016-09-20 01:38:00 -07:00
|
|
|
size_t extracted_samples = 0;
|
2013-01-29 12:09:21 +00:00
|
|
|
|
|
|
|
|
// Packet extraction loop.
|
|
|
|
|
do {
|
2016-10-18 04:06:13 -07:00
|
|
|
timestamp_ = next_packet->timestamp;
|
2018-06-19 13:26:36 +02:00
|
|
|
absl::optional<Packet> packet = packet_buffer_->GetNextPacket();
|
2021-07-28 20:00:17 +02:00
|
|
|
// `next_packet` may be invalid after the `packet_buffer_` operation.
|
2016-10-24 08:25:28 -07:00
|
|
|
next_packet = nullptr;
|
2013-01-29 12:09:21 +00:00
|
|
|
if (!packet) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_ERROR) << "Should always be able to extract a packet here";
|
2021-11-15 16:57:07 +01:00
|
|
|
RTC_DCHECK_NOTREACHED(); // Should always be able to extract a packet
|
|
|
|
|
// here.
|
2013-01-29 12:09:21 +00:00
|
|
|
return -1;
|
|
|
|
|
}
|
2017-10-02 12:00:34 +02:00
|
|
|
const uint64_t waiting_time_ms = packet->waiting_time->ElapsedMs();
|
2019-03-05 16:59:03 +01:00
|
|
|
stats_->StoreWaitingTime(waiting_time_ms);
|
2016-09-20 01:38:00 -07:00
|
|
|
RTC_DCHECK(!packet->empty());
|
2013-01-29 12:09:21 +00:00
|
|
|
|
|
|
|
|
if (first_packet) {
|
|
|
|
|
first_packet = false;
|
2015-10-29 05:36:24 -07:00
|
|
|
if (nack_enabled_) {
|
|
|
|
|
RTC_DCHECK(nack_);
|
|
|
|
|
// TODO(henrik.lundin): Should we update this for all decoded packets?
|
2016-10-18 04:06:13 -07:00
|
|
|
nack_->UpdateLastDecodedPacket(packet->sequence_number,
|
|
|
|
|
packet->timestamp);
|
2015-10-29 05:36:24 -07:00
|
|
|
}
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
2017-01-02 07:00:50 -08:00
|
|
|
const bool has_cng_packet =
|
|
|
|
|
decoder_database_->IsComfortNoise(packet->payload_type);
|
2013-01-29 12:09:21 +00:00
|
|
|
// Store number of extracted samples.
|
2016-09-20 01:38:00 -07:00
|
|
|
size_t packet_duration = 0;
|
|
|
|
|
if (packet->frame) {
|
|
|
|
|
packet_duration = packet->frame->Duration();
|
2016-09-22 02:06:28 -07:00
|
|
|
// TODO(ossu): Is this the correct way to track Opus FEC packets?
|
|
|
|
|
if (packet->priority.codec_level > 0) {
|
2019-03-05 16:59:03 +01:00
|
|
|
stats_->SecondaryDecodedSamples(
|
2017-03-01 18:52:48 -08:00
|
|
|
rtc::dchecked_cast<int>(packet_duration));
|
2014-03-21 12:07:40 +00:00
|
|
|
}
|
2017-01-02 07:00:50 -08:00
|
|
|
} else if (!has_cng_packet) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_WARNING) << "Unknown payload type "
|
|
|
|
|
<< static_cast<int>(packet->payload_type);
|
2021-11-15 16:57:07 +01:00
|
|
|
RTC_DCHECK_NOTREACHED();
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
2016-09-20 01:38:00 -07:00
|
|
|
|
|
|
|
|
if (packet_duration == 0) {
|
2013-01-29 12:09:21 +00:00
|
|
|
// Decoder did not return a packet duration. Assume that the packet
|
|
|
|
|
// contains the same number of samples as the previous one.
|
2016-09-20 01:38:00 -07:00
|
|
|
packet_duration = decoder_frame_length_;
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
2016-10-18 04:06:13 -07:00
|
|
|
extracted_samples = packet->timestamp - first_timestamp + packet_duration;
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2020-03-11 11:18:54 +01:00
|
|
|
RTC_DCHECK(controller_);
|
2021-11-08 17:22:51 +01:00
|
|
|
stats_->JitterBufferDelay(packet_duration, waiting_time_ms,
|
2022-07-19 16:33:10 +02:00
|
|
|
controller_->TargetLevelMs(),
|
|
|
|
|
controller_->UnlimitedTargetLevelMs());
|
2017-10-02 12:00:34 +02:00
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
// Check what packet is available next.
|
2016-10-18 04:06:13 -07:00
|
|
|
next_packet = packet_buffer_->PeekNextPacket();
|
2023-04-11 16:36:02 +02:00
|
|
|
next_packet_available =
|
|
|
|
|
next_packet && next_packet->payload_type == packet->payload_type &&
|
|
|
|
|
next_packet->timestamp == packet->timestamp + packet_duration &&
|
|
|
|
|
!has_cng_packet;
|
|
|
|
|
|
|
|
|
|
packet_list->push_back(std::move(*packet)); // Store packet in list.
|
|
|
|
|
packet = absl::nullopt; // Ensure it's never used after the move.
|
2016-09-20 01:38:00 -07:00
|
|
|
} while (extracted_samples < required_samples && next_packet_available);
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2014-09-22 08:30:07 +00:00
|
|
|
if (extracted_samples > 0) {
|
|
|
|
|
// Delete old packets only when we are going to decode something. Otherwise,
|
|
|
|
|
// we could end up in the situation where we never decode anything, since
|
|
|
|
|
// all incoming packets are considered too old but the buffer will also
|
|
|
|
|
// never be flooded and flushed.
|
2023-11-07 10:10:47 +01:00
|
|
|
packet_buffer_->DiscardAllOldPackets(timestamp_);
|
2014-09-22 08:30:07 +00:00
|
|
|
}
|
|
|
|
|
|
2017-03-01 18:52:48 -08:00
|
|
|
return rtc::dchecked_cast<int>(extracted_samples);
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
2014-04-11 18:47:55 +00:00
|
|
|
void NetEqImpl::UpdatePlcComponents(int fs_hz, size_t channels) {
|
|
|
|
|
// Delete objects and create new ones.
|
|
|
|
|
expand_.reset(expand_factory_->Create(background_noise_.get(),
|
|
|
|
|
sync_buffer_.get(), &random_vector_,
|
2019-03-05 16:59:03 +01:00
|
|
|
stats_.get(), fs_hz, channels));
|
2014-04-11 18:47:55 +00:00
|
|
|
merge_.reset(new Merge(fs_hz, channels, expand_.get(), sync_buffer_.get()));
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
void NetEqImpl::SetSampleRateAndChannels(int fs_hz, size_t channels) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_VERBOSE) << "SetSampleRateAndChannels " << fs_hz << " "
|
|
|
|
|
<< channels;
|
2013-01-29 12:09:21 +00:00
|
|
|
// TODO(hlundin): Change to an enumerator and skip assert.
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(fs_hz == 8000 || fs_hz == 16000 || fs_hz == 32000 ||
|
|
|
|
|
fs_hz == 48000);
|
|
|
|
|
RTC_DCHECK_GT(channels, 0);
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2019-11-19 12:58:11 +01:00
|
|
|
// Before changing the sample rate, end and report any ongoing expand event.
|
|
|
|
|
stats_->EndExpandEvent(fs_hz_);
|
2013-01-29 12:09:21 +00:00
|
|
|
fs_hz_ = fs_hz;
|
|
|
|
|
fs_mult_ = fs_hz / 8000;
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
output_size_samples_ = static_cast<size_t>(kOutputSizeMs * 8 * fs_mult_);
|
2013-01-29 12:09:21 +00:00
|
|
|
decoder_frame_length_ = 3 * output_size_samples_; // Initialize to 30ms.
|
|
|
|
|
|
2019-10-31 14:38:11 +01:00
|
|
|
last_mode_ = Mode::kNormal;
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2016-04-25 07:55:58 -07:00
|
|
|
ComfortNoiseDecoder* cng_decoder = decoder_database_->GetActiveCngDecoder();
|
2015-08-27 15:22:11 +02:00
|
|
|
if (cng_decoder)
|
|
|
|
|
cng_decoder->Reset();
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2013-09-02 07:59:30 +00:00
|
|
|
// Delete algorithm buffer and create a new one.
|
2013-09-30 20:38:44 +00:00
|
|
|
algorithm_buffer_.reset(new AudioMultiVector(channels));
|
2013-09-02 07:59:30 +00:00
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
// Delete sync buffer and create a new one.
|
2013-09-18 21:12:38 +00:00
|
|
|
sync_buffer_.reset(new SyncBuffer(channels, kSyncBufferSize * fs_mult_));
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2014-08-07 12:27:37 +00:00
|
|
|
// Delete BackgroundNoise object and create a new one.
|
2013-09-18 21:12:38 +00:00
|
|
|
background_noise_.reset(new BackgroundNoise(channels));
|
2013-01-29 12:09:21 +00:00
|
|
|
|
|
|
|
|
// Reset random vector.
|
|
|
|
|
random_vector_.Reset();
|
|
|
|
|
|
2014-04-11 18:47:55 +00:00
|
|
|
UpdatePlcComponents(fs_hz, channels);
|
|
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
// Move index so that we create a small set of future samples (all 0).
|
|
|
|
|
sync_buffer_->set_next_index(sync_buffer_->next_index() -
|
2018-06-19 15:03:05 +02:00
|
|
|
expand_->overlap_length());
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2013-09-18 12:19:50 +00:00
|
|
|
normal_.reset(new Normal(fs_hz, decoder_database_.get(), *background_noise_,
|
2021-02-10 10:38:50 +01:00
|
|
|
expand_.get(), stats_.get()));
|
2014-01-14 10:18:45 +00:00
|
|
|
accelerate_.reset(
|
|
|
|
|
accelerate_factory_->Create(fs_hz, channels, *background_noise_));
|
2014-04-11 18:47:55 +00:00
|
|
|
preemptive_expand_.reset(preemptive_expand_factory_->Create(
|
Update a ton of audio code to use size_t more correctly and in general reduce
use of int16_t/uint16_t.
This is the upshot of a recommendation by henrik.lundin and kwiberg on an original small change ( https://webrtc-codereview.appspot.com/42569004/#ps1 ) to stop using int16_t just because values could fit in it, and is similar in nature to a previous "mass change to use size_t more" ( https://webrtc-codereview.appspot.com/23129004/ ) which also needed to be split up for review but to land all at once, since, like adding "const", such changes tend to cause a lot of transitive effects.
This was be reviewed and approved in pieces:
https://codereview.webrtc.org/1224093003
https://codereview.webrtc.org/1224123002
https://codereview.webrtc.org/1224163002
https://codereview.webrtc.org/1225133003
https://codereview.webrtc.org/1225173002
https://codereview.webrtc.org/1227163003
https://codereview.webrtc.org/1227203003
https://codereview.webrtc.org/1227213002
https://codereview.webrtc.org/1227893002
https://codereview.webrtc.org/1228793004
https://codereview.webrtc.org/1228803003
https://codereview.webrtc.org/1228823002
https://codereview.webrtc.org/1228823003
https://codereview.webrtc.org/1228843002
https://codereview.webrtc.org/1230693002
https://codereview.webrtc.org/1231713002
The change is being landed as TBR to all the folks who reviewed the above.
BUG=chromium:81439
TEST=none
R=andrew@webrtc.org, pbos@webrtc.org
TBR=aluebs, andrew, asapersson, henrika, hlundin, jan.skoglund, kwiberg, minyue, pbos, pthatcher
Review URL: https://codereview.webrtc.org/1230503003 .
Cr-Commit-Position: refs/heads/master@{#9768}
2015-08-24 14:52:23 -07:00
|
|
|
fs_hz, channels, *background_noise_, expand_->overlap_length()));
|
2013-09-18 12:19:50 +00:00
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
// Delete ComfortNoise object and create a new one.
|
2018-06-19 15:03:05 +02:00
|
|
|
comfort_noise_.reset(
|
|
|
|
|
new ComfortNoise(fs_hz, decoder_database_.get(), sync_buffer_.get()));
|
2013-01-29 12:09:21 +00:00
|
|
|
|
2021-07-28 20:00:17 +02:00
|
|
|
// Verify that `decoded_buffer_` is long enough.
|
2013-01-29 12:09:21 +00:00
|
|
|
if (decoded_buffer_length_ < kMaxFrameSize * channels) {
|
|
|
|
|
// Reallocate to larger size.
|
|
|
|
|
decoded_buffer_length_ = kMaxFrameSize * channels;
|
|
|
|
|
decoded_buffer_.reset(new int16_t[decoded_buffer_length_]);
|
|
|
|
|
}
|
2019-10-24 15:20:39 +02:00
|
|
|
RTC_CHECK(controller_) << "Unexpectedly found no NetEqController";
|
|
|
|
|
controller_->SetSampleRate(fs_hz_, output_size_samples_);
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
2016-03-08 02:37:57 -08:00
|
|
|
NetEqImpl::OutputType NetEqImpl::LastOutputType() {
|
2021-07-08 20:08:20 +02:00
|
|
|
RTC_DCHECK(expand_.get());
|
2019-10-31 14:38:11 +01:00
|
|
|
if (last_mode_ == Mode::kCodecInternalCng ||
|
|
|
|
|
last_mode_ == Mode::kRfc3389Cng) {
|
2016-03-08 02:37:57 -08:00
|
|
|
return OutputType::kCNG;
|
2019-10-31 14:38:11 +01:00
|
|
|
} else if (last_mode_ == Mode::kExpand && expand_->MuteFactor(0) == 0) {
|
2013-01-29 12:09:21 +00:00
|
|
|
// Expand mode has faded down to background noise only (very long expand).
|
2016-03-08 02:37:57 -08:00
|
|
|
return OutputType::kPLCCNG;
|
2019-10-31 14:38:11 +01:00
|
|
|
} else if (last_mode_ == Mode::kExpand) {
|
2016-03-08 02:37:57 -08:00
|
|
|
return OutputType::kPLC;
|
2019-10-31 14:38:11 +01:00
|
|
|
} else if (last_mode_ == Mode::kCodecPlc) {
|
2019-08-07 18:15:08 +02:00
|
|
|
return OutputType::kCodecPLC;
|
2013-01-29 12:09:21 +00:00
|
|
|
} else {
|
2016-03-08 02:37:57 -08:00
|
|
|
return OutputType::kNormalSpeech;
|
2013-01-29 12:09:21 +00:00
|
|
|
}
|
|
|
|
|
}
|
2024-02-05 11:30:21 +01:00
|
|
|
|
|
|
|
|
NetEqController::PacketArrivedInfo NetEqImpl::ToPacketArrivedInfo(
|
|
|
|
|
const Packet& packet) const {
|
|
|
|
|
const DecoderDatabase::DecoderInfo* dec_info =
|
|
|
|
|
decoder_database_->GetDecoderInfo(packet.payload_type);
|
|
|
|
|
|
|
|
|
|
NetEqController::PacketArrivedInfo info;
|
|
|
|
|
info.is_cng_or_dtmf =
|
|
|
|
|
dec_info && (dec_info->IsComfortNoise() || dec_info->IsDtmf());
|
|
|
|
|
info.packet_length_samples =
|
|
|
|
|
packet.frame ? packet.frame->Duration() : decoder_frame_length_;
|
|
|
|
|
info.main_timestamp = packet.timestamp;
|
|
|
|
|
info.main_sequence_number = packet.sequence_number;
|
|
|
|
|
info.is_dtx = packet.frame && packet.frame->IsDtxPacket();
|
|
|
|
|
return info;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-29 12:09:21 +00:00
|
|
|
} // namespace webrtc
|