icecat: add release icecat-140.10.1-1gnu1 for ecne
This commit is contained in:
parent
a5f93cb214
commit
ff85d7c623
1256 changed files with 63469 additions and 24141 deletions
1
icecat/third_party/libwebrtc/call/BUILD.gn
vendored
1
icecat/third_party/libwebrtc/call/BUILD.gn
vendored
|
|
@ -590,6 +590,7 @@ if (rtc_include_tests) {
|
|||
"../api/video:video_codec_constants",
|
||||
"../api/video:video_frame",
|
||||
"../api/video:video_frame_type",
|
||||
"../api/video:video_layers_allocation",
|
||||
"../api/video:video_rtp_headers",
|
||||
"../api/video_codecs:video_codecs_api",
|
||||
"../audio",
|
||||
|
|
|
|||
|
|
@ -699,6 +699,11 @@ void RtpVideoSender::OnVideoLayersAllocationUpdated(
|
|||
transport_queue_.PostTask(
|
||||
SafeTask(safety_.flag(), [this, sending = std::move(sending)] {
|
||||
RTC_DCHECK_RUN_ON(&transport_checker_);
|
||||
// It's possible for another task to be scheduled on the transport
|
||||
// checker ahead of this call that makes the sender not active.
|
||||
if (!IsActive()) {
|
||||
return;
|
||||
}
|
||||
RTC_CHECK_EQ(sending.size(), rtp_streams_.size());
|
||||
for (size_t i = 0; i < sending.size(); ++i) {
|
||||
SetModuleIsActive(sending[i], *rtp_streams_[i].rtp_rtcp);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include "api/video/encoded_image.h"
|
||||
#include "api/video/video_codec_type.h"
|
||||
#include "api/video/video_frame_type.h"
|
||||
#include "api/video/video_layers_allocation.h"
|
||||
#include "api/video_codecs/video_encoder.h"
|
||||
#include "call/rtp_config.h"
|
||||
#include "call/rtp_transport_config.h"
|
||||
|
|
@ -1670,4 +1671,73 @@ TEST(RtpVideoSenderTest, RetransmitsBaseLayerOnly) {
|
|||
EXPECT_EQ(retransmitted_rtp_sequence_numbers, base_rtp_sequence_numbers);
|
||||
}
|
||||
|
||||
TEST(RtpVideoSenderTest, PostTaskRaceDoesNotLeadToDanglingPointer) {
|
||||
NiceMock<MockTransport> transport;
|
||||
NiceMock<MockRtcpIntraFrameObserver> encoder_feedback;
|
||||
|
||||
GlobalSimulatedTimeController time_controller(Timestamp::Millis(1000000));
|
||||
Environment env = CreateEnvironment(time_controller.GetClock(),
|
||||
time_controller.CreateTaskQueueFactory());
|
||||
|
||||
VideoSendStream::Config config(&transport);
|
||||
config.rtp.ssrcs = {kSsrc1};
|
||||
|
||||
SendStatisticsProxy stats_proxy(
|
||||
time_controller.GetClock(), config,
|
||||
VideoEncoderConfig::ContentType::kRealtimeVideo, env.field_trials());
|
||||
|
||||
BitrateConstraints bitrate_config = GetBitrateConfig();
|
||||
RtpTransportConfig transport_config{.env = env,
|
||||
.bitrate_config = bitrate_config};
|
||||
RtpTransportControllerSend transport_controller(transport_config);
|
||||
transport_controller.EnsureStarted();
|
||||
|
||||
RateLimiter retransmission_rate_limiter(time_controller.GetClock(),
|
||||
kRetransmitWindowSizeMs);
|
||||
|
||||
std::map<uint32_t, RtpState> suspended_ssrcs;
|
||||
std::map<uint32_t, RtpPayloadState> suspended_payload_states;
|
||||
|
||||
auto router = std::make_unique<RtpVideoSender>(
|
||||
env, time_controller.GetMainThread(), suspended_ssrcs,
|
||||
suspended_payload_states, config.rtp, config.rtcp_report_interval_ms,
|
||||
&transport,
|
||||
CreateObservers(&encoder_feedback, &stats_proxy, &stats_proxy,
|
||||
&stats_proxy, nullptr, &stats_proxy),
|
||||
&transport_controller, &retransmission_rate_limiter,
|
||||
std::make_unique<FecControllerDefault>(env), nullptr, CryptoOptions{},
|
||||
nullptr);
|
||||
|
||||
router->SetSending(true);
|
||||
// Verify it's registered
|
||||
EXPECT_TRUE(
|
||||
transport_controller.packet_router()->SsrcOfFirstSender().has_value());
|
||||
|
||||
// Trigger race:
|
||||
// 1. OnVideoLayersAllocationUpdated posts a task to re-register modules
|
||||
// because it sees active_ is true.
|
||||
VideoLayersAllocation allocation;
|
||||
allocation.active_spatial_layers.push_back({.rtp_stream_index = 0});
|
||||
router->OnVideoLayersAllocationUpdated(allocation);
|
||||
|
||||
// 2. Immediately set active_ to false. This happens BEFORE the posted task
|
||||
// runs.
|
||||
router->SetSending(false);
|
||||
|
||||
// 3. Let the posted task run. With the fix, it should return early and not
|
||||
// re-register the module because active_ is now false.
|
||||
time_controller.AdvanceTime(TimeDelta::Zero());
|
||||
|
||||
// 4. Verify that PacketRouter does NOT have a sender.
|
||||
EXPECT_FALSE(
|
||||
transport_controller.packet_router()->SsrcOfFirstSender().has_value());
|
||||
|
||||
// 5. Destroy the router.
|
||||
router.reset();
|
||||
|
||||
// 6. Verify that PacketRouter still does not have a sender.
|
||||
EXPECT_FALSE(
|
||||
transport_controller.packet_router()->SsrcOfFirstSender().has_value());
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
|
|||
|
|
@ -230,14 +230,21 @@ void RtpPacket::SetCsrcs(rtc::ArrayView<const uint32_t> csrcs) {
|
|||
RTC_DCHECK_EQ(padding_size_, 0);
|
||||
RTC_DCHECK_LE(csrcs.size(), 0x0fu);
|
||||
RTC_DCHECK_LE(kFixedHeaderSize + 4 * csrcs.size(), capacity());
|
||||
|
||||
if (csrcs.size() > kMaxCsrcs) {
|
||||
RTC_LOG(LS_WARNING) << "Truncating CSRC list to spec length " << kMaxCsrcs
|
||||
<< " from " << csrcs.size();
|
||||
csrcs = csrcs.subview(0, kMaxCsrcs);
|
||||
}
|
||||
|
||||
payload_offset_ = kFixedHeaderSize + 4 * csrcs.size();
|
||||
buffer_.SetSize(payload_offset_);
|
||||
WriteAt(0, (data()[0] & 0xF0) | dchecked_cast<uint8_t>(csrcs.size()));
|
||||
size_t offset = kFixedHeaderSize;
|
||||
for (uint32_t csrc : csrcs) {
|
||||
ByteWriter<uint32_t>::WriteBigEndian(WriteAt(offset), csrc);
|
||||
offset += 4;
|
||||
}
|
||||
buffer_.SetSize(payload_offset_);
|
||||
}
|
||||
|
||||
rtc::ArrayView<uint8_t> RtpPacket::AllocateRawExtension(int id, size_t length) {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,12 @@ class RtpPacket {
|
|||
using ExtensionType = RTPExtensionType;
|
||||
using ExtensionManager = RtpHeaderExtensionMap;
|
||||
|
||||
// Maximum number of CSRCs in an RTP packet as specified in section
|
||||
// "5.1 RTP Fixed Header Fields" of RFC 3550.
|
||||
// Note: This is a different limit than the one that applies to RTCP packets
|
||||
// (which is specified in section 6.1).
|
||||
static constexpr size_t kMaxCsrcs = 15;
|
||||
|
||||
// `extensions` required for SetExtension/ReserveExtension functions during
|
||||
// packet creating and used if available in Parse function.
|
||||
// Adding and getting extensions will fail until `extensions` is
|
||||
|
|
|
|||
|
|
@ -71,9 +71,6 @@ class ScopedDav1dPicture
|
|||
|
||||
constexpr char kDav1dName[] = "dav1d";
|
||||
|
||||
// Calling `dav1d_data_wrap` requires a `free_callback` to be registered.
|
||||
void NullFreeCallback(const uint8_t* /* buffer */, void* /* opaque */) {}
|
||||
|
||||
Dav1dDecoder::Dav1dDecoder() = default;
|
||||
|
||||
Dav1dDecoder::~Dav1dDecoder() {
|
||||
|
|
@ -127,9 +124,25 @@ int32_t Dav1dDecoder::Decode(const EncodedImage& encoded_image,
|
|||
|
||||
ScopedDav1dData scoped_dav1d_data;
|
||||
Dav1dData& dav1d_data = scoped_dav1d_data.Data();
|
||||
dav1d_data_wrap(&dav1d_data, encoded_image.data(), encoded_image.size(),
|
||||
/*free_callback=*/&NullFreeCallback,
|
||||
/*user_data=*/nullptr);
|
||||
|
||||
// Calling GetEncodedData will create a new `scoped_refptr` and increment the
|
||||
// ref count. By simply releasing we are now responsible for decrementing
|
||||
// the ref count when appropriate, which is when dav1d calls the
|
||||
// `free_callback` to indicate that the buffer is no longer needed.
|
||||
EncodedImageBufferInterface* bitstream_buffer =
|
||||
encoded_image.GetEncodedData().release();
|
||||
|
||||
// Note that the `bitstream_buffer` can have a higher capacity than what is
|
||||
// actually being used, so `encoded_image.size()` should be used to get the
|
||||
// actual size of the bitstream.
|
||||
dav1d_data_wrap(
|
||||
&dav1d_data, encoded_image.data(), encoded_image.size(),
|
||||
/*free_callback=*/
|
||||
[](const uint8_t* /* buffer */, void* user_data) {
|
||||
auto* bb = static_cast<EncodedImageBufferInterface*>(user_data);
|
||||
bb->Release();
|
||||
},
|
||||
/*user_data=*/bitstream_buffer);
|
||||
|
||||
if (int decode_res = dav1d_send_data(context_, &dav1d_data)) {
|
||||
RTC_LOG(LS_WARNING)
|
||||
|
|
|
|||
1
icecat/third_party/libwebrtc/moz-patch-stack/77d265670f.no-op-cherry-pick-msg
vendored
Normal file
1
icecat/third_party/libwebrtc/moz-patch-stack/77d265670f.no-op-cherry-pick-msg
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
We cherry-picked this in bug 2029776
|
||||
|
|
@ -133,6 +133,9 @@ OutstandingData::AckInfo OutstandingData::HandleSack(
|
|||
UnwrappedTSN cumulative_tsn_ack,
|
||||
rtc::ArrayView<const SackChunk::GapAckBlock> gap_ack_blocks,
|
||||
bool is_in_fast_recovery) {
|
||||
bool cumulative_tsn_ack_advanced =
|
||||
cumulative_tsn_ack > last_cumulative_tsn_ack_;
|
||||
|
||||
OutstandingData::AckInfo ack_info(cumulative_tsn_ack);
|
||||
// Erase all items up to cumulative_tsn_ack.
|
||||
RemoveAcked(cumulative_tsn_ack, ack_info);
|
||||
|
|
@ -142,7 +145,7 @@ OutstandingData::AckInfo OutstandingData::HandleSack(
|
|||
|
||||
// NACK and possibly mark for retransmit chunks that weren't acked.
|
||||
NackBetweenAckBlocks(cumulative_tsn_ack, gap_ack_blocks, is_in_fast_recovery,
|
||||
ack_info);
|
||||
cumulative_tsn_ack_advanced, ack_info);
|
||||
|
||||
RTC_DCHECK(IsConsistent());
|
||||
return ack_info;
|
||||
|
|
@ -215,6 +218,7 @@ void OutstandingData::NackBetweenAckBlocks(
|
|||
UnwrappedTSN cumulative_tsn_ack,
|
||||
rtc::ArrayView<const SackChunk::GapAckBlock> gap_ack_blocks,
|
||||
bool is_in_fast_recovery,
|
||||
bool cumulative_tsn_acked_advanced,
|
||||
OutstandingData::AckInfo& ack_info) {
|
||||
// Mark everything between the blocks as NACKED/TO_BE_RETRANSMITTED.
|
||||
// https://tools.ietf.org/html/rfc4960#section-7.2.4
|
||||
|
|
@ -227,7 +231,7 @@ void OutstandingData::NackBetweenAckBlocks(
|
|||
// in-flight and between gaps should be nacked. This means that SCTP relies on
|
||||
// the T3-RTX-timer to re-send packets otherwise.
|
||||
UnwrappedTSN max_tsn_to_nack = ack_info.highest_tsn_acked;
|
||||
if (is_in_fast_recovery && cumulative_tsn_ack > last_cumulative_tsn_ack_) {
|
||||
if (is_in_fast_recovery && cumulative_tsn_acked_advanced) {
|
||||
// https://tools.ietf.org/html/rfc4960#section-7.2.4
|
||||
// "If an endpoint is in Fast Recovery and a SACK arrives that advances
|
||||
// the Cumulative TSN Ack Point, the miss indications are incremented for
|
||||
|
|
@ -242,7 +246,8 @@ void OutstandingData::NackBetweenAckBlocks(
|
|||
UnwrappedTSN cur_block_first_acked =
|
||||
UnwrappedTSN::AddTo(cumulative_tsn_ack, block.start);
|
||||
for (UnwrappedTSN tsn = prev_block_last_acked.next_value();
|
||||
tsn < cur_block_first_acked && tsn <= max_tsn_to_nack;
|
||||
tsn < cur_block_first_acked && tsn <= max_tsn_to_nack &&
|
||||
tsn < next_tsn();
|
||||
tsn = tsn.next_value()) {
|
||||
ack_info.has_packet_loss |=
|
||||
NackItem(tsn, /*retransmit_now=*/false,
|
||||
|
|
|
|||
|
|
@ -320,6 +320,7 @@ class OutstandingData {
|
|||
UnwrappedTSN cumulative_tsn_ack,
|
||||
rtc::ArrayView<const SackChunk::GapAckBlock> gap_ack_blocks,
|
||||
bool is_in_fast_recovery,
|
||||
bool cumulative_tsn_acked_advanced,
|
||||
OutstandingData::AckInfo& ack_info);
|
||||
|
||||
// Process the acknowledgement of the chunk referenced by `iter` and updates
|
||||
|
|
|
|||
|
|
@ -252,6 +252,14 @@ bool RetransmissionQueue::IsSackValid(const SackChunk& sack) const {
|
|||
} else if (cumulative_tsn_ack > outstanding_data_.highest_outstanding_tsn()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& block : sack.gap_ack_blocks()) {
|
||||
if (UnwrappedTSN::AddTo(cumulative_tsn_ack, block.end) >
|
||||
outstanding_data_.highest_outstanding_tsn()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"files":{".circleci/config.yml":"7f3dc865105ca8f33965a7958b1fe2e627ae2d5a703f3b2a4ab6e2e796018597",".editorconfig":"4e53b182bcc78b83d7e1b5c03efa14d22d4955c4ed2514d1ba4e99c1eb1a50ba",".githooks/pre-push":"8b8b26544cd56f54c0c33812551f786bb25cb08c86dbfeb6bf3daad881c826a1",".github/workflows/test.yml":"cf6ebe6d41b022897360866b526d19ba8843aa82ae99a1d28393985576b6a782",".travis.yml":"dc07bac53f70f16c9bdf52264bdc58500ae6018c1b4c567bc7642f6b4ca3cc35","Cargo.toml":"63b221c28d209afb8dfc53191b61f7ba9d3faa1591fddb5547e4c400301a8138","LICENSE":"6e6f56aff5bbf3cbc60747e152fb1a719bd0716aaf6d711c554f57d92e96297c","README.md":"0007782a05a5330f739ad789c19c82562c82e32386b0447000fc72c0d48405bc","build-audiounit-rust-in-cubeb.sh":"d228a05985dcd02ec1ecac66a2b64dae5a530804a25a7054ccc95905aedfb7ef","install_git_hook.sh":"d38c8e51e636f6b90b489621ac34ccd1d1b1f40dccce3d178ed1da1c5068f16d","install_rustfmt_clippy.sh":"4ae90d8dcb9757cb3ae4ae142ef80e5377c0dde61c63f4a3c32418646e80ca7b","run_device_tests.sh":"967448b6cd46a8e60d465d56be0b1e6794a18110592a30939d2cb0650c4e5bc6","run_sanitizers.sh":"84e93a0da137803018f37403511e8c92760be730426bf6cea34419d93d1a7ff8","run_tests.sh":"bae82f66dd47a060b6fdcc238520084aec1079d5b1b1d66d103baa1ffaa8773d","src/backend/aggregate_device.rs":"f408ea934a20f5a24372fdcaa3bbc113713239fdb32323de0fd6334034c25e46","src/backend/auto_release.rs":"050fdcee74cf46b9a8a85a877e166d72a853d33220f59cf734cbb6ea09daa441","src/backend/buffer_manager.rs":"e9bcf964347daa8952f98caa2746e34a31ea8908375204896593f56e4b6147ca","src/backend/device_property.rs":"30ceeceee4fc1f6f872c6c61765e41d582ccd91d2d1ac3ca9b1e5ac18dd11a71","src/backend/mixer.rs":"c4d09291598cbffb2217b551770ec590f34b6dd6b461dd99b019d5bb70f0eef3","src/backend/mod.rs":"6f38a9e3d5b8864e9f921a47fa7655d9322ecf8789a63560fb2f5fcc63076d33","src/backend/resampler.rs":"48bf8f56ae8d60dbabca6417b768000619abee8731ac3902164b45651ac08a4d","src/backend/tests/aggregate_device.rs":"afbdf1da1fcaddcad2986bd3146bf93ca75c24b3362f5f23a09517a926290ca2","src/backend/tests/api.rs":"3b0936810b3afa84cb80428c471e1097701fd790460d00c0a5715fd8026d0a4d","src/backend/tests/backlog.rs":"3b189a7e036543c467cc242af0ed3332721179ee2b1c8847a6db563546f1ac52","src/backend/tests/device_change.rs":"bb4f7df992d915723222f62a4f995896cce861821c73351d831cb01a34cef0c4","src/backend/tests/device_property.rs":"4ef3ab625809fe95e944c19cc5dc1cc79f473520a4314d123b1f80c6b7e11411","src/backend/tests/interfaces.rs":"a96d1432afd381bf74dcbe73e892dfc4ddc68721a956606c94fd4128c6589adc","src/backend/tests/manual.rs":"f72625c05110534775c4608ccc45472ea108286657ffc1f029844a13d0b883bf","src/backend/tests/mod.rs":"e388a37edd5f53cda04fe1ac8bf033e423c6604014792177c623c8456fe5d257","src/backend/tests/parallel.rs":"a7ebd579339c40ca64c0757cc9da6baec641e670f226e1b2ec5049894700bd7a","src/backend/tests/sync_callback.rs":"20e7ba57714c0d2bff3bc8d3a912f17fdab293737bc729eae1684070b90b72c4","src/backend/tests/tone.rs":"b028c67777b6453a26190b6a49785dfe28556adcbe179cb10862ce0d47ee8509","src/backend/tests/utils.rs":"9f4f486b3d59081747785dae4828ec22a4ecbab755ac4c09ff2c0c065865a358","src/backend/utils.rs":"6c3ffbcd602e6cc9f56deb9ecb07b2eef2e6f074ef924178e466f380aae5c595","src/capi.rs":"21b66b70545bf04ec719928004d1d9adb45b24ced51288f5b2993d79aaf78f5f","src/lib.rs":"be88c967e470bf6c120f3e42f7155fe89a4718f56a35524ea4c17181856757d5","todo.md":"efc1f012eb9a331a040cad4ac03aa79307f25885f71b6fb38f3ad7af8d7d515c"},"package":null}
|
||||
{"files":{".circleci/config.yml":"7f3dc865105ca8f33965a7958b1fe2e627ae2d5a703f3b2a4ab6e2e796018597",".editorconfig":"4e53b182bcc78b83d7e1b5c03efa14d22d4955c4ed2514d1ba4e99c1eb1a50ba",".githooks/pre-push":"8b8b26544cd56f54c0c33812551f786bb25cb08c86dbfeb6bf3daad881c826a1",".github/workflows/test.yml":"cf6ebe6d41b022897360866b526d19ba8843aa82ae99a1d28393985576b6a782",".travis.yml":"dc07bac53f70f16c9bdf52264bdc58500ae6018c1b4c567bc7642f6b4ca3cc35","Cargo.toml":"63b221c28d209afb8dfc53191b61f7ba9d3faa1591fddb5547e4c400301a8138","LICENSE":"6e6f56aff5bbf3cbc60747e152fb1a719bd0716aaf6d711c554f57d92e96297c","README.md":"0007782a05a5330f739ad789c19c82562c82e32386b0447000fc72c0d48405bc","build-audiounit-rust-in-cubeb.sh":"d228a05985dcd02ec1ecac66a2b64dae5a530804a25a7054ccc95905aedfb7ef","install_git_hook.sh":"d38c8e51e636f6b90b489621ac34ccd1d1b1f40dccce3d178ed1da1c5068f16d","install_rustfmt_clippy.sh":"4ae90d8dcb9757cb3ae4ae142ef80e5377c0dde61c63f4a3c32418646e80ca7b","run_device_tests.sh":"967448b6cd46a8e60d465d56be0b1e6794a18110592a30939d2cb0650c4e5bc6","run_sanitizers.sh":"84e93a0da137803018f37403511e8c92760be730426bf6cea34419d93d1a7ff8","run_tests.sh":"bae82f66dd47a060b6fdcc238520084aec1079d5b1b1d66d103baa1ffaa8773d","src/backend/aggregate_device.rs":"3e2b5d1fa24130a9b14d6761b443fc7d1ed2f7884c545013ed2d048a1de2c3e6","src/backend/auto_release.rs":"050fdcee74cf46b9a8a85a877e166d72a853d33220f59cf734cbb6ea09daa441","src/backend/buffer_manager.rs":"e9bcf964347daa8952f98caa2746e34a31ea8908375204896593f56e4b6147ca","src/backend/device_property.rs":"30ceeceee4fc1f6f872c6c61765e41d582ccd91d2d1ac3ca9b1e5ac18dd11a71","src/backend/mixer.rs":"c4d09291598cbffb2217b551770ec590f34b6dd6b461dd99b019d5bb70f0eef3","src/backend/mod.rs":"6f38a9e3d5b8864e9f921a47fa7655d9322ecf8789a63560fb2f5fcc63076d33","src/backend/resampler.rs":"48bf8f56ae8d60dbabca6417b768000619abee8731ac3902164b45651ac08a4d","src/backend/tests/aggregate_device.rs":"afbdf1da1fcaddcad2986bd3146bf93ca75c24b3362f5f23a09517a926290ca2","src/backend/tests/api.rs":"3b0936810b3afa84cb80428c471e1097701fd790460d00c0a5715fd8026d0a4d","src/backend/tests/backlog.rs":"3b189a7e036543c467cc242af0ed3332721179ee2b1c8847a6db563546f1ac52","src/backend/tests/device_change.rs":"bb4f7df992d915723222f62a4f995896cce861821c73351d831cb01a34cef0c4","src/backend/tests/device_property.rs":"4ef3ab625809fe95e944c19cc5dc1cc79f473520a4314d123b1f80c6b7e11411","src/backend/tests/interfaces.rs":"a96d1432afd381bf74dcbe73e892dfc4ddc68721a956606c94fd4128c6589adc","src/backend/tests/manual.rs":"f72625c05110534775c4608ccc45472ea108286657ffc1f029844a13d0b883bf","src/backend/tests/mod.rs":"e388a37edd5f53cda04fe1ac8bf033e423c6604014792177c623c8456fe5d257","src/backend/tests/parallel.rs":"a7ebd579339c40ca64c0757cc9da6baec641e670f226e1b2ec5049894700bd7a","src/backend/tests/sync_callback.rs":"20e7ba57714c0d2bff3bc8d3a912f17fdab293737bc729eae1684070b90b72c4","src/backend/tests/tone.rs":"b028c67777b6453a26190b6a49785dfe28556adcbe179cb10862ce0d47ee8509","src/backend/tests/utils.rs":"9f4f486b3d59081747785dae4828ec22a4ecbab755ac4c09ff2c0c065865a358","src/backend/utils.rs":"6c3ffbcd602e6cc9f56deb9ecb07b2eef2e6f074ef924178e466f380aae5c595","src/capi.rs":"21b66b70545bf04ec719928004d1d9adb45b24ced51288f5b2993d79aaf78f5f","src/lib.rs":"be88c967e470bf6c120f3e42f7155fe89a4718f56a35524ea4c17181856757d5","todo.md":"efc1f012eb9a331a040cad4ac03aa79307f25885f71b6fb38f3ad7af8d7d515c"},"package":null}
|
||||
|
|
@ -334,17 +334,19 @@ impl AggregateDevice {
|
|||
return Err(Error::from(status));
|
||||
}
|
||||
|
||||
let cleanup = || {
|
||||
let _teardown = finally(|| {
|
||||
let status = audio_object_remove_property_listener(
|
||||
device_id,
|
||||
&address,
|
||||
devices_changed_callback,
|
||||
data_ptr as *mut c_void,
|
||||
);
|
||||
// kAudioHardwareBadObjectError implies device_id is somehow dead,
|
||||
// so its listener should receive nothing.
|
||||
assert!(status == NO_ERR || status == (kAudioHardwareBadObjectError as OSStatus));
|
||||
sync_callback_registry_unregister(data_ptr as usize);
|
||||
unsafe { drop(Box::from_raw(data_ptr)) };
|
||||
status
|
||||
};
|
||||
});
|
||||
|
||||
Self::set_sub_devices(device_id, input_id, output_id)?;
|
||||
|
||||
|
|
@ -362,10 +364,6 @@ impl AggregateDevice {
|
|||
);
|
||||
}
|
||||
if *dev != device_id {
|
||||
let status = cleanup();
|
||||
// If the error is kAudioHardwareBadObjectError, it implies `device_id` is somehow
|
||||
// dead, so its listener should receive nothing. It's ok to leave here.
|
||||
assert!(status == NO_ERR || status == (kAudioHardwareBadObjectError as OSStatus));
|
||||
return Err(Error::from(waiting_time));
|
||||
}
|
||||
}
|
||||
|
|
@ -386,8 +384,6 @@ impl AggregateDevice {
|
|||
NO_ERR
|
||||
}
|
||||
|
||||
let status = cleanup();
|
||||
assert_eq!(status, NO_ERR);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue