From 5cc97a55e6cc97aeea3d2e877348fc0fd43e88ea Mon Sep 17 00:00:00 2001 From: "pbos@webrtc.org" Date: Wed, 29 Oct 2014 15:28:39 +0000 Subject: Use external VideoDecoders in VideoReceiveStream. Removes direct VideoCodec use from the new API, exposes VideoDecoders through webrtc/video_decoder.h similar to VideoEncoders. Also includes some preparation for wiring up external decoders in WebRtcVideoEngine2 by adding AllocatedDecoders that specify whether they were allocated internally or externally. Additionally addresses a data race in VideoReceiver that was exposed with this change. R=mflodman@webrtc.org, stefan@webrtc.org TBR=pthatcher@webrtc.org BUG=2854,1667 Review URL: https://webrtc-codereview.appspot.com/27829004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7560 4adac7df-926f-26a2-2b94-8c16560cd09d --- media/webrtc/webrtcvideoengine2.cc | 50 +++++++++++++++++------------ media/webrtc/webrtcvideoengine2.h | 13 ++++++++ media/webrtc/webrtcvideoengine2_unittest.cc | 7 ++-- media/webrtc/webrtcvideoengine2_unittest.h | 1 - 4 files changed, 45 insertions(+), 26 deletions(-) (limited to 'media/webrtc') diff --git a/media/webrtc/webrtcvideoengine2.cc b/media/webrtc/webrtcvideoengine2.cc index 5783f5b..7df6809 100644 --- a/media/webrtc/webrtcvideoengine2.cc +++ b/media/webrtc/webrtcvideoengine2.cc @@ -42,6 +42,7 @@ #include "webrtc/base/logging.h" #include "webrtc/base/stringutils.h" #include "webrtc/call.h" +#include "webrtc/video_decoder.h" #include "webrtc/video_encoder.h" #define UNIMPLEMENTED \ @@ -1008,8 +1009,8 @@ bool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) { webrtc::VideoReceiveStream::Config config; ConfigureReceiverRtp(&config, sp); - receive_streams_[ssrc] = - new WebRtcVideoReceiveStream(call_.get(), config, recv_codecs_); + receive_streams_[ssrc] = new WebRtcVideoReceiveStream( + call_.get(), external_decoder_factory_, config, recv_codecs_); return true; } @@ -1854,11 +1855,13 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( webrtc::Call* call, + WebRtcVideoDecoderFactory* external_decoder_factory, const webrtc::VideoReceiveStream::Config& config, const std::vector& recv_codecs) : call_(call), stream_(NULL), config_(config), + external_decoder_factory_(external_decoder_factory), renderer_(NULL), last_width_(-1), last_height_(-1) { @@ -1869,6 +1872,7 @@ WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( WebRtcVideoChannel2::WebRtcVideoReceiveStream::~WebRtcVideoReceiveStream() { call_->DestroyVideoReceiveStream(stream_); + ClearDecoders(); } void WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRecvCodecs( @@ -1877,24 +1881,18 @@ void WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRecvCodecs( // TODO(pbos): Base receive codecs off recv_codecs_ and set up using a // DecoderFactory similar to send side. Pending webrtc:2854. // Also set up default codecs if there's nothing in recv_codecs_. - webrtc::VideoCodec codec; - memset(&codec, 0, sizeof(codec)); - - codec.plType = kDefaultVideoCodecPref.payload_type; - strcpy(codec.plName, kDefaultVideoCodecPref.name); - codec.codecType = webrtc::kVideoCodecVP8; - codec.codecSpecific.VP8.resilience = webrtc::kResilientStream; - codec.codecSpecific.VP8.numberOfTemporalLayers = 1; - codec.codecSpecific.VP8.denoisingOn = true; - codec.codecSpecific.VP8.errorConcealmentOn = false; - codec.codecSpecific.VP8.automaticResizeOn = false; - codec.codecSpecific.VP8.frameDroppingOn = true; - codec.codecSpecific.VP8.keyFrameInterval = 3000; - // Bitrates don't matter and are ignored for the receiver. This is put in to - // have the current underlying implementation accept the VideoCodec. - codec.minBitrate = codec.startBitrate = codec.maxBitrate = 300; - config_.codecs.clear(); - config_.codecs.push_back(codec); + ClearDecoders(); + + AllocatedDecoder allocated_decoder( + webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kVp8), false); + allocated_decoders_.push_back(allocated_decoder); + + webrtc::VideoReceiveStream::Decoder decoder; + decoder.decoder = allocated_decoder.decoder; + decoder.payload_type = kDefaultVideoCodecPref.payload_type; + decoder.payload_name = "VP8"; + + config_.decoders.push_back(decoder); config_.rtp.fec = recv_codecs.front().fec; @@ -1919,6 +1917,18 @@ void WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { stream_->Start(); } +void WebRtcVideoChannel2::WebRtcVideoReceiveStream::ClearDecoders() { + for (size_t i = 0; i < allocated_decoders_.size(); ++i) { + if (allocated_decoders_[i].external) { + external_decoder_factory_->DestroyVideoDecoder( + allocated_decoders_[i].decoder); + } else { + delete allocated_decoders_[i].decoder; + } + } + allocated_decoders_.clear(); +} + void WebRtcVideoChannel2::WebRtcVideoReceiveStream::RenderFrame( const webrtc::I420VideoFrame& frame, int time_to_render_ms) { diff --git a/media/webrtc/webrtcvideoengine2.h b/media/webrtc/webrtcvideoengine2.h index e87c258..d32abb2 100644 --- a/media/webrtc/webrtcvideoengine2.h +++ b/media/webrtc/webrtcvideoengine2.h @@ -389,6 +389,7 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler, public: WebRtcVideoReceiveStream( webrtc::Call*, + WebRtcVideoDecoderFactory* external_decoder_factory, const webrtc::VideoReceiveStream::Config& config, const std::vector& recv_codecs); ~WebRtcVideoReceiveStream(); @@ -405,14 +406,26 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler, VideoReceiverInfo GetVideoReceiverInfo(); private: + struct AllocatedDecoder { + AllocatedDecoder(webrtc::VideoDecoder* decoder, bool external) + : decoder(decoder), external(external) {} + webrtc::VideoDecoder* decoder; + bool external; + }; + void SetSize(int width, int height); void RecreateWebRtcStream(); + void ClearDecoders(); + webrtc::Call* const call_; webrtc::VideoReceiveStream* stream_; webrtc::VideoReceiveStream::Config config_; + WebRtcVideoDecoderFactory* const external_decoder_factory_; + std::vector allocated_decoders_; + rtc::CriticalSection renderer_lock_; cricket::VideoRenderer* renderer_ GUARDED_BY(renderer_lock_); int last_width_ GUARDED_BY(renderer_lock_); diff --git a/media/webrtc/webrtcvideoengine2_unittest.cc b/media/webrtc/webrtcvideoengine2_unittest.cc index 29c7dd5..835bb7c 100644 --- a/media/webrtc/webrtcvideoengine2_unittest.cc +++ b/media/webrtc/webrtcvideoengine2_unittest.cc @@ -174,9 +174,6 @@ void FakeVideoReceiveStream::Stop() { receiving_ = false; } -void FakeVideoReceiveStream::GetCurrentReceiveCodec(webrtc::VideoCodec* codec) { -} - FakeCall::FakeCall(const webrtc::Call::Config& config) : config_(config), network_state_(kNetworkUp) { SetVideoCodecs(GetDefaultVideoCodecs()); @@ -1622,8 +1619,8 @@ TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsAcceptDefaultCodecs) { FakeVideoReceiveStream* stream = AddRecvStream(); webrtc::VideoReceiveStream::Config config = stream->GetConfig(); - EXPECT_STREQ(engine_.codecs()[0].name.c_str(), config.codecs[0].plName); - EXPECT_EQ(engine_.codecs()[0].id, config.codecs[0].plType); + EXPECT_EQ(engine_.codecs()[0].name, config.decoders[0].payload_name); + EXPECT_EQ(engine_.codecs()[0].id, config.decoders[0].payload_type); } TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectUnsupportedCodec) { diff --git a/media/webrtc/webrtcvideoengine2_unittest.h b/media/webrtc/webrtcvideoengine2_unittest.h index de151a2..3b62289 100644 --- a/media/webrtc/webrtcvideoengine2_unittest.h +++ b/media/webrtc/webrtcvideoengine2_unittest.h @@ -87,7 +87,6 @@ class FakeVideoReceiveStream : public webrtc::VideoReceiveStream { virtual void Start() OVERRIDE; virtual void Stop() OVERRIDE; - virtual void GetCurrentReceiveCodec(webrtc::VideoCodec* codec); webrtc::VideoReceiveStream::Config config_; bool receiving_; -- cgit v1.2.3