Review URL: http://webrtc-codereview.appspot.com/23013
git-svn-id: http://webrtc.googlecode.com/svn/trunk@75 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
17705a9c5a
commit
385345d5e5
@ -171,7 +171,7 @@ public:
|
||||
unsigned int name, const char* data,
|
||||
unsigned short dataLengthInBytes) = 0;
|
||||
|
||||
// This function enables Negative Acknowledgement (NACK) using RTCP,
|
||||
// This function enables Negative Acknowledgment (NACK) using RTCP,
|
||||
// implemented based on RFC 4585. NACK retransmits RTP packets if lost on
|
||||
// the network. This creates a lossless transport at the expense of delay.
|
||||
// If using NACK, NACK should be enabled on both endpoints in a call.
|
||||
@ -185,6 +185,19 @@ public:
|
||||
const unsigned char payloadTypeRED,
|
||||
const unsigned char payloadTypeFEC) = 0;
|
||||
|
||||
// This function enables hybrid Negative Acknowledgment using RTCP
|
||||
// and Forward Error Correction (FEC) implemented based on RFC 5109,
|
||||
// to improve packet loss robustness. Extra
|
||||
// FEC packets are sent together with the usual media packets, hence will
|
||||
// part of the bitrate be used for FEC packets.
|
||||
// The hybrid mode will choose between nack only, fec only and both based on
|
||||
// network conditions. When both are applied, only packets that were not
|
||||
// recovered by the FEC will be nacked.
|
||||
virtual int SetHybridNACKFECStatus(const int videoChannel,
|
||||
const bool enable,
|
||||
const unsigned char payloadTypeRED,
|
||||
const unsigned char payloadTypeFEC) = 0;
|
||||
|
||||
// This function enables RTCP key frame requests.
|
||||
virtual int SetKeyFrameRequestMethod(
|
||||
const int videoChannel, const ViEKeyFrameRequestMethod method) = 0;
|
||||
|
@ -419,7 +419,7 @@ WebRtc_Word32 ViEChannel::RegisterCodecObserver(ViEDecoderObserver* observer)
|
||||
if (_codecObserver)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
||||
ViEId(_engineId, _channelId), "%s: alread added",
|
||||
ViEId(_engineId, _channelId), "%s: already added",
|
||||
__FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
@ -615,23 +615,44 @@ WebRtc_Word32 ViEChannel::GetRTCPMode(RTCPMethod& rtcpMode)
|
||||
|
||||
WebRtc_Word32 ViEChannel::SetNACKStatus(const bool enable)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(_engineId, _channelId),
|
||||
"%s(enable: %d)", __FUNCTION__, enable);
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo,
|
||||
ViEId(_engineId, _channelId),
|
||||
"%s(enable: %d)", __FUNCTION__, enable);
|
||||
|
||||
// Update the decoding VCM
|
||||
if (_vcm.SetVideoProtection(kProtectionNack, enable) != VCM_OK)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
||||
ViEId(_engineId, _channelId),
|
||||
"%s: Could not set VCM NACK protection: %d", __FUNCTION__,
|
||||
enable);
|
||||
ViEId(_engineId, _channelId),
|
||||
"%s: Could not set VCM NACK protection: %d", __FUNCTION__,
|
||||
enable);
|
||||
return -1;
|
||||
}
|
||||
if (enable)
|
||||
{
|
||||
// Disable possible FEC
|
||||
SetFECStatus(false, 0, 0);
|
||||
}
|
||||
// Update the decoding VCM
|
||||
if (_vcm.SetVideoProtection(kProtectionNack, enable) != VCM_OK)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
||||
ViEId(_engineId, _channelId),
|
||||
"%s: Could not set VCM NACK protection: %d", __FUNCTION__,
|
||||
enable);
|
||||
return -1;
|
||||
}
|
||||
return ProcessNACKRequest(enable);
|
||||
}
|
||||
|
||||
WebRtc_Word32 ViEChannel::ProcessNACKRequest(const bool enable)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo,
|
||||
ViEId(_engineId, _channelId),
|
||||
"%s(enable: %d)", __FUNCTION__, enable);
|
||||
|
||||
if (enable)
|
||||
{
|
||||
// Turn on NACK,
|
||||
NACKMethod nackMethod = kNackRtcp;
|
||||
if (_rtpRtcp.RTCP() == kRtcpOff)
|
||||
@ -649,8 +670,9 @@ WebRtc_Word32 ViEChannel::SetNACKStatus(const bool enable)
|
||||
nackMethod);
|
||||
return -1;
|
||||
}
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(_engineId, _channelId),
|
||||
"%s: Using NACK method %d", __FUNCTION__, nackMethod);
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo,
|
||||
ViEId(_engineId, _channelId),
|
||||
"%s: Using NACK method %d", __FUNCTION__, nackMethod);
|
||||
_rtpRtcp.SetStorePacketsStatus(true, kNackHistorySize);
|
||||
_vcm.RegisterPacketRequestCallback(this);
|
||||
}
|
||||
@ -677,16 +699,25 @@ WebRtc_Word32 ViEChannel::SetFECStatus(const bool enable,
|
||||
const unsigned char payloadTypeRED,
|
||||
const unsigned char payloadTypeFEC)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_engineId, _channelId),
|
||||
"%s(enable: %d, payloadTypeRED: %u, payloadTypeFEC: %u)",
|
||||
__FUNCTION__, enable, payloadTypeRED, payloadTypeFEC);
|
||||
|
||||
// Disable possible NACK
|
||||
if (enable)
|
||||
{
|
||||
SetNACKStatus(false);
|
||||
}
|
||||
|
||||
return ProcessFECRequest(enable, payloadTypeRED, payloadTypeFEC);
|
||||
|
||||
}
|
||||
WebRtc_Word32
|
||||
ViEChannel::ProcessFECRequest(const bool enable,
|
||||
const unsigned char payloadTypeRED,
|
||||
const unsigned char payloadTypeFEC)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
||||
ViEId(_engineId, _channelId),
|
||||
"%s(enable: %d, payloadTypeRED: %u, payloadTypeFEC: %u)",
|
||||
__FUNCTION__, enable, payloadTypeRED, payloadTypeFEC);
|
||||
|
||||
if (_rtpRtcp.SetGenericFECStatus(enable, payloadTypeRED, payloadTypeFEC)
|
||||
!= 0)
|
||||
{
|
||||
@ -700,6 +731,34 @@ WebRtc_Word32 ViEChannel::SetFECStatus(const bool enable,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// EnableNACKFECStatus
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
WebRtc_Word32
|
||||
ViEChannel::SetHybridNACKFECStatus(const bool enable,
|
||||
const unsigned char payloadTypeRED,
|
||||
const unsigned char payloadTypeFEC)
|
||||
{
|
||||
// Update the decoding VCM with hybrid mode
|
||||
if (_vcm.SetVideoProtection(kProtectionNackFEC, enable) != VCM_OK)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
||||
ViEId(_engineId, _channelId),
|
||||
"%s: Could not set VCM NACK protection: %d", __FUNCTION__,
|
||||
enable);
|
||||
return -1;
|
||||
}
|
||||
|
||||
WebRtc_Word32 retVal = 0;
|
||||
retVal = ProcessNACKRequest(enable);
|
||||
if (retVal < 0)
|
||||
{
|
||||
return retVal;
|
||||
}
|
||||
return ProcessFECRequest(enable, payloadTypeRED, payloadTypeFEC);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// KeyFrameRequestMethod
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -111,6 +111,9 @@ public:
|
||||
WebRtc_Word32 SetFECStatus(const bool enable,
|
||||
const unsigned char payloadTypeRED,
|
||||
const unsigned char payloadTypeFEC);
|
||||
WebRtc_Word32 SetHybridNACKFECStatus(const bool enable,
|
||||
const unsigned char payloadTypeRED,
|
||||
const unsigned char payloadTypeFEC);
|
||||
|
||||
WebRtc_Word32
|
||||
SetKeyFrameRequestMethod(const KeyFrameRequestMethod method);
|
||||
@ -410,6 +413,13 @@ private:
|
||||
WebRtc_Word32 StartDecodeThread();
|
||||
WebRtc_Word32 StopDecodeThread();
|
||||
|
||||
// Protection
|
||||
WebRtc_Word32 ProcessNACKRequest(const bool enable);
|
||||
|
||||
WebRtc_Word32 ProcessFECRequest(const bool enable,
|
||||
const unsigned char payloadTypeRED,
|
||||
const unsigned char payloadTypeFEC);
|
||||
|
||||
// General members
|
||||
WebRtc_Word32 _channelId;
|
||||
WebRtc_Word32 _engineId;
|
||||
|
@ -40,8 +40,10 @@ ViEEncoder::ViEEncoder(WebRtc_Word32 engineId, WebRtc_Word32 channelId,
|
||||
_engineId(engineId),
|
||||
_channelId(channelId),
|
||||
_numberOfCores(numberOfCores),
|
||||
_vcm(*webrtc::VideoCodingModule::Create(ViEModuleId(engineId, channelId))),
|
||||
_vpm(*webrtc::VideoProcessingModule::Create(ViEModuleId(engineId, channelId))),
|
||||
_vcm(*webrtc::VideoCodingModule::Create(ViEModuleId(engineId,
|
||||
channelId))),
|
||||
_vpm(*webrtc::VideoProcessingModule::Create(ViEModuleId(engineId,
|
||||
channelId))),
|
||||
_rtpRtcp(*RtpRtcp::CreateRtpRtcp(ViEModuleId(engineId,
|
||||
channelId),
|
||||
false)),
|
||||
@ -49,14 +51,15 @@ ViEEncoder::ViEEncoder(WebRtc_Word32 engineId, WebRtc_Word32 channelId,
|
||||
_dataCritsect(*CriticalSectionWrapper::CreateCriticalSection()),
|
||||
_paused(false), _timeLastIntraRequestMs(0),
|
||||
_channelsDroppingDeltaFrames(0), _dropNextFrame(false),
|
||||
_fecEnabled(false), _codecObserver(NULL), _effectFilter(NULL),
|
||||
_moduleProcessThread(moduleProcessThread), _hasReceivedSLI(false),
|
||||
_pictureIdSLI(0), _hasReceivedRPSI(false), _pictureIdRPSI(0),
|
||||
_fileRecorder(channelId)
|
||||
_fecEnabled(false), _nackEnabled(false), _codecObserver(NULL),
|
||||
_effectFilter(NULL), _moduleProcessThread(moduleProcessThread),
|
||||
_hasReceivedSLI(false), _pictureIdSLI(0), _hasReceivedRPSI(false),
|
||||
_pictureIdRPSI(0), _fileRecorder(channelId)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, ViEId(engineId, channelId),
|
||||
"%s(engineId: %d) 0x%p - Constructor", __FUNCTION__, engineId,
|
||||
this);
|
||||
WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo,
|
||||
ViEId(engineId, channelId),
|
||||
"%s(engineId: %d) 0x%p - Constructor", __FUNCTION__, engineId,
|
||||
this);
|
||||
|
||||
_vcm.InitializeSender();
|
||||
_vpm.EnableTemporalDecimation(true);
|
||||
@ -80,7 +83,8 @@ ViEEncoder::ViEEncoder(WebRtc_Word32 engineId, WebRtc_Word32 channelId,
|
||||
VideoCodec videoCodec;
|
||||
if (_vcm.Codec(webrtc::kVideoCodecVP8, &videoCodec) == VCM_OK)
|
||||
{
|
||||
_vcm.RegisterSendCodec(&videoCodec, _numberOfCores, _rtpRtcp.MaxDataPayloadLength());
|
||||
_vcm.RegisterSendCodec(&videoCodec, _numberOfCores,
|
||||
_rtpRtcp.MaxDataPayloadLength());
|
||||
_rtpRtcp.RegisterSendPayload(videoCodec.plName, videoCodec.plType);
|
||||
}
|
||||
else
|
||||
@ -91,7 +95,8 @@ ViEEncoder::ViEEncoder(WebRtc_Word32 engineId, WebRtc_Word32 channelId,
|
||||
VideoCodec videoCodec;
|
||||
if (_vcm.Codec(webrtc::kVideoCodecI420, &videoCodec) == VCM_OK)
|
||||
{
|
||||
_vcm.RegisterSendCodec(&videoCodec, _numberOfCores, _rtpRtcp.MaxDataPayloadLength());
|
||||
_vcm.RegisterSendCodec(&videoCodec, _numberOfCores,
|
||||
_rtpRtcp.MaxDataPayloadLength());
|
||||
_rtpRtcp.RegisterSendPayload(videoCodec.plName, videoCodec.plType);
|
||||
}
|
||||
else
|
||||
@ -127,8 +132,9 @@ ViEEncoder::ViEEncoder(WebRtc_Word32 engineId, WebRtc_Word32 channelId,
|
||||
|
||||
ViEEncoder::~ViEEncoder()
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, ViEId(_engineId, _channelId),
|
||||
"ViEEncoder Destructor 0x%p, engineId: %d", this, _engineId);
|
||||
WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo,
|
||||
ViEId(_engineId, _channelId),
|
||||
"ViEEncoder Destructor 0x%p, engineId: %d", this, _engineId);
|
||||
|
||||
if (_rtpRtcp.NumberChildModules() > 0)
|
||||
{
|
||||
@ -161,16 +167,18 @@ ViEEncoder::~ViEEncoder()
|
||||
|
||||
void ViEEncoder::Pause()
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(_engineId, _channelId),
|
||||
"%s", __FUNCTION__);
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo,
|
||||
ViEId(_engineId, _channelId),
|
||||
"%s", __FUNCTION__);
|
||||
CriticalSectionScoped cs(_dataCritsect);
|
||||
_paused = true;
|
||||
}
|
||||
|
||||
void ViEEncoder::Restart()
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(_engineId, _channelId),
|
||||
"%s", __FUNCTION__);
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo,
|
||||
ViEId(_engineId, _channelId),
|
||||
"%s", __FUNCTION__);
|
||||
CriticalSectionScoped cs(_dataCritsect);
|
||||
_paused = false;
|
||||
}
|
||||
@ -183,8 +191,9 @@ void ViEEncoder::Restart()
|
||||
|
||||
WebRtc_Word32 ViEEncoder::DropDeltaAfterKey(bool enable)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(_engineId, _channelId),
|
||||
"%s(%d)", __FUNCTION__, enable);
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo,
|
||||
ViEId(_engineId, _channelId),
|
||||
"%s(%d)", __FUNCTION__, enable);
|
||||
CriticalSectionScoped cs(_dataCritsect);
|
||||
|
||||
if (enable)
|
||||
@ -196,9 +205,9 @@ WebRtc_Word32 ViEEncoder::DropDeltaAfterKey(bool enable)
|
||||
if (_channelsDroppingDeltaFrames < 0)
|
||||
{
|
||||
_channelsDroppingDeltaFrames = 0;
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(_engineId,
|
||||
_channelId),
|
||||
"%s: Called too many times", __FUNCTION__, enable);
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo,
|
||||
ViEId(_engineId, _channelId),
|
||||
"%s: Called too many times", __FUNCTION__, enable);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -238,12 +247,12 @@ WebRtc_Word32 ViEEncoder::GetCodec(WebRtc_UWord8 listIndex,
|
||||
// ----------------------------------------------------------------------------
|
||||
// External encoder
|
||||
// ----------------------------------------------------------------------------
|
||||
WebRtc_Word32 ViEEncoder::RegisterExternalEncoder(
|
||||
webrtc::VideoEncoder* encoder,
|
||||
WebRtc_Word32 ViEEncoder::RegisterExternalEncoder(webrtc::VideoEncoder* encoder,
|
||||
WebRtc_UWord8 plType)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(_engineId, _channelId),
|
||||
"%s: pltype %u", __FUNCTION__, plType);
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo,
|
||||
ViEId(_engineId, _channelId),
|
||||
"%s: pltype %u", __FUNCTION__, plType);
|
||||
|
||||
if (encoder == NULL)
|
||||
return -1;
|
||||
@ -260,8 +269,9 @@ WebRtc_Word32 ViEEncoder::RegisterExternalEncoder(
|
||||
|
||||
WebRtc_Word32 ViEEncoder::DeRegisterExternalEncoder(WebRtc_UWord8 plType)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(_engineId, _channelId),
|
||||
"%s: pltype %u", __FUNCTION__, plType);
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo,
|
||||
ViEId(_engineId, _channelId),
|
||||
"%s: pltype %u", __FUNCTION__, plType);
|
||||
|
||||
webrtc::VideoCodec currentSendCodec;
|
||||
if (_vcm.SendCodec(¤tSendCodec) == VCM_OK)
|
||||
@ -284,9 +294,9 @@ WebRtc_Word32 ViEEncoder::DeRegisterExternalEncoder(WebRtc_UWord8 plType)
|
||||
if (_vcm.RegisterSendCodec(¤tSendCodec, _numberOfCores,
|
||||
maxDataPayloadLength) != VCM_OK)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId,
|
||||
_channelId),
|
||||
"Could not use internal encoder");
|
||||
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
||||
ViEId(_engineId, _channelId),
|
||||
"Could not use internal encoder");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -299,8 +309,9 @@ WebRtc_Word32 ViEEncoder::DeRegisterExternalEncoder(WebRtc_UWord8 plType)
|
||||
|
||||
WebRtc_Word32 ViEEncoder::SetEncoder(const webrtc::VideoCodec& videoCodec)
|
||||
{
|
||||
WEBRTC_TRACE( webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(_engineId, _channelId),
|
||||
"%s: CodecType: %d, width: %u, height: %u, maxPayloadLength: %u",
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo,
|
||||
ViEId(_engineId, _channelId),
|
||||
"%s: CodecType: %d, width: %u, height: %u, maxPayloadLength: %u",
|
||||
__FUNCTION__, videoCodec.codecType, videoCodec.width,
|
||||
videoCodec.height);
|
||||
|
||||
@ -687,6 +698,7 @@ WebRtc_Word32 ViEEncoder::UpdateProtectionMethod()
|
||||
WebRtc_UWord8 dummyPTypeRed = 0;
|
||||
WebRtc_UWord8 dummyPTypeFEC = 0;
|
||||
|
||||
// check if fec is enabled
|
||||
WebRtc_Word32 error = _rtpRtcp.GenericFECStatus(fecEnabled, dummyPTypeRed,
|
||||
dummyPTypeFEC);
|
||||
if (error)
|
||||
@ -694,19 +706,35 @@ WebRtc_Word32 ViEEncoder::UpdateProtectionMethod()
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_fecEnabled != fecEnabled)
|
||||
// check if nack is enabled
|
||||
bool nackEnabled = (_rtpRtcp.NACK() == kNackOff) ? false : true;
|
||||
if (_fecEnabled == fecEnabled && _nackEnabled == nackEnabled)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(_engineId, _channelId),
|
||||
"%s: FEC status ", __FUNCTION__, fecEnabled);
|
||||
// no change to current state
|
||||
return 0;
|
||||
}
|
||||
_fecEnabled = fecEnabled;
|
||||
_nackEnabled = nackEnabled;
|
||||
|
||||
_vcm.SetVideoProtection(webrtc::kProtectionFEC, fecEnabled);
|
||||
if (fecEnabled)
|
||||
{
|
||||
_vcm.RegisterProtectionCallback(this);
|
||||
} else
|
||||
{
|
||||
_vcm.RegisterProtectionCallback(NULL);
|
||||
}
|
||||
// Set Video Protection for VCM
|
||||
if (fecEnabled && nackEnabled)
|
||||
{
|
||||
_vcm.SetVideoProtection(webrtc::kProtectionNackFEC, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
_vcm.SetVideoProtection(webrtc::kProtectionFEC, _fecEnabled);
|
||||
_vcm.SetVideoProtection(webrtc::kProtectionNack, _nackEnabled);
|
||||
_vcm.SetVideoProtection(webrtc::kProtectionNackFEC, false);
|
||||
}
|
||||
|
||||
// If nack and/or fec is enalbed, the following should be triggered
|
||||
if (fecEnabled || nackEnabled)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo,
|
||||
ViEId(_engineId, _channelId),
|
||||
"%s: FEC status ", __FUNCTION__, fecEnabled);
|
||||
_vcm.RegisterProtectionCallback(this);
|
||||
// Need to reregister the send codec in order to set the new MTU
|
||||
webrtc::VideoCodec codec;
|
||||
if (_vcm.SendCodec(&codec) == 0)
|
||||
@ -715,19 +743,20 @@ WebRtc_Word32 ViEEncoder::UpdateProtectionMethod()
|
||||
codec.startBitrate = _vcm.Bitrate();
|
||||
if (_vcm.RegisterSendCodec(&codec, _numberOfCores, maxPayLoad) != 0)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId,
|
||||
_channelId),
|
||||
"%s: Failed to update Sendcodec when enabling FEC",
|
||||
__FUNCTION__, fecEnabled);
|
||||
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
||||
ViEId(_engineId, _channelId),
|
||||
"%s: Failed to update Sendcodec when enabling FEC",
|
||||
__FUNCTION__, fecEnabled);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
_fecEnabled = fecEnabled;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// FEC and NACK are disabled
|
||||
_vcm.RegisterProtectionCallback(NULL);
|
||||
}
|
||||
|
||||
// Update NACK status
|
||||
_vcm.SetVideoProtection(webrtc::kProtectionNack, _rtpRtcp.NACK() != kNackOff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -162,6 +162,7 @@ private:
|
||||
bool _dropNextFrame;
|
||||
//Loss protection
|
||||
bool _fecEnabled;
|
||||
bool _nackEnabled;
|
||||
// Uses
|
||||
ViEEncoderObserver* _codecObserver;
|
||||
ViEEffectFilter* _effectFilter;
|
||||
|
@ -279,12 +279,7 @@ WebRtc_Word32 ViEReceiver::OnReceivedPayloadData(const WebRtc_UWord8* payloadDat
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (rtpHeader->frameType == webrtc::kFrameEmpty)
|
||||
{
|
||||
// Don't care about empty rtp packets, we might
|
||||
// get this e.g. when using FEC
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_vcm.IncomingPacket(payloadData, payloadSize, *rtpHeader) != 0)
|
||||
{
|
||||
// Check this...
|
||||
|
@ -651,6 +651,7 @@ int ViERTP_RTCPImpl::SetFECStatus(const int videoChannel, const bool enable,
|
||||
const unsigned char payloadTypeRED,
|
||||
const unsigned char payloadTypeFEC)
|
||||
{
|
||||
|
||||
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
||||
ViEId(_instanceId, videoChannel),
|
||||
"%s(channel: %d, enable: %d, payloadTypeRED: %u, "
|
||||
@ -698,6 +699,64 @@ int ViERTP_RTCPImpl::SetFECStatus(const int videoChannel, const bool enable,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetHybridNACKFECStatus
|
||||
//
|
||||
// Enables/disables hybrid NACK/FEC and sets the payloadtypes
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
int ViERTP_RTCPImpl::SetHybridNACKFECStatus(const int videoChannel,
|
||||
const bool enable,
|
||||
const unsigned char payloadTypeRED,
|
||||
const unsigned char payloadTypeFEC)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
||||
ViEId(_instanceId, videoChannel),
|
||||
"%s(channel: %d, enable: %d, payloadTypeRED: %u, "
|
||||
"payloadTypeFEC: %u)",
|
||||
__FUNCTION__, videoChannel, enable, payloadTypeRED,
|
||||
payloadTypeFEC);
|
||||
|
||||
// Get the channel
|
||||
ViEChannelManagerScoped cs(_channelManager);
|
||||
ViEChannel* ptrViEChannel = cs.Channel(videoChannel);
|
||||
if (ptrViEChannel == NULL)
|
||||
{
|
||||
// The channel doesn't exists
|
||||
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
||||
ViEId(_instanceId, videoChannel),
|
||||
"%s: Channel %d doesn't exist", __FUNCTION__,
|
||||
videoChannel);
|
||||
SetLastError(kViERtpRtcpInvalidChannelId);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Update the channel status with hybrid NACK FEC mode
|
||||
if (ptrViEChannel->SetHybridNACKFECStatus(enable, payloadTypeRED,
|
||||
payloadTypeFEC) != 0)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
||||
ViEId(_instanceId, videoChannel),
|
||||
"%s: failed for channel %d", __FUNCTION__, videoChannel);
|
||||
SetLastError(kViERtpRtcpUnknownError);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Update the encoder
|
||||
ViEEncoder* ptrViEEncoder = cs.Encoder(videoChannel);
|
||||
if (ptrViEEncoder == NULL)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
||||
ViEId(_instanceId, videoChannel),
|
||||
"%s: Could not get encoder for channel %d", __FUNCTION__,
|
||||
videoChannel);
|
||||
SetLastError(kViERtpRtcpUnknownError);
|
||||
return -1;
|
||||
}
|
||||
ptrViEEncoder->UpdateProtectionMethod();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetKeyFrameRequestMethod
|
||||
//
|
||||
|
@ -76,6 +76,9 @@ public:
|
||||
virtual int SetFECStatus(const int videoChannel, const bool enable,
|
||||
const unsigned char payloadTypeRED,
|
||||
const unsigned char payloadTypeFEC);
|
||||
virtual int SetHybridNACKFECStatus(const int videoChannel, const bool enable,
|
||||
const unsigned char payloadTypeRED,
|
||||
const unsigned char payloadTypeFEC);
|
||||
|
||||
virtual int SetKeyFrameRequestMethod(const int videoChannel,
|
||||
const ViEKeyFrameRequestMethod method);
|
||||
|
Loading…
x
Reference in New Issue
Block a user