// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "media/cast/net/rtcp/receiver_rtcp_event_subscriber.h" #include #include #include #include #include "base/memory/ref_counted.h" #include "base/test/simple_test_tick_clock.h" #include "base/time/tick_clock.h" #include "media/base/fake_single_thread_task_runner.h" #include "media/cast/cast_environment.h" #include "media/cast/logging/logging_defines.h" #include "testing/gtest/include/gtest/gtest.h" namespace media { namespace cast { namespace { const size_t kMaxEventEntries = 10u; const int64_t kDelayMs = 20L; } // namespace class ReceiverRtcpEventSubscriberTest : public ::testing::Test { protected: ReceiverRtcpEventSubscriberTest() : task_runner_(new FakeSingleThreadTaskRunner(&testing_clock_)), cast_environment_(new CastEnvironment(&testing_clock_, task_runner_, task_runner_, task_runner_)) {} ~ReceiverRtcpEventSubscriberTest() override = default; void TearDown() final { if (event_subscriber_) { cast_environment_->logger()->Unsubscribe(event_subscriber_.get()); event_subscriber_.reset(); } } void Init(EventMediaType type) { event_subscriber_ = std::make_unique(kMaxEventEntries, type); cast_environment_->logger()->Subscribe(event_subscriber_.get()); } void InsertEvents() { // Video events std::unique_ptr playout_event(new FrameEvent()); playout_event->timestamp = testing_clock_.NowTicks(); playout_event->type = FRAME_PLAYOUT; playout_event->media_type = VIDEO_EVENT; playout_event->rtp_timestamp = RtpTimeTicks().Expand(UINT32_C(100)); playout_event->frame_id = FrameId::first() + 2; playout_event->delay_delta = base::Milliseconds(kDelayMs); cast_environment_->logger()->DispatchFrameEvent(std::move(playout_event)); std::unique_ptr decode_event(new FrameEvent()); decode_event->timestamp = testing_clock_.NowTicks(); decode_event->type = FRAME_DECODED; decode_event->media_type = VIDEO_EVENT; decode_event->rtp_timestamp = RtpTimeTicks().Expand(UINT32_C(200)); decode_event->frame_id = FrameId::first() + 1; cast_environment_->logger()->DispatchFrameEvent(std::move(decode_event)); std::unique_ptr receive_event(new PacketEvent()); receive_event->timestamp = testing_clock_.NowTicks(); receive_event->type = PACKET_RECEIVED; receive_event->media_type = VIDEO_EVENT; receive_event->rtp_timestamp = RtpTimeTicks().Expand(UINT32_C(200)); receive_event->frame_id = FrameId::first() + 2; receive_event->packet_id = 1u; receive_event->max_packet_id = 10u; receive_event->size = 1024u; cast_environment_->logger()->DispatchPacketEvent(std::move(receive_event)); // Audio events playout_event = std::make_unique(); playout_event->timestamp = testing_clock_.NowTicks(); playout_event->type = FRAME_PLAYOUT; playout_event->media_type = AUDIO_EVENT; playout_event->rtp_timestamp = RtpTimeTicks().Expand(UINT32_C(300)); playout_event->frame_id = FrameId::first() + 4; playout_event->delay_delta = base::Milliseconds(kDelayMs); cast_environment_->logger()->DispatchFrameEvent(std::move(playout_event)); decode_event = std::make_unique(); decode_event->timestamp = testing_clock_.NowTicks(); decode_event->type = FRAME_DECODED; decode_event->media_type = AUDIO_EVENT; decode_event->rtp_timestamp = RtpTimeTicks().Expand(UINT32_C(400)); decode_event->frame_id = FrameId::first() + 3; cast_environment_->logger()->DispatchFrameEvent(std::move(decode_event)); receive_event = std::make_unique(); receive_event->timestamp = testing_clock_.NowTicks(); receive_event->type = PACKET_RECEIVED; receive_event->media_type = AUDIO_EVENT; receive_event->rtp_timestamp = RtpTimeTicks().Expand(UINT32_C(400)); receive_event->frame_id = FrameId::first() + 5; receive_event->packet_id = 1u; receive_event->max_packet_id = 10u; receive_event->size = 128u; cast_environment_->logger()->DispatchPacketEvent(std::move(receive_event)); // Unrelated events std::unique_ptr encode_event(new FrameEvent()); encode_event->timestamp = testing_clock_.NowTicks(); encode_event->type = FRAME_ENCODED; encode_event->media_type = VIDEO_EVENT; encode_event->rtp_timestamp = RtpTimeTicks().Expand(UINT32_C(100)); encode_event->frame_id = FrameId::first() + 1; cast_environment_->logger()->DispatchFrameEvent(std::move(encode_event)); encode_event = std::make_unique(); encode_event->timestamp = testing_clock_.NowTicks(); encode_event->type = FRAME_ENCODED; encode_event->media_type = AUDIO_EVENT; encode_event->rtp_timestamp = RtpTimeTicks().Expand(UINT32_C(100)); encode_event->frame_id = FrameId::first() + 1; cast_environment_->logger()->DispatchFrameEvent(std::move(encode_event)); } base::SimpleTestTickClock testing_clock_; scoped_refptr task_runner_; scoped_refptr cast_environment_; std::unique_ptr event_subscriber_; }; TEST_F(ReceiverRtcpEventSubscriberTest, LogVideoEvents) { Init(VIDEO_EVENT); InsertEvents(); ReceiverRtcpEventSubscriber::RtcpEvents rtcp_events; event_subscriber_->GetRtcpEventsWithRedundancy(&rtcp_events); EXPECT_EQ(3u, rtcp_events.size()); } TEST_F(ReceiverRtcpEventSubscriberTest, LogAudioEvents) { Init(AUDIO_EVENT); InsertEvents(); ReceiverRtcpEventSubscriber::RtcpEvents rtcp_events; event_subscriber_->GetRtcpEventsWithRedundancy(&rtcp_events); EXPECT_EQ(3u, rtcp_events.size()); } TEST_F(ReceiverRtcpEventSubscriberTest, DropEventsWhenSizeExceeded) { Init(VIDEO_EVENT); for (int i = 1; i <= 10; ++i) { std::unique_ptr decode_event(new FrameEvent()); decode_event->timestamp = testing_clock_.NowTicks(); decode_event->type = FRAME_DECODED; decode_event->media_type = VIDEO_EVENT; decode_event->rtp_timestamp = RtpTimeTicks().Expand(static_cast(i * 10)); decode_event->frame_id = FrameId::first() + i; cast_environment_->logger()->DispatchFrameEvent(std::move(decode_event)); } ReceiverRtcpEventSubscriber::RtcpEvents rtcp_events; event_subscriber_->GetRtcpEventsWithRedundancy(&rtcp_events); EXPECT_EQ(10u, rtcp_events.size()); } } // namespace cast } // namespace media