Use VideoReceiveStream as an ExternalRenderer.

Removes AddRenderCallback from ViERenderer and implements
VideoReceiveStream on top of DeliverI420Frame like WebRtcVideoEngine
currently does today.

Also adds ::IsTextureSupported() to the VideoRenderer interface to
permit querying whether an external renderer supports texture rendering.

R=stefan@webrtc.org
TBR=mflodman@webrtc.org
BUG=1667

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

Cr-Commit-Position: refs/heads/master@{#8299}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8299 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
pbos@webrtc.org 2015-02-09 15:14:36 +00:00
parent d6e25a5b27
commit 0d852d5c27
16 changed files with 208 additions and 176 deletions

View File

@ -1998,6 +1998,10 @@ void WebRtcVideoChannel2::WebRtcVideoReceiveStream::RenderFrame(
renderer_->RenderFrame(&render_frame);
}
bool WebRtcVideoChannel2::WebRtcVideoReceiveStream::IsTextureSupported() const {
return true;
}
void WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRenderer(
cricket::VideoRenderer* renderer) {
rtc::CritScope crit(&renderer_lock_);

View File

@ -90,7 +90,7 @@ class DefaultUnsignalledSsrcHandler : public UnsignalledSsrcHandler {
public:
DefaultUnsignalledSsrcHandler();
virtual Action OnUnsignalledSsrc(VideoMediaChannel* engine,
uint32_t ssrc) OVERRIDE;
uint32_t ssrc) override;
VideoRenderer* GetDefaultRenderer() const;
void SetDefaultRenderer(VideoMediaChannel* channel, VideoRenderer* renderer);
@ -191,52 +191,50 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler,
bool Init();
// VideoMediaChannel implementation
virtual bool SetRecvCodecs(const std::vector<VideoCodec>& codecs) OVERRIDE;
virtual bool SetSendCodecs(const std::vector<VideoCodec>& codecs) OVERRIDE;
virtual bool GetSendCodec(VideoCodec* send_codec) OVERRIDE;
virtual bool SetRecvCodecs(const std::vector<VideoCodec>& codecs) override;
virtual bool SetSendCodecs(const std::vector<VideoCodec>& codecs) override;
virtual bool GetSendCodec(VideoCodec* send_codec) override;
virtual bool SetSendStreamFormat(uint32 ssrc,
const VideoFormat& format) OVERRIDE;
virtual bool SetRender(bool render) OVERRIDE;
virtual bool SetSend(bool send) OVERRIDE;
const VideoFormat& format) override;
virtual bool SetRender(bool render) override;
virtual bool SetSend(bool send) override;
virtual bool AddSendStream(const StreamParams& sp) OVERRIDE;
virtual bool RemoveSendStream(uint32 ssrc) OVERRIDE;
virtual bool AddRecvStream(const StreamParams& sp) OVERRIDE;
virtual bool RemoveRecvStream(uint32 ssrc) OVERRIDE;
virtual bool SetRenderer(uint32 ssrc, VideoRenderer* renderer) OVERRIDE;
virtual bool AddSendStream(const StreamParams& sp) override;
virtual bool RemoveSendStream(uint32 ssrc) override;
virtual bool AddRecvStream(const StreamParams& sp) override;
virtual bool RemoveRecvStream(uint32 ssrc) override;
virtual bool SetRenderer(uint32 ssrc, VideoRenderer* renderer) override;
virtual bool GetStats(const StatsOptions& options,
VideoMediaInfo* info) OVERRIDE;
virtual bool SetCapturer(uint32 ssrc, VideoCapturer* capturer) OVERRIDE;
virtual bool SendIntraFrame() OVERRIDE;
virtual bool RequestIntraFrame() OVERRIDE;
VideoMediaInfo* info) override;
virtual bool SetCapturer(uint32 ssrc, VideoCapturer* capturer) override;
virtual bool SendIntraFrame() override;
virtual bool RequestIntraFrame() override;
virtual void OnPacketReceived(rtc::Buffer* packet,
const rtc::PacketTime& packet_time)
OVERRIDE;
const rtc::PacketTime& packet_time) override;
virtual void OnRtcpReceived(rtc::Buffer* packet,
const rtc::PacketTime& packet_time)
OVERRIDE;
virtual void OnReadyToSend(bool ready) OVERRIDE;
virtual bool MuteStream(uint32 ssrc, bool mute) OVERRIDE;
const rtc::PacketTime& packet_time) override;
virtual void OnReadyToSend(bool ready) override;
virtual bool MuteStream(uint32 ssrc, bool mute) override;
// Set send/receive RTP header extensions. This must be done before creating
// streams as it only has effect on future streams.
virtual bool SetRecvRtpHeaderExtensions(
const std::vector<RtpHeaderExtension>& extensions) OVERRIDE;
const std::vector<RtpHeaderExtension>& extensions) override;
virtual bool SetSendRtpHeaderExtensions(
const std::vector<RtpHeaderExtension>& extensions) OVERRIDE;
virtual bool SetMaxSendBandwidth(int bps) OVERRIDE;
virtual bool SetOptions(const VideoOptions& options) OVERRIDE;
virtual bool GetOptions(VideoOptions* options) const OVERRIDE {
const std::vector<RtpHeaderExtension>& extensions) override;
virtual bool SetMaxSendBandwidth(int bps) override;
virtual bool SetOptions(const VideoOptions& options) override;
virtual bool GetOptions(VideoOptions* options) const override {
*options = options_;
return true;
}
virtual void SetInterface(NetworkInterface* iface) OVERRIDE;
virtual void UpdateAspectRatio(int ratio_w, int ratio_h) OVERRIDE;
virtual void SetInterface(NetworkInterface* iface) override;
virtual void UpdateAspectRatio(int ratio_w, int ratio_h) override;
virtual void OnMessage(rtc::Message* msg) OVERRIDE;
virtual void OnMessage(rtc::Message* msg) override;
virtual void OnLoadUpdate(Load load) OVERRIDE;
virtual void OnLoadUpdate(Load load) override;
// Implemented for VideoMediaChannelTest.
bool sending() const { return sending_; }
@ -395,7 +393,8 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler,
void SetRtpExtensions(const std::vector<webrtc::RtpExtension>& extensions);
virtual void RenderFrame(const webrtc::I420VideoFrame& frame,
int time_to_render_ms) OVERRIDE;
int time_to_render_ms) override;
virtual bool IsTextureSupported() const override;
void SetRenderer(cricket::VideoRenderer* renderer);
cricket::VideoRenderer* GetRenderer();
@ -446,8 +445,8 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler,
void Construct(webrtc::Call* call, WebRtcVideoEngine2* engine);
void SetDefaultOptions();
virtual bool SendRtp(const uint8_t* data, size_t len) OVERRIDE;
virtual bool SendRtcp(const uint8_t* data, size_t len) OVERRIDE;
virtual bool SendRtp(const uint8_t* data, size_t len) override;
virtual bool SendRtcp(const uint8_t* data, size_t len) override;
void StartAllSendStreams();
void StopAllSendStreams();

View File

@ -26,8 +26,10 @@ class GlxRenderer : public GlRenderer {
size_t height);
virtual ~GlxRenderer();
virtual void RenderFrame(const webrtc::I420VideoFrame& frame, int delta)
OVERRIDE;
virtual void RenderFrame(const webrtc::I420VideoFrame& frame,
int delta) override;
virtual bool IsTextureSupported() const override { return false; }
private:
GlxRenderer(size_t width, size_t height);

View File

@ -27,7 +27,8 @@ class MacRenderer : public GlRenderer {
bool Init(const char* window_title, int width, int height);
// Implements GlRenderer.
virtual void RenderFrame(const I420VideoFrame& frame, int delta) OVERRIDE;
virtual void RenderFrame(const I420VideoFrame& frame, int delta) override;
virtual bool IsTextureSupported() const override { return false; }
private:
CocoaWindow* window_;

View File

@ -18,7 +18,8 @@ namespace test {
class NullRenderer : public VideoRenderer {
virtual void RenderFrame(const I420VideoFrame& video_frame,
int time_to_render_ms) OVERRIDE {}
int time_to_render_ms) override {}
virtual bool IsTextureSupported() const override { return false; }
};
VideoRenderer* VideoRenderer::Create(const char* window_title,

View File

@ -27,8 +27,10 @@ class D3dRenderer : public VideoRenderer {
size_t height);
virtual ~D3dRenderer();
virtual void RenderFrame(const webrtc::I420VideoFrame& frame, int delta)
OVERRIDE;
virtual void RenderFrame(const webrtc::I420VideoFrame& frame,
int delta) override;
virtual bool IsTextureSupported() const override { return false; }
private:
D3dRenderer(size_t width, size_t height);

View File

@ -180,6 +180,8 @@ class VideoRtcpAndSyncObserver : public SyncRtcpObserver, public VideoRenderer {
}
}
virtual bool IsTextureSupported() const override { return false; }
private:
Clock* const clock_;
int voe_channel_;
@ -372,6 +374,8 @@ void CallPerfTest::TestCaptureNtpTime(const FakeNetworkPipe::Config& net_config,
EXPECT_TRUE(std::abs(time_offset_ms) < threshold_ms_);
}
virtual bool IsTextureSupported() const override { return false; }
virtual Action OnSendRtp(const uint8_t* packet, size_t length) {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));

View File

@ -59,12 +59,12 @@ class EndToEndTest : public test::CallTest {
protected:
class UnusedTransport : public newapi::Transport {
private:
virtual bool SendRtp(const uint8_t* packet, size_t length) OVERRIDE {
virtual bool SendRtp(const uint8_t* packet, size_t length) override {
ADD_FAILURE() << "Unexpected RTP sent.";
return false;
}
virtual bool SendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
virtual bool SendRtcp(const uint8_t* packet, size_t length) override {
ADD_FAILURE() << "Unexpected RTCP sent.";
return false;
}
@ -122,10 +122,12 @@ TEST_F(EndToEndTest, RendersSingleDelayedFrame) {
Renderer() : event_(EventWrapper::Create()) {}
virtual void RenderFrame(const I420VideoFrame& video_frame,
int /*time_to_render_ms*/) OVERRIDE {
int /*time_to_render_ms*/) override {
event_->Set();
}
virtual bool IsTextureSupported() const override { return false; }
EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
scoped_ptr<EventWrapper> event_;
@ -138,7 +140,7 @@ TEST_F(EndToEndTest, RendersSingleDelayedFrame) {
EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
private:
virtual void FrameCallback(I420VideoFrame* frame) OVERRIDE {
virtual void FrameCallback(I420VideoFrame* frame) override {
SleepMs(kDelayRenderCallbackMs);
event_->Set();
}
@ -188,9 +190,10 @@ TEST_F(EndToEndTest, TransmitsFirstFrame) {
Renderer() : event_(EventWrapper::Create()) {}
virtual void RenderFrame(const I420VideoFrame& video_frame,
int /*time_to_render_ms*/) OVERRIDE {
int /*time_to_render_ms*/) override {
event_->Set();
}
virtual bool IsTextureSupported() const override { return false; }
EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
@ -236,7 +239,7 @@ TEST_F(EndToEndTest, SendsAndReceivesVP9) {
decoder_(VP9Decoder::Create()),
frame_counter_(0) {}
virtual void PerformTest() OVERRIDE {
virtual void PerformTest() override {
EXPECT_EQ(kEventSignaled, Wait())
<< "Timed out while waiting for enough frames to be decoded.";
}
@ -244,7 +247,7 @@ TEST_F(EndToEndTest, SendsAndReceivesVP9) {
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) OVERRIDE {
VideoEncoderConfig* encoder_config) override {
send_config->encoder_settings.encoder = encoder_.get();
send_config->encoder_settings.payload_name = "VP9";
send_config->encoder_settings.payload_type = VCM_VP9_PAYLOAD_TYPE;
@ -262,12 +265,14 @@ TEST_F(EndToEndTest, SendsAndReceivesVP9) {
}
virtual void RenderFrame(const I420VideoFrame& video_frame,
int time_to_render_ms) OVERRIDE {
int time_to_render_ms) override {
const int kRequiredFrames = 500;
if (++frame_counter_ == kRequiredFrames)
observation_complete_->Set();
}
virtual bool IsTextureSupported() const override { return false; }
private:
scoped_ptr<webrtc::VideoEncoder> encoder_;
scoped_ptr<webrtc::VideoDecoder> decoder_;
@ -285,7 +290,7 @@ TEST_F(EndToEndTest, SendsAndReceivesH264) {
fake_encoder_(Clock::GetRealTimeClock()),
frame_counter_(0) {}
virtual void PerformTest() OVERRIDE {
virtual void PerformTest() override {
EXPECT_EQ(kEventSignaled, Wait())
<< "Timed out while waiting for enough frames to be decoded.";
}
@ -293,7 +298,7 @@ TEST_F(EndToEndTest, SendsAndReceivesH264) {
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) OVERRIDE {
VideoEncoderConfig* encoder_config) override {
send_config->encoder_settings.encoder = &fake_encoder_;
send_config->encoder_settings.payload_name = "H264";
send_config->encoder_settings.payload_type = kFakeSendPayloadType;
@ -311,12 +316,14 @@ TEST_F(EndToEndTest, SendsAndReceivesH264) {
}
virtual void RenderFrame(const I420VideoFrame& video_frame,
int time_to_render_ms) OVERRIDE {
int time_to_render_ms) override {
const int kRequiredFrames = 500;
if (++frame_counter_ == kRequiredFrames)
observation_complete_->Set();
}
virtual bool IsTextureSupported() const override { return false; }
private:
test::FakeH264Decoder fake_decoder_;
test::FakeH264Encoder fake_encoder_;
@ -332,7 +339,7 @@ TEST_F(EndToEndTest, ReceiverUsesLocalSsrc) {
SyncRtcpObserver() : EndToEndTest(kDefaultTimeoutMs) {}
virtual Action OnReceiveRtcp(const uint8_t* packet,
size_t length) OVERRIDE {
size_t length) override {
RTCPUtility::RTCPParserV2 parser(packet, length, true);
EXPECT_TRUE(parser.IsValid());
uint32_t ssrc = 0;
@ -346,7 +353,7 @@ TEST_F(EndToEndTest, ReceiverUsesLocalSsrc) {
return SEND_PACKET;
}
virtual void PerformTest() OVERRIDE {
virtual void PerformTest() override {
EXPECT_EQ(kEventSignaled, Wait())
<< "Timed out while waiting for a receiver RTCP packet to be sent.";
}
@ -369,7 +376,7 @@ TEST_F(EndToEndTest, ReceivesAndRetransmitsNack) {
nacks_left_(kNumberOfNacksToObserve) {}
private:
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
RTPHeader header;
EXPECT_TRUE(rtp_parser_->Parse(packet, length, &header));
@ -404,7 +411,7 @@ TEST_F(EndToEndTest, ReceivesAndRetransmitsNack) {
}
virtual Action OnReceiveRtcp(const uint8_t* packet,
size_t length) OVERRIDE {
size_t length) override {
RTCPUtility::RTCPParserV2 parser(packet, length, true);
EXPECT_TRUE(parser.IsValid());
@ -422,12 +429,12 @@ TEST_F(EndToEndTest, ReceivesAndRetransmitsNack) {
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) OVERRIDE {
VideoEncoderConfig* encoder_config) override {
send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
(*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
}
virtual void PerformTest() OVERRIDE {
virtual void PerformTest() override {
EXPECT_EQ(kEventSignaled, Wait())
<< "Timed out waiting for packets to be NACKed, retransmitted and "
"rendered.";
@ -451,7 +458,7 @@ TEST_F(EndToEndTest, CanReceiveFec) {
: EndToEndTest(kDefaultTimeoutMs), state_(kFirstPacket) {}
private:
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE
virtual Action OnSendRtp(const uint8_t* packet, size_t length) override
EXCLUSIVE_LOCKS_REQUIRED(crit_) {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
@ -496,7 +503,7 @@ TEST_F(EndToEndTest, CanReceiveFec) {
}
virtual void RenderFrame(const I420VideoFrame& video_frame,
int time_to_render_ms) OVERRIDE {
int time_to_render_ms) override {
CriticalSectionScoped lock(crit_.get());
// Rendering frame with timestamp of packet that was dropped -> FEC
// protection worked.
@ -504,6 +511,8 @@ TEST_F(EndToEndTest, CanReceiveFec) {
observation_complete_->Set();
}
virtual bool IsTextureSupported() const override { return false; }
enum {
kFirstPacket,
kDropEveryOtherPacketUntilFec,
@ -513,7 +522,7 @@ TEST_F(EndToEndTest, CanReceiveFec) {
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) OVERRIDE {
VideoEncoderConfig* encoder_config) override {
// TODO(pbos): Run this test with combined NACK/FEC enabled as well.
// int rtp_history_ms = 1000;
// (*receive_configs)[0].rtp.nack.rtp_history_ms = rtp_history_ms;
@ -526,7 +535,7 @@ TEST_F(EndToEndTest, CanReceiveFec) {
(*receive_configs)[0].renderer = this;
}
virtual void PerformTest() OVERRIDE {
virtual void PerformTest() override {
EXPECT_EQ(kEventSignaled, Wait())
<< "Timed out waiting for dropped frames frames to be rendered.";
}
@ -559,7 +568,7 @@ void EndToEndTest::TestReceivedFecPacketsNotNacked(
last_sequence_number_(0) {}
private:
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
EXPECT_EQ(kRedPayloadType, header.payloadType);
@ -602,8 +611,8 @@ void EndToEndTest::TestReceivedFecPacketsNotNacked(
return SEND_PACKET;
}
virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length)
OVERRIDE {
virtual Action OnReceiveRtcp(const uint8_t* packet,
size_t length) override {
if (state_ == kVerifyFecPacketNotInNackList) {
test::RtcpPacketParser rtcp_parser;
rtcp_parser.Parse(packet, length);
@ -621,7 +630,7 @@ void EndToEndTest::TestReceivedFecPacketsNotNacked(
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) OVERRIDE {
VideoEncoderConfig* encoder_config) override {
// Configure hybrid NACK/FEC.
send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
send_config->rtp.fec.red_payload_type = kRedPayloadType;
@ -631,7 +640,7 @@ void EndToEndTest::TestReceivedFecPacketsNotNacked(
(*receive_configs)[0].rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
}
virtual void PerformTest() OVERRIDE {
virtual void PerformTest() override {
EXPECT_EQ(kEventSignaled, Wait())
<< "Timed out while waiting for FEC packets to be received.";
}
@ -667,7 +676,7 @@ void EndToEndTest::DecodesRetransmittedFrame(bool retransmit_over_rtx) {
frame_retransmitted_(false) {}
private:
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
@ -691,7 +700,7 @@ void EndToEndTest::DecodesRetransmittedFrame(bool retransmit_over_rtx) {
return SEND_PACKET;
}
virtual void FrameCallback(I420VideoFrame* frame) OVERRIDE {
virtual void FrameCallback(I420VideoFrame* frame) override {
CriticalSectionScoped lock(crit_.get());
if (frame->timestamp() == retransmitted_timestamp_) {
EXPECT_TRUE(frame_retransmitted_);
@ -702,7 +711,7 @@ void EndToEndTest::DecodesRetransmittedFrame(bool retransmit_over_rtx) {
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) OVERRIDE {
VideoEncoderConfig* encoder_config) override {
send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
(*receive_configs)[0].pre_render_callback = this;
(*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
@ -716,7 +725,7 @@ void EndToEndTest::DecodesRetransmittedFrame(bool retransmit_over_rtx) {
}
}
virtual void PerformTest() OVERRIDE {
virtual void PerformTest() override {
EXPECT_EQ(kEventSignaled, Wait())
<< "Timed out while waiting for retransmission to render.";
}
@ -748,13 +757,15 @@ TEST_F(EndToEndTest, UsesFrameCallbacks) {
Renderer() : event_(EventWrapper::Create()) {}
virtual void RenderFrame(const I420VideoFrame& video_frame,
int /*time_to_render_ms*/) OVERRIDE {
int /*time_to_render_ms*/) override {
EXPECT_EQ(0, *video_frame.buffer(kYPlane))
<< "Rendered frame should have zero luma which is applied by the "
"pre-render callback.";
event_->Set();
}
virtual bool IsTextureSupported() const override { return false; }
EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
scoped_ptr<EventWrapper> event_;
} renderer;
@ -855,7 +866,7 @@ void EndToEndTest::ReceivesPliAndRecovers(int rtp_history_ms) {
received_pli_(false) {}
private:
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
@ -873,7 +884,7 @@ void EndToEndTest::ReceivesPliAndRecovers(int rtp_history_ms) {
}
virtual Action OnReceiveRtcp(const uint8_t* packet,
size_t length) OVERRIDE {
size_t length) override {
RTCPUtility::RTCPParserV2 parser(packet, length, true);
EXPECT_TRUE(parser.IsValid());
@ -892,7 +903,7 @@ void EndToEndTest::ReceivesPliAndRecovers(int rtp_history_ms) {
}
virtual void RenderFrame(const I420VideoFrame& video_frame,
int time_to_render_ms) OVERRIDE {
int time_to_render_ms) override {
CriticalSectionScoped lock(crit_.get());
if (received_pli_ &&
video_frame.timestamp() > highest_dropped_timestamp_) {
@ -902,16 +913,18 @@ void EndToEndTest::ReceivesPliAndRecovers(int rtp_history_ms) {
frames_to_drop_ = kPacketsToDrop;
}
virtual bool IsTextureSupported() const override { return false; }
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) OVERRIDE {
VideoEncoderConfig* encoder_config) override {
send_config->rtp.nack.rtp_history_ms = rtp_history_ms_;
(*receive_configs)[0].rtp.nack.rtp_history_ms = rtp_history_ms_;
(*receive_configs)[0].renderer = this;
}
virtual void PerformTest() OVERRIDE {
virtual void PerformTest() override {
EXPECT_EQ(kEventSignaled, Wait()) << "Timed out waiting for PLI to be "
"received and a frame to be "
"rendered afterwards.";
@ -948,7 +961,7 @@ TEST_F(EndToEndTest, UnknownRtpPacketGivesUnknownSsrcReturnCode) {
private:
virtual DeliveryStatus DeliverPacket(const uint8_t* packet,
size_t length) OVERRIDE {
size_t length) override {
if (RtpHeaderParser::IsRtcp(packet, length)) {
return receiver_->DeliverPacket(packet, length);
} else {
@ -1004,7 +1017,7 @@ void EndToEndTest::RespectsRtcpMode(newapi::RtcpMode rtcp_mode) {
sent_rtcp_(0) {}
private:
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
if (++sent_rtp_ % 3 == 0)
return DROP_PACKET;
@ -1012,7 +1025,7 @@ void EndToEndTest::RespectsRtcpMode(newapi::RtcpMode rtcp_mode) {
}
virtual Action OnReceiveRtcp(const uint8_t* packet,
size_t length) OVERRIDE {
size_t length) override {
++sent_rtcp_;
RTCPUtility::RTCPParserV2 parser(packet, length, true);
EXPECT_TRUE(parser.IsValid());
@ -1052,13 +1065,13 @@ void EndToEndTest::RespectsRtcpMode(newapi::RtcpMode rtcp_mode) {
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) OVERRIDE {
VideoEncoderConfig* encoder_config) override {
send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
(*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
(*receive_configs)[0].rtp.rtcp_mode = rtcp_mode_;
}
virtual void PerformTest() OVERRIDE {
virtual void PerformTest() override {
EXPECT_EQ(kEventSignaled, Wait())
<< (rtcp_mode_ == newapi::kRtcpCompound
? "Timed out before observing enough compound packets."
@ -1099,13 +1112,15 @@ TEST_F(EndToEndTest, SendsAndReceivesMultipleStreams) {
done_(EventWrapper::Create()) {}
virtual void RenderFrame(const I420VideoFrame& video_frame,
int time_to_render_ms) OVERRIDE {
int time_to_render_ms) override {
EXPECT_EQ(width_, video_frame.width());
EXPECT_EQ(height_, video_frame.height());
(*capturer_)->Stop();
done_->Set();
}
virtual bool IsTextureSupported() const override { return false; }
EventTypeWrapper Wait() { return done_->Wait(kDefaultTimeoutMs); }
private:
@ -1276,7 +1291,7 @@ TEST_F(EndToEndTest, ReceiveStreamSendsRemb) {
RembObserver() : EndToEndTest(kDefaultTimeoutMs) {}
virtual Action OnReceiveRtcp(const uint8_t* packet,
size_t length) OVERRIDE {
size_t length) override {
RTCPUtility::RTCPParserV2 parser(packet, length, true);
EXPECT_TRUE(parser.IsValid());
@ -1301,7 +1316,7 @@ TEST_F(EndToEndTest, ReceiveStreamSendsRemb) {
observation_complete_->Set();
return SEND_PACKET;
}
virtual void PerformTest() OVERRIDE {
virtual void PerformTest() override {
EXPECT_EQ(kEventSignaled, Wait()) << "Timed out while waiting for a "
"receiver RTCP REMB packet to be "
"sent.";
@ -1321,7 +1336,7 @@ TEST_F(EndToEndTest, VerifyBandwidthStats) {
has_seen_pacer_delay_(false) {}
virtual DeliveryStatus DeliverPacket(const uint8_t* packet,
size_t length) OVERRIDE {
size_t length) override {
Call::Stats sender_stats = sender_call_->GetStats();
Call::Stats receiver_stats = receiver_call_->GetStats();
if (!has_seen_pacer_delay_)
@ -1334,19 +1349,19 @@ TEST_F(EndToEndTest, VerifyBandwidthStats) {
}
virtual void OnCallsCreated(Call* sender_call,
Call* receiver_call) OVERRIDE {
Call* receiver_call) override {
sender_call_ = sender_call;
receiver_call_ = receiver_call;
}
virtual void PerformTest() OVERRIDE {
virtual void PerformTest() override {
EXPECT_EQ(kEventSignaled, Wait()) << "Timed out while waiting for "
"non-zero bandwidth stats.";
}
virtual void SetReceivers(
PacketReceiver* send_transport_receiver,
PacketReceiver* receive_transport_receiver) OVERRIDE {
PacketReceiver* receive_transport_receiver) override {
test::RtpRtcpObserver::SetReceivers(this, receive_transport_receiver);
}
@ -1374,7 +1389,7 @@ void EndToEndTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) {
private:
// Receive stream should send RR packets (and RRTR packets if enabled).
virtual Action OnReceiveRtcp(const uint8_t* packet,
size_t length) OVERRIDE {
size_t length) override {
RTCPUtility::RTCPParserV2 parser(packet, length, true);
EXPECT_TRUE(parser.IsValid());
@ -1424,13 +1439,13 @@ void EndToEndTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) {
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) OVERRIDE {
VideoEncoderConfig* encoder_config) override {
(*receive_configs)[0].rtp.rtcp_mode = newapi::kRtcpReducedSize;
(*receive_configs)[0].rtp.rtcp_xr.receiver_reference_time_report =
enable_rrtr_;
}
virtual void PerformTest() OVERRIDE {
virtual void PerformTest() override {
EXPECT_EQ(kEventSignaled, Wait())
<< "Timed out while waiting for RTCP SR/RR packets to be sent.";
}
@ -1462,7 +1477,7 @@ void EndToEndTest::TestSendsSetSsrcs(size_t num_ssrcs,
}
private:
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
@ -1487,12 +1502,12 @@ void EndToEndTest::TestSendsSetSsrcs(size_t num_ssrcs,
return SEND_PACKET;
}
virtual size_t GetNumStreams() const OVERRIDE { return num_ssrcs_; }
virtual size_t GetNumStreams() const override { return num_ssrcs_; }
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) OVERRIDE {
VideoEncoderConfig* encoder_config) override {
if (num_ssrcs_ > 1) {
// Set low simulcast bitrates to not have to wait for bandwidth ramp-up.
for (size_t i = 0; i < encoder_config->streams.size(); ++i) {
@ -1509,11 +1524,11 @@ void EndToEndTest::TestSendsSetSsrcs(size_t num_ssrcs,
virtual void OnStreamsCreated(
VideoSendStream* send_stream,
const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE {
const std::vector<VideoReceiveStream*>& receive_streams) override {
send_stream_ = send_stream;
}
virtual void PerformTest() OVERRIDE {
virtual void PerformTest() override {
EXPECT_EQ(kEventSignaled, Wait())
<< "Timed out while waiting for "
<< (send_single_ssrc_first_ ? "first SSRC." : "SSRCs.");
@ -1556,28 +1571,28 @@ TEST_F(EndToEndTest, GetStats) {
check_stats_event_(EventWrapper::Create()) {}
private:
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
check_stats_event_->Set();
return SEND_PACKET;
}
virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
virtual Action OnSendRtcp(const uint8_t* packet, size_t length) override {
check_stats_event_->Set();
return SEND_PACKET;
}
virtual Action OnReceiveRtp(const uint8_t* packet, size_t length) OVERRIDE {
virtual Action OnReceiveRtp(const uint8_t* packet, size_t length) override {
check_stats_event_->Set();
return SEND_PACKET;
}
virtual Action OnReceiveRtcp(const uint8_t* packet,
size_t length) OVERRIDE {
size_t length) override {
check_stats_event_->Set();
return SEND_PACKET;
}
virtual void FrameCallback(I420VideoFrame* video_frame) OVERRIDE {
virtual void FrameCallback(I420VideoFrame* video_frame) override {
// Ensure that we have at least 5ms send side delay.
int64_t render_time = video_frame->render_time_ms();
if (render_time > 0)
@ -1687,7 +1702,7 @@ TEST_F(EndToEndTest, GetStats) {
return true;
}
Call::Config GetSenderCallConfig() OVERRIDE {
Call::Config GetSenderCallConfig() override {
Call::Config config = EndToEndTest::GetSenderCallConfig();
config.stream_bitrates.start_bitrate_bps = kStartBitrateBps;
return config;
@ -1696,7 +1711,7 @@ TEST_F(EndToEndTest, GetStats) {
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) OVERRIDE {
VideoEncoderConfig* encoder_config) override {
send_config->pre_encode_callback = this; // Used to inject delay.
send_config->rtp.c_name = "SomeCName";
@ -1708,16 +1723,16 @@ TEST_F(EndToEndTest, GetStats) {
expected_cname_ = send_config->rtp.c_name;
}
virtual size_t GetNumStreams() const OVERRIDE { return kNumSsrcs; }
virtual size_t GetNumStreams() const override { return kNumSsrcs; }
virtual void OnStreamsCreated(
VideoSendStream* send_stream,
const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE {
const std::vector<VideoReceiveStream*>& receive_streams) override {
send_stream_ = send_stream;
receive_stream_ = receive_streams[0];
}
virtual void PerformTest() OVERRIDE {
virtual void PerformTest() override {
Clock* clock = Clock::GetRealTimeClock();
int64_t now = clock->TimeInMilliseconds();
int64_t stop_time = now + test::CallTest::kLongTimeoutMs;
@ -1795,11 +1810,11 @@ TEST_F(EndToEndTest, TestReceivedRtpPacketStats) {
private:
virtual void OnStreamsCreated(
VideoSendStream* send_stream,
const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE {
const std::vector<VideoReceiveStream*>& receive_streams) override {
receive_stream_ = receive_streams[0];
}
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
if (sent_rtp_ >= kNumRtpPacketsToSend) {
VideoReceiveStream::Stats stats = receive_stream_->GetStats();
if (kNumRtpPacketsToSend == stats.rtp_stats.transmitted.packets) {
@ -1811,7 +1826,7 @@ TEST_F(EndToEndTest, TestReceivedRtpPacketStats) {
return SEND_PACKET;
}
virtual void PerformTest() OVERRIDE {
virtual void PerformTest() override {
EXPECT_EQ(kEventSignaled, Wait())
<< "Timed out while verifying number of received RTP packets.";
}
@ -1844,7 +1859,7 @@ TEST_F(EndToEndTest, DISABLED_RedundantPayloadsTransmittedOnAllSsrcs) {
}
private:
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
@ -1867,12 +1882,12 @@ TEST_F(EndToEndTest, DISABLED_RedundantPayloadsTransmittedOnAllSsrcs) {
return SEND_PACKET;
}
virtual size_t GetNumStreams() const OVERRIDE { return kNumSsrcs; }
virtual size_t GetNumStreams() const override { return kNumSsrcs; }
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) OVERRIDE {
VideoEncoderConfig* encoder_config) override {
// Set low simulcast bitrates to not have to wait for bandwidth ramp-up.
for (size_t i = 0; i < encoder_config->streams.size(); ++i) {
encoder_config->streams[i].min_bitrate_bps = 10000;
@ -1890,7 +1905,7 @@ TEST_F(EndToEndTest, DISABLED_RedundantPayloadsTransmittedOnAllSsrcs) {
encoder_config->min_transmit_bitrate_bps = 100000;
}
virtual void PerformTest() OVERRIDE {
virtual void PerformTest() override {
EXPECT_EQ(kEventSignaled, Wait())
<< "Timed out while waiting for redundant payloads on all SSRCs.";
}
@ -1927,7 +1942,7 @@ void EndToEndTest::TestRtpStatePreservation(bool use_rtx) {
}
private:
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
RTPHeader header;
EXPECT_TRUE(parser_->Parse(packet, length, &header));
const uint32_t ssrc = header.ssrc;
@ -2114,7 +2129,7 @@ TEST_F(EndToEndTest, RespectsNetworkState) {
down_receiver_rtcp_(0),
down_frames_(0) {}
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
CriticalSectionScoped lock(test_crit_.get());
if (sender_state_ == Call::kNetworkDown) {
++down_sender_rtp_;
@ -2128,7 +2143,7 @@ TEST_F(EndToEndTest, RespectsNetworkState) {
return SEND_PACKET;
}
virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
virtual Action OnSendRtcp(const uint8_t* packet, size_t length) override {
CriticalSectionScoped lock(test_crit_.get());
if (sender_state_ == Call::kNetworkDown) {
++down_sender_rtcp_;
@ -2142,13 +2157,13 @@ TEST_F(EndToEndTest, RespectsNetworkState) {
return SEND_PACKET;
}
virtual Action OnReceiveRtp(const uint8_t* packet, size_t length) OVERRIDE {
virtual Action OnReceiveRtp(const uint8_t* packet, size_t length) override {
ADD_FAILURE() << "Unexpected receiver RTP, should not be sending.";
return SEND_PACKET;
}
virtual Action OnReceiveRtcp(const uint8_t* packet,
size_t length) OVERRIDE {
size_t length) override {
CriticalSectionScoped lock(test_crit_.get());
if (receiver_state_ == Call::kNetworkDown) {
++down_receiver_rtcp_;
@ -2163,7 +2178,7 @@ TEST_F(EndToEndTest, RespectsNetworkState) {
}
virtual void OnCallsCreated(Call* sender_call,
Call* receiver_call) OVERRIDE {
Call* receiver_call) override {
sender_call_ = sender_call;
receiver_call_ = receiver_call;
}
@ -2171,11 +2186,11 @@ TEST_F(EndToEndTest, RespectsNetworkState) {
virtual void ModifyConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) OVERRIDE {
VideoEncoderConfig* encoder_config) override {
send_config->encoder_settings.encoder = this;
}
virtual void PerformTest() OVERRIDE {
virtual void PerformTest() override {
EXPECT_EQ(kEventSignaled, encoded_frames_->Wait(kDefaultTimeoutMs))
<< "No frames received by the encoder.";
EXPECT_EQ(kEventSignaled, sender_packets_->Wait(kDefaultTimeoutMs))
@ -2219,10 +2234,10 @@ TEST_F(EndToEndTest, RespectsNetworkState) {
<< "Timed out waiting for receiver-side packets.";
}
virtual int32_t Encode(const I420VideoFrame& input_image,
const CodecSpecificInfo* codec_specific_info,
const std::vector<VideoFrameType>* frame_types)
OVERRIDE {
virtual int32_t Encode(
const I420VideoFrame& input_image,
const CodecSpecificInfo* codec_specific_info,
const std::vector<VideoFrameType>* frame_types) override {
{
CriticalSectionScoped lock(test_crit_.get());
if (sender_state_ == Call::kNetworkDown) {
@ -2301,10 +2316,10 @@ TEST_F(EndToEndTest, NewSendStreamsRespectNetworkDown) {
class UnusedEncoder : public test::FakeEncoder {
public:
UnusedEncoder() : FakeEncoder(Clock::GetRealTimeClock()) {}
virtual int32_t Encode(const I420VideoFrame& input_image,
const CodecSpecificInfo* codec_specific_info,
const std::vector<VideoFrameType>* frame_types)
OVERRIDE {
virtual int32_t Encode(
const I420VideoFrame& input_image,
const CodecSpecificInfo* codec_specific_info,
const std::vector<VideoFrameType>* frame_types) override {
ADD_FAILURE() << "Unexpected frame encode.";
return test::FakeEncoder::Encode(
input_image, codec_specific_info, frame_types);

View File

@ -191,6 +191,8 @@ class VideoAnalyzer : public PacketReceiver,
last_rendered_frame_.CopyFrame(video_frame);
}
virtual bool IsTextureSupported() const override { return false; }
void Wait() {
EXPECT_EQ(kEventSignaled, done_->Wait(FullStackTest::kLongTimeoutMs));
}

View File

@ -174,6 +174,8 @@ class FileRenderPassthrough : public VideoRenderer {
PrintI420VideoFrame(video_frame, file_);
}
virtual bool IsTextureSupported() const override { return false; }
const std::string basename_;
VideoRenderer* const renderer_;
FILE* file_;

View File

@ -15,6 +15,7 @@
#include <string>
#include "webrtc/base/checks.h"
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/system_wrappers/interface/clock.h"
#include "webrtc/system_wrappers/interface/logging.h"
@ -259,7 +260,7 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine,
render_ = ViERender::GetInterface(video_engine);
assert(render_ != NULL);
render_->AddRenderCallback(channel_, this);
render_->AddRenderer(channel_, kVideoI420, this);
if (voice_engine && config_.audio_channel_id != -1) {
video_engine_base_->SetVoiceEngine(voice_engine);
@ -343,18 +344,40 @@ void VideoReceiveStream::FrameCallback(I420VideoFrame* video_frame) {
config_.pre_render_callback->FrameCallback(video_frame);
}
int32_t VideoReceiveStream::RenderFrame(const uint32_t stream_id,
I420VideoFrame& video_frame) {
int VideoReceiveStream::FrameSizeChange(unsigned int width,
unsigned int height,
unsigned int number_of_streams) {
return 0;
}
int VideoReceiveStream::DeliverFrame(unsigned char* buffer,
size_t buffer_size,
uint32_t timestamp,
int64_t ntp_time_ms,
int64_t render_time_ms,
void* handle) {
CHECK(false) << "Renderer should be configured as kVideoI420 and never "
"receive callbacks on DeliverFrame.";
return 0;
}
int VideoReceiveStream::DeliverI420Frame(const I420VideoFrame* video_frame) {
if (config_.renderer != NULL)
config_.renderer->RenderFrame(
video_frame,
video_frame.render_time_ms() - clock_->TimeInMilliseconds());
*video_frame,
video_frame->render_time_ms() - clock_->TimeInMilliseconds());
stats_proxy_->OnRenderedFrame();
return 0;
}
bool VideoReceiveStream::IsTextureSupported() {
if (config_.renderer == NULL)
return false;
return config_.renderer->IsTextureSupported();
}
void VideoReceiveStream::SignalNetworkState(Call::NetworkState state) {
if (state == Call::kNetworkUp)
SetRtcpMode(config_.rtp.rtcp_mode);

View File

@ -40,7 +40,7 @@ namespace internal {
class VideoReceiveStream : public webrtc::VideoReceiveStream,
public I420FrameCallback,
public VideoRenderCallback {
public ExternalRenderer {
public:
VideoReceiveStream(webrtc::VideoEngine* video_engine,
const VideoReceiveStream::Config& config,
@ -49,16 +49,25 @@ class VideoReceiveStream : public webrtc::VideoReceiveStream,
int base_channel);
virtual ~VideoReceiveStream();
virtual void Start() OVERRIDE;
virtual void Stop() OVERRIDE;
virtual Stats GetStats() const OVERRIDE;
virtual void Start() override;
virtual void Stop() override;
virtual Stats GetStats() const override;
// Overrides I420FrameCallback.
virtual void FrameCallback(I420VideoFrame* video_frame) OVERRIDE;
virtual void FrameCallback(I420VideoFrame* video_frame) override;
// Overrides VideoRenderCallback.
virtual int32_t RenderFrame(const uint32_t stream_id,
I420VideoFrame& video_frame) OVERRIDE;
// Overrides ExternalRenderer.
virtual int FrameSizeChange(unsigned int width,
unsigned int height,
unsigned int number_of_streams) override;
virtual int DeliverFrame(unsigned char* buffer,
size_t buffer_size,
uint32_t timestamp,
int64_t ntp_time_ms,
int64_t render_time_ms,
void* handle) override;
virtual int DeliverI420Frame(const I420VideoFrame* webrtc_frame) override;
virtual bool IsTextureSupported() override;
void SignalNetworkState(Call::NetworkState state);

View File

@ -119,13 +119,6 @@ class ViERender {
RawVideoType video_input_format,
ExternalRenderer* renderer) = 0;
// Propagating VideoRenderCallback down to the VideoRender module for new API.
// Contains default-implementation not to break code mocking this interface.
// (Ugly, but temporary.)
virtual int AddRenderCallback(int render_id, VideoRenderCallback* callback) {
return 0;
}
protected:
ViERender() {}
virtual ~ViERender() {}

View File

@ -323,29 +323,4 @@ int ViERenderImpl::AddRenderer(const int render_id,
}
}
int ViERenderImpl::AddRenderCallback(int render_id,
VideoRenderCallback* callback) {
if (render_id < kViEChannelIdBase || render_id > kViEChannelIdMax)
return -1;
// This is a channel.
ViEChannelManagerScoped cm(*(shared_data_->channel_manager()));
ViEFrameProviderBase* frame_provider = cm.Channel(render_id);
if (!frame_provider) {
shared_data_->SetLastError(kViERenderInvalidRenderId);
return -1;
}
ViERenderer* renderer = shared_data_->render_manager()->AddRenderStream(
render_id, NULL, 0, 0.0f, 0.0f, 1.0f, 1.0f);
if (!renderer) {
shared_data_->SetLastError(kViERenderUnknownError);
return -1;
}
if (renderer->SetVideoRenderCallback(render_id, callback) != 0) {
shared_data_->SetLastError(kViERenderUnknownError);
return -1;
}
return frame_provider->RegisterFrameCallback(render_id, renderer);
}
} // namespace webrtc

View File

@ -45,8 +45,6 @@ class ViERenderImpl
const bool mirror_yaxis);
virtual int AddRenderer(const int render_id, RawVideoType video_input_format,
ExternalRenderer* renderer);
virtual int AddRenderCallback(int render_id,
VideoRenderCallback* callback) OVERRIDE;
protected:
explicit ViERenderImpl(ViESharedData* shared_data);

View File

@ -23,6 +23,8 @@ class VideoRenderer {
virtual void RenderFrame(const I420VideoFrame& video_frame,
int time_to_render_ms) = 0;
virtual bool IsTextureSupported() const = 0;
protected:
virtual ~VideoRenderer() {}
};