diff options
author | pbos@webrtc.org <pbos@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d> | 2013-11-14 08:58:14 +0000 |
---|---|---|
committer | pbos@webrtc.org <pbos@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d> | 2013-11-14 08:58:14 +0000 |
commit | 690405437efa09fcd269b9e40b623ad065b0b822 (patch) | |
tree | 33cce068909fb0084a7fdfcdb5a6f2192a577efe | |
parent | 2f9e587aa9fafb91a9c537f252d11bc366611028 (diff) | |
download | webrtc-690405437efa09fcd269b9e40b623ad065b0b822.tar.gz |
Implement VideoSendStream::SetCodec().
Removing assertion that SSRC count should be the same as the number of
streams in the codec. It makes sense that you don't always use the same
number of streams under one call. Dropping resolution due to CPU overuse
for instance can require less streams, but the SSRCs should stay
allocated so that operations can resume when not overusing any more.
This change also means we can get rid of the ugly SendStreamState whose
content wasn't defined. Instead we use SetCodec to change resolution
etc. on the fly. Should something else have to be replaced on the fly
then that functionality simply has to be implemented.
BUG=
R=mflodman@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/3499005
git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@5123 4adac7df-926f-26a2-2b94-8c16560cd09d
-rw-r--r-- | call.cc | 8 | ||||
-rw-r--r-- | call.h | 2 | ||||
-rw-r--r-- | video/video_send_stream.cc | 36 | ||||
-rw-r--r-- | video/video_send_stream.h | 9 | ||||
-rw-r--r-- | video/video_send_stream_tests.cc | 80 | ||||
-rw-r--r-- | video_send_stream.h | 14 |
6 files changed, 102 insertions, 47 deletions
@@ -41,8 +41,7 @@ class Call : public webrtc::Call, public PacketReceiver { virtual VideoSendStream* CreateSendStream( const VideoSendStream::Config& config) OVERRIDE; - virtual SendStreamState* DestroySendStream( - webrtc::VideoSendStream* send_stream) OVERRIDE; + virtual void DestroySendStream(webrtc::VideoSendStream* send_stream) OVERRIDE; virtual VideoReceiveStream::Config GetDefaultReceiveConfig() OVERRIDE; @@ -228,7 +227,7 @@ VideoSendStream* Call::CreateSendStream(const VideoSendStream::Config& config) { return send_stream; } -SendStreamState* Call::DestroySendStream(webrtc::VideoSendStream* send_stream) { +void Call::DestroySendStream(webrtc::VideoSendStream* send_stream) { assert(send_stream != NULL); VideoSendStream* send_stream_impl = NULL; @@ -248,9 +247,6 @@ SendStreamState* Call::DestroySendStream(webrtc::VideoSendStream* send_stream) { assert(send_stream_impl != NULL); delete send_stream_impl; - - // TODO(pbos): Return its previous state - return NULL; } VideoReceiveStream::Config Call::GetDefaultReceiveConfig() { @@ -66,7 +66,7 @@ class Call { // Returns the internal state of the send stream, for resume sending with a // new stream with different settings. // Note: Only the last returned send-stream state is valid. - virtual SendStreamState* DestroySendStream(VideoSendStream* send_stream) = 0; + virtual void DestroySendStream(VideoSendStream* send_stream) = 0; virtual VideoReceiveStream::Config GetDefaultReceiveConfig() = 0; diff --git a/video/video_send_stream.cc b/video/video_send_stream.cc index 8814c359..5ae1e941 100644 --- a/video/video_send_stream.cc +++ b/video/video_send_stream.cc @@ -82,14 +82,10 @@ VideoSendStream::VideoSendStream(newapi::Transport* transport, bool overuse_detection, webrtc::VideoEngine* video_engine, const VideoSendStream::Config& config) - : transport_adapter_(transport), config_(config), external_codec_(NULL) { - - if (config_.codec.numberOfSimulcastStreams > 0) { - assert(config_.rtp.ssrcs.size() == config_.codec.numberOfSimulcastStreams); - } else { - assert(config_.rtp.ssrcs.size() == 1); - } - + : transport_adapter_(transport), + codec_lock_(CriticalSectionWrapper::CreateCriticalSection()), + config_(config), + external_codec_(NULL) { video_engine_base_ = ViEBase::GetInterface(video_engine); video_engine_base_->CreateChannel(channel_); assert(channel_ != -1); @@ -97,6 +93,7 @@ VideoSendStream::VideoSendStream(newapi::Transport* transport, rtp_rtcp_ = ViERTP_RTCP::GetInterface(video_engine); assert(rtp_rtcp_ != NULL); + assert(config_.rtp.ssrcs.size() > 0); if (config_.rtp.ssrcs.size() == 1) { rtp_rtcp_->SetLocalSSRC(channel_, config_.rtp.ssrcs[0]); } else { @@ -186,9 +183,8 @@ VideoSendStream::VideoSendStream(newapi::Transport* transport, } codec_ = ViECodec::GetInterface(video_engine); - if (codec_->SetSendCodec(channel_, config_.codec) != 0) { + if (!SetCodec(config_.codec)) abort(); - } if (overuse_detection) { overuse_observer_.reset( @@ -275,15 +271,21 @@ void VideoSendStream::StopSend() { abort(); } -bool VideoSendStream::SetTargetBitrate( - int min_bitrate, - int max_bitrate, - const std::vector<SimulcastStream>& streams) { - return false; +bool VideoSendStream::SetCodec(const VideoCodec& codec) { + if (codec.numberOfSimulcastStreams > 0) + assert(config_.rtp.ssrcs.size() >= codec.numberOfSimulcastStreams); + + CriticalSectionScoped crit(codec_lock_.get()); + if (codec_->SetSendCodec(channel_, codec) != 0) + return false; + + config_.codec = codec; + return true; } -void VideoSendStream::GetSendCodec(VideoCodec* send_codec) { - *send_codec = config_.codec; +VideoCodec VideoSendStream::GetCodec() { + CriticalSectionScoped crit(codec_lock_.get()); + return config_.codec; } bool VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) { diff --git a/video/video_send_stream.h b/video/video_send_stream.h index 304d825d..2d077e3a 100644 --- a/video/video_send_stream.h +++ b/video/video_send_stream.h @@ -17,6 +17,7 @@ #include "webrtc/video/transport_adapter.h" #include "webrtc/video_receive_stream.h" #include "webrtc/video_send_stream.h" +#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" namespace webrtc { @@ -53,17 +54,15 @@ class VideoSendStream : public webrtc::VideoSendStream, virtual void StopSend() OVERRIDE; - virtual bool SetTargetBitrate(int min_bitrate, int max_bitrate, - const std::vector<SimulcastStream>& streams) - OVERRIDE; - - virtual void GetSendCodec(VideoCodec* send_codec) OVERRIDE; + virtual bool SetCodec(const VideoCodec& codec) OVERRIDE; + virtual VideoCodec GetCodec() OVERRIDE; public: bool DeliverRtcp(const uint8_t* packet, size_t length); private: TransportAdapter transport_adapter_; + scoped_ptr<CriticalSectionWrapper> codec_lock_; VideoSendStream::Config config_; ViEBase* video_engine_base_; diff --git a/video/video_send_stream_tests.cc b/video/video_send_stream_tests.cc index 358ecf3f..f17d4a59 100644 --- a/video/video_send_stream_tests.cc +++ b/video/video_send_stream_tests.cc @@ -38,7 +38,9 @@ class SendTransportObserver : public test::NullTransport { send_test_complete_(EventWrapper::Create()), timeout_ms_(timeout_ms) {} - EventTypeWrapper Wait() { return send_test_complete_->Wait(timeout_ms_); } + virtual EventTypeWrapper Wait() { + return send_test_complete_->Wait(timeout_ms_); + } virtual void Stop() {} @@ -58,19 +60,19 @@ class VideoSendStreamTest : public ::testing::Test { void RunSendTest(Call* call, const VideoSendStream::Config& config, SendTransportObserver* observer) { - VideoSendStream* send_stream = call->CreateSendStream(config); + send_stream_ = call->CreateSendStream(config); scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer( test::FrameGeneratorCapturer::Create( - send_stream->Input(), 320, 240, 30, Clock::GetRealTimeClock())); - send_stream->StartSend(); + send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock())); + send_stream_->StartSend(); frame_generator_capturer->Start(); EXPECT_EQ(kEventSignaled, observer->Wait()); observer->Stop(); frame_generator_capturer->Stop(); - send_stream->StopSend(); - call->DestroySendStream(send_stream); + send_stream_->StopSend(); + call->DestroySendStream(send_stream_); } VideoSendStream::Config GetSendTestConfig(Call* call) { @@ -87,6 +89,7 @@ class VideoSendStreamTest : public ::testing::Test { static const uint32_t kSendSsrc; static const uint32_t kSendRtxSsrc; + VideoSendStream* send_stream_; test::FakeEncoder fake_encoder_; }; @@ -491,6 +494,71 @@ TEST_F(VideoSendStreamTest, MaxPacketSize) { RunSendTest(call.get(), send_config, &observer); } +TEST_F(VideoSendStreamTest, CanChangeSendCodec) { + static const uint8_t kFirstPayloadType = 121; + static const uint8_t kSecondPayloadType = 122; + + class CodecChangeObserver : public SendTransportObserver { + public: + CodecChangeObserver(VideoSendStream** send_stream_ptr) + : SendTransportObserver(30 * 1000), + received_first_payload_(EventWrapper::Create()), + send_stream_ptr_(send_stream_ptr) {} + + virtual bool SendRTP(const uint8_t* packet, size_t length) OVERRIDE { + RTPHeader header; + EXPECT_TRUE( + rtp_header_parser_->Parse(packet, static_cast<int>(length), &header)); + + if (header.payloadType == kFirstPayloadType) { + received_first_payload_->Set(); + } else if (header.payloadType == kSecondPayloadType) { + send_test_complete_->Set(); + } + + return true; + } + + virtual EventTypeWrapper Wait() OVERRIDE { + EXPECT_EQ(kEventSignaled, received_first_payload_->Wait(30 * 1000)) + << "Timed out while waiting for first payload."; + + EXPECT_TRUE((*send_stream_ptr_)->SetCodec(second_codec_)); + + EXPECT_EQ(kEventSignaled, SendTransportObserver::Wait()) + << "Timed out while waiting for second payload type."; + + // Return OK regardless, prevents double error reporting. + return kEventSignaled; + } + + void SetSecondCodec(const VideoCodec& codec) { + second_codec_ = codec; + } + + private: + scoped_ptr<EventWrapper> received_first_payload_; + VideoSendStream** send_stream_ptr_; + VideoCodec second_codec_; + } observer(&send_stream_); + + Call::Config call_config(&observer); + scoped_ptr<Call> call(Call::Create(call_config)); + + std::vector<VideoCodec> codecs = call->GetVideoCodecs(); + ASSERT_GE(codecs.size(), 2u) + << "Test needs at least 2 separate codecs to work."; + codecs[0].plType = kFirstPayloadType; + codecs[1].plType = kSecondPayloadType; + observer.SetSecondCodec(codecs[1]); + + VideoSendStream::Config send_config = GetSendTestConfig(call.get()); + send_config.codec = codecs[0]; + send_config.encoder = NULL; + + RunSendTest(call.get(), send_config, &observer); +} + // The test will go through a number of phases. // 1. Start sending packets. // 2. As soon as the RTP stream has been detected, signal a low REMB value to diff --git a/video_send_stream.h b/video_send_stream.h index af33b7ca..2df282b4 100644 --- a/video_send_stream.h +++ b/video_send_stream.h @@ -23,8 +23,6 @@ namespace webrtc { class VideoEncoder; -struct SendStreamState; - // Class to deliver captured frame to the video send stream. class VideoSendStreamInput { public: @@ -81,7 +79,6 @@ class VideoSendStream { target_delay_ms(0), pacing(false), stats_callback(NULL), - start_state(NULL), auto_mute(false) {} VideoCodec codec; @@ -145,9 +142,6 @@ class VideoSendStream { // Callback for periodically receiving send stats. StatsCallback* stats_callback; - // Set to resume a previously destroyed send stream. - SendStreamState* start_state; - // True if video should be muted when video goes under the minimum video // bitrate. Unless muted, video will be sent at a bitrate higher than // estimated available. @@ -161,12 +155,8 @@ class VideoSendStream { virtual void StartSend() = 0; virtual void StopSend() = 0; - // TODO(mflodman) Change VideoCodec struct and use here. - virtual bool SetTargetBitrate( - int min_bitrate, int max_bitrate, - const std::vector<SimulcastStream>& streams) = 0; - - virtual void GetSendCodec(VideoCodec* send_codec) = 0; + virtual bool SetCodec(const VideoCodec& codec) = 0; + virtual VideoCodec GetCodec() = 0; protected: virtual ~VideoSendStream() {} |