| /* |
| * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| #ifndef WEBRTC_VIDEO_ENGINE_TEST_COMMON_RTP_RTCP_OBSERVER_H_ |
| #define WEBRTC_VIDEO_ENGINE_TEST_COMMON_RTP_RTCP_OBSERVER_H_ |
| |
| #include <map> |
| #include <vector> |
| |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| #include "webrtc/base/criticalsection.h" |
| #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" |
| #include "webrtc/test/direct_transport.h" |
| #include "webrtc/typedefs.h" |
| #include "webrtc/video_send_stream.h" |
| |
| namespace webrtc { |
| namespace test { |
| |
| class RtpRtcpObserver { |
| public: |
| virtual ~RtpRtcpObserver() {} |
| newapi::Transport* SendTransport() { |
| return &send_transport_; |
| } |
| |
| newapi::Transport* ReceiveTransport() { |
| return &receive_transport_; |
| } |
| |
| virtual void SetReceivers(PacketReceiver* send_transport_receiver, |
| PacketReceiver* receive_transport_receiver) { |
| send_transport_.SetReceiver(send_transport_receiver); |
| receive_transport_.SetReceiver(receive_transport_receiver); |
| } |
| |
| void StopSending() { |
| send_transport_.StopSending(); |
| receive_transport_.StopSending(); |
| } |
| |
| virtual EventTypeWrapper Wait() { |
| EventTypeWrapper result = observation_complete_->Wait(timeout_ms_); |
| return result; |
| } |
| |
| protected: |
| RtpRtcpObserver(unsigned int event_timeout_ms, |
| const FakeNetworkPipe::Config& configuration) |
| : observation_complete_(EventWrapper::Create()), |
| parser_(RtpHeaderParser::Create()), |
| send_transport_(&crit_, |
| this, |
| &RtpRtcpObserver::OnSendRtp, |
| &RtpRtcpObserver::OnSendRtcp, |
| configuration), |
| receive_transport_(&crit_, |
| this, |
| &RtpRtcpObserver::OnReceiveRtp, |
| &RtpRtcpObserver::OnReceiveRtcp, |
| configuration), |
| timeout_ms_(event_timeout_ms) {} |
| |
| explicit RtpRtcpObserver(unsigned int event_timeout_ms) |
| : observation_complete_(EventWrapper::Create()), |
| parser_(RtpHeaderParser::Create()), |
| send_transport_(&crit_, |
| this, |
| &RtpRtcpObserver::OnSendRtp, |
| &RtpRtcpObserver::OnSendRtcp, |
| FakeNetworkPipe::Config()), |
| receive_transport_(&crit_, |
| this, |
| &RtpRtcpObserver::OnReceiveRtp, |
| &RtpRtcpObserver::OnReceiveRtcp, |
| FakeNetworkPipe::Config()), |
| timeout_ms_(event_timeout_ms) {} |
| |
| enum Action { |
| SEND_PACKET, |
| DROP_PACKET, |
| }; |
| |
| virtual Action OnSendRtp(const uint8_t* packet, size_t length) |
| EXCLUSIVE_LOCKS_REQUIRED(crit_) { |
| return SEND_PACKET; |
| } |
| |
| virtual Action OnSendRtcp(const uint8_t* packet, size_t length) |
| EXCLUSIVE_LOCKS_REQUIRED(crit_) { |
| return SEND_PACKET; |
| } |
| |
| virtual Action OnReceiveRtp(const uint8_t* packet, size_t length) |
| EXCLUSIVE_LOCKS_REQUIRED(crit_) { |
| return SEND_PACKET; |
| } |
| |
| virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) |
| EXCLUSIVE_LOCKS_REQUIRED(crit_) { |
| return SEND_PACKET; |
| } |
| |
| private: |
| class PacketTransport : public test::DirectTransport { |
| public: |
| typedef Action (RtpRtcpObserver::*PacketTransportAction)(const uint8_t*, |
| size_t); |
| |
| PacketTransport(rtc::CriticalSection* lock, |
| RtpRtcpObserver* observer, |
| PacketTransportAction on_rtp, |
| PacketTransportAction on_rtcp, |
| const FakeNetworkPipe::Config& configuration) |
| : test::DirectTransport(configuration), |
| crit_(lock), |
| observer_(observer), |
| on_rtp_(on_rtp), |
| on_rtcp_(on_rtcp) {} |
| |
| private: |
| bool SendRtp(const uint8_t* packet, size_t length) override { |
| EXPECT_FALSE(RtpHeaderParser::IsRtcp(packet, length)); |
| Action action; |
| { |
| rtc::CritScope lock(crit_); |
| action = (observer_->*on_rtp_)(packet, length); |
| } |
| switch (action) { |
| case DROP_PACKET: |
| // Drop packet silently. |
| return true; |
| case SEND_PACKET: |
| return test::DirectTransport::SendRtp(packet, length); |
| } |
| return true; // Will never happen, makes compiler happy. |
| } |
| |
| bool SendRtcp(const uint8_t* packet, size_t length) override { |
| EXPECT_TRUE(RtpHeaderParser::IsRtcp(packet, length)); |
| Action action; |
| { |
| rtc::CritScope lock(crit_); |
| action = (observer_->*on_rtcp_)(packet, length); |
| } |
| switch (action) { |
| case DROP_PACKET: |
| // Drop packet silently. |
| return true; |
| case SEND_PACKET: |
| return test::DirectTransport::SendRtcp(packet, length); |
| } |
| return true; // Will never happen, makes compiler happy. |
| } |
| |
| // Pointer to shared lock instance protecting on_rtp_/on_rtcp_ calls. |
| rtc::CriticalSection* const crit_; |
| |
| RtpRtcpObserver* const observer_; |
| const PacketTransportAction on_rtp_, on_rtcp_; |
| }; |
| |
| protected: |
| rtc::CriticalSection crit_; |
| const rtc::scoped_ptr<EventWrapper> observation_complete_; |
| const rtc::scoped_ptr<RtpHeaderParser> parser_; |
| |
| private: |
| PacketTransport send_transport_, receive_transport_; |
| unsigned int timeout_ms_; |
| }; |
| } // namespace test |
| } // namespace webrtc |
| |
| #endif // WEBRTC_VIDEO_ENGINE_TEST_COMMON_RTP_RTCP_OBSERVER_H_ |