Adding a send side API for streaming
Review URL: https://webrtc-codereview.appspot.com/1070009 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3457 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
becf9c897c
commit
dbe97d2550
webrtc/video_engine
@ -22,7 +22,7 @@
|
|||||||
#ifndef WEBRTC_VIDEO_ENGINE_INCLUDE_VIE_RTP_RTCP_H_
|
#ifndef WEBRTC_VIDEO_ENGINE_INCLUDE_VIE_RTP_RTCP_H_
|
||||||
#define WEBRTC_VIDEO_ENGINE_INCLUDE_VIE_RTP_RTCP_H_
|
#define WEBRTC_VIDEO_ENGINE_INCLUDE_VIE_RTP_RTCP_H_
|
||||||
|
|
||||||
#include "common_types.h"
|
#include "webrtc/common_types.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
@ -199,6 +199,12 @@ class WEBRTC_DLLEXPORT ViERTP_RTCP {
|
|||||||
const unsigned char payload_typeRED,
|
const unsigned char payload_typeRED,
|
||||||
const unsigned char payload_typeFEC) = 0;
|
const unsigned char payload_typeFEC) = 0;
|
||||||
|
|
||||||
|
// Enables send side support for delayed video streaming (actual delay will
|
||||||
|
// be exhibited on the receiver side).
|
||||||
|
// Target delay should be set to zero for real-time mode.
|
||||||
|
virtual int EnableSenderStreamingMode(int video_channel,
|
||||||
|
int target_delay_ms) = 0;
|
||||||
|
|
||||||
// This function enables RTCP key frame requests.
|
// This function enables RTCP key frame requests.
|
||||||
virtual int SetKeyFrameRequestMethod(
|
virtual int SetKeyFrameRequestMethod(
|
||||||
const int video_channel, const ViEKeyFrameRequestMethod method) = 0;
|
const int video_channel, const ViEKeyFrameRequestMethod method) = 0;
|
||||||
|
@ -687,6 +687,21 @@ void ViEAutoTest::ViERtpRtcpAPITest()
|
|||||||
EXPECT_EQ(0, ViE.rtp_rtcp->SetTransmissionSmoothingStatus(
|
EXPECT_EQ(0, ViE.rtp_rtcp->SetTransmissionSmoothingStatus(
|
||||||
tbChannel.videoChannel, false));
|
tbChannel.videoChannel, false));
|
||||||
|
|
||||||
|
// Streaming Mode.
|
||||||
|
EXPECT_EQ(-1, ViE.rtp_rtcp->EnableSenderStreamingMode(
|
||||||
|
invalid_channel_id, 0));
|
||||||
|
int invalid_delay = -1;
|
||||||
|
EXPECT_EQ(-1, ViE.rtp_rtcp->EnableSenderStreamingMode(
|
||||||
|
tbChannel.videoChannel, invalid_delay));
|
||||||
|
invalid_delay = 15000;
|
||||||
|
EXPECT_EQ(-1, ViE.rtp_rtcp->EnableSenderStreamingMode(
|
||||||
|
tbChannel.videoChannel, invalid_delay));
|
||||||
|
EXPECT_EQ(0, ViE.rtp_rtcp->EnableSenderStreamingMode(
|
||||||
|
tbChannel.videoChannel, 5000));
|
||||||
|
// Real-time mode.
|
||||||
|
EXPECT_EQ(0, ViE.rtp_rtcp->EnableSenderStreamingMode(
|
||||||
|
tbChannel.videoChannel, 0));
|
||||||
|
|
||||||
//***************************************************************
|
//***************************************************************
|
||||||
// Testing finished. Tear down Video Engine
|
// Testing finished. Tear down Video Engine
|
||||||
//***************************************************************
|
//***************************************************************
|
||||||
|
@ -35,6 +35,7 @@ namespace webrtc {
|
|||||||
|
|
||||||
const int kMaxDecodeWaitTimeMs = 50;
|
const int kMaxDecodeWaitTimeMs = 50;
|
||||||
const int kInvalidRtpExtensionId = 0;
|
const int kInvalidRtpExtensionId = 0;
|
||||||
|
static const int kMaxTargetDelayMs = 10000;
|
||||||
|
|
||||||
// Helper class receiving statistics callbacks.
|
// Helper class receiving statistics callbacks.
|
||||||
class ChannelStatsObserver : public StatsObserver {
|
class ChannelStatsObserver : public StatsObserver {
|
||||||
@ -102,7 +103,8 @@ ViEChannel::ViEChannel(WebRtc_Word32 channel_id,
|
|||||||
color_enhancement_(false),
|
color_enhancement_(false),
|
||||||
file_recorder_(channel_id),
|
file_recorder_(channel_id),
|
||||||
mtu_(0),
|
mtu_(0),
|
||||||
sender_(sender) {
|
sender_(sender),
|
||||||
|
nack_history_size_sender_(kSendSidePacketHistorySize) {
|
||||||
WEBRTC_TRACE(kTraceMemory, kTraceVideo, ViEId(engine_id, channel_id),
|
WEBRTC_TRACE(kTraceMemory, kTraceVideo, ViEId(engine_id, channel_id),
|
||||||
"ViEChannel::ViEChannel(channel_id: %d, engine_id: %d)",
|
"ViEChannel::ViEChannel(channel_id: %d, engine_id: %d)",
|
||||||
channel_id, engine_id);
|
channel_id, engine_id);
|
||||||
@ -151,7 +153,7 @@ WebRtc_Word32 ViEChannel::Init() {
|
|||||||
"%s: RTP::SetRTCPStatus failure", __FUNCTION__);
|
"%s: RTP::SetRTCPStatus failure", __FUNCTION__);
|
||||||
}
|
}
|
||||||
if (paced_sender_) {
|
if (paced_sender_) {
|
||||||
if (rtp_rtcp_->SetStorePacketsStatus(true, kSendSidePacketHistorySize) !=
|
if (rtp_rtcp_->SetStorePacketsStatus(true, nack_history_size_sender_) !=
|
||||||
0) {
|
0) {
|
||||||
WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, channel_id_),
|
WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||||
"%s:SetStorePacketsStatus failure", __FUNCTION__);
|
"%s:SetStorePacketsStatus failure", __FUNCTION__);
|
||||||
@ -295,10 +297,10 @@ WebRtc_Word32 ViEChannel::SetSendCodec(const VideoCodec& video_codec,
|
|||||||
"%s: RTP::SetRTCPStatus failure", __FUNCTION__);
|
"%s: RTP::SetRTCPStatus failure", __FUNCTION__);
|
||||||
}
|
}
|
||||||
if (nack_method != kNackOff) {
|
if (nack_method != kNackOff) {
|
||||||
rtp_rtcp->SetStorePacketsStatus(true, kSendSidePacketHistorySize);
|
rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
|
||||||
rtp_rtcp->SetNACKStatus(nack_method, kMaxPacketAgeToNack);
|
rtp_rtcp->SetNACKStatus(nack_method, kMaxPacketAgeToNack);
|
||||||
} else if (paced_sender_) {
|
} else if (paced_sender_) {
|
||||||
rtp_rtcp->SetStorePacketsStatus(true, kSendSidePacketHistorySize);
|
rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
|
||||||
}
|
}
|
||||||
if (fec_enabled) {
|
if (fec_enabled) {
|
||||||
rtp_rtcp->SetGenericFECStatus(fec_enabled, payload_type_red,
|
rtp_rtcp->SetGenericFECStatus(fec_enabled, payload_type_red,
|
||||||
@ -628,7 +630,7 @@ WebRtc_Word32 ViEChannel::ProcessNACKRequest(const bool enable) {
|
|||||||
}
|
}
|
||||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
|
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||||
"%s: Using NACK method %d", __FUNCTION__, nackMethod);
|
"%s: Using NACK method %d", __FUNCTION__, nackMethod);
|
||||||
rtp_rtcp_->SetStorePacketsStatus(true, kSendSidePacketHistorySize);
|
rtp_rtcp_->SetStorePacketsStatus(true, nack_history_size_sender_);
|
||||||
|
|
||||||
vcm_.RegisterPacketRequestCallback(this);
|
vcm_.RegisterPacketRequestCallback(this);
|
||||||
|
|
||||||
@ -639,7 +641,7 @@ WebRtc_Word32 ViEChannel::ProcessNACKRequest(const bool enable) {
|
|||||||
it++) {
|
it++) {
|
||||||
RtpRtcp* rtp_rtcp = *it;
|
RtpRtcp* rtp_rtcp = *it;
|
||||||
rtp_rtcp->SetNACKStatus(nackMethod, kMaxPacketAgeToNack);
|
rtp_rtcp->SetNACKStatus(nackMethod, kMaxPacketAgeToNack);
|
||||||
rtp_rtcp->SetStorePacketsStatus(true, kSendSidePacketHistorySize);
|
rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CriticalSectionScoped cs(rtp_rtcp_cs_.get());
|
CriticalSectionScoped cs(rtp_rtcp_cs_.get());
|
||||||
@ -721,6 +723,45 @@ WebRtc_Word32 ViEChannel::SetHybridNACKFECStatus(
|
|||||||
return ProcessFECRequest(enable, payload_typeRED, payload_typeFEC);
|
return ProcessFECRequest(enable, payload_typeRED, payload_typeFEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ViEChannel::EnableSenderStreamingMode(int target_delay_ms) {
|
||||||
|
if ((target_delay_ms < 0) || (target_delay_ms > kMaxTargetDelayMs)) {
|
||||||
|
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||||
|
"%s: Target streaming delay out of bounds: %d", __FUNCTION__,
|
||||||
|
target_delay_ms);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (target_delay_ms == 0) {
|
||||||
|
// Real-time mode.
|
||||||
|
nack_history_size_sender_ = kSendSidePacketHistorySize;
|
||||||
|
vcm_.EnableFrameDropper(true);
|
||||||
|
} else {
|
||||||
|
// The max size of the nack list should be large enough to accommodate the
|
||||||
|
// the number of packets(frames) resulting from the increased delay.
|
||||||
|
// Roughly estimating for ~15 packets per frame @ 30fps.
|
||||||
|
nack_history_size_sender_ = target_delay_ms * 15 * 30 / 1000;
|
||||||
|
// Don't allow a number lower than the default value.
|
||||||
|
if (nack_history_size_sender_ < kSendSidePacketHistorySize) {
|
||||||
|
nack_history_size_sender_ = kSendSidePacketHistorySize;
|
||||||
|
}
|
||||||
|
// Disable external VCM frame-dropper. In streaming mode, we are more
|
||||||
|
// flexible with rate control constraints.
|
||||||
|
vcm_.EnableFrameDropper(false);
|
||||||
|
}
|
||||||
|
// Setting nack_history_size_.
|
||||||
|
// First disabling (forcing free) and then resetting to desired value.
|
||||||
|
if (rtp_rtcp_->SetStorePacketsStatus(false, 0) != 0) {
|
||||||
|
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||||
|
"%s:SetStorePacketsStatus failure", __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (rtp_rtcp_->SetStorePacketsStatus(true, nack_history_size_sender_) != 0) {
|
||||||
|
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||||
|
"%s:SetStorePacketsStatus failure", __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
WebRtc_Word32 ViEChannel::SetKeyFrameRequestMethod(
|
WebRtc_Word32 ViEChannel::SetKeyFrameRequestMethod(
|
||||||
const KeyFrameRequestMethod method) {
|
const KeyFrameRequestMethod method) {
|
||||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
|
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||||
|
@ -116,6 +116,7 @@ class ViEChannel
|
|||||||
WebRtc_Word32 SetHybridNACKFECStatus(const bool enable,
|
WebRtc_Word32 SetHybridNACKFECStatus(const bool enable,
|
||||||
const unsigned char payload_typeRED,
|
const unsigned char payload_typeRED,
|
||||||
const unsigned char payload_typeFEC);
|
const unsigned char payload_typeFEC);
|
||||||
|
int EnableSenderStreamingMode(int target_delay_ms);
|
||||||
WebRtc_Word32 SetKeyFrameRequestMethod(const KeyFrameRequestMethod method);
|
WebRtc_Word32 SetKeyFrameRequestMethod(const KeyFrameRequestMethod method);
|
||||||
bool EnableRemb(bool enable);
|
bool EnableRemb(bool enable);
|
||||||
int SetSendTimestampOffsetStatus(bool enable, int id);
|
int SetSendTimestampOffsetStatus(bool enable, int id);
|
||||||
@ -422,6 +423,8 @@ class ViEChannel
|
|||||||
// User set MTU, -1 if not set.
|
// User set MTU, -1 if not set.
|
||||||
uint16_t mtu_;
|
uint16_t mtu_;
|
||||||
const bool sender_;
|
const bool sender_;
|
||||||
|
|
||||||
|
int nack_history_size_sender_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -553,6 +553,33 @@ int ViERTP_RTCPImpl::SetHybridNACKFECStatus(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ViERTP_RTCPImpl::EnableSenderStreamingMode(int video_channel,
|
||||||
|
int target_delay_ms) {
|
||||||
|
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
|
||||||
|
ViEId(shared_data_->instance_id(), video_channel),
|
||||||
|
"%s(channel: %d, target_delay: %d)",
|
||||||
|
__FUNCTION__, video_channel, target_delay_ms);
|
||||||
|
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
|
||||||
|
ViEChannel* vie_channel = cs.Channel(video_channel);
|
||||||
|
if (!vie_channel) {
|
||||||
|
WEBRTC_TRACE(kTraceError, kTraceVideo,
|
||||||
|
ViEId(shared_data_->instance_id(), video_channel),
|
||||||
|
"%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
|
||||||
|
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the channel's streaming mode settings.
|
||||||
|
if (vie_channel->EnableSenderStreamingMode(target_delay_ms) != 0) {
|
||||||
|
WEBRTC_TRACE(kTraceError, kTraceVideo,
|
||||||
|
ViEId(shared_data_->instance_id(), video_channel),
|
||||||
|
"%s: failed for channel %d", __FUNCTION__, video_channel);
|
||||||
|
shared_data_->SetLastError(kViERtpRtcpUnknownError);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int ViERTP_RTCPImpl::SetKeyFrameRequestMethod(
|
int ViERTP_RTCPImpl::SetKeyFrameRequestMethod(
|
||||||
const int video_channel,
|
const int video_channel,
|
||||||
const ViEKeyFrameRequestMethod method) {
|
const ViEKeyFrameRequestMethod method) {
|
||||||
|
@ -64,6 +64,8 @@ class ViERTP_RTCPImpl
|
|||||||
virtual int SetHybridNACKFECStatus(const int video_channel, const bool enable,
|
virtual int SetHybridNACKFECStatus(const int video_channel, const bool enable,
|
||||||
const unsigned char payload_typeRED,
|
const unsigned char payload_typeRED,
|
||||||
const unsigned char payload_typeFEC);
|
const unsigned char payload_typeFEC);
|
||||||
|
virtual int EnableSenderStreamingMode(int video_channel,
|
||||||
|
int target_delay_ms);
|
||||||
virtual int SetKeyFrameRequestMethod(const int video_channel,
|
virtual int SetKeyFrameRequestMethod(const int video_channel,
|
||||||
const ViEKeyFrameRequestMethod method);
|
const ViEKeyFrameRequestMethod method);
|
||||||
virtual int SetTMMBRStatus(const int video_channel, const bool enable);
|
virtual int SetTMMBRStatus(const int video_channel, const bool enable);
|
||||||
|
Loading…
Reference in New Issue
Block a user