diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc b/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc index 8893759800..ee470fd5f5 100644 --- a/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc +++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc @@ -845,6 +845,9 @@ void RtcEventLogEncoderNewFormat::EncodeAudioNetworkAdaptation( proto_batch->set_enable_fec(base_event->config().enable_fec.value()); if (base_event->config().enable_dtx.has_value()) proto_batch->set_enable_dtx(base_event->config().enable_dtx.value()); + // Note that |num_channels_deltas| encodes N as N-1, to keep deltas smaller, + // but there's no reason to do the same for the base event's value, since + // no bits will be spared. if (base_event->config().num_channels.has_value()) proto_batch->set_num_channels(base_event->config().num_channels.value()); @@ -940,9 +943,27 @@ void RtcEventLogEncoderNewFormat::EncodeAudioNetworkAdaptation( // num_channels for (size_t i = 0; i < values.size(); ++i) { const RtcEventAudioNetworkAdaptation* event = batch[i + 1]; - values[i] = event->config().num_channels; + const absl::optional num_channels = event->config().num_channels; + if (num_channels.has_value()) { + // Since the number of channels is always greater than 0, we can encode + // N channels as N-1, thereby making sure that we get smaller deltas. + // That is, a toggle of 1->2->1 can be encoded as deltas vector (1, 1), + // rather than as (1, 3) or (1, -1), either of which would require two + // bits per delta. + RTC_DCHECK_GT(num_channels.value(), 0u); + values[i] = num_channels.value() - 1; + } else { + values[i].reset(); + } } - encoded_deltas = EncodeDeltas(base_event->config().num_channels, values); + // In the base event, N channels encoded as N channels, but for delta + // compression purposes, also shifted down by 1. + absl::optional shifted_base_num_channels; + if (base_event->config().num_channels.has_value()) { + RTC_DCHECK_GT(base_event->config().num_channels.value(), 0u); + shifted_base_num_channels = base_event->config().num_channels.value() - 1; + } + encoded_deltas = EncodeDeltas(shifted_base_num_channels, values); if (!encoded_deltas.empty()) { proto_batch->set_num_channels_deltas(encoded_deltas); } diff --git a/logging/rtc_event_log/rtc_event_log_parser_new.cc b/logging/rtc_event_log/rtc_event_log_parser_new.cc index 78e2746503..131a0a7cb4 100644 --- a/logging/rtc_event_log/rtc_event_log_parser_new.cc +++ b/logging/rtc_event_log/rtc_event_log_parser_new.cc @@ -2323,7 +2323,7 @@ void ParsedRtcEventLogNew::StoreAudioNetworkAdaptationEvent( runtime_config.enable_dtx = proto.enable_dtx(); } if (proto.has_num_channels()) { - // TODO(eladalon): Encode 1/2 -> 0/1, to improve + // Note: Encoding N as N-1 only done for |num_channels_deltas|. runtime_config.num_channels = proto.num_channels(); } audio_network_adaptation_events_.emplace_back(1000 * proto.timestamp_ms(), @@ -2387,11 +2387,23 @@ void ParsedRtcEventLogNew::StoreAudioNetworkAdaptationEvent( RTC_CHECK_EQ(enable_dtx_values.size(), number_of_deltas); // num_channels - const absl::optional num_channels = - proto.has_num_channels() ? absl::optional(proto.num_channels()) - : absl::optional(); - std::vector> num_channels_values = - DecodeDeltas(proto.num_channels_deltas(), num_channels, number_of_deltas); + // Note: For delta encoding, all num_channel values, including the base, + // were shifted down by one, but in the base event, they were not. + // We likewise shift the base event down by one, to get the same base as + // encoding had, but then shift all of the values (except the base) back up + // to their original value. + absl::optional shifted_base_num_channels; + if (proto.has_num_channels()) { + shifted_base_num_channels = + absl::optional(proto.num_channels() - 1); + } + std::vector> num_channels_values = DecodeDeltas( + proto.num_channels_deltas(), shifted_base_num_channels, number_of_deltas); + for (size_t i = 0; i < num_channels_values.size(); ++i) { + if (num_channels_values[i].has_value()) { + num_channels_values[i] = num_channels_values[i].value() + 1; + } + } RTC_CHECK_EQ(num_channels_values.size(), number_of_deltas); // Delta decoding