Wire up target_media_bitrate in VideoSendStream.

Also wires up target_enc_bitrate in WebRtcVideoEngine2.

BUG=1667,1788
R=mflodman@webrtc.org, stefan@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/42479004

Cr-Commit-Position: refs/heads/master@{#8515}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8515 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
pbos@webrtc.org 2015-02-26 13:15:22 +00:00
parent 9dd0ebc379
commit 891d48393e
24 changed files with 172 additions and 54 deletions

View File

@ -1825,6 +1825,7 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::FillBandwidthEstimationInfo(
bwe_info->transmit_bitrate += it->second.total_bitrate_bps; bwe_info->transmit_bitrate += it->second.total_bitrate_bps;
bwe_info->retransmit_bitrate += it->second.retransmit_bitrate_bps; bwe_info->retransmit_bitrate += it->second.retransmit_bitrate_bps;
} }
bwe_info->target_enc_bitrate += stats.target_media_bitrate_bps;
bwe_info->actual_enc_bitrate += stats.media_bitrate_bps; bwe_info->actual_enc_bitrate += stats.media_bitrate_bps;
} }

View File

@ -2224,6 +2224,7 @@ TEST_F(WebRtcVideoChannel2Test, TranslatesCallStatsCorrectly) {
TEST_F(WebRtcVideoChannel2Test, TranslatesSenderBitrateStatsCorrectly) { TEST_F(WebRtcVideoChannel2Test, TranslatesSenderBitrateStatsCorrectly) {
FakeVideoSendStream* stream = AddSendStream(); FakeVideoSendStream* stream = AddSendStream();
webrtc::VideoSendStream::Stats stats; webrtc::VideoSendStream::Stats stats;
stats.target_media_bitrate_bps = 156;
stats.media_bitrate_bps = 123; stats.media_bitrate_bps = 123;
stats.substreams[17].total_bitrate_bps = 1; stats.substreams[17].total_bitrate_bps = 1;
stats.substreams[17].retransmit_bitrate_bps = 2; stats.substreams[17].retransmit_bitrate_bps = 2;
@ -2233,6 +2234,7 @@ TEST_F(WebRtcVideoChannel2Test, TranslatesSenderBitrateStatsCorrectly) {
FakeVideoSendStream* stream2 = AddSendStream(); FakeVideoSendStream* stream2 = AddSendStream();
webrtc::VideoSendStream::Stats stats2; webrtc::VideoSendStream::Stats stats2;
stats2.target_media_bitrate_bps = 200;
stats2.media_bitrate_bps = 321; stats2.media_bitrate_bps = 321;
stats2.substreams[13].total_bitrate_bps = 5; stats2.substreams[13].total_bitrate_bps = 5;
stats2.substreams[13].retransmit_bitrate_bps = 6; stats2.substreams[13].retransmit_bitrate_bps = 6;
@ -2247,6 +2249,8 @@ TEST_F(WebRtcVideoChannel2Test, TranslatesSenderBitrateStatsCorrectly) {
// is OK as std::maps are sorted and AddSendStream() gives increasing SSRCs. // is OK as std::maps are sorted and AddSendStream() gives increasing SSRCs.
EXPECT_EQ(stats.media_bitrate_bps, info.senders[0].nominal_bitrate); EXPECT_EQ(stats.media_bitrate_bps, info.senders[0].nominal_bitrate);
EXPECT_EQ(stats2.media_bitrate_bps, info.senders[1].nominal_bitrate); EXPECT_EQ(stats2.media_bitrate_bps, info.senders[1].nominal_bitrate);
EXPECT_EQ(stats.target_media_bitrate_bps + stats2.target_media_bitrate_bps,
info.bw_estimations[0].target_enc_bitrate);
EXPECT_EQ(stats.media_bitrate_bps + stats2.media_bitrate_bps, EXPECT_EQ(stats.media_bitrate_bps + stats2.media_bitrate_bps,
info.bw_estimations[0].actual_enc_bitrate); info.bw_estimations[0].actual_enc_bitrate);
EXPECT_EQ(1 + 3 + 5 + 7, info.bw_estimations[0].transmit_bitrate) EXPECT_EQ(1 + 3 + 5 + 7, info.bw_estimations[0].transmit_bitrate)

View File

@ -14,7 +14,8 @@
#include "webrtc/modules/video_coding/main/source/encoded_frame.h" #include "webrtc/modules/video_coding/main/source/encoded_frame.h"
namespace webrtc { namespace webrtc {
VideoCoder::VideoCoder() : _vcm(VideoCodingModule::Create()), _decodedVideo(0) { VideoCoder::VideoCoder()
: _vcm(VideoCodingModule::Create(nullptr)), _decodedVideo(0) {
_vcm->InitializeSender(); _vcm->InitializeSender();
_vcm->InitializeReceiver(); _vcm->InitializeReceiver();

View File

@ -81,7 +81,8 @@ public:
kReferenceSelection kReferenceSelection
}; };
static VideoCodingModule* Create(); static VideoCodingModule* Create(
VideoEncoderRateObserver* encoder_rate_observer);
static VideoCodingModule* Create(Clock* clock, EventFactory* event_factory); static VideoCodingModule* Create(Clock* clock, EventFactory* event_factory);

View File

@ -148,6 +148,12 @@ class VCMProtectionCallback {
} }
}; };
class VideoEncoderRateObserver {
public:
virtual ~VideoEncoderRateObserver() {}
virtual void OnSetRates(uint32_t bitrate_bps, int framerate) = 0;
};
// Callback class used for telling the user about what frame type needed to continue decoding. // Callback class used for telling the user about what frame type needed to continue decoding.
// Typically a key frame when the stream has been corrupted in some way. // Typically a key frame when the stream has been corrupted in some way.
class VCMFrameTypeCallback { class VCMFrameTypeCallback {

View File

@ -93,7 +93,8 @@ VCMExtDecoderMapItem::VCMExtDecoderMapItem(
internal_render_timing(internal_render_timing) { internal_render_timing(internal_render_timing) {
} }
VCMCodecDataBase::VCMCodecDataBase() VCMCodecDataBase::VCMCodecDataBase(
VideoEncoderRateObserver* encoder_rate_observer)
: number_of_cores_(0), : number_of_cores_(0),
max_payload_size_(kDefaultPayloadSize), max_payload_size_(kDefaultPayloadSize),
periodic_key_frames_(false), periodic_key_frames_(false),
@ -104,11 +105,13 @@ VCMCodecDataBase::VCMCodecDataBase()
external_payload_type_(0), external_payload_type_(0),
external_encoder_(NULL), external_encoder_(NULL),
internal_source_(false), internal_source_(false),
encoder_rate_observer_(encoder_rate_observer),
ptr_encoder_(NULL), ptr_encoder_(NULL),
ptr_decoder_(NULL), ptr_decoder_(NULL),
current_dec_is_external_(false), current_dec_is_external_(false),
dec_map_(), dec_map_(),
dec_external_map_() {} dec_external_map_() {
}
VCMCodecDataBase::~VCMCodecDataBase() { VCMCodecDataBase::~VCMCodecDataBase() {
ResetSender(); ResetSender();
@ -295,7 +298,8 @@ bool VCMCodecDataBase::SetSendCodec(
DeleteEncoder(); DeleteEncoder();
if (send_codec->plType == external_payload_type_) { if (send_codec->plType == external_payload_type_) {
// External encoder. // External encoder.
ptr_encoder_ = new VCMGenericEncoder(*external_encoder_, internal_source_); ptr_encoder_ = new VCMGenericEncoder(
external_encoder_, encoder_rate_observer_, internal_source_);
current_enc_is_external_ = true; current_enc_is_external_ = true;
} else { } else {
ptr_encoder_ = CreateEncoder(send_codec->codecType); ptr_encoder_ = CreateEncoder(send_codec->codecType);
@ -679,15 +683,18 @@ VCMGenericEncoder* VCMCodecDataBase::CreateEncoder(
switch (type) { switch (type) {
#ifdef VIDEOCODEC_VP8 #ifdef VIDEOCODEC_VP8
case kVideoCodecVP8: case kVideoCodecVP8:
return new VCMGenericEncoder(*(VP8Encoder::Create())); return new VCMGenericEncoder(VP8Encoder::Create(), encoder_rate_observer_,
false);
#endif #endif
#ifdef VIDEOCODEC_VP9 #ifdef VIDEOCODEC_VP9
case kVideoCodecVP9: case kVideoCodecVP9:
return new VCMGenericEncoder(*(VP9Encoder::Create())); return new VCMGenericEncoder(VP9Encoder::Create(), encoder_rate_observer_,
false);
#endif #endif
#ifdef VIDEOCODEC_I420 #ifdef VIDEOCODEC_I420
case kVideoCodecI420: case kVideoCodecI420:
return new VCMGenericEncoder(*(new I420Encoder)); return new VCMGenericEncoder(new I420Encoder(), encoder_rate_observer_,
false);
#endif #endif
default: default:
LOG(LS_WARNING) << "No internal encoder of this type exists."; LOG(LS_WARNING) << "No internal encoder of this type exists.";
@ -698,9 +705,8 @@ VCMGenericEncoder* VCMCodecDataBase::CreateEncoder(
void VCMCodecDataBase::DeleteEncoder() { void VCMCodecDataBase::DeleteEncoder() {
if (ptr_encoder_) { if (ptr_encoder_) {
ptr_encoder_->Release(); ptr_encoder_->Release();
if (!current_enc_is_external_) { if (!current_enc_is_external_)
delete &ptr_encoder_->_encoder; delete ptr_encoder_->encoder_;
}
delete ptr_encoder_; delete ptr_encoder_;
ptr_encoder_ = NULL; ptr_encoder_ = NULL;
} }

View File

@ -46,7 +46,7 @@ struct VCMExtDecoderMapItem {
class VCMCodecDataBase { class VCMCodecDataBase {
public: public:
VCMCodecDataBase(); explicit VCMCodecDataBase(VideoEncoderRateObserver* encoder_rate_observer);
~VCMCodecDataBase(); ~VCMCodecDataBase();
// Sender Side // Sender Side
@ -180,6 +180,7 @@ class VCMCodecDataBase {
uint8_t external_payload_type_; uint8_t external_payload_type_;
VideoEncoder* external_encoder_; VideoEncoder* external_encoder_;
bool internal_source_; bool internal_source_;
VideoEncoderRateObserver* const encoder_rate_observer_;
VCMGenericEncoder* ptr_encoder_; VCMGenericEncoder* ptr_encoder_;
VCMGenericDecoder* ptr_decoder_; VCMGenericDecoder* ptr_decoder_;
bool current_dec_is_external_; bool current_dec_is_external_;

View File

@ -55,18 +55,18 @@ void CopyCodecSpecific(const CodecSpecificInfo* info, RTPVideoHeader** rtp) {
//#define DEBUG_ENCODER_BIT_STREAM //#define DEBUG_ENCODER_BIT_STREAM
VCMGenericEncoder::VCMGenericEncoder(VideoEncoder& encoder, bool internalSource /*= false*/) VCMGenericEncoder::VCMGenericEncoder(VideoEncoder* encoder,
: VideoEncoderRateObserver* rate_observer,
_encoder(encoder), bool internalSource)
_codecType(kVideoCodecUnknown), : encoder_(encoder),
_VCMencodedFrameCallback(NULL), rate_observer_(rate_observer),
_bitRate(0), _codecType(kVideoCodecUnknown),
_frameRate(0), _VCMencodedFrameCallback(NULL),
_internalSource(internalSource) _bitRate(0),
{ _frameRate(0),
_internalSource(internalSource) {
} }
VCMGenericEncoder::~VCMGenericEncoder() VCMGenericEncoder::~VCMGenericEncoder()
{ {
} }
@ -76,7 +76,7 @@ int32_t VCMGenericEncoder::Release()
_bitRate = 0; _bitRate = 0;
_frameRate = 0; _frameRate = 0;
_VCMencodedFrameCallback = NULL; _VCMencodedFrameCallback = NULL;
return _encoder.Release(); return encoder_->Release();
} }
int32_t int32_t
@ -87,7 +87,7 @@ VCMGenericEncoder::InitEncode(const VideoCodec* settings,
_bitRate = settings->startBitrate * 1000; _bitRate = settings->startBitrate * 1000;
_frameRate = settings->maxFramerate; _frameRate = settings->maxFramerate;
_codecType = settings->codecType; _codecType = settings->codecType;
if (_encoder.InitEncode(settings, numberOfCores, maxPayloadSize) != 0) { if (encoder_->InitEncode(settings, numberOfCores, maxPayloadSize) != 0) {
LOG(LS_ERROR) << "Failed to initialize the encoder associated with " LOG(LS_ERROR) << "Failed to initialize the encoder associated with "
"payload name: " << settings->plName; "payload name: " << settings->plName;
return -1; return -1;
@ -102,33 +102,35 @@ VCMGenericEncoder::Encode(const I420VideoFrame& inputFrame,
std::vector<VideoFrameType> video_frame_types(frameTypes.size(), std::vector<VideoFrameType> video_frame_types(frameTypes.size(),
kDeltaFrame); kDeltaFrame);
VCMEncodedFrame::ConvertFrameTypes(frameTypes, &video_frame_types); VCMEncodedFrame::ConvertFrameTypes(frameTypes, &video_frame_types);
return _encoder.Encode(inputFrame, codecSpecificInfo, &video_frame_types); return encoder_->Encode(inputFrame, codecSpecificInfo, &video_frame_types);
} }
int32_t int32_t
VCMGenericEncoder::SetChannelParameters(int32_t packetLoss, int64_t rtt) VCMGenericEncoder::SetChannelParameters(int32_t packetLoss, int64_t rtt)
{ {
return _encoder.SetChannelParameters(packetLoss, rtt); return encoder_->SetChannelParameters(packetLoss, rtt);
} }
int32_t int32_t
VCMGenericEncoder::SetRates(uint32_t newBitRate, uint32_t frameRate) VCMGenericEncoder::SetRates(uint32_t newBitRate, uint32_t frameRate)
{ {
uint32_t target_bitrate_kbps = (newBitRate + 500) / 1000; uint32_t target_bitrate_kbps = (newBitRate + 500) / 1000;
int32_t ret = _encoder.SetRates(target_bitrate_kbps, frameRate); int32_t ret = encoder_->SetRates(target_bitrate_kbps, frameRate);
if (ret < 0) if (ret < 0)
{ {
return ret; return ret;
} }
_bitRate = newBitRate; _bitRate = newBitRate;
_frameRate = frameRate; _frameRate = frameRate;
if (rate_observer_ != nullptr)
rate_observer_->OnSetRates(newBitRate, frameRate);
return VCM_OK; return VCM_OK;
} }
int32_t int32_t
VCMGenericEncoder::CodecConfigParameters(uint8_t* buffer, int32_t size) VCMGenericEncoder::CodecConfigParameters(uint8_t* buffer, int32_t size)
{ {
int32_t ret = _encoder.CodecConfigParameters(buffer, size); int32_t ret = encoder_->CodecConfigParameters(buffer, size);
if (ret < 0) if (ret < 0)
{ {
return ret; return ret;
@ -149,7 +151,7 @@ uint32_t VCMGenericEncoder::FrameRate() const
int32_t int32_t
VCMGenericEncoder::SetPeriodicKeyFrames(bool enable) VCMGenericEncoder::SetPeriodicKeyFrames(bool enable)
{ {
return _encoder.SetPeriodicKeyFrames(enable); return encoder_->SetPeriodicKeyFrames(enable);
} }
int32_t VCMGenericEncoder::RequestFrame( int32_t VCMGenericEncoder::RequestFrame(
@ -158,7 +160,7 @@ int32_t VCMGenericEncoder::RequestFrame(
std::vector<VideoFrameType> video_frame_types(frame_types.size(), std::vector<VideoFrameType> video_frame_types(frame_types.size(),
kDeltaFrame); kDeltaFrame);
VCMEncodedFrame::ConvertFrameTypes(frame_types, &video_frame_types); VCMEncodedFrame::ConvertFrameTypes(frame_types, &video_frame_types);
return _encoder.Encode(image, NULL, &video_frame_types); return encoder_->Encode(image, NULL, &video_frame_types);
} }
int32_t int32_t
@ -166,7 +168,7 @@ VCMGenericEncoder::RegisterEncodeCallback(VCMEncodedFrameCallback* VCMencodedFra
{ {
_VCMencodedFrameCallback = VCMencodedFrameCallback; _VCMencodedFrameCallback = VCMencodedFrameCallback;
_VCMencodedFrameCallback->SetInternalSource(_internalSource); _VCMencodedFrameCallback->SetInternalSource(_internalSource);
return _encoder.RegisterEncodeCompleteCallback(_VCMencodedFrameCallback); return encoder_->RegisterEncodeCompleteCallback(_VCMencodedFrameCallback);
} }
bool bool

View File

@ -12,6 +12,7 @@
#define WEBRTC_MODULES_VIDEO_CODING_GENERIC_ENCODER_H_ #define WEBRTC_MODULES_VIDEO_CODING_GENERIC_ENCODER_H_
#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h" #include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
#include "webrtc/modules/video_coding/main/interface/video_coding_defines.h"
#include <stdio.h> #include <stdio.h>
@ -73,7 +74,9 @@ class VCMGenericEncoder
{ {
friend class VCMCodecDataBase; friend class VCMCodecDataBase;
public: public:
VCMGenericEncoder(VideoEncoder& encoder, bool internalSource = false); VCMGenericEncoder(VideoEncoder* encoder,
VideoEncoderRateObserver* rate_observer,
bool internalSource);
~VCMGenericEncoder(); ~VCMGenericEncoder();
/** /**
* Free encoder memory * Free encoder memory
@ -127,7 +130,8 @@ public:
bool InternalSource() const; bool InternalSource() const;
private: private:
VideoEncoder& _encoder; VideoEncoder* const encoder_;
VideoEncoderRateObserver* const rate_observer_;
VideoCodecType _codecType; VideoCodecType _codecType;
VCMEncodedFrameCallback* _VCMencodedFrameCallback; VCMEncodedFrameCallback* _VCMencodedFrameCallback;
uint32_t _bitRate; uint32_t _bitRate;

View File

@ -73,9 +73,12 @@ class VideoCodingModuleImpl : public VideoCodingModule {
public: public:
VideoCodingModuleImpl(Clock* clock, VideoCodingModuleImpl(Clock* clock,
EventFactory* event_factory, EventFactory* event_factory,
bool owns_event_factory) bool owns_event_factory,
VideoEncoderRateObserver* encoder_rate_observer)
: VideoCodingModule(), : VideoCodingModule(),
sender_(new vcm::VideoSender(clock, &post_encode_callback_)), sender_(new vcm::VideoSender(clock,
&post_encode_callback_,
encoder_rate_observer)),
receiver_(new vcm::VideoReceiver(clock, event_factory)), receiver_(new vcm::VideoReceiver(clock, event_factory)),
own_event_factory_(owns_event_factory ? event_factory : NULL) {} own_event_factory_(owns_event_factory ? event_factory : NULL) {}
@ -383,16 +386,19 @@ int32_t VideoCodingModule::Codec(VideoCodecType codecType, VideoCodec* codec) {
return VCMCodecDataBase::Codec(codecType, codec) ? 0 : -1; return VCMCodecDataBase::Codec(codecType, codec) ? 0 : -1;
} }
VideoCodingModule* VideoCodingModule::Create() { VideoCodingModule* VideoCodingModule::Create(
return new VideoCodingModuleImpl( VideoEncoderRateObserver* encoder_rate_observer) {
Clock::GetRealTimeClock(), new EventFactoryImpl, true); return new VideoCodingModuleImpl(Clock::GetRealTimeClock(),
new EventFactoryImpl, true,
encoder_rate_observer);
} }
VideoCodingModule* VideoCodingModule::Create(Clock* clock, VideoCodingModule* VideoCodingModule::Create(
Clock* clock,
EventFactory* event_factory) { EventFactory* event_factory) {
assert(clock); assert(clock);
assert(event_factory); assert(event_factory);
return new VideoCodingModuleImpl(clock, event_factory, false); return new VideoCodingModuleImpl(clock, event_factory, false, nullptr);
} }
void VideoCodingModule::Destroy(VideoCodingModule* module) { void VideoCodingModule::Destroy(VideoCodingModule* module) {

View File

@ -56,7 +56,9 @@ class VideoSender {
public: public:
typedef VideoCodingModule::SenderNackMode SenderNackMode; typedef VideoCodingModule::SenderNackMode SenderNackMode;
VideoSender(Clock* clock, EncodedImageCallback* post_encode_callback); VideoSender(Clock* clock,
EncodedImageCallback* post_encode_callback,
VideoEncoderRateObserver* encoder_rate_observer);
~VideoSender(); ~VideoSender();

View File

@ -46,7 +46,7 @@ VideoReceiver::VideoReceiver(Clock* clock, EventFactory* event_factory)
_scheduleKeyRequest(false), _scheduleKeyRequest(false),
max_nack_list_size_(0), max_nack_list_size_(0),
pre_decode_image_callback_(NULL), pre_decode_image_callback_(NULL),
_codecDataBase(), _codecDataBase(NULL),
_receiveStatsTimer(1000, clock_), _receiveStatsTimer(1000, clock_),
_retransmissionTimer(10, clock_), _retransmissionTimer(10, clock_),
_keyRequestTimer(500, clock_) { _keyRequestTimer(500, clock_) {

View File

@ -60,7 +60,8 @@ class DebugRecorder {
}; };
VideoSender::VideoSender(Clock* clock, VideoSender::VideoSender(Clock* clock,
EncodedImageCallback* post_encode_callback) EncodedImageCallback* post_encode_callback,
VideoEncoderRateObserver* encoder_rate_observer)
: clock_(clock), : clock_(clock),
recorder_(new DebugRecorder()), recorder_(new DebugRecorder()),
process_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), process_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
@ -70,7 +71,7 @@ VideoSender::VideoSender(Clock* clock,
_nextFrameTypes(1, kVideoFrameDelta), _nextFrameTypes(1, kVideoFrameDelta),
_mediaOpt(clock_), _mediaOpt(clock_),
_sendStatsCallback(NULL), _sendStatsCallback(NULL),
_codecDataBase(), _codecDataBase(encoder_rate_observer),
frame_dropper_enabled_(true), frame_dropper_enabled_(true),
_sendStatsTimer(1000, clock_), _sendStatsTimer(1000, clock_),
current_codec_(), current_codec_(),

View File

@ -172,7 +172,7 @@ class TestVideoSender : public ::testing::Test {
TestVideoSender() : clock_(1000), packetization_callback_(&clock_) {} TestVideoSender() : clock_(1000), packetization_callback_(&clock_) {}
virtual void SetUp() OVERRIDE { virtual void SetUp() OVERRIDE {
sender_.reset(new VideoSender(&clock_, &post_encode_callback_)); sender_.reset(new VideoSender(&clock_, &post_encode_callback_, nullptr));
EXPECT_EQ(0, sender_->InitializeSender()); EXPECT_EQ(0, sender_->InitializeSender());
EXPECT_EQ(0, sender_->RegisterTransportCallback(&packetization_callback_)); EXPECT_EQ(0, sender_->RegisterTransportCallback(&packetization_callback_));
} }

View File

@ -29,7 +29,7 @@ using namespace webrtc;
int CodecDataBaseTest::RunTest(CmdArgs& args) int CodecDataBaseTest::RunTest(CmdArgs& args)
{ {
VideoCodingModule* vcm = VideoCodingModule::Create(); VideoCodingModule* vcm = VideoCodingModule::Create(nullptr);
CodecDataBaseTest* cdbt = new CodecDataBaseTest(vcm); CodecDataBaseTest* cdbt = new CodecDataBaseTest(vcm);
cdbt->Perform(args); cdbt->Perform(args);
VideoCodingModule::Destroy(vcm); VideoCodingModule::Destroy(vcm);

View File

@ -32,7 +32,7 @@ int MediaOptTest::RunTest(int testNum, CmdArgs& args)
Trace::CreateTrace(); Trace::CreateTrace();
Trace::SetTraceFile((test::OutputPath() + "mediaOptTestTrace.txt").c_str()); Trace::SetTraceFile((test::OutputPath() + "mediaOptTestTrace.txt").c_str());
Trace::set_level_filter(webrtc::kTraceAll); Trace::set_level_filter(webrtc::kTraceAll);
VideoCodingModule* vcm = VideoCodingModule::Create(); VideoCodingModule* vcm = VideoCodingModule::Create(nullptr);
Clock* clock = Clock::GetRealTimeClock(); Clock* clock = Clock::GetRealTimeClock();
MediaOptTest* mot = new MediaOptTest(vcm, clock); MediaOptTest* mot = new MediaOptTest(vcm, clock);
if (testNum == 0) if (testNum == 0)

View File

@ -145,7 +145,7 @@ int MTRxTxTest(CmdArgs& args)
printf("Cannot read file %s.\n", outname.c_str()); printf("Cannot read file %s.\n", outname.c_str());
return -1; return -1;
} }
VideoCodingModule* vcm = VideoCodingModule::Create(); VideoCodingModule* vcm = VideoCodingModule::Create(nullptr);
RtpDataCallback dataCallback(vcm); RtpDataCallback dataCallback(vcm);
RTPSendCompleteCallback* outgoingTransport = RTPSendCompleteCallback* outgoingTransport =

View File

@ -1566,6 +1566,64 @@ void EndToEndTest::TestSendsSetSsrcs(size_t num_ssrcs,
RunBaseTest(&test); RunBaseTest(&test);
} }
TEST_F(EndToEndTest, ReportsSetEncoderRates) {
class EncoderRateStatsTest : public test::EndToEndTest,
public test::FakeEncoder {
public:
EncoderRateStatsTest()
: EndToEndTest(kDefaultTimeoutMs),
FakeEncoder(Clock::GetRealTimeClock()) {}
virtual void OnStreamsCreated(
VideoSendStream* send_stream,
const std::vector<VideoReceiveStream*>& receive_streams) override {
send_stream_ = send_stream;
}
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
send_config->encoder_settings.encoder = this;
}
int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
// Make sure not to trigger on any default zero bitrates.
if (new_target_bitrate == 0)
return 0;
CriticalSectionScoped lock(crit_.get());
bitrate_kbps_ = new_target_bitrate;
observation_complete_->Set();
return 0;
}
void PerformTest() override {
ASSERT_EQ(kEventSignaled, Wait())
<< "Timed out while waiting for encoder SetRates() call.";
// Wait for GetStats to report a corresponding bitrate.
for (unsigned int i = 0; i < kDefaultTimeoutMs; ++i) {
VideoSendStream::Stats stats = send_stream_->GetStats();
{
CriticalSectionScoped lock(crit_.get());
if ((stats.target_media_bitrate_bps + 500) / 1000 ==
static_cast<int>(bitrate_kbps_)) {
return;
}
}
SleepMs(1);
}
FAIL()
<< "Timed out waiting for stats reporting the currently set bitrate.";
}
private:
VideoSendStream* send_stream_;
uint32_t bitrate_kbps_ GUARDED_BY(crit_);
} test;
RunBaseTest(&test);
}
TEST_F(EndToEndTest, GetStats) { TEST_F(EndToEndTest, GetStats) {
static const int kStartBitrateBps = 3000000; static const int kStartBitrateBps = 3000000;
class StatsObserver : public test::EndToEndTest, public I420FrameCallback { class StatsObserver : public test::EndToEndTest, public I420FrameCallback {

View File

@ -95,6 +95,11 @@ VideoSendStream::StreamStats* SendStatisticsProxy::GetStatsEntry(
return &stats_.substreams[ssrc]; // Insert new entry and return ptr. return &stats_.substreams[ssrc]; // Insert new entry and return ptr.
} }
void SendStatisticsProxy::OnSetRates(uint32_t bitrate_bps, int framerate) {
CriticalSectionScoped lock(crit_.get());
stats_.target_media_bitrate_bps = bitrate_bps;
}
void SendStatisticsProxy::OnSendEncodedImage( void SendStatisticsProxy::OnSendEncodedImage(
const EncodedImage& encoded_image, const EncodedImage& encoded_image,
const RTPVideoHeader* rtp_video_header) { const RTPVideoHeader* rtp_video_header) {

View File

@ -16,6 +16,7 @@
#include "webrtc/base/thread_annotations.h" #include "webrtc/base/thread_annotations.h"
#include "webrtc/common_types.h" #include "webrtc/common_types.h"
#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h" #include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
#include "webrtc/modules/video_coding/main/interface/video_coding_defines.h"
#include "webrtc/system_wrappers/interface/clock.h" #include "webrtc/system_wrappers/interface/clock.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h" #include "webrtc/system_wrappers/interface/scoped_ptr.h"
#include "webrtc/video_engine/include/vie_base.h" #include "webrtc/video_engine/include/vie_base.h"
@ -35,6 +36,7 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver,
public FrameCountObserver, public FrameCountObserver,
public ViEEncoderObserver, public ViEEncoderObserver,
public ViECaptureObserver, public ViECaptureObserver,
public VideoEncoderRateObserver,
public SendSideDelayObserver { public SendSideDelayObserver {
public: public:
static const int kStatsTimeoutMs; static const int kStatsTimeoutMs;
@ -47,6 +49,9 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver,
virtual void OnSendEncodedImage(const EncodedImage& encoded_image, virtual void OnSendEncodedImage(const EncodedImage& encoded_image,
const RTPVideoHeader* rtp_video_header); const RTPVideoHeader* rtp_video_header);
// From VideoEncoderRateObserver.
void OnSetRates(uint32_t bitrate_bps, int framerate) override;
protected: protected:
// From CpuOveruseMetricsObserver. // From CpuOveruseMetricsObserver.
void CpuOveruseMetricsUpdated(const CpuOveruseMetrics& metrics) OVERRIDE; void CpuOveruseMetricsUpdated(const CpuOveruseMetrics& metrics) OVERRIDE;

View File

@ -102,7 +102,7 @@ ViEChannel::ViEChannel(int32_t channel_id,
rtp_rtcp_cs_(CriticalSectionWrapper::CreateCriticalSection()), rtp_rtcp_cs_(CriticalSectionWrapper::CreateCriticalSection()),
send_payload_router_(new PayloadRouter()), send_payload_router_(new PayloadRouter()),
vcm_protection_callback_(new ViEChannelProtectionCallback(this)), vcm_protection_callback_(new ViEChannelProtectionCallback(this)),
vcm_(VideoCodingModule::Create()), vcm_(VideoCodingModule::Create(nullptr)),
vie_receiver_(channel_id, vcm_, remote_bitrate_estimator, this), vie_receiver_(channel_id, vcm_, remote_bitrate_estimator, this),
vie_sender_(channel_id), vie_sender_(channel_id),
vie_sync_(vcm_, this), vie_sync_(vcm_, this),

View File

@ -136,7 +136,7 @@ ViEEncoder::ViEEncoder(int32_t channel_id,
: channel_id_(channel_id), : channel_id_(channel_id),
number_of_cores_(number_of_cores), number_of_cores_(number_of_cores),
disable_default_encoder_(disable_default_encoder), disable_default_encoder_(disable_default_encoder),
vcm_(*webrtc::VideoCodingModule::Create()), vcm_(*webrtc::VideoCodingModule::Create(this)),
vpm_(*webrtc::VideoProcessingModule::Create(ViEModuleId(-1, channel_id))), vpm_(*webrtc::VideoProcessingModule::Create(ViEModuleId(-1, channel_id))),
send_payload_router_(NULL), send_payload_router_(NULL),
vcm_protection_callback_(NULL), vcm_protection_callback_(NULL),
@ -705,6 +705,12 @@ void ViEEncoder::SetSenderBufferingMode(int target_delay_ms) {
} }
} }
void ViEEncoder::OnSetRates(uint32_t bitrate_bps, int framerate) {
CriticalSectionScoped cs(callback_cs_.get());
if (send_statistics_proxy_ != nullptr)
send_statistics_proxy_->OnSetRates(bitrate_bps, framerate);
}
int32_t ViEEncoder::SendData( int32_t ViEEncoder::SendData(
const uint8_t payload_type, const uint8_t payload_type,
const EncodedImage& encoded_image, const EncodedImage& encoded_image,
@ -712,7 +718,9 @@ int32_t ViEEncoder::SendData(
const RTPVideoHeader* rtp_video_hdr) { const RTPVideoHeader* rtp_video_hdr) {
DCHECK(send_payload_router_ != NULL); DCHECK(send_payload_router_ != NULL);
if (send_statistics_proxy_ != NULL) { {
CriticalSectionScoped cs(callback_cs_.get());
if (send_statistics_proxy_ != NULL)
send_statistics_proxy_->OnSendEncodedImage(encoded_image, rtp_video_hdr); send_statistics_proxy_->OnSendEncodedImage(encoded_image, rtp_video_hdr);
} }
@ -959,6 +967,7 @@ void ViEEncoder::DeRegisterPostEncodeImageCallback() {
void ViEEncoder::RegisterSendStatisticsProxy( void ViEEncoder::RegisterSendStatisticsProxy(
SendStatisticsProxy* send_statistics_proxy) { SendStatisticsProxy* send_statistics_proxy) {
CriticalSectionScoped cs(callback_cs_.get());
send_statistics_proxy_ = send_statistics_proxy; send_statistics_proxy_ = send_statistics_proxy;
} }

View File

@ -46,6 +46,7 @@ class ViEPacedSenderCallback;
class ViEEncoder class ViEEncoder
: public RtcpIntraFrameObserver, : public RtcpIntraFrameObserver,
public VideoEncoderRateObserver,
public VCMPacketizationCallback, public VCMPacketizationCallback,
public VCMSendStatisticsCallback, public VCMSendStatisticsCallback,
public ViEFrameCallback { public ViEFrameCallback {
@ -130,6 +131,9 @@ class ViEEncoder
// Buffering mode. // Buffering mode.
void SetSenderBufferingMode(int target_delay_ms); void SetSenderBufferingMode(int target_delay_ms);
// Implements VideoEncoderRateObserver.
void OnSetRates(uint32_t bitrate_bps, int framerate) override;
// Implements VCMPacketizationCallback. // Implements VCMPacketizationCallback.
virtual int32_t SendData(uint8_t payload_type, virtual int32_t SendData(uint8_t payload_type,
const EncodedImage& encoded_image, const EncodedImage& encoded_image,
@ -243,7 +247,7 @@ class ViEEncoder
I420FrameCallback* pre_encode_callback_ GUARDED_BY(callback_cs_); I420FrameCallback* pre_encode_callback_ GUARDED_BY(callback_cs_);
const int64_t start_ms_; const int64_t start_ms_;
SendStatisticsProxy* send_statistics_proxy_; SendStatisticsProxy* send_statistics_proxy_ GUARDED_BY(callback_cs_);
}; };
} // namespace webrtc } // namespace webrtc

View File

@ -57,12 +57,14 @@ class VideoSendStream {
encode_frame_rate(0), encode_frame_rate(0),
avg_encode_time_ms(0), avg_encode_time_ms(0),
encode_usage_percent(0), encode_usage_percent(0),
target_media_bitrate_bps(0),
media_bitrate_bps(0), media_bitrate_bps(0),
suspended(false) {} suspended(false) {}
int input_frame_rate; int input_frame_rate;
int encode_frame_rate; int encode_frame_rate;
int avg_encode_time_ms; int avg_encode_time_ms;
int encode_usage_percent; int encode_usage_percent;
int target_media_bitrate_bps;
int media_bitrate_bps; int media_bitrate_bps;
bool suspended; bool suspended;
std::map<uint32_t, StreamStats> substreams; std::map<uint32_t, StreamStats> substreams;