summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source_test.cc')
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source_test.cc234
1 files changed, 234 insertions, 0 deletions
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source_test.cc
new file mode 100644
index 00000000000..2e9aa9ddfbf
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source_test.cc
@@ -0,0 +1,234 @@
+// 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 "third_party/blink/public/web/modules/peerconnection/media_stream_remote_video_source.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
+#include "base/synchronization/waitable_event.h"
+#include "media/base/video_frame.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/mediastream/media_stream.mojom-blink.h"
+#include "third_party/blink/public/platform/modules/webrtc/track_observer.h"
+#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
+#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
+#include "third_party/blink/public/web/modules/mediastream/mock_media_stream_video_sink.h"
+#include "third_party/blink/public/web/modules/peerconnection/mock_peer_connection_dependency_factory.h"
+#include "third_party/blink/public/web/web_heap.h"
+#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h"
+#include "third_party/webrtc/api/video/color_space.h"
+#include "third_party/webrtc/api/video/i420_buffer.h"
+#include "ui/gfx/color_space.h"
+
+namespace blink {
+
+ACTION_P(RunClosure, closure) {
+ closure.Run();
+}
+
+class MediaStreamRemoteVideoSourceUnderTest
+ : public blink::MediaStreamRemoteVideoSource {
+ public:
+ explicit MediaStreamRemoteVideoSourceUnderTest(
+ std::unique_ptr<blink::TrackObserver> observer)
+ : MediaStreamRemoteVideoSource(std::move(observer)) {}
+ using MediaStreamRemoteVideoSource::SinkInterfaceForTesting;
+ using MediaStreamRemoteVideoSource::StartSourceImpl;
+};
+
+class MediaStreamRemoteVideoSourceTest : public ::testing::Test {
+ public:
+ MediaStreamRemoteVideoSourceTest()
+ : mock_factory_(new blink::MockPeerConnectionDependencyFactory()),
+ webrtc_video_track_(blink::MockWebRtcVideoTrack::Create("test")),
+ remote_source_(nullptr),
+ number_of_successful_track_starts_(0),
+ number_of_failed_track_starts_(0) {}
+
+ void SetUp() override {
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread =
+ blink::scheduler::GetSingleThreadTaskRunnerForTesting();
+
+ base::WaitableEvent waitable_event(
+ base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
+
+ std::unique_ptr<blink::TrackObserver> track_observer;
+ mock_factory_->GetWebRtcSignalingTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](scoped_refptr<base::SingleThreadTaskRunner> main_thread,
+ webrtc::MediaStreamTrackInterface* webrtc_track,
+ std::unique_ptr<blink::TrackObserver>* track_observer,
+ base::WaitableEvent* waitable_event) {
+ track_observer->reset(
+ new blink::TrackObserver(main_thread, webrtc_track));
+ waitable_event->Signal();
+ },
+ main_thread, base::Unretained(webrtc_video_track_.get()),
+ base::Unretained(&track_observer),
+ base::Unretained(&waitable_event)));
+ waitable_event.Wait();
+
+ remote_source_ =
+ new MediaStreamRemoteVideoSourceUnderTest(std::move(track_observer));
+ web_source_.Initialize(blink::WebString::FromASCII("dummy_source_id"),
+ blink::WebMediaStreamSource::kTypeVideo,
+ blink::WebString::FromASCII("dummy_source_name"),
+ true /* remote */);
+ web_source_.SetPlatformSource(base::WrapUnique(remote_source_));
+ }
+
+ void TearDown() override {
+ remote_source_->OnSourceTerminated();
+ web_source_.Reset();
+ blink::WebHeap::CollectAllGarbageForTesting();
+ }
+
+ MediaStreamRemoteVideoSourceUnderTest* source() { return remote_source_; }
+
+ blink::MediaStreamVideoTrack* CreateTrack() {
+ bool enabled = true;
+ return new blink::MediaStreamVideoTrack(
+ source(),
+ base::Bind(&MediaStreamRemoteVideoSourceTest::OnTrackStarted,
+ base::Unretained(this)),
+ enabled);
+ }
+
+ int NumberOfSuccessConstraintsCallbacks() const {
+ return number_of_successful_track_starts_;
+ }
+
+ int NumberOfFailedConstraintsCallbacks() const {
+ return number_of_failed_track_starts_;
+ }
+
+ void StopWebRtcTrack() {
+ base::WaitableEvent waitable_event(
+ base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
+ mock_factory_->GetWebRtcSignalingTaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](blink::MockWebRtcVideoTrack* video_track,
+ base::WaitableEvent* waitable_event) {
+ video_track->SetEnded();
+ waitable_event->Signal();
+ },
+ base::Unretained(static_cast<blink::MockWebRtcVideoTrack*>(
+ webrtc_video_track_.get())),
+ base::Unretained(&waitable_event)));
+ waitable_event.Wait();
+ }
+
+ const blink::WebMediaStreamSource& webkit_source() const {
+ return web_source_;
+ }
+
+ private:
+ void OnTrackStarted(blink::WebPlatformMediaStreamSource* source,
+ blink::mojom::MediaStreamRequestResult result,
+ const blink::WebString& result_name) {
+ ASSERT_EQ(source, remote_source_);
+ if (result == blink::mojom::MediaStreamRequestResult::OK)
+ ++number_of_successful_track_starts_;
+ else
+ ++number_of_failed_track_starts_;
+ }
+
+ ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_;
+ std::unique_ptr<blink::MockPeerConnectionDependencyFactory> mock_factory_;
+ scoped_refptr<webrtc::VideoTrackInterface> webrtc_video_track_;
+ // |remote_source_| is owned by |web_source_|.
+ MediaStreamRemoteVideoSourceUnderTest* remote_source_;
+ blink::WebMediaStreamSource web_source_;
+ int number_of_successful_track_starts_;
+ int number_of_failed_track_starts_;
+};
+
+TEST_F(MediaStreamRemoteVideoSourceTest, StartTrack) {
+ std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack());
+ EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
+
+ blink::MockMediaStreamVideoSink sink;
+ track->AddSink(&sink, sink.GetDeliverFrameCB(), false);
+ base::RunLoop run_loop;
+ base::Closure quit_closure = run_loop.QuitClosure();
+ EXPECT_CALL(sink, OnVideoFrame())
+ .WillOnce(RunClosure(std::move(quit_closure)));
+ rtc::scoped_refptr<webrtc::I420Buffer> buffer(
+ new rtc::RefCountedObject<webrtc::I420Buffer>(320, 240));
+
+ webrtc::I420Buffer::SetBlack(buffer);
+
+ source()->SinkInterfaceForTesting()->OnFrame(
+ webrtc::VideoFrame::Builder()
+ .set_video_frame_buffer(buffer)
+ .set_rotation(webrtc::kVideoRotation_0)
+ .set_timestamp_us(1000)
+ .build());
+ run_loop.Run();
+
+ EXPECT_EQ(1, sink.number_of_frames());
+ track->RemoveSink(&sink);
+}
+
+TEST_F(MediaStreamRemoteVideoSourceTest, RemoteTrackStop) {
+ std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack());
+
+ blink::MockMediaStreamVideoSink sink;
+ track->AddSink(&sink, sink.GetDeliverFrameCB(), false);
+ EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateLive, sink.state());
+ EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateLive,
+ webkit_source().GetReadyState());
+ StopWebRtcTrack();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateEnded,
+ webkit_source().GetReadyState());
+ EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateEnded, sink.state());
+
+ track->RemoveSink(&sink);
+}
+
+TEST_F(MediaStreamRemoteVideoSourceTest, PreservesColorSpace) {
+ std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack());
+ blink::MockMediaStreamVideoSink sink;
+ track->AddSink(&sink, sink.GetDeliverFrameCB(), false);
+
+ base::RunLoop run_loop;
+ EXPECT_CALL(sink, OnVideoFrame())
+ .WillOnce(RunClosure(run_loop.QuitClosure()));
+ rtc::scoped_refptr<webrtc::I420Buffer> buffer(
+ new rtc::RefCountedObject<webrtc::I420Buffer>(320, 240));
+ webrtc::ColorSpace kColorSpace(webrtc::ColorSpace::PrimaryID::kSMPTE240M,
+ webrtc::ColorSpace::TransferID::kSMPTE240M,
+ webrtc::ColorSpace::MatrixID::kSMPTE240M,
+ webrtc::ColorSpace::RangeID::kLimited);
+ const webrtc::VideoFrame& input_frame =
+ webrtc::VideoFrame::Builder()
+ .set_video_frame_buffer(buffer)
+ .set_timestamp_ms(0)
+ .set_rotation(webrtc::kVideoRotation_0)
+ .set_color_space(kColorSpace)
+ .build();
+ source()->SinkInterfaceForTesting()->OnFrame(input_frame);
+ run_loop.Run();
+
+ EXPECT_EQ(1, sink.number_of_frames());
+ scoped_refptr<media::VideoFrame> output_frame = sink.last_frame();
+ EXPECT_TRUE(output_frame);
+ EXPECT_TRUE(output_frame->ColorSpace() ==
+ gfx::ColorSpace(gfx::ColorSpace::PrimaryID::SMPTE240M,
+ gfx::ColorSpace::TransferID::SMPTE240M,
+ gfx::ColorSpace::MatrixID::SMPTE240M,
+ gfx::ColorSpace::RangeID::LIMITED));
+ track->RemoveSink(&sink);
+}
+
+} // namespace blink