mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 822129: don't alloc/free on every packet send in MediaPipeline r=bwc
This commit is contained in:
parent
b898fa537d
commit
2f96e4ab5b
@ -17,29 +17,54 @@ namespace mozilla {
|
||||
|
||||
class DataBuffer {
|
||||
public:
|
||||
DataBuffer() : data_(nullptr), len_(0) {}
|
||||
DataBuffer() : data_(nullptr), len_(0), capacity_(0) {}
|
||||
DataBuffer(const uint8_t *data, size_t len) {
|
||||
Assign(data, len);
|
||||
Assign(data, len, len);
|
||||
}
|
||||
DataBuffer(const uint8_t *data, size_t len, size_t capacity) {
|
||||
Assign(data, len, capacity);
|
||||
}
|
||||
|
||||
void Assign(const uint8_t *data, size_t len) {
|
||||
Allocate(len);
|
||||
// to ensure extra space for expansion
|
||||
void Assign(const uint8_t *data, size_t len, size_t capacity) {
|
||||
MOZ_RELEASE_ASSERT(len <= capacity);
|
||||
Allocate(capacity);
|
||||
memcpy(static_cast<void *>(data_.get()),
|
||||
static_cast<const void *>(data), len);
|
||||
len_ = len;
|
||||
}
|
||||
|
||||
void Allocate(size_t len) {
|
||||
data_.reset(new uint8_t[len ? len : 1]); // Don't depend on new [0].
|
||||
void Allocate(size_t capacity) {
|
||||
data_.reset(new uint8_t[capacity ? capacity : 1]); // Don't depend on new [0].
|
||||
capacity_ = capacity;
|
||||
}
|
||||
|
||||
void EnsureCapacity(size_t capacity) {
|
||||
if (capacity_ < capacity) {
|
||||
uint8_t *new_data = new uint8_t[ capacity ? capacity : 1];
|
||||
memcpy(static_cast<void *>(new_data),
|
||||
static_cast<const void *>(data_.get()), len_);
|
||||
data_.reset(new_data); // after copying! Deletes old data
|
||||
capacity_ = capacity;
|
||||
}
|
||||
}
|
||||
|
||||
// used when something writes to the buffer (having checked
|
||||
// capacity() or used EnsureCapacity()) and increased the length.
|
||||
void SetLength(size_t len) {
|
||||
MOZ_RELEASE_ASSERT(len <= capacity_);
|
||||
len_ = len;
|
||||
}
|
||||
|
||||
const uint8_t *data() const { return data_.get(); }
|
||||
uint8_t *data() { return data_.get(); }
|
||||
size_t len() const { return len_; }
|
||||
size_t capacity() const { return capacity_; }
|
||||
|
||||
private:
|
||||
UniquePtr<uint8_t[]> data_;
|
||||
size_t len_;
|
||||
size_t capacity_;
|
||||
|
||||
DISALLOW_COPY_ASSIGN(DataBuffer);
|
||||
};
|
||||
|
@ -750,109 +750,85 @@ nsresult MediaPipeline::PipelineTransport::SendRtpPacket(
|
||||
const void *data, int len) {
|
||||
|
||||
nsAutoPtr<DataBuffer> buf(new DataBuffer(static_cast<const uint8_t *>(data),
|
||||
len));
|
||||
len, len + SRTP_MAX_EXPANSION));
|
||||
|
||||
RUN_ON_THREAD(sts_thread_,
|
||||
WrapRunnable(
|
||||
RefPtr<MediaPipeline::PipelineTransport>(this),
|
||||
&MediaPipeline::PipelineTransport::SendRtpPacket_s,
|
||||
buf),
|
||||
&MediaPipeline::PipelineTransport::SendRtpRtcpPacket_s,
|
||||
buf, true),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult MediaPipeline::PipelineTransport::SendRtpPacket_s(
|
||||
nsAutoPtr<DataBuffer> data) {
|
||||
ASSERT_ON_THREAD(sts_thread_);
|
||||
if (!pipeline_)
|
||||
return NS_OK; // Detached
|
||||
nsresult MediaPipeline::PipelineTransport::SendRtpRtcpPacket_s(
|
||||
nsAutoPtr<DataBuffer> data,
|
||||
bool is_rtp) {
|
||||
|
||||
if (!pipeline_->rtp_.send_srtp_) {
|
||||
MOZ_MTLOG(ML_DEBUG, "Couldn't write RTP packet; SRTP not set up yet");
|
||||
ASSERT_ON_THREAD(sts_thread_);
|
||||
if (!pipeline_) {
|
||||
return NS_OK; // Detached
|
||||
}
|
||||
TransportInfo& transport = is_rtp ? pipeline_->rtp_ : pipeline_->rtcp_;
|
||||
|
||||
if (!transport.send_srtp_) {
|
||||
MOZ_MTLOG(ML_DEBUG, "Couldn't write RTP/RTCP packet; SRTP not set up yet");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(pipeline_->rtp_.transport_);
|
||||
NS_ENSURE_TRUE(pipeline_->rtp_.transport_, NS_ERROR_NULL_POINTER);
|
||||
MOZ_ASSERT(transport.transport_);
|
||||
NS_ENSURE_TRUE(transport.transport_, NS_ERROR_NULL_POINTER);
|
||||
|
||||
// libsrtp enciphers in place, so we need a new, big enough
|
||||
// buffer.
|
||||
// XXX. allocates and deletes one buffer per packet sent.
|
||||
// Bug 822129
|
||||
int max_len = data->len() + SRTP_MAX_EXPANSION;
|
||||
ScopedDeletePtr<unsigned char> inner_data(
|
||||
new unsigned char[max_len]);
|
||||
memcpy(inner_data, data->data(), data->len());
|
||||
// libsrtp enciphers in place, so we need a big enough buffer.
|
||||
MOZ_ASSERT(data->capacity() >= data->len() + SRTP_MAX_EXPANSION);
|
||||
|
||||
int out_len;
|
||||
nsresult res = pipeline_->rtp_.send_srtp_->ProtectRtp(inner_data,
|
||||
data->len(),
|
||||
max_len,
|
||||
&out_len);
|
||||
if (!NS_SUCCEEDED(res))
|
||||
nsresult res;
|
||||
if (is_rtp) {
|
||||
res = transport.send_srtp_->ProtectRtp(data->data(),
|
||||
data->len(),
|
||||
data->capacity(),
|
||||
&out_len);
|
||||
} else {
|
||||
res = transport.send_srtp_->ProtectRtcp(data->data(),
|
||||
data->len(),
|
||||
data->capacity(),
|
||||
&out_len);
|
||||
}
|
||||
if (!NS_SUCCEEDED(res)) {
|
||||
return res;
|
||||
}
|
||||
|
||||
MOZ_MTLOG(ML_DEBUG, pipeline_->description_ << " sending RTP packet.");
|
||||
pipeline_->increment_rtp_packets_sent(out_len);
|
||||
return pipeline_->SendPacket(pipeline_->rtp_.transport_, inner_data,
|
||||
out_len);
|
||||
// paranoia; don't have uninitialized bytes included in data->len()
|
||||
data->SetLength(out_len);
|
||||
|
||||
MOZ_MTLOG(ML_DEBUG, pipeline_->description_ << " sending " <<
|
||||
(is_rtp ? "RTP" : "RTCP") << " packet");
|
||||
if (is_rtp) {
|
||||
pipeline_->increment_rtp_packets_sent(out_len);
|
||||
} else {
|
||||
pipeline_->increment_rtcp_packets_sent();
|
||||
}
|
||||
return pipeline_->SendPacket(transport.transport_, data->data(), out_len);
|
||||
}
|
||||
|
||||
nsresult MediaPipeline::PipelineTransport::SendRtcpPacket(
|
||||
const void *data, int len) {
|
||||
|
||||
nsAutoPtr<DataBuffer> buf(new DataBuffer(static_cast<const uint8_t *>(data),
|
||||
len));
|
||||
len, len + SRTP_MAX_EXPANSION));
|
||||
|
||||
RUN_ON_THREAD(sts_thread_,
|
||||
WrapRunnable(
|
||||
RefPtr<MediaPipeline::PipelineTransport>(this),
|
||||
&MediaPipeline::PipelineTransport::SendRtcpPacket_s,
|
||||
buf),
|
||||
&MediaPipeline::PipelineTransport::SendRtpRtcpPacket_s,
|
||||
buf, false),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult MediaPipeline::PipelineTransport::SendRtcpPacket_s(
|
||||
nsAutoPtr<DataBuffer> data) {
|
||||
ASSERT_ON_THREAD(sts_thread_);
|
||||
if (!pipeline_)
|
||||
return NS_OK; // Detached
|
||||
|
||||
if (!pipeline_->rtcp_.send_srtp_) {
|
||||
MOZ_MTLOG(ML_DEBUG, "Couldn't write RTCP packet; SRTCP not set up yet");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(pipeline_->rtcp_.transport_);
|
||||
NS_ENSURE_TRUE(pipeline_->rtcp_.transport_, NS_ERROR_NULL_POINTER);
|
||||
|
||||
// libsrtp enciphers in place, so we need a new, big enough
|
||||
// buffer.
|
||||
// XXX. allocates and deletes one buffer per packet sent.
|
||||
// Bug 822129.
|
||||
int max_len = data->len() + SRTP_MAX_EXPANSION;
|
||||
ScopedDeletePtr<unsigned char> inner_data(
|
||||
new unsigned char[max_len]);
|
||||
memcpy(inner_data, data->data(), data->len());
|
||||
|
||||
int out_len;
|
||||
nsresult res = pipeline_->rtcp_.send_srtp_->ProtectRtcp(inner_data,
|
||||
data->len(),
|
||||
max_len,
|
||||
&out_len);
|
||||
|
||||
if (!NS_SUCCEEDED(res))
|
||||
return res;
|
||||
|
||||
MOZ_MTLOG(ML_DEBUG, pipeline_->description_ << " sending RTCP packet.");
|
||||
pipeline_->increment_rtcp_packets_sent();
|
||||
return pipeline_->SendPacket(pipeline_->rtcp_.transport_, inner_data,
|
||||
out_len);
|
||||
}
|
||||
|
||||
void MediaPipelineTransmit::PipelineListener::
|
||||
UnsetTrackId(MediaStreamGraphImpl* graph) {
|
||||
#ifndef USE_FAKE_MEDIA_STREAMS
|
||||
|
@ -191,8 +191,8 @@ class MediaPipeline : public sigslot::has_slots<> {
|
||||
virtual nsresult SendRtcpPacket(const void* data, int len);
|
||||
|
||||
private:
|
||||
virtual nsresult SendRtpPacket_s(nsAutoPtr<DataBuffer> data);
|
||||
virtual nsresult SendRtcpPacket_s(nsAutoPtr<DataBuffer> data);
|
||||
nsresult SendRtpRtcpPacket_s(nsAutoPtr<DataBuffer> data,
|
||||
bool is_rtp);
|
||||
|
||||
MediaPipeline *pipeline_; // Raw pointer to avoid cycles
|
||||
nsCOMPtr<nsIEventTarget> sts_thread_;
|
||||
|
@ -22,9 +22,9 @@ namespace mozilla {
|
||||
#define SRTP_MASTER_SALT_LENGTH 14
|
||||
#define SRTP_TOTAL_KEY_LENGTH (SRTP_MASTER_KEY_LENGTH + SRTP_MASTER_SALT_LENGTH)
|
||||
|
||||
// For some reason libsrtp increases packet size by > 12 for RTCP even though
|
||||
// the doc claims otherwise.
|
||||
#define SRTP_MAX_EXPANSION 20
|
||||
// SRTCP requires an auth tag *plus* a 4-byte index-plus-'E'-bit value (see
|
||||
// RFC 3711)
|
||||
#define SRTP_MAX_EXPANSION (SRTP_MAX_TRAILER_LEN+4)
|
||||
|
||||
|
||||
class SrtpFlow {
|
||||
|
Loading…
Reference in New Issue
Block a user