Replaced the _audio parameter with a strategy.
The purpose is to make _rtpReceiver mostly agnostic to if it processes audio or video, and make its delegates responsible for that. This patch makes the actual interfaces and interactions between the classes a lot clearer which will probably help straighten out the rather convoluted business logic in here. There are a number of rough edges I hope to address in coming patches. In particular, I think there are a lot of audio-specific hacks, especially when it comes to telephone event handling. I think we will see a lot of benefit once that stuff moves out of rtp_receiver altogether. The new strategy I introduced doesn't quite pull its own weight yet, but I think I will be able to remove a lot of that interface later once the responsibilities of the classes becomes move cohesive (e.g. that audio specific stuff actually lives in the audio class, and so on). Also I think it should be possible to extract payload type management to a helper class later on. BUG= TEST=vie/voe_auto_test, trybots Review URL: https://webrtc-codereview.appspot.com/1001006 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3306 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
59ad541e57
commit
07bf43c673
@ -24,6 +24,7 @@
|
|||||||
#define TIMEOUT_SEI_MESSAGES_MS 30000 // in milliseconds
|
#define TIMEOUT_SEI_MESSAGES_MS 30000 // in milliseconds
|
||||||
|
|
||||||
namespace webrtc{
|
namespace webrtc{
|
||||||
|
|
||||||
enum RTCPMethod
|
enum RTCPMethod
|
||||||
{
|
{
|
||||||
kRtcpOff = 0,
|
kRtcpOff = 0,
|
||||||
|
@ -8,17 +8,20 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "trace.h"
|
|
||||||
#include "rtp_receiver.h"
|
#include "rtp_receiver.h"
|
||||||
|
|
||||||
#include "rtp_rtcp_defines.h"
|
|
||||||
#include "rtp_rtcp_impl.h"
|
|
||||||
#include "critical_section_wrapper.h"
|
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <string.h> //memcpy
|
|
||||||
#include <math.h> // floor
|
#include <math.h> // floor
|
||||||
#include <stdlib.h> // abs
|
#include <stdlib.h> // abs
|
||||||
|
#include <string.h> //memcpy
|
||||||
|
|
||||||
|
#include "critical_section_wrapper.h"
|
||||||
|
#include "rtp_receiver_audio.h"
|
||||||
|
#include "rtp_receiver_strategy.h"
|
||||||
|
#include "rtp_receiver_video.h"
|
||||||
|
#include "rtp_rtcp_defines.h"
|
||||||
|
#include "rtp_rtcp_impl.h"
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
@ -36,7 +39,6 @@ RTPReceiver::RTPReceiver(const WebRtc_Word32 id,
|
|||||||
RtpAudioFeedback* incomingMessagesCallback) :
|
RtpAudioFeedback* incomingMessagesCallback) :
|
||||||
Bitrate(clock),
|
Bitrate(clock),
|
||||||
_id(id),
|
_id(id),
|
||||||
_audio(audio),
|
|
||||||
_rtpRtcp(*owner),
|
_rtpRtcp(*owner),
|
||||||
_criticalSectionCbs(CriticalSectionWrapper::CreateCriticalSection()),
|
_criticalSectionCbs(CriticalSectionWrapper::CreateCriticalSection()),
|
||||||
_cbRtpFeedback(NULL),
|
_cbRtpFeedback(NULL),
|
||||||
@ -48,8 +50,6 @@ RTPReceiver::RTPReceiver(const WebRtc_Word32 id,
|
|||||||
_lastReceivedPayloadLength(0),
|
_lastReceivedPayloadLength(0),
|
||||||
_lastReceivedPayloadType(-1),
|
_lastReceivedPayloadType(-1),
|
||||||
_lastReceivedMediaPayloadType(-1),
|
_lastReceivedMediaPayloadType(-1),
|
||||||
_lastReceivedAudioSpecific(),
|
|
||||||
_lastReceivedVideoSpecific(),
|
|
||||||
|
|
||||||
_packetTimeOutMS(0),
|
_packetTimeOutMS(0),
|
||||||
|
|
||||||
@ -95,16 +95,21 @@ RTPReceiver::RTPReceiver(const WebRtc_Word32 id,
|
|||||||
_nackMethod(kNackOff),
|
_nackMethod(kNackOff),
|
||||||
_RTX(false),
|
_RTX(false),
|
||||||
_ssrcRTX(0) {
|
_ssrcRTX(0) {
|
||||||
|
// TODO(phoglund): Remove hacks requiring direct access to the audio receiver
|
||||||
|
// and only instantiate one of these directly into the _rtpMediaReceiver
|
||||||
|
// field. Right now an audio receiver carries around a video handler and
|
||||||
|
// vice versa, which doesn't make sense.
|
||||||
_rtpReceiverAudio = new RTPReceiverAudio(id, this, incomingMessagesCallback);
|
_rtpReceiverAudio = new RTPReceiverAudio(id, this, incomingMessagesCallback);
|
||||||
_rtpReceiverVideo = new RTPReceiverVideo(id, this, owner);
|
_rtpReceiverVideo = new RTPReceiverVideo(id, this, owner);
|
||||||
|
|
||||||
|
if (audio) {
|
||||||
|
_rtpMediaReceiver = _rtpReceiverAudio;
|
||||||
|
} else {
|
||||||
|
_rtpMediaReceiver = _rtpReceiverVideo;
|
||||||
|
}
|
||||||
|
|
||||||
memset(_currentRemoteCSRC, 0, sizeof(_currentRemoteCSRC));
|
memset(_currentRemoteCSRC, 0, sizeof(_currentRemoteCSRC));
|
||||||
memset(_currentRemoteEnergy, 0, sizeof(_currentRemoteEnergy));
|
memset(_currentRemoteEnergy, 0, sizeof(_currentRemoteEnergy));
|
||||||
memset(&_lastReceivedAudioSpecific, 0, sizeof(_lastReceivedAudioSpecific));
|
|
||||||
|
|
||||||
_lastReceivedAudioSpecific.channels = 1;
|
|
||||||
_lastReceivedVideoSpecific.maxRate = 0;
|
|
||||||
_lastReceivedVideoSpecific.videoCodecType = kRtpNoVideo;
|
|
||||||
|
|
||||||
WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__);
|
WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__);
|
||||||
}
|
}
|
||||||
@ -131,13 +136,17 @@ RTPReceiver::~RTPReceiver() {
|
|||||||
RtpVideoCodecTypes
|
RtpVideoCodecTypes
|
||||||
RTPReceiver::VideoCodecType() const
|
RTPReceiver::VideoCodecType() const
|
||||||
{
|
{
|
||||||
return _lastReceivedVideoSpecific.videoCodecType;
|
ModuleRTPUtility::PayloadUnion mediaSpecific;
|
||||||
|
_rtpMediaReceiver->GetLastMediaSpecificPayload(&mediaSpecific);
|
||||||
|
return mediaSpecific.Video.videoCodecType;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebRtc_UWord32
|
WebRtc_UWord32
|
||||||
RTPReceiver::MaxConfiguredBitrate() const
|
RTPReceiver::MaxConfiguredBitrate() const
|
||||||
{
|
{
|
||||||
return _lastReceivedVideoSpecific.maxRate;
|
ModuleRTPUtility::PayloadUnion mediaSpecific;
|
||||||
|
_rtpMediaReceiver->GetLastMediaSpecificPayload(&mediaSpecific);
|
||||||
|
return mediaSpecific.Video.maxRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -201,7 +210,7 @@ void RTPReceiver::PacketTimeout()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RTPReceiver::ProcessDeadOrAlive(const bool RTCPalive, const WebRtc_Word64 now)
|
RTPReceiver::ProcessDeadOrAlive(const bool rtcpAlive, const WebRtc_Word64 now)
|
||||||
{
|
{
|
||||||
if(_cbRtpFeedback == NULL)
|
if(_cbRtpFeedback == NULL)
|
||||||
{
|
{
|
||||||
@ -217,25 +226,10 @@ RTPReceiver::ProcessDeadOrAlive(const bool RTCPalive, const WebRtc_Word64 now)
|
|||||||
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
if(RTCPalive)
|
if(rtcpAlive)
|
||||||
{
|
{
|
||||||
if(_audio)
|
alive = _rtpMediaReceiver->ProcessDeadOrAlive(
|
||||||
{
|
_lastReceivedPayloadLength);
|
||||||
// alive depends on CNG
|
|
||||||
// if last received size < 10 likely CNG
|
|
||||||
if(_lastReceivedPayloadLength < 10) // our CNG is 9 bytes
|
|
||||||
{
|
|
||||||
// potential CNG
|
|
||||||
// receiver need to check kRtpNoRtp against NetEq speechType kOutputPLCtoCNG
|
|
||||||
alive = kRtpNoRtp;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
// dead
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
// dead for video
|
|
||||||
}
|
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
// no RTP packet for 1 sec and no RTCP
|
// no RTP packet for 1 sec and no RTCP
|
||||||
@ -331,19 +325,9 @@ WebRtc_Word32 RTPReceiver::RegisterReceivePayload(
|
|||||||
// if same ignore sending an error
|
// if same ignore sending an error
|
||||||
if (payloadNameLength == nameLength &&
|
if (payloadNameLength == nameLength &&
|
||||||
StringCompare(payload->name, payloadName, payloadNameLength)) {
|
StringCompare(payload->name, payloadName, payloadNameLength)) {
|
||||||
if (_audio &&
|
if (_rtpMediaReceiver->PayloadIsCompatible(*payload, frequency,
|
||||||
payload->audio &&
|
channels, rate)) {
|
||||||
payload->typeSpecific.Audio.frequency == frequency &&
|
_rtpMediaReceiver->UpdatePayloadRate(payload, rate);
|
||||||
payload->typeSpecific.Audio.channels == channels &&
|
|
||||||
(payload->typeSpecific.Audio.rate == rate ||
|
|
||||||
payload->typeSpecific.Audio.rate == 0 || rate == 0)) {
|
|
||||||
payload->typeSpecific.Audio.rate = rate;
|
|
||||||
// Ensure that we update the rate if new or old is zero
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (!_audio && !payload->audio) {
|
|
||||||
// update maxBitrate for video
|
|
||||||
payload->typeSpecific.Video.maxRate = rate;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -352,38 +336,11 @@ WebRtc_Word32 RTPReceiver::RegisterReceivePayload(
|
|||||||
__FUNCTION__, payloadType);
|
__FUNCTION__, payloadType);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (_audio) {
|
|
||||||
// remove existing item, hence search for the name
|
|
||||||
// only for audio, for video we allow a codecs to use multiple pltypes
|
|
||||||
std::map<WebRtc_Word8, Payload*>::iterator audio_it =
|
|
||||||
_payloadTypeMap.begin();
|
|
||||||
while (audio_it != _payloadTypeMap.end()) {
|
|
||||||
Payload* payload = audio_it->second;
|
|
||||||
size_t nameLength = strlen(payload->name);
|
|
||||||
|
|
||||||
if (payloadNameLength == nameLength &&
|
_rtpMediaReceiver->PossiblyRemoveExistingPayloadType(
|
||||||
StringCompare(payload->name, payloadName, payloadNameLength)) {
|
&_payloadTypeMap, payloadName, payloadNameLength, frequency, channels,
|
||||||
// we found the payload name in the list
|
rate);
|
||||||
// if audio check frequency and rate
|
|
||||||
if (payload->audio) {
|
|
||||||
if (payload->typeSpecific.Audio.frequency == frequency &&
|
|
||||||
(payload->typeSpecific.Audio.rate == rate ||
|
|
||||||
payload->typeSpecific.Audio.rate == 0 || rate == 0) &&
|
|
||||||
payload->typeSpecific.Audio.channels == channels) {
|
|
||||||
// remove old setting
|
|
||||||
delete payload;
|
|
||||||
_payloadTypeMap.erase(audio_it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if(StringCompare(payloadName,"red",3)) {
|
|
||||||
delete payload;
|
|
||||||
_payloadTypeMap.erase(audio_it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
audio_it++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Payload* payload = NULL;
|
Payload* payload = NULL;
|
||||||
|
|
||||||
// save the RED payload type
|
// save the RED payload type
|
||||||
@ -395,13 +352,8 @@ WebRtc_Word32 RTPReceiver::RegisterReceivePayload(
|
|||||||
payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
|
payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
|
||||||
strncpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1);
|
strncpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1);
|
||||||
} else {
|
} else {
|
||||||
if (_audio) {
|
payload = _rtpMediaReceiver->CreatePayloadType(
|
||||||
payload = _rtpReceiverAudio->RegisterReceiveAudioPayload(
|
payloadName, payloadType, frequency, channels, rate);
|
||||||
payloadName, payloadType, frequency, channels, rate);
|
|
||||||
} else {
|
|
||||||
payload = _rtpReceiverVideo->RegisterReceiveVideoPayload(
|
|
||||||
payloadName, payloadType, rate);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (payload == NULL) {
|
if (payload == NULL) {
|
||||||
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
|
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
|
||||||
@ -512,7 +464,7 @@ WebRtc_Word32 RTPReceiver::ReceivePayload(
|
|||||||
if(payload->audio) {
|
if(payload->audio) {
|
||||||
*frequency = payload->typeSpecific.Audio.frequency;
|
*frequency = payload->typeSpecific.Audio.frequency;
|
||||||
} else {
|
} else {
|
||||||
*frequency = 90000;
|
*frequency = kDefaultVideoFrequency;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (channels) {
|
if (channels) {
|
||||||
@ -565,7 +517,7 @@ WebRtc_Word32 RTPReceiver::RemotePayload(
|
|||||||
if (payload->audio) {
|
if (payload->audio) {
|
||||||
*frequency = payload->typeSpecific.Audio.frequency;
|
*frequency = payload->typeSpecific.Audio.frequency;
|
||||||
} else {
|
} else {
|
||||||
*frequency = 90000;
|
*frequency = kDefaultVideoFrequency;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (channels) {
|
if (channels) {
|
||||||
@ -721,19 +673,12 @@ WebRtc_Word32 RTPReceiver::IncomingRTPPacket(
|
|||||||
CheckSSRCChanged(rtp_header);
|
CheckSSRCChanged(rtp_header);
|
||||||
|
|
||||||
bool is_red = false;
|
bool is_red = false;
|
||||||
VideoPayload video_specific;
|
ModuleRTPUtility::PayloadUnion specificPayload;
|
||||||
video_specific.maxRate = 0;
|
|
||||||
video_specific.videoCodecType = kRtpNoVideo;
|
|
||||||
|
|
||||||
AudioPayload audio_specific;
|
|
||||||
audio_specific.channels = 0;
|
|
||||||
audio_specific.frequency = 0;
|
|
||||||
|
|
||||||
if (CheckPayloadChanged(rtp_header,
|
if (CheckPayloadChanged(rtp_header,
|
||||||
first_payload_byte,
|
first_payload_byte,
|
||||||
is_red,
|
is_red,
|
||||||
audio_specific,
|
&specificPayload) == -1) {
|
||||||
video_specific) == -1) {
|
|
||||||
if (length - rtp_header->header.headerLength == 0)
|
if (length - rtp_header->header.headerLength == 0)
|
||||||
{
|
{
|
||||||
// ok keepalive packet
|
// ok keepalive packet
|
||||||
@ -749,22 +694,13 @@ WebRtc_Word32 RTPReceiver::IncomingRTPPacket(
|
|||||||
}
|
}
|
||||||
CheckCSRC(rtp_header);
|
CheckCSRC(rtp_header);
|
||||||
|
|
||||||
const WebRtc_UWord8* payload_data =
|
|
||||||
packet + rtp_header->header.headerLength;
|
|
||||||
|
|
||||||
WebRtc_UWord16 payload_data_length =
|
WebRtc_UWord16 payload_data_length =
|
||||||
static_cast<WebRtc_UWord16>(length - rtp_header->header.headerLength);
|
ModuleRTPUtility::GetPayloadDataLength(rtp_header, packet_length);
|
||||||
|
|
||||||
|
WebRtc_Word32 retVal = _rtpMediaReceiver->ParseRtpPacket(
|
||||||
|
rtp_header, specificPayload, is_red, packet,
|
||||||
|
packet_length, _clock.GetTimeInMS());
|
||||||
|
|
||||||
WebRtc_Word32 retVal = 0;
|
|
||||||
if(_audio) {
|
|
||||||
retVal = _rtpReceiverAudio->ParseAudioCodecSpecific(
|
|
||||||
rtp_header, payload_data, payload_data_length, audio_specific, is_red);
|
|
||||||
} else {
|
|
||||||
retVal = _rtpReceiverVideo->ParseVideoCodecSpecific(
|
|
||||||
rtp_header, payload_data, payload_data_length,
|
|
||||||
video_specific.videoCodecType, is_red, packet, packet_length,
|
|
||||||
_clock.GetTimeInMS());
|
|
||||||
}
|
|
||||||
if(retVal < 0) {
|
if(retVal < 0) {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
@ -816,11 +752,7 @@ RTPReceiver::UpdateStatistics(const WebRtcRTPHeader* rtpHeader,
|
|||||||
const WebRtc_UWord16 bytes,
|
const WebRtc_UWord16 bytes,
|
||||||
const bool oldPacket)
|
const bool oldPacket)
|
||||||
{
|
{
|
||||||
WebRtc_UWord32 freq = 90000;
|
WebRtc_UWord32 freq = _rtpMediaReceiver->GetFrequencyHz();
|
||||||
if(_audio)
|
|
||||||
{
|
|
||||||
freq = _rtpReceiverAudio->AudioFrequency();
|
|
||||||
}
|
|
||||||
|
|
||||||
Bitrate::Update(bytes);
|
Bitrate::Update(bytes);
|
||||||
|
|
||||||
@ -918,10 +850,8 @@ bool RTPReceiver::RetransmitOfOldPacket(
|
|||||||
if (InOrderPacket(sequenceNumber)) {
|
if (InOrderPacket(sequenceNumber)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
WebRtc_UWord32 frequencyKHz = 90; // Video frequency.
|
|
||||||
if (_audio) {
|
WebRtc_UWord32 frequencyKHz = _rtpMediaReceiver->GetFrequencyHz() / 1000;
|
||||||
frequencyKHz = _rtpReceiverAudio->AudioFrequency() / 1000;
|
|
||||||
}
|
|
||||||
WebRtc_Word64 timeDiffMS = _clock.GetTimeInMS() - _lastReceiveTime;
|
WebRtc_Word64 timeDiffMS = _clock.GetTimeInMS() - _lastReceiveTime;
|
||||||
// Diff in time stamp since last received in order.
|
// Diff in time stamp since last received in order.
|
||||||
WebRtc_Word32 rtpTimeStampDiffMS = static_cast<WebRtc_Word32>(
|
WebRtc_Word32 rtpTimeStampDiffMS = static_cast<WebRtc_Word32>(
|
||||||
@ -1025,11 +955,8 @@ WebRtc_Word32
|
|||||||
RTPReceiver::EstimatedRemoteTimeStamp(WebRtc_UWord32& timestamp) const
|
RTPReceiver::EstimatedRemoteTimeStamp(WebRtc_UWord32& timestamp) const
|
||||||
{
|
{
|
||||||
CriticalSectionScoped lock(_criticalSectionRTPReceiver);
|
CriticalSectionScoped lock(_criticalSectionRTPReceiver);
|
||||||
WebRtc_UWord32 freq = 90000;
|
WebRtc_UWord32 freq = _rtpMediaReceiver->GetFrequencyHz();
|
||||||
if(_audio)
|
|
||||||
{
|
|
||||||
freq = _rtpReceiverAudio->AudioFrequency();
|
|
||||||
}
|
|
||||||
if(_localTimeLastReceivedTimestamp == 0)
|
if(_localTimeLastReceivedTimestamp == 0)
|
||||||
{
|
{
|
||||||
WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "%s invalid state", __FUNCTION__);
|
WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "%s invalid state", __FUNCTION__);
|
||||||
@ -1079,7 +1006,7 @@ void RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtpHeader) {
|
|||||||
bool newSSRC = false;
|
bool newSSRC = false;
|
||||||
bool reInitializeDecoder = false;
|
bool reInitializeDecoder = false;
|
||||||
char payloadName[RTP_PAYLOAD_NAME_SIZE];
|
char payloadName[RTP_PAYLOAD_NAME_SIZE];
|
||||||
WebRtc_UWord32 frequency = 90000; // default video freq
|
WebRtc_UWord32 frequency = kDefaultVideoFrequency; // default video freq
|
||||||
WebRtc_UWord8 channels = 1;
|
WebRtc_UWord8 channels = 1;
|
||||||
WebRtc_UWord32 rate = 0;
|
WebRtc_UWord32 rate = 0;
|
||||||
|
|
||||||
@ -1119,7 +1046,7 @@ void RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtpHeader) {
|
|||||||
channels = payload->typeSpecific.Audio.channels;
|
channels = payload->typeSpecific.Audio.channels;
|
||||||
rate = payload->typeSpecific.Audio.rate;
|
rate = payload->typeSpecific.Audio.rate;
|
||||||
} else {
|
} else {
|
||||||
frequency = 90000;
|
frequency = kDefaultVideoFrequency;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1149,12 +1076,17 @@ void RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtpHeader) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// no criticalsection when called
|
// no criticalsection when called
|
||||||
|
// TODO(phoglund): Move as much as possible of this code path into the media
|
||||||
|
// specific receivers. Basically this method goes through a lot of trouble to
|
||||||
|
// compute something which is only used by the media specific parts later. If
|
||||||
|
// this code path moves we can get rid of some of the rtp_receiver ->
|
||||||
|
// media_specific interface (such as CheckPayloadChange, possibly get/set
|
||||||
|
// last known payload).
|
||||||
WebRtc_Word32 RTPReceiver::CheckPayloadChanged(
|
WebRtc_Word32 RTPReceiver::CheckPayloadChanged(
|
||||||
const WebRtcRTPHeader* rtpHeader,
|
const WebRtcRTPHeader* rtpHeader,
|
||||||
const WebRtc_Word8 firstPayloadByte,
|
const WebRtc_Word8 firstPayloadByte,
|
||||||
bool& isRED,
|
bool& isRED,
|
||||||
AudioPayload& audioSpecificPayload,
|
ModuleRTPUtility::PayloadUnion* specificPayload) {
|
||||||
VideoPayload& videoSpecificPayload) {
|
|
||||||
bool reInitializeDecoder = false;
|
bool reInitializeDecoder = false;
|
||||||
|
|
||||||
char payloadName[RTP_PAYLOAD_NAME_SIZE];
|
char payloadName[RTP_PAYLOAD_NAME_SIZE];
|
||||||
@ -1178,39 +1110,25 @@ WebRtc_Word32 RTPReceiver::CheckPayloadChanged(
|
|||||||
|
|
||||||
//when we receive RED we need to check the real payload type
|
//when we receive RED we need to check the real payload type
|
||||||
if (payloadType == _lastReceivedPayloadType) {
|
if (payloadType == _lastReceivedPayloadType) {
|
||||||
if(_audio)
|
_rtpMediaReceiver->GetLastMediaSpecificPayload(specificPayload);
|
||||||
{
|
|
||||||
memcpy(&audioSpecificPayload, &_lastReceivedAudioSpecific,
|
|
||||||
sizeof(_lastReceivedAudioSpecific));
|
|
||||||
} else {
|
|
||||||
memcpy(&videoSpecificPayload, &_lastReceivedVideoSpecific,
|
|
||||||
sizeof(_lastReceivedVideoSpecific));
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_audio) {
|
bool shouldResetStatistics = false;
|
||||||
if (_rtpReceiverAudio->TelephoneEventPayloadType(payloadType)) {
|
bool shouldDiscardChanges = false;
|
||||||
// don't do callbacks for DTMF packets
|
|
||||||
isRED = false;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// frequency is updated for CNG
|
|
||||||
bool cngPayloadTypeHasChanged = false;
|
|
||||||
bool isCngPayloadType = _rtpReceiverAudio->CNGPayloadType(
|
|
||||||
payloadType, &audioSpecificPayload.frequency,
|
|
||||||
&cngPayloadTypeHasChanged);
|
|
||||||
|
|
||||||
if (cngPayloadTypeHasChanged) {
|
_rtpMediaReceiver->CheckPayloadChanged(
|
||||||
ResetStatistics();
|
payloadType, specificPayload, &shouldResetStatistics,
|
||||||
}
|
&shouldDiscardChanges);
|
||||||
|
|
||||||
if (isCngPayloadType) {
|
if (shouldResetStatistics) {
|
||||||
// don't do callbacks for DTMF packets
|
ResetStatistics();
|
||||||
isRED = false;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (shouldDiscardChanges) {
|
||||||
|
isRED = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
std::map<WebRtc_Word8, ModuleRTPUtility::Payload*>::iterator it =
|
std::map<WebRtc_Word8, ModuleRTPUtility::Payload*>::iterator it =
|
||||||
_payloadTypeMap.find(payloadType);
|
_payloadTypeMap.find(payloadType);
|
||||||
|
|
||||||
@ -1222,22 +1140,16 @@ WebRtc_Word32 RTPReceiver::CheckPayloadChanged(
|
|||||||
assert(payload);
|
assert(payload);
|
||||||
payloadName[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
|
payloadName[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
|
||||||
strncpy(payloadName, payload->name, RTP_PAYLOAD_NAME_SIZE - 1);
|
strncpy(payloadName, payload->name, RTP_PAYLOAD_NAME_SIZE - 1);
|
||||||
|
|
||||||
_lastReceivedPayloadType = payloadType;
|
_lastReceivedPayloadType = payloadType;
|
||||||
|
|
||||||
reInitializeDecoder = true;
|
reInitializeDecoder = true;
|
||||||
|
|
||||||
if(payload->audio) {
|
_rtpMediaReceiver->SetLastMediaSpecificPayload(payload->typeSpecific);
|
||||||
memcpy(&_lastReceivedAudioSpecific, &(payload->typeSpecific.Audio),
|
_rtpMediaReceiver->GetLastMediaSpecificPayload(specificPayload);
|
||||||
sizeof(_lastReceivedAudioSpecific));
|
|
||||||
memcpy(&audioSpecificPayload, &(payload->typeSpecific.Audio),
|
|
||||||
sizeof(_lastReceivedAudioSpecific));
|
|
||||||
} else {
|
|
||||||
memcpy(&_lastReceivedVideoSpecific, &(payload->typeSpecific.Video),
|
|
||||||
sizeof(_lastReceivedVideoSpecific));
|
|
||||||
memcpy(&videoSpecificPayload, &(payload->typeSpecific.Video),
|
|
||||||
sizeof(_lastReceivedVideoSpecific));
|
|
||||||
|
|
||||||
if (_lastReceivedVideoSpecific.videoCodecType == kRtpFecVideo)
|
if(!payload->audio) {
|
||||||
|
if (VideoCodecType() == kRtpFecVideo)
|
||||||
{
|
{
|
||||||
// Only reset the decoder on media packets.
|
// Only reset the decoder on media packets.
|
||||||
reInitializeDecoder = false;
|
reInitializeDecoder = false;
|
||||||
@ -1254,39 +1166,16 @@ WebRtc_Word32 RTPReceiver::CheckPayloadChanged(
|
|||||||
ResetStatistics();
|
ResetStatistics();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(_audio)
|
_rtpMediaReceiver->GetLastMediaSpecificPayload(specificPayload);
|
||||||
{
|
|
||||||
memcpy(&audioSpecificPayload, &_lastReceivedAudioSpecific,
|
|
||||||
sizeof(_lastReceivedAudioSpecific));
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
memcpy(&videoSpecificPayload, &_lastReceivedVideoSpecific,
|
|
||||||
sizeof(_lastReceivedVideoSpecific));
|
|
||||||
}
|
|
||||||
isRED = false;
|
isRED = false;
|
||||||
}
|
}
|
||||||
} // end critsect
|
} // end critsect
|
||||||
if (reInitializeDecoder) {
|
if (reInitializeDecoder) {
|
||||||
CriticalSectionScoped lock(_criticalSectionCbs);
|
CriticalSectionScoped lock(_criticalSectionCbs);
|
||||||
if (_cbRtpFeedback) {
|
if (_cbRtpFeedback) {
|
||||||
// create new decoder instance
|
if (-1 == _rtpMediaReceiver->InvokeOnInitializeDecoder(
|
||||||
if(_audio) {
|
_cbRtpFeedback, _id, payloadType, payloadName, *specificPayload)) {
|
||||||
if (-1 == _cbRtpFeedback->OnInitializeDecoder(_id, payloadType,
|
return -1; // Wrong payload type.
|
||||||
payloadName, audioSpecificPayload.frequency,
|
|
||||||
audioSpecificPayload.channels, audioSpecificPayload.rate)) {
|
|
||||||
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
|
|
||||||
"Failed to create audio decoder for payload type:%d",
|
|
||||||
payloadType);
|
|
||||||
return -1; // Wrong payload type
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (-1 == _cbRtpFeedback->OnInitializeDecoder(_id, payloadType,
|
|
||||||
payloadName, 90000, 1, 0)) {
|
|
||||||
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
|
|
||||||
"Failed to create video decoder for payload type:%d",
|
|
||||||
payloadType);
|
|
||||||
return -1; // Wrong payload type
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,6 @@
|
|||||||
#include "rtp_header_extension.h"
|
#include "rtp_header_extension.h"
|
||||||
#include "rtp_rtcp.h"
|
#include "rtp_rtcp.h"
|
||||||
#include "rtp_rtcp_defines.h"
|
#include "rtp_rtcp_defines.h"
|
||||||
#include "rtp_receiver_audio.h"
|
|
||||||
#include "rtp_receiver_video.h"
|
|
||||||
#include "rtcp_receiver_help.h"
|
#include "rtcp_receiver_help.h"
|
||||||
#include "Bitrate.h"
|
#include "Bitrate.h"
|
||||||
|
|
||||||
@ -28,6 +26,11 @@ namespace webrtc {
|
|||||||
class RtpRtcpFeedback;
|
class RtpRtcpFeedback;
|
||||||
class ModuleRtpRtcpImpl;
|
class ModuleRtpRtcpImpl;
|
||||||
class Trace;
|
class Trace;
|
||||||
|
class RTPReceiverAudio;
|
||||||
|
class RTPReceiverVideo;
|
||||||
|
class RTPReceiverStrategy;
|
||||||
|
|
||||||
|
const WebRtc_Word32 kDefaultVideoFrequency = 90000;
|
||||||
|
|
||||||
class RTPReceiver : public Bitrate
|
class RTPReceiver : public Bitrate
|
||||||
{
|
{
|
||||||
@ -186,8 +189,7 @@ private:
|
|||||||
WebRtc_Word32 CheckPayloadChanged(const WebRtcRTPHeader* rtpHeader,
|
WebRtc_Word32 CheckPayloadChanged(const WebRtcRTPHeader* rtpHeader,
|
||||||
const WebRtc_Word8 firstPayloadByte,
|
const WebRtc_Word8 firstPayloadByte,
|
||||||
bool& isRED,
|
bool& isRED,
|
||||||
ModuleRTPUtility::AudioPayload& audioSpecific,
|
ModuleRTPUtility::PayloadUnion* payload);
|
||||||
ModuleRTPUtility::VideoPayload& videoSpecific);
|
|
||||||
|
|
||||||
void UpdateNACKBitRate(WebRtc_Word32 bytes, WebRtc_UWord32 now);
|
void UpdateNACKBitRate(WebRtc_Word32 bytes, WebRtc_UWord32 now);
|
||||||
bool ProcessNACKBitRate(WebRtc_UWord32 now);
|
bool ProcessNACKBitRate(WebRtc_UWord32 now);
|
||||||
@ -195,9 +197,9 @@ private:
|
|||||||
private:
|
private:
|
||||||
RTPReceiverAudio* _rtpReceiverAudio;
|
RTPReceiverAudio* _rtpReceiverAudio;
|
||||||
RTPReceiverVideo* _rtpReceiverVideo;
|
RTPReceiverVideo* _rtpReceiverVideo;
|
||||||
|
RTPReceiverStrategy* _rtpMediaReceiver;
|
||||||
|
|
||||||
WebRtc_Word32 _id;
|
WebRtc_Word32 _id;
|
||||||
const bool _audio;
|
|
||||||
ModuleRtpRtcpImpl& _rtpRtcp;
|
ModuleRtpRtcpImpl& _rtpRtcp;
|
||||||
|
|
||||||
CriticalSectionWrapper* _criticalSectionCbs;
|
CriticalSectionWrapper* _criticalSectionCbs;
|
||||||
@ -210,14 +212,11 @@ private:
|
|||||||
WebRtc_Word8 _lastReceivedPayloadType;
|
WebRtc_Word8 _lastReceivedPayloadType;
|
||||||
WebRtc_Word8 _lastReceivedMediaPayloadType;
|
WebRtc_Word8 _lastReceivedMediaPayloadType;
|
||||||
|
|
||||||
ModuleRTPUtility::AudioPayload _lastReceivedAudioSpecific;
|
|
||||||
ModuleRTPUtility::VideoPayload _lastReceivedVideoSpecific;
|
|
||||||
|
|
||||||
WebRtc_UWord32 _packetTimeOutMS;
|
WebRtc_UWord32 _packetTimeOutMS;
|
||||||
WebRtc_Word8 _redPayloadType;
|
WebRtc_Word8 _redPayloadType;
|
||||||
|
|
||||||
std::map<WebRtc_Word8, ModuleRTPUtility::Payload*> _payloadTypeMap;
|
ModuleRTPUtility::PayloadTypeMap _payloadTypeMap;
|
||||||
RtpHeaderExtensionMap _rtpHeaderExtensionMap;
|
RtpHeaderExtensionMap _rtpHeaderExtensionMap;
|
||||||
|
|
||||||
// SSRCs
|
// SSRCs
|
||||||
WebRtc_UWord32 _SSRC;
|
WebRtc_UWord32 _SSRC;
|
||||||
@ -265,6 +264,7 @@ private:
|
|||||||
bool _RTX;
|
bool _RTX;
|
||||||
WebRtc_UWord32 _ssrcRTX;
|
WebRtc_UWord32 _ssrcRTX;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_H_
|
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_H_
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "critical_section_wrapper.h"
|
#include "critical_section_wrapper.h"
|
||||||
#include "rtp_receiver.h"
|
#include "rtp_receiver.h"
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
RTPReceiverAudio::RTPReceiverAudio(const WebRtc_Word32 id,
|
RTPReceiverAudio::RTPReceiverAudio(const WebRtc_Word32 id,
|
||||||
@ -39,6 +40,7 @@ RTPReceiverAudio::RTPReceiverAudio(const WebRtc_Word32 id,
|
|||||||
_lastReceivedG722(false),
|
_lastReceivedG722(false),
|
||||||
_cbAudioFeedback(incomingMessagesCallback)
|
_cbAudioFeedback(incomingMessagesCallback)
|
||||||
{
|
{
|
||||||
|
last_payload_.Audio.channels = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebRtc_UWord32
|
WebRtc_UWord32
|
||||||
@ -182,7 +184,7 @@ RTPReceiverAudio::CNGPayloadType(const WebRtc_Word8 payloadType,
|
|||||||
G7221 frame N/A
|
G7221 frame N/A
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ModuleRTPUtility::Payload* RTPReceiverAudio::RegisterReceiveAudioPayload(
|
ModuleRTPUtility::Payload* RTPReceiverAudio::CreatePayloadType(
|
||||||
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
||||||
const WebRtc_Word8 payloadType,
|
const WebRtc_Word8 payloadType,
|
||||||
const WebRtc_UWord32 frequency,
|
const WebRtc_UWord32 frequency,
|
||||||
@ -248,6 +250,142 @@ void RTPReceiverAudio::SendTelephoneEvents(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WebRtc_Word32 RTPReceiverAudio::ParseRtpPacket(
|
||||||
|
WebRtcRTPHeader* rtpHeader,
|
||||||
|
const ModuleRTPUtility::PayloadUnion& specificPayload,
|
||||||
|
const bool isRed,
|
||||||
|
const WebRtc_UWord8* packet,
|
||||||
|
const WebRtc_UWord16 packetLength,
|
||||||
|
const WebRtc_Word64 timestampMs) {
|
||||||
|
|
||||||
|
const WebRtc_UWord8* payloadData =
|
||||||
|
ModuleRTPUtility::GetPayloadData(rtpHeader, packet);
|
||||||
|
const WebRtc_UWord16 payloadDataLength =
|
||||||
|
ModuleRTPUtility::GetPayloadDataLength(rtpHeader, packetLength);
|
||||||
|
|
||||||
|
return ParseAudioCodecSpecific(rtpHeader, payloadData, payloadDataLength,
|
||||||
|
specificPayload.Audio, isRed);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebRtc_Word32 RTPReceiverAudio::GetFrequencyHz() const {
|
||||||
|
return AudioFrequency();
|
||||||
|
}
|
||||||
|
|
||||||
|
RTPAliveType RTPReceiverAudio::ProcessDeadOrAlive(
|
||||||
|
WebRtc_UWord16 lastPayloadLength) const {
|
||||||
|
|
||||||
|
// Our CNG is 9 bytes; if it's a likely CNG the receiver needs to check
|
||||||
|
// kRtpNoRtp against NetEq speechType kOutputPLCtoCNG.
|
||||||
|
if(lastPayloadLength < 10) // our CNG is 9 bytes
|
||||||
|
{
|
||||||
|
return kRtpNoRtp;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
return kRtpDead;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RTPReceiverAudio::PayloadIsCompatible(
|
||||||
|
const ModuleRTPUtility::Payload& payload,
|
||||||
|
const WebRtc_UWord32 frequency,
|
||||||
|
const WebRtc_UWord8 channels,
|
||||||
|
const WebRtc_UWord32 rate) const {
|
||||||
|
return
|
||||||
|
payload.audio &&
|
||||||
|
payload.typeSpecific.Audio.frequency == frequency &&
|
||||||
|
payload.typeSpecific.Audio.channels == channels &&
|
||||||
|
(payload.typeSpecific.Audio.rate == rate ||
|
||||||
|
payload.typeSpecific.Audio.rate == 0 || rate == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTPReceiverAudio::UpdatePayloadRate(
|
||||||
|
ModuleRTPUtility::Payload* payload,
|
||||||
|
const WebRtc_UWord32 rate) const {
|
||||||
|
payload->typeSpecific.Audio.rate = rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTPReceiverAudio::PossiblyRemoveExistingPayloadType(
|
||||||
|
ModuleRTPUtility::PayloadTypeMap* payloadTypeMap,
|
||||||
|
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
||||||
|
const size_t payloadNameLength,
|
||||||
|
const WebRtc_UWord32 frequency,
|
||||||
|
const WebRtc_UWord8 channels,
|
||||||
|
const WebRtc_UWord32 rate) const {
|
||||||
|
ModuleRTPUtility::PayloadTypeMap::iterator audio_it = payloadTypeMap->begin();
|
||||||
|
while (audio_it != payloadTypeMap->end()) {
|
||||||
|
ModuleRTPUtility::Payload* payload = audio_it->second;
|
||||||
|
size_t nameLength = strlen(payload->name);
|
||||||
|
|
||||||
|
if (payloadNameLength == nameLength &&
|
||||||
|
ModuleRTPUtility::StringCompare(payload->name,
|
||||||
|
payloadName, payloadNameLength)) {
|
||||||
|
// we found the payload name in the list
|
||||||
|
// if audio check frequency and rate
|
||||||
|
if (payload->audio) {
|
||||||
|
if (payload->typeSpecific.Audio.frequency == frequency &&
|
||||||
|
(payload->typeSpecific.Audio.rate == rate ||
|
||||||
|
payload->typeSpecific.Audio.rate == 0 || rate == 0) &&
|
||||||
|
payload->typeSpecific.Audio.channels == channels) {
|
||||||
|
// remove old setting
|
||||||
|
delete payload;
|
||||||
|
payloadTypeMap->erase(audio_it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if(ModuleRTPUtility::StringCompare(payloadName,"red",3)) {
|
||||||
|
delete payload;
|
||||||
|
payloadTypeMap->erase(audio_it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
audio_it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTPReceiverAudio::CheckPayloadChanged(
|
||||||
|
const WebRtc_Word8 payloadType,
|
||||||
|
ModuleRTPUtility::PayloadUnion* specificPayload,
|
||||||
|
bool* shouldResetStatistics,
|
||||||
|
bool* shouldDiscardChanges) {
|
||||||
|
*shouldDiscardChanges = false;
|
||||||
|
*shouldResetStatistics = false;
|
||||||
|
|
||||||
|
if (TelephoneEventPayloadType(payloadType)) {
|
||||||
|
// Don't do callbacks for DTMF packets.
|
||||||
|
*shouldDiscardChanges = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// frequency is updated for CNG
|
||||||
|
bool cngPayloadTypeHasChanged = false;
|
||||||
|
bool isCngPayloadType = CNGPayloadType(
|
||||||
|
payloadType, &specificPayload->Audio.frequency,
|
||||||
|
&cngPayloadTypeHasChanged);
|
||||||
|
|
||||||
|
*shouldResetStatistics = cngPayloadTypeHasChanged;
|
||||||
|
|
||||||
|
if (isCngPayloadType) {
|
||||||
|
// Don't do callbacks for DTMF packets.
|
||||||
|
*shouldDiscardChanges = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WebRtc_Word32 RTPReceiverAudio::InvokeOnInitializeDecoder(
|
||||||
|
RtpFeedback* callback,
|
||||||
|
const WebRtc_Word32 id,
|
||||||
|
const WebRtc_Word8 payloadType,
|
||||||
|
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
||||||
|
const ModuleRTPUtility::PayloadUnion& specificPayload) const {
|
||||||
|
if (-1 == callback->OnInitializeDecoder(
|
||||||
|
id, payloadType, payloadName, specificPayload.Audio.frequency,
|
||||||
|
specificPayload.Audio.channels, specificPayload.Audio.rate)) {
|
||||||
|
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, id,
|
||||||
|
"Failed to create video decoder for payload type:%d",
|
||||||
|
payloadType);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// we are not allowed to have any critsects when calling CallbackOfReceivedPayloadData
|
// we are not allowed to have any critsects when calling CallbackOfReceivedPayloadData
|
||||||
WebRtc_Word32
|
WebRtc_Word32
|
||||||
RTPReceiverAudio::ParseAudioCodecSpecific(WebRtcRTPHeader* rtpHeader,
|
RTPReceiverAudio::ParseAudioCodecSpecific(WebRtcRTPHeader* rtpHeader,
|
||||||
|
@ -13,10 +13,11 @@
|
|||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#include "rtp_receiver.h"
|
||||||
|
#include "rtp_receiver_strategy.h"
|
||||||
#include "rtp_rtcp_defines.h"
|
#include "rtp_rtcp_defines.h"
|
||||||
#include "rtp_utility.h"
|
#include "rtp_utility.h"
|
||||||
#include "scoped_ptr.h"
|
#include "scoped_ptr.h"
|
||||||
|
|
||||||
#include "typedefs.h"
|
#include "typedefs.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -24,20 +25,13 @@ class CriticalSectionWrapper;
|
|||||||
class RTPReceiver;
|
class RTPReceiver;
|
||||||
|
|
||||||
// Handles audio RTP packets. This class is thread-safe.
|
// Handles audio RTP packets. This class is thread-safe.
|
||||||
class RTPReceiverAudio
|
class RTPReceiverAudio : public RTPReceiverStrategy
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RTPReceiverAudio(const WebRtc_Word32 id,
|
RTPReceiverAudio(const WebRtc_Word32 id,
|
||||||
RTPReceiver* parent,
|
RTPReceiver* parent,
|
||||||
RtpAudioFeedback* incomingMessagesCallback);
|
RtpAudioFeedback* incomingMessagesCallback);
|
||||||
|
|
||||||
ModuleRTPUtility::Payload* RegisterReceiveAudioPayload(
|
|
||||||
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
|
||||||
const WebRtc_Word8 payloadType,
|
|
||||||
const WebRtc_UWord32 frequency,
|
|
||||||
const WebRtc_UWord8 channels,
|
|
||||||
const WebRtc_UWord32 rate);
|
|
||||||
|
|
||||||
WebRtc_UWord32 AudioFrequency() const;
|
WebRtc_UWord32 AudioFrequency() const;
|
||||||
|
|
||||||
// Outband TelephoneEvent (DTMF) detection
|
// Outband TelephoneEvent (DTMF) detection
|
||||||
@ -60,11 +54,59 @@ public:
|
|||||||
WebRtc_UWord32* frequency,
|
WebRtc_UWord32* frequency,
|
||||||
bool* cngPayloadTypeHasChanged);
|
bool* cngPayloadTypeHasChanged);
|
||||||
|
|
||||||
WebRtc_Word32 ParseAudioCodecSpecific(WebRtcRTPHeader* rtpHeader,
|
WebRtc_Word32 ParseRtpPacket(
|
||||||
const WebRtc_UWord8* payloadData,
|
WebRtcRTPHeader* rtpHeader,
|
||||||
const WebRtc_UWord16 payloadLength,
|
const ModuleRTPUtility::PayloadUnion& specificPayload,
|
||||||
const ModuleRTPUtility::AudioPayload& audioSpecific,
|
const bool isRed,
|
||||||
const bool isRED);
|
const WebRtc_UWord8* packet,
|
||||||
|
const WebRtc_UWord16 packetLength,
|
||||||
|
const WebRtc_Word64 timestampMs);
|
||||||
|
|
||||||
|
WebRtc_Word32 GetFrequencyHz() const;
|
||||||
|
|
||||||
|
RTPAliveType ProcessDeadOrAlive(WebRtc_UWord16 lastPayloadLength) const;
|
||||||
|
|
||||||
|
bool PayloadIsCompatible(
|
||||||
|
const ModuleRTPUtility::Payload& payload,
|
||||||
|
const WebRtc_UWord32 frequency,
|
||||||
|
const WebRtc_UWord8 channels,
|
||||||
|
const WebRtc_UWord32 rate) const;
|
||||||
|
|
||||||
|
void UpdatePayloadRate(
|
||||||
|
ModuleRTPUtility::Payload* payload,
|
||||||
|
const WebRtc_UWord32 rate) const;
|
||||||
|
|
||||||
|
ModuleRTPUtility::Payload* CreatePayloadType(
|
||||||
|
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
||||||
|
const WebRtc_Word8 payloadType,
|
||||||
|
const WebRtc_UWord32 frequency,
|
||||||
|
const WebRtc_UWord8 channels,
|
||||||
|
const WebRtc_UWord32 rate);
|
||||||
|
|
||||||
|
WebRtc_Word32 InvokeOnInitializeDecoder(
|
||||||
|
RtpFeedback* callback,
|
||||||
|
const WebRtc_Word32 id,
|
||||||
|
const WebRtc_Word8 payloadType,
|
||||||
|
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
||||||
|
const ModuleRTPUtility::PayloadUnion& specificPayload) const;
|
||||||
|
|
||||||
|
// We do not allow codecs to have multiple payload types for audio, so we
|
||||||
|
// need to override the default behavior (which is to do nothing).
|
||||||
|
void PossiblyRemoveExistingPayloadType(
|
||||||
|
ModuleRTPUtility::PayloadTypeMap* payloadTypeMap,
|
||||||
|
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
||||||
|
const size_t payloadNameLength,
|
||||||
|
const WebRtc_UWord32 frequency,
|
||||||
|
const WebRtc_UWord8 channels,
|
||||||
|
const WebRtc_UWord32 rate) const;
|
||||||
|
|
||||||
|
// We need to look out for special payload types here and sometimes reset
|
||||||
|
// statistics. In addition we sometimes need to tweak the frequency.
|
||||||
|
void CheckPayloadChanged(
|
||||||
|
const WebRtc_Word8 payloadType,
|
||||||
|
ModuleRTPUtility::PayloadUnion* specificPayload,
|
||||||
|
bool* shouldResetStatistics,
|
||||||
|
bool* shouldDiscardChanges);
|
||||||
private:
|
private:
|
||||||
void SendTelephoneEvents(
|
void SendTelephoneEvents(
|
||||||
WebRtc_UWord8 numberOfNewEvents,
|
WebRtc_UWord8 numberOfNewEvents,
|
||||||
@ -72,6 +114,13 @@ private:
|
|||||||
WebRtc_UWord8 numberOfRemovedEvents,
|
WebRtc_UWord8 numberOfRemovedEvents,
|
||||||
WebRtc_UWord8 removedEvents[MAX_NUMBER_OF_PARALLEL_TELEPHONE_EVENTS]);
|
WebRtc_UWord8 removedEvents[MAX_NUMBER_OF_PARALLEL_TELEPHONE_EVENTS]);
|
||||||
|
|
||||||
|
WebRtc_Word32 ParseAudioCodecSpecific(
|
||||||
|
WebRtcRTPHeader* rtpHeader,
|
||||||
|
const WebRtc_UWord8* payloadData,
|
||||||
|
const WebRtc_UWord16 payloadLength,
|
||||||
|
const ModuleRTPUtility::AudioPayload& audioSpecific,
|
||||||
|
const bool isRED);
|
||||||
|
|
||||||
WebRtc_Word32 _id;
|
WebRtc_Word32 _id;
|
||||||
RTPReceiver* _parent;
|
RTPReceiver* _parent;
|
||||||
scoped_ptr<CriticalSectionWrapper> _criticalSectionRtpReceiverAudio;
|
scoped_ptr<CriticalSectionWrapper> _criticalSectionRtpReceiverAudio;
|
||||||
|
31
webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.cc
Normal file
31
webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.cc
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
RTPReceiverStrategy::RTPReceiverStrategy() {
|
||||||
|
memset(&last_payload_, 0, sizeof(last_payload_));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTPReceiverStrategy::GetLastMediaSpecificPayload(
|
||||||
|
ModuleRTPUtility::PayloadUnion* payload) const {
|
||||||
|
memcpy(payload, &last_payload_, sizeof(*payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTPReceiverStrategy::SetLastMediaSpecificPayload(
|
||||||
|
const ModuleRTPUtility::PayloadUnion& payload) {
|
||||||
|
memcpy(&last_payload_, &payload, sizeof(last_payload_));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
115
webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h
Normal file
115
webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_STRATEGY_H_
|
||||||
|
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_STRATEGY_H_
|
||||||
|
|
||||||
|
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
|
||||||
|
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
|
||||||
|
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
|
||||||
|
#include "webrtc/typedefs.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
// This strategy deals with media-specific RTP packet processing.
|
||||||
|
// This class is not thread-safe and must be protected by its caller.
|
||||||
|
class RTPReceiverStrategy {
|
||||||
|
public:
|
||||||
|
RTPReceiverStrategy();
|
||||||
|
virtual ~RTPReceiverStrategy() {}
|
||||||
|
|
||||||
|
// Parses the RTP packet. Implementations should keep a reference to the
|
||||||
|
// calling RTPReceiver and call CallbackOfReceivedPayloadData if parsing
|
||||||
|
// succeeds.
|
||||||
|
// TODO(phoglund): This interaction is really ugly: clean up by removing
|
||||||
|
// the need of a back reference to parent, perhaps by returning something
|
||||||
|
// instead of calling back.
|
||||||
|
virtual WebRtc_Word32 ParseRtpPacket(
|
||||||
|
WebRtcRTPHeader* rtp_header,
|
||||||
|
const ModuleRTPUtility::PayloadUnion& specific_payload,
|
||||||
|
const bool is_red,
|
||||||
|
const WebRtc_UWord8* packet,
|
||||||
|
const WebRtc_UWord16 packet_length,
|
||||||
|
const WebRtc_Word64 timestamp_ms) = 0;
|
||||||
|
|
||||||
|
// Retrieves the last known applicable frequency.
|
||||||
|
virtual WebRtc_Word32 GetFrequencyHz() const = 0;
|
||||||
|
|
||||||
|
// Computes the current dead-or-alive state.
|
||||||
|
virtual RTPAliveType ProcessDeadOrAlive(
|
||||||
|
WebRtc_UWord16 last_payload_length) const = 0;
|
||||||
|
|
||||||
|
// Checks if the provided payload can be handled by this strategy and if
|
||||||
|
// it is compatible with the provided parameters.
|
||||||
|
virtual bool PayloadIsCompatible(
|
||||||
|
const ModuleRTPUtility::Payload& payload,
|
||||||
|
const WebRtc_UWord32 frequency,
|
||||||
|
const WebRtc_UWord8 channels,
|
||||||
|
const WebRtc_UWord32 rate) const = 0;
|
||||||
|
|
||||||
|
// Updates the rate in the payload in a media-specific way.
|
||||||
|
virtual void UpdatePayloadRate(
|
||||||
|
ModuleRTPUtility::Payload* payload,
|
||||||
|
const WebRtc_UWord32 rate) const = 0;
|
||||||
|
|
||||||
|
// Creates a media-specific payload instance from the provided parameters.
|
||||||
|
virtual ModuleRTPUtility::Payload* CreatePayloadType(
|
||||||
|
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
|
||||||
|
const WebRtc_Word8 payload_type,
|
||||||
|
const WebRtc_UWord32 frequency,
|
||||||
|
const WebRtc_UWord8 channels,
|
||||||
|
const WebRtc_UWord32 rate) = 0;
|
||||||
|
|
||||||
|
// Invokes the OnInitializeDecoder callback in a media-specific way.
|
||||||
|
virtual WebRtc_Word32 InvokeOnInitializeDecoder(
|
||||||
|
RtpFeedback* callback,
|
||||||
|
const WebRtc_Word32 id,
|
||||||
|
const WebRtc_Word8 payload_type,
|
||||||
|
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
|
||||||
|
const ModuleRTPUtility::PayloadUnion& specific_payload) const = 0;
|
||||||
|
|
||||||
|
// Prunes the payload type map of the specific payload type, if it exists.
|
||||||
|
// TODO(phoglund): Move this responsibility into some payload management
|
||||||
|
// class along with rtp_receiver's payload management.
|
||||||
|
virtual void PossiblyRemoveExistingPayloadType(
|
||||||
|
ModuleRTPUtility::PayloadTypeMap* payload_type_map,
|
||||||
|
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
|
||||||
|
const size_t payload_name_length,
|
||||||
|
const WebRtc_UWord32 frequency,
|
||||||
|
const WebRtc_UWord8 channels,
|
||||||
|
const WebRtc_UWord32 rate) const {
|
||||||
|
// Default: do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if the payload type has changed, and returns whether we should
|
||||||
|
// reset statistics and/or discard this packet.
|
||||||
|
virtual void CheckPayloadChanged(
|
||||||
|
const WebRtc_Word8 payload_type,
|
||||||
|
ModuleRTPUtility::PayloadUnion* specific_payload,
|
||||||
|
bool* should_reset_statistics,
|
||||||
|
bool* should_discard_changes) {
|
||||||
|
// Default: Keep changes and don't reset statistics.
|
||||||
|
*should_discard_changes = false;
|
||||||
|
*should_reset_statistics = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stores / retrieves the last media specific payload for later reference.
|
||||||
|
void GetLastMediaSpecificPayload(
|
||||||
|
ModuleRTPUtility::PayloadUnion* payload) const;
|
||||||
|
void SetLastMediaSpecificPayload(
|
||||||
|
const ModuleRTPUtility::PayloadUnion& payload);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ModuleRTPUtility::PayloadUnion last_payload_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_STRATEGY_H_
|
@ -43,10 +43,12 @@ RTPReceiverVideo::~RTPReceiverVideo() {
|
|||||||
delete _receiveFEC;
|
delete _receiveFEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModuleRTPUtility::Payload* RTPReceiverVideo::RegisterReceiveVideoPayload(
|
ModuleRTPUtility::Payload* RTPReceiverVideo::CreatePayloadType(
|
||||||
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
||||||
const WebRtc_Word8 payloadType,
|
const WebRtc_Word8 payloadType,
|
||||||
const WebRtc_UWord32 maxRate) {
|
const WebRtc_UWord32 frequency,
|
||||||
|
const WebRtc_UWord8 channels,
|
||||||
|
const WebRtc_UWord32 rate) {
|
||||||
RtpVideoCodecTypes videoType = kRtpNoVideo;
|
RtpVideoCodecTypes videoType = kRtpNoVideo;
|
||||||
if (ModuleRTPUtility::StringCompare(payloadName, "VP8", 3)) {
|
if (ModuleRTPUtility::StringCompare(payloadName, "VP8", 3)) {
|
||||||
videoType = kRtpVp8Video;
|
videoType = kRtpVp8Video;
|
||||||
@ -67,11 +69,68 @@ ModuleRTPUtility::Payload* RTPReceiverVideo::RegisterReceiveVideoPayload(
|
|||||||
payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
|
payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
|
||||||
strncpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1);
|
strncpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1);
|
||||||
payload->typeSpecific.Video.videoCodecType = videoType;
|
payload->typeSpecific.Video.videoCodecType = videoType;
|
||||||
payload->typeSpecific.Video.maxRate = maxRate;
|
payload->typeSpecific.Video.maxRate = rate;
|
||||||
payload->audio = false;
|
payload->audio = false;
|
||||||
return payload;
|
return payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WebRtc_Word32 RTPReceiverVideo::ParseRtpPacket(
|
||||||
|
WebRtcRTPHeader* rtpHeader,
|
||||||
|
const ModuleRTPUtility::PayloadUnion& specificPayload,
|
||||||
|
const bool isRed,
|
||||||
|
const WebRtc_UWord8* packet,
|
||||||
|
const WebRtc_UWord16 packetLength,
|
||||||
|
const WebRtc_Word64 timestampMs) {
|
||||||
|
const WebRtc_UWord8* payloadData =
|
||||||
|
ModuleRTPUtility::GetPayloadData(rtpHeader, packet);
|
||||||
|
const WebRtc_UWord16 payloadDataLength =
|
||||||
|
ModuleRTPUtility::GetPayloadDataLength(rtpHeader, packetLength);
|
||||||
|
return ParseVideoCodecSpecific(
|
||||||
|
rtpHeader, payloadData, payloadDataLength,
|
||||||
|
specificPayload.Video.videoCodecType, isRed, packet, packetLength,
|
||||||
|
timestampMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebRtc_Word32 RTPReceiverVideo::GetFrequencyHz() const {
|
||||||
|
return kDefaultVideoFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
RTPAliveType RTPReceiverVideo::ProcessDeadOrAlive(
|
||||||
|
WebRtc_UWord16 lastPayloadLength) const {
|
||||||
|
return kRtpDead;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RTPReceiverVideo::PayloadIsCompatible(
|
||||||
|
const ModuleRTPUtility::Payload& payload,
|
||||||
|
const WebRtc_UWord32 frequency,
|
||||||
|
const WebRtc_UWord8 channels,
|
||||||
|
const WebRtc_UWord32 rate) const {
|
||||||
|
return !payload.audio;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTPReceiverVideo::UpdatePayloadRate(
|
||||||
|
ModuleRTPUtility::Payload* payload,
|
||||||
|
const WebRtc_UWord32 rate) const {
|
||||||
|
payload->typeSpecific.Video.maxRate = rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
WebRtc_Word32 RTPReceiverVideo::InvokeOnInitializeDecoder(
|
||||||
|
RtpFeedback* callback,
|
||||||
|
const WebRtc_Word32 id,
|
||||||
|
const WebRtc_Word8 payloadType,
|
||||||
|
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
||||||
|
const ModuleRTPUtility::PayloadUnion& specificPayload) const {
|
||||||
|
// For video we just go with default values.
|
||||||
|
if (-1 == callback->OnInitializeDecoder(
|
||||||
|
id, payloadType, payloadName, kDefaultVideoFrequency, 1, 0)) {
|
||||||
|
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, id,
|
||||||
|
"Failed to create video decoder for payload type:%d",
|
||||||
|
payloadType);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// we have no critext when calling this
|
// we have no critext when calling this
|
||||||
// we are not allowed to have any critsects when calling
|
// we are not allowed to have any critsects when calling
|
||||||
// CallbackOfReceivedPayloadData
|
// CallbackOfReceivedPayloadData
|
||||||
|
@ -11,21 +11,20 @@
|
|||||||
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_VIDEO_H_
|
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_VIDEO_H_
|
||||||
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_VIDEO_H_
|
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_VIDEO_H_
|
||||||
|
|
||||||
|
#include "Bitrate.h"
|
||||||
|
#include "rtp_receiver.h"
|
||||||
|
#include "rtp_receiver_strategy.h"
|
||||||
#include "rtp_rtcp_defines.h"
|
#include "rtp_rtcp_defines.h"
|
||||||
#include "rtp_utility.h"
|
#include "rtp_utility.h"
|
||||||
|
|
||||||
#include "typedefs.h"
|
|
||||||
|
|
||||||
#include "Bitrate.h"
|
|
||||||
#include "scoped_ptr.h"
|
#include "scoped_ptr.h"
|
||||||
|
#include "typedefs.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
class CriticalSectionWrapper;
|
class CriticalSectionWrapper;
|
||||||
class ModuleRtpRtcpImpl;
|
class ModuleRtpRtcpImpl;
|
||||||
class ReceiverFEC;
|
class ReceiverFEC;
|
||||||
class RTPReceiver;
|
|
||||||
|
|
||||||
class RTPReceiverVideo {
|
class RTPReceiverVideo : public RTPReceiverStrategy {
|
||||||
public:
|
public:
|
||||||
RTPReceiverVideo(const WebRtc_Word32 id,
|
RTPReceiverVideo(const WebRtc_Word32 id,
|
||||||
RTPReceiver* parent,
|
RTPReceiver* parent,
|
||||||
@ -33,20 +32,41 @@ class RTPReceiverVideo {
|
|||||||
|
|
||||||
virtual ~RTPReceiverVideo();
|
virtual ~RTPReceiverVideo();
|
||||||
|
|
||||||
ModuleRTPUtility::Payload* RegisterReceiveVideoPayload(
|
WebRtc_Word32 ParseRtpPacket(
|
||||||
|
WebRtcRTPHeader* rtp_header,
|
||||||
|
const ModuleRTPUtility::PayloadUnion& specificPayload,
|
||||||
|
const bool is_red,
|
||||||
|
const WebRtc_UWord8* packet,
|
||||||
|
const WebRtc_UWord16 packet_length,
|
||||||
|
const WebRtc_Word64 timestamp);
|
||||||
|
|
||||||
|
WebRtc_Word32 GetFrequencyHz() const;
|
||||||
|
|
||||||
|
RTPAliveType ProcessDeadOrAlive(WebRtc_UWord16 lastPayloadLength) const;
|
||||||
|
|
||||||
|
bool PayloadIsCompatible(
|
||||||
|
const ModuleRTPUtility::Payload& payload,
|
||||||
|
const WebRtc_UWord32 frequency,
|
||||||
|
const WebRtc_UWord8 channels,
|
||||||
|
const WebRtc_UWord32 rate) const;
|
||||||
|
|
||||||
|
void UpdatePayloadRate(
|
||||||
|
ModuleRTPUtility::Payload* payload,
|
||||||
|
const WebRtc_UWord32 rate) const;
|
||||||
|
|
||||||
|
ModuleRTPUtility::Payload* CreatePayloadType(
|
||||||
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
||||||
const WebRtc_Word8 payloadType,
|
const WebRtc_Word8 payloadType,
|
||||||
const WebRtc_UWord32 maxRate);
|
const WebRtc_UWord32 frequency,
|
||||||
|
const WebRtc_UWord8 channels,
|
||||||
|
const WebRtc_UWord32 rate);
|
||||||
|
|
||||||
WebRtc_Word32 ParseVideoCodecSpecific(
|
WebRtc_Word32 InvokeOnInitializeDecoder(
|
||||||
WebRtcRTPHeader* rtpHeader,
|
RtpFeedback* callback,
|
||||||
const WebRtc_UWord8* payloadData,
|
const WebRtc_Word32 id,
|
||||||
const WebRtc_UWord16 payloadDataLength,
|
const WebRtc_Word8 payloadType,
|
||||||
const RtpVideoCodecTypes videoType,
|
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
||||||
const bool isRED,
|
const ModuleRTPUtility::PayloadUnion& specificPayload) const;
|
||||||
const WebRtc_UWord8* incomingRtpPacket,
|
|
||||||
const WebRtc_UWord16 incomingRtpPacketSize,
|
|
||||||
const WebRtc_Word64 nowMS);
|
|
||||||
|
|
||||||
virtual WebRtc_Word32 ReceiveRecoveredPacketCallback(
|
virtual WebRtc_Word32 ReceiveRecoveredPacketCallback(
|
||||||
WebRtcRTPHeader* rtpHeader,
|
WebRtcRTPHeader* rtpHeader,
|
||||||
@ -77,6 +97,16 @@ class RTPReceiverVideo {
|
|||||||
WebRtc_UWord8* dataBuffer) const;
|
WebRtc_UWord8* dataBuffer) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
WebRtc_Word32 ParseVideoCodecSpecific(
|
||||||
|
WebRtcRTPHeader* rtpHeader,
|
||||||
|
const WebRtc_UWord8* payloadData,
|
||||||
|
const WebRtc_UWord16 payloadDataLength,
|
||||||
|
const RtpVideoCodecTypes videoType,
|
||||||
|
const bool isRED,
|
||||||
|
const WebRtc_UWord8* incomingRtpPacket,
|
||||||
|
const WebRtc_UWord16 incomingRtpPacketSize,
|
||||||
|
const WebRtc_Word64 nowMS);
|
||||||
|
|
||||||
WebRtc_Word32 _id;
|
WebRtc_Word32 _id;
|
||||||
RTPReceiver* _parent;
|
RTPReceiver* _parent;
|
||||||
|
|
||||||
|
@ -73,6 +73,8 @@
|
|||||||
'producer_fec.h',
|
'producer_fec.h',
|
||||||
'rtp_packet_history.cc',
|
'rtp_packet_history.cc',
|
||||||
'rtp_packet_history.h',
|
'rtp_packet_history.h',
|
||||||
|
'rtp_receiver_strategy.cc',
|
||||||
|
'rtp_receiver_stragegy.h',
|
||||||
'rtp_receiver_video.cc',
|
'rtp_receiver_video.cc',
|
||||||
'rtp_receiver_video.h',
|
'rtp_receiver_video.h',
|
||||||
'rtp_sender_video.cc',
|
'rtp_sender_video.cc',
|
||||||
|
@ -8,9 +8,7 @@
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common_types.h"
|
|
||||||
#include "rtp_rtcp_impl.h"
|
#include "rtp_rtcp_impl.h"
|
||||||
#include "trace.h"
|
|
||||||
|
|
||||||
#ifdef MATLAB
|
#ifdef MATLAB
|
||||||
#include "../test/BWEStandAlone/MatlabPlot.h"
|
#include "../test/BWEStandAlone/MatlabPlot.h"
|
||||||
@ -20,6 +18,11 @@ extern MatlabEngine eng; // global variable defined elsewhere
|
|||||||
#include <string.h> //memcpy
|
#include <string.h> //memcpy
|
||||||
#include <cassert> //assert
|
#include <cassert> //assert
|
||||||
|
|
||||||
|
#include "common_types.h"
|
||||||
|
#include "rtp_receiver_audio.h"
|
||||||
|
#include "rtp_receiver_video.h"
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
// local for this file
|
// local for this file
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -313,6 +313,18 @@ bool OldTimestamp(uint32_t newTimestamp,
|
|||||||
* Misc utility routines
|
* Misc utility routines
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const WebRtc_UWord8* GetPayloadData(const WebRtcRTPHeader* rtp_header,
|
||||||
|
const WebRtc_UWord8* packet) {
|
||||||
|
return packet + rtp_header->header.headerLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
WebRtc_UWord16 GetPayloadDataLength(const WebRtcRTPHeader* rtp_header,
|
||||||
|
const WebRtc_UWord16 packet_length) {
|
||||||
|
WebRtc_UWord16 length = packet_length - rtp_header->header.paddingLength -
|
||||||
|
rtp_header->header.headerLength;
|
||||||
|
return static_cast<WebRtc_UWord16>(length);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
bool StringCompare(const char* str1, const char* str2,
|
bool StringCompare(const char* str1, const char* str2,
|
||||||
const WebRtc_UWord32 length) {
|
const WebRtc_UWord32 length) {
|
||||||
|
@ -59,6 +59,8 @@ namespace ModuleRTPUtility
|
|||||||
PayloadUnion typeSpecific;
|
PayloadUnion typeSpecific;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::map<WebRtc_Word8, Payload*> PayloadTypeMap;
|
||||||
|
|
||||||
// Return a clock that reads the time as reported by the operating
|
// Return a clock that reads the time as reported by the operating
|
||||||
// system. The returned instances are guaranteed to read the same
|
// system. The returned instances are guaranteed to read the same
|
||||||
// times; in particular, they return relative times relative to
|
// times; in particular, they return relative times relative to
|
||||||
@ -85,6 +87,14 @@ namespace ModuleRTPUtility
|
|||||||
|
|
||||||
WebRtc_UWord32 pow2(WebRtc_UWord8 exp);
|
WebRtc_UWord32 pow2(WebRtc_UWord8 exp);
|
||||||
|
|
||||||
|
// Returns a pointer to the payload data given a packet.
|
||||||
|
const WebRtc_UWord8* GetPayloadData(const WebRtcRTPHeader* rtp_header,
|
||||||
|
const WebRtc_UWord8* packet);
|
||||||
|
|
||||||
|
// Returns payload length given a packet.
|
||||||
|
WebRtc_UWord16 GetPayloadDataLength(const WebRtcRTPHeader* rtp_header,
|
||||||
|
const WebRtc_UWord16 packet_length);
|
||||||
|
|
||||||
// Returns true if |newTimestamp| is older than |existingTimestamp|.
|
// Returns true if |newTimestamp| is older than |existingTimestamp|.
|
||||||
// |wrapped| will be set to true if there has been a wraparound between the
|
// |wrapped| will be set to true if there has been a wraparound between the
|
||||||
// two timestamps.
|
// two timestamps.
|
||||||
@ -170,7 +180,7 @@ namespace ModuleRTPUtility
|
|||||||
int frameWidth;
|
int frameWidth;
|
||||||
int frameHeight;
|
int frameHeight;
|
||||||
|
|
||||||
const WebRtc_UWord8* data;
|
const WebRtc_UWord8* data;
|
||||||
WebRtc_UWord16 dataLength;
|
WebRtc_UWord16 dataLength;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user