Refactored ViESender.

In a later CL:
- References -> const or ptr.

Review URL: http://webrtc-codereview.appspot.com/291003

git-svn-id: http://webrtc.googlecode.com/svn/trunk@1011 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
mflodman@webrtc.org 2011-11-24 08:31:06 +00:00
parent d492f72e43
commit 6d26ef76ea
2 changed files with 183 additions and 403 deletions

View File

@ -8,388 +8,186 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
/*
* vie_sender.cc
*/
#include <cassert> #include <cassert>
#include "vie_sender.h"
#include "critical_section_wrapper.h" #include "critical_section_wrapper.h"
#ifdef WEBRTC_SRTP
#include "SrtpModule.h"
#endif
#include "rtp_dump.h" #include "rtp_dump.h"
#include "vie_sender.h"
#include "trace.h" #include "trace.h"
namespace webrtc { namespace webrtc {
// ---------------------------------------------------------------------------- ViESender::ViESender(int engine_id, int channel_id)
// Constructor : engine_id_(engine_id),
// ---------------------------------------------------------------------------- channel_id_(channel_id),
critsect_(*CriticalSectionWrapper::CreateCriticalSection()),
ViESender::ViESender(int engineId, int channelId) external_encryption_(NULL),
: _engineId(engineId), _channelId(channelId), encryption_buffer_(NULL),
_sendCritsect(*CriticalSectionWrapper::CreateCriticalSection()), transport_(NULL),
#ifdef WEBRTC_SRTP rtp_dump_(NULL) {
_ptrSrtp(NULL),
_ptrSrtcp(NULL),
#endif
_ptrExternalEncryption(NULL), _ptrSrtpBuffer(NULL),
_ptrSrtcpBuffer(NULL), _ptrEncryptionBuffer(NULL), _ptrTransport(NULL),
_rtpDump(NULL)
{
} }
// ---------------------------------------------------------------------------- ViESender::~ViESender() {
// Destructor delete &critsect_;
// ----------------------------------------------------------------------------
ViESender::~ViESender()
{
delete &_sendCritsect;
if (_ptrSrtpBuffer) if (encryption_buffer_) {
{ delete[] encryption_buffer_;
delete[] _ptrSrtpBuffer; encryption_buffer_ = NULL;
_ptrSrtpBuffer = NULL; }
}
if (_ptrSrtcpBuffer) if (rtp_dump_) {
{ rtp_dump_->Stop();
delete[] _ptrSrtcpBuffer; RtpDump::DestroyRtpDump(rtp_dump_);
_ptrSrtcpBuffer = NULL; rtp_dump_ = NULL;
} }
if (_ptrEncryptionBuffer)
{
delete[] _ptrEncryptionBuffer;
_ptrEncryptionBuffer = NULL;
}
if (_rtpDump)
{
_rtpDump->Stop();
RtpDump::DestroyRtpDump(_rtpDump);
_rtpDump = NULL;
}
} }
// ---------------------------------------------------------------------------- int ViESender::RegisterExternalEncryption(Encryption* encryption) {
// RegisterExternalEncryption CriticalSectionScoped cs(critsect_);
// ---------------------------------------------------------------------------- if (external_encryption_) {
return -1;
int ViESender::RegisterExternalEncryption(Encryption* encryption) }
{ encryption_buffer_ = new WebRtc_UWord8[kViEMaxMtu];
CriticalSectionScoped cs(_sendCritsect); if (encryption_buffer_ == NULL) {
if (_ptrExternalEncryption) return -1;
{ }
return -1; external_encryption_ = encryption;
} return 0;
_ptrEncryptionBuffer = new WebRtc_UWord8[kViEMaxMtu];
if (_ptrEncryptionBuffer == NULL)
{
return -1;
}
_ptrExternalEncryption = encryption;
return 0;
} }
// ---------------------------------------------------------------------------- int ViESender::DeregisterExternalEncryption() {
// DeregisterExternalEncryption CriticalSectionScoped cs(critsect_);
// ---------------------------------------------------------------------------- if (external_encryption_ == NULL) {
return -1;
int ViESender::DeregisterExternalEncryption() }
{ if (encryption_buffer_) {
CriticalSectionScoped cs(_sendCritsect); delete encryption_buffer_;
if (_ptrExternalEncryption == NULL) encryption_buffer_ = NULL;
{ }
return -1; external_encryption_ = NULL;
} return 0;
if (_ptrEncryptionBuffer)
{
delete _ptrEncryptionBuffer;
_ptrEncryptionBuffer = NULL;
}
_ptrExternalEncryption = NULL;
return 0;
} }
// ---------------------------------------------------------------------------- int ViESender::RegisterSendTransport(Transport* transport) {
// RegisterSendTransport CriticalSectionScoped cs(critsect_);
// ---------------------------------------------------------------------------- if (transport_) {
return -1;
int ViESender::RegisterSendTransport(Transport* transport) }
{ transport_ = transport;
CriticalSectionScoped cs(_sendCritsect); return 0;
if (_ptrTransport)
{
return -1;
}
_ptrTransport = transport;
return 0;
} }
// ---------------------------------------------------------------------------- int ViESender::DeregisterSendTransport() {
// DeregisterSendTransport CriticalSectionScoped cs(critsect_);
// ---------------------------------------------------------------------------- if (transport_ == NULL) {
return -1;
int ViESender::DeregisterSendTransport() }
{ transport_ = NULL;
CriticalSectionScoped cs(_sendCritsect); return 0;
if (_ptrTransport == NULL)
{
return -1;
}
_ptrTransport = NULL;
return 0;
} }
#ifdef WEBRTC_SRTP int ViESender::StartRTPDump(const char file_nameUTF8[1024]) {
// ---------------------------------------------------------------------------- CriticalSectionScoped cs(critsect_);
// RegisterSRTPModule if (rtp_dump_) {
// ---------------------------------------------------------------------------- // Packet dump is already started, restart it.
rtp_dump_->Stop();
int ViESender::RegisterSRTPModule(SrtpModule* srtpModule) } else {
{ rtp_dump_ = RtpDump::CreateRtpDump();
CriticalSectionScoped cs(_sendCritsect); if (rtp_dump_ == NULL) {
if (_ptrSrtp || WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
srtpModule == NULL) ViEId(engine_id_, channel_id_),
{ "StartSRTPDump: Failed to create RTP dump");
return -1; return -1;
} }
_ptrSrtpBuffer = new WebRtc_UWord8[KMaxPacketSize]; }
if (_ptrSrtpBuffer == NULL) if (rtp_dump_->Start(file_nameUTF8) != 0) {
{ RtpDump::DestroyRtpDump(rtp_dump_);
return -1; rtp_dump_ = NULL;
} WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
_ptrSrtp = srtpModule; ViEId(engine_id_, channel_id_),
"StartRTPDump: Failed to start RTP dump");
return 0; return -1;
}
return 0;
} }
// ---------------------------------------------------------------------------- int ViESender::StopRTPDump() {
// DeregisterSRTPModule CriticalSectionScoped cs(critsect_);
// ---------------------------------------------------------------------------- if (rtp_dump_) {
if (rtp_dump_->IsActive()) {
int ViESender::DeregisterSRTPModule() rtp_dump_->Stop();
{ } else {
CriticalSectionScoped cs(_sendCritsect); WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
if (_ptrSrtp == NULL) ViEId(engine_id_, channel_id_),
{ "StopRTPDump: Dump not active");
return -1;
} }
if (_ptrSrtpBuffer) RtpDump::DestroyRtpDump(rtp_dump_);
{ rtp_dump_ = NULL;
delete [] _ptrSrtpBuffer; } else {
_ptrSrtpBuffer = NULL; WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
} ViEId(engine_id_, channel_id_),
_ptrSrtp = NULL; "StopRTPDump: RTP dump not started");
return 0; return -1;
} }
// ---------------------------------------------------------------------------- return 0;
// RegisterSRTCPModule
// ----------------------------------------------------------------------------
int ViESender::RegisterSRTCPModule(SrtpModule* srtcpModule)
{
CriticalSectionScoped cs(_sendCritsect);
if (_ptrSrtcp ||
srtcpModule == NULL)
{
return -1;
}
_ptrSrtcpBuffer = new WebRtc_UWord8[KMaxPacketSize];
if (_ptrSrtcpBuffer == NULL)
{
return -1;
}
_ptrSrtcp = srtcpModule;
return 0;
} }
// ---------------------------------------------------------------------------- int ViESender::SendPacket(int vie_id, const void* data, int len) {
// DeregisterSRTCPModule CriticalSectionScoped cs(critsect_);
// ---------------------------------------------------------------------------- if (!transport_) {
// No transport
return -1;
}
int ViESender::DeregisterSRTCPModule() assert(ChannelId(vie_id) == channel_id_);
{
CriticalSectionScoped cs(_sendCritsect);
if (_ptrSrtcp == NULL)
{
return -1;
}
if (_ptrSrtcpBuffer)
{
delete [] _ptrSrtcpBuffer;
_ptrSrtcpBuffer = NULL;
}
_ptrSrtcp = NULL;
return 0;
}
#endif
// ---------------------------------------------------------------------------- // TODO(mflodman) Change decrypt to get rid of this cast.
// StartRTPDump void* tmp_ptr = const_cast<void*>(data);
// ---------------------------------------------------------------------------- unsigned char* send_packet = static_cast<unsigned char*>(tmp_ptr);
int send_packet_length = len;
int ViESender::StartRTPDump(const char fileNameUTF8[1024]) if (rtp_dump_) {
{ rtp_dump_->DumpPacket(send_packet, send_packet_length);
CriticalSectionScoped cs(_sendCritsect); }
if (_rtpDump)
{ if (external_encryption_) {
// Restart it if it already exists and is started external_encryption_->encrypt(channel_id_, send_packet,
_rtpDump->Stop(); encryption_buffer_, send_packet_length,
} else static_cast<int*>(&send_packet_length));
{ send_packet = encryption_buffer_;
_rtpDump = RtpDump::CreateRtpDump(); }
if (_rtpDump == NULL)
{ return transport_->SendPacket(channel_id_, send_packet, send_packet_length);
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId,
_channelId),
"%s: Failed to create RTP dump", __FUNCTION__);
return -1;
}
}
if (_rtpDump->Start(fileNameUTF8) != 0)
{
RtpDump::DestroyRtpDump(_rtpDump);
_rtpDump = NULL;
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
ViEId(_engineId, _channelId),
"%s: Failed to start RTP dump", __FUNCTION__);
return -1;
}
return 0;
} }
// ---------------------------------------------------------------------------- int ViESender::SendRTCPPacket(int vie_id, const void* data, int len) {
// StopRTPDump CriticalSectionScoped cs(critsect_);
// ----------------------------------------------------------------------------
int ViESender::StopRTPDump() if (!transport_) {
{ return -1;
CriticalSectionScoped cs(_sendCritsect); }
if (_rtpDump)
{ assert(ChannelId(vie_id) == channel_id_);
if (_rtpDump->IsActive())
{ // Prepare for possible encryption and sending.
_rtpDump->Stop(); // TODO(mflodman) Change decrypt to get rid of this cast.
} else void* tmp_ptr = const_cast<void*>(data);
{ unsigned char* send_packet = static_cast<unsigned char*>(tmp_ptr);
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId, int send_packet_length = len;
_channelId),
"%s: Dump not active", __FUNCTION__); if (rtp_dump_) {
} rtp_dump_->DumpPacket(send_packet, send_packet_length);
RtpDump::DestroyRtpDump(_rtpDump); }
_rtpDump = NULL;
} else if (external_encryption_) {
{ external_encryption_->encrypt_rtcp(
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, channel_id_, send_packet, encryption_buffer_, send_packet_length,
ViEId(_engineId, _channelId), "%s: RTP dump not started", static_cast<int*>(&send_packet_length));
__FUNCTION__); send_packet = encryption_buffer_;
return -1; }
}
return 0; return transport_->SendRTCPPacket(channel_id_, send_packet,
send_packet_length);
} }
// ---------------------------------------------------------------------------- } // namespace webrtc
// SendPacket
// ----------------------------------------------------------------------------
int ViESender::SendPacket(int vieId, const void *data, int len)
{
CriticalSectionScoped cs(_sendCritsect);
if (!_ptrTransport)
{
// No transport
return -1;
}
assert(ChannelId(vieId) == _channelId);
// Prepare for possible encryption and sending
WebRtc_UWord8* sendPacket = (WebRtc_UWord8*) data;
int sendPacketLength = len;
if (_rtpDump)
{
_rtpDump->DumpPacket(sendPacket, sendPacketLength);
}
#ifdef WEBRTC_SRTP
if (_ptrSrtp)
{
_ptrSrtp->encrypt(_channelId, sendPacket, _ptrSrtpBuffer, sendPacketLength, (int*) &sendPacketLength);
if (sendPacketLength <= 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId, _channelId), "RTP encryption failed for channel");
return -1;
}
else if (sendPacketLength > KMaxPacketSize)
{
WEBRTC_TRACE(webrtc::kTraceCritical, webrtc::kTraceVideo, ViEId(_engineId, _channelId),
" %d bytes is allocated as RTP output => memory is now corrupted", KMaxPacketSize);
return -1;
}
sendPacket = _ptrSrtpBuffer;
}
#endif
if (_ptrExternalEncryption)
{
_ptrExternalEncryption->encrypt(_channelId, sendPacket,
_ptrEncryptionBuffer, sendPacketLength,
(int*) &sendPacketLength);
sendPacket = _ptrEncryptionBuffer;
}
return _ptrTransport->SendPacket(_channelId, sendPacket, sendPacketLength);
}
// ----------------------------------------------------------------------------
// SendRTCPPacket
// ----------------------------------------------------------------------------
int ViESender::SendRTCPPacket(int vieId, const void *data, int len)
{
CriticalSectionScoped cs(_sendCritsect);
if (!_ptrTransport)
{
// No transport
return -1;
}
assert(ChannelId(vieId) == _channelId);
// Prepare for possible encryption and sending
WebRtc_UWord8* sendPacket = (WebRtc_UWord8*) data;
int sendPacketLength = len;
if (_rtpDump)
{
_rtpDump->DumpPacket(sendPacket, sendPacketLength);
}
#ifdef WEBRTC_SRTP
if (_ptrSrtcp)
{
_ptrSrtcp->encrypt_rtcp(_channelId, sendPacket, _ptrSrtcpBuffer, sendPacketLength, (int*) &sendPacketLength);
if (sendPacketLength <= 0)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId, _channelId), "RTCP encryption failed for channel");
return -1;
}
else if (sendPacketLength > KMaxPacketSize)
{
WEBRTC_TRACE(webrtc::kTraceCritical, webrtc::kTraceVideo, ViEId(_engineId, _channelId), " %d bytes is allocated as RTCP output => memory is now corrupted", KMaxPacketSize);
return -1;
}
sendPacket = _ptrSrtcpBuffer;
}
#endif
if (_ptrExternalEncryption)
{
_ptrExternalEncryption->encrypt_rtcp(_channelId, sendPacket,
_ptrEncryptionBuffer,
sendPacketLength,
(int*) &sendPacketLength);
sendPacket = _ptrEncryptionBuffer;
}
return _ptrTransport->SendRTCPPacket(_channelId, sendPacket,
sendPacketLength);
}
} // namespace webrtc

View File

@ -8,75 +8,57 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
/* // ViESender is responsible for encrypting, if enabled, packets and send to
* vie_sender.h // network.
*/
#ifndef WEBRTC_VIDEO_ENGINE_MAIN_SOURCE_VIE_SENDER_H_ #ifndef WEBRTC_VIDEO_ENGINE_VIE_SENDER_H_
#define WEBRTC_VIDEO_ENGINE_MAIN_SOURCE_VIE_SENDER_H_ #define WEBRTC_VIDEO_ENGINE_VIE_SENDER_H_
// Defines
#include "engine_configurations.h"
#include "vie_defines.h"
#include "typedefs.h"
#include "common_types.h" #include "common_types.h"
#include "engine_configurations.h"
// Forward declarations #include "typedefs.h"
#include "vie_defines.h"
#ifdef WEBRTC_SRTP
class SrtpModule;
#endif
namespace webrtc { namespace webrtc {
class CriticalSectionWrapper; class CriticalSectionWrapper;
class RtpDump; class RtpDump;
class Transport; class Transport;
class VideoCodingModule; class VideoCodingModule;
class ViESender: public Transport class ViESender: public Transport {
{ public:
public: ViESender(int engine_id, int channel_id);
ViESender(int engineId, int channelId); ~ViESender();
~ViESender();
int RegisterExternalEncryption(Encryption* encryption); // Registers an encryption class to use before sending packets.
int DeregisterExternalEncryption(); int RegisterExternalEncryption(Encryption* encryption);
int DeregisterExternalEncryption();
int RegisterSendTransport(Transport* transport); // Registers transport to use for sending RTP and RTCP.
int DeregisterSendTransport(); int RegisterSendTransport(Transport* transport);
int DeregisterSendTransport();
#ifdef WEBRTC_SRTP // Stores all incoming packets to file.
int RegisterSRTPModule(SrtpModule* srtpModule); int StartRTPDump(const char file_nameUTF8[1024]);
int DeregisterSRTPModule(); int StopRTPDump();
int RegisterSRTCPModule(SrtpModule* srtpModule); // Implements Transport.
int DeregisterSRTCPModule(); virtual int SendPacket(int vie_id, const void* data, int len);
#endif virtual int SendRTCPPacket(int vie_id, const void* data, int len);
int StartRTPDump(const char fileNameUTF8[1024]); private:
int StopRTPDump(); int engine_id_;
int channel_id_;
// Implements Transport CriticalSectionWrapper& critsect_;
virtual int SendPacket(int vieId, const void *data, int len);
virtual int SendRTCPPacket(int vieId, const void *data, int len);
private: Encryption* external_encryption_;
int _engineId; WebRtc_UWord8* encryption_buffer_;
int _channelId; Transport* transport_;
CriticalSectionWrapper& _sendCritsect; RtpDump* rtp_dump_;
#ifdef WEBRTC_SRTP
SrtpModule* _ptrSrtp;
SrtpModule* _ptrSrtcp;
#endif
Encryption* _ptrExternalEncryption;
WebRtc_UWord8* _ptrSrtpBuffer;
WebRtc_UWord8* _ptrSrtcpBuffer;
WebRtc_UWord8* _ptrEncryptionBuffer;
Transport* _ptrTransport;
RtpDump* _rtpDump;
}; };
} // namespace webrtc } // namespace webrtc
#endif // WEBRTC_VIDEO_ENGINE_MAIN_SOURCE_VIE_SENDER_H_
#endif // WEBRTC_VIDEO_ENGINE_VIE_SENDER_H_