diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /dom/media/webrtc/transport/transportlayerloopback.cpp | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/media/webrtc/transport/transportlayerloopback.cpp')
-rw-r--r-- | dom/media/webrtc/transport/transportlayerloopback.cpp | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/dom/media/webrtc/transport/transportlayerloopback.cpp b/dom/media/webrtc/transport/transportlayerloopback.cpp new file mode 100644 index 0000000000..ab2a52c17e --- /dev/null +++ b/dom/media/webrtc/transport/transportlayerloopback.cpp @@ -0,0 +1,119 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Original author: ekr@rtfm.com + +#include "logging.h" +#include "prlock.h" + +#include "nsNetCID.h" +#include "nsServiceManagerUtils.h" +#include "nsString.h" + +#include "transportlayerloopback.h" + +namespace mozilla { + +MOZ_MTLOG_MODULE("mtransport") + +nsresult TransportLayerLoopback::Init() { + nsresult rv; + target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + if (!NS_SUCCEEDED(rv)) return rv; + + timer_ = NS_NewTimer(target_); + MOZ_ASSERT(timer_); + if (!timer_) return NS_ERROR_FAILURE; + + packets_lock_ = PR_NewLock(); + MOZ_ASSERT(packets_lock_); + if (!packets_lock_) return NS_ERROR_FAILURE; + + deliverer_ = new Deliverer(this); + + timer_->InitWithCallback(deliverer_, 100, nsITimer::TYPE_REPEATING_SLACK); + + return NS_OK; +} + +// Connect to the other side +void TransportLayerLoopback::Connect(TransportLayerLoopback* peer) { + peer_ = peer; + + TL_SET_STATE(TS_OPEN); +} + +TransportResult TransportLayerLoopback::SendPacket(MediaPacket& packet) { + MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "SendPacket(" << packet.len() << ")"); + + if (!peer_) { + MOZ_MTLOG(ML_ERROR, "Discarding packet because peer not attached"); + return TE_ERROR; + } + + size_t len = packet.len(); + nsresult res = peer_->QueuePacket(packet); + if (!NS_SUCCEEDED(res)) return TE_ERROR; + + return static_cast<TransportResult>(len); +} + +nsresult TransportLayerLoopback::QueuePacket(MediaPacket& packet) { + MOZ_ASSERT(packets_lock_); + + PR_Lock(packets_lock_); + + if (combinePackets_ && !packets_.empty()) { + MediaPacket* prevPacket = packets_.front(); + + MOZ_MTLOG(ML_DEBUG, LAYER_INFO << " Enqueuing combined packets of length " + << prevPacket->len() << " and " + << packet.len()); + auto combined = MakeUnique<uint8_t[]>(prevPacket->len() + packet.len()); + memcpy(combined.get(), prevPacket->data(), prevPacket->len()); + memcpy(combined.get() + prevPacket->len(), packet.data(), packet.len()); + prevPacket->Take(std::move(combined), prevPacket->len() + packet.len()); + } else { + MOZ_MTLOG(ML_DEBUG, + LAYER_INFO << " Enqueuing packet of length " << packet.len()); + packets_.push(new MediaPacket(std::move(packet))); + } + + PRStatus r = PR_Unlock(packets_lock_); + MOZ_ASSERT(r == PR_SUCCESS); + if (r != PR_SUCCESS) return NS_ERROR_FAILURE; + + return NS_OK; +} + +void TransportLayerLoopback::DeliverPackets() { + while (!packets_.empty()) { + UniquePtr<MediaPacket> packet(packets_.front()); + packets_.pop(); + + MOZ_MTLOG(ML_DEBUG, + LAYER_INFO << " Delivering packet of length " << packet->len()); + SignalPacketReceived(this, *packet); + } +} + +NS_IMPL_ISUPPORTS(TransportLayerLoopback::Deliverer, nsITimerCallback, nsINamed) + +NS_IMETHODIMP TransportLayerLoopback::Deliverer::Notify(nsITimer* timer) { + if (!layer_) return NS_OK; + + layer_->DeliverPackets(); + + return NS_OK; +} + +NS_IMETHODIMP TransportLayerLoopback::Deliverer::GetName(nsACString& aName) { + aName.AssignLiteral("TransportLayerLoopback::Deliverer"); + return NS_OK; +} + +} // namespace mozilla |