1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// found in the LICENSE file. 4effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/bind.h" 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/bind_helpers.h" 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/callback.h" 8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/message_loop/message_loop.h" 9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/run_loop.h" 10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/strings/utf_string_conversions.h" 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/threading/thread_checker_impl.h" 12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/child/child_process.h" 13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/renderer/media/media_stream_video_track.h" 14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/renderer/media/mock_media_stream_video_sink.h" 15effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/renderer/media/mock_media_stream_video_source.h" 16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "media/base/video_frame.h" 17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "testing/gtest/include/gtest/gtest.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/WebKit/public/web/WebHeap.h" 19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace content { 21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const uint8 kBlackValue = 0x00; 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const uint8 kColorValue = 0xAB; 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ACTION_P(RunClosure, closure) { 26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) closure.Run(); 27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass MediaStreamVideoTrackTest : public ::testing::Test { 30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch public: 31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch MediaStreamVideoTrackTest() 32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : child_process_(new ChildProcess()), 33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mock_source_(new MockMediaStreamVideoSource(false)), 340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch source_started_(false) { 350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch blink_source_.initialize(base::UTF8ToUTF16("dummy_source_id"), 36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blink::WebMediaStreamSource::TypeVideo, 37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::UTF8ToUTF16("dummy_source_name")); 380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch blink_source_.setExtraData(mock_source_); 39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) virtual ~MediaStreamVideoTrackTest() { 42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void TearDown() OVERRIDE { 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blink_source_.reset(); 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blink::WebHeap::collectAllGarbageForTesting(); 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void DeliverVideoFrameAndWaitForRenderer(MockMediaStreamVideoSink* sink) { 50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::RunLoop run_loop; 51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Closure quit_closure = run_loop.QuitClosure(); 52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_CALL(*sink, OnVideoFrame()).WillOnce( 53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RunClosure(quit_closure)); 54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<media::VideoFrame> frame = 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) media::VideoFrame::CreateColorFrame( 56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gfx::Size(MediaStreamVideoSource::kDefaultWidth, 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MediaStreamVideoSource::kDefaultHeight), 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kColorValue, kColorValue, kColorValue, base::TimeDelta()); 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mock_source()->DeliverVideoFrame(frame); 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) run_loop.Run(); 61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch protected: 64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::MessageLoop* io_message_loop() const { 65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return child_process_->io_message_loop(); 66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Create a track that's associated with |mock_source_|. 69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blink::WebMediaStreamTrack CreateTrack() { 70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blink::WebMediaConstraints constraints; 71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch constraints.initialize(); 72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bool enabled = true; 73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blink::WebMediaStreamTrack track = 74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch MediaStreamVideoTrack::CreateVideoTrack( 75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch mock_source_, constraints, 760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch MediaStreamSource::ConstraintsCallback(), enabled); 770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!source_started_) { 780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch mock_source_->StartMockedSource(); 790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch source_started_ = true; 800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return track; 82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch MockMediaStreamVideoSource* mock_source() { return mock_source_; } 850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const blink::WebMediaStreamSource& blink_source() const { 860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return blink_source_; 870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch private: 90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::MessageLoopForUI message_loop_; 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<ChildProcess> child_process_; 920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch blink::WebMediaStreamSource blink_source_; 93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // |mock_source_| is owned by |webkit_source_|. 94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch MockMediaStreamVideoSource* mock_source_; 950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch bool source_started_; 96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}; 97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 98effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_F(MediaStreamVideoTrackTest, AddAndRemoveSink) { 99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch MockMediaStreamVideoSink sink; 100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blink::WebMediaStreamTrack track = CreateTrack(); 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MediaStreamVideoSink::AddToVideoTrack( 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &sink, sink.GetDeliverFrameCB(), track); 103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DeliverVideoFrameAndWaitForRenderer(&sink); 105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_EQ(1, sink.number_of_frames()); 106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DeliverVideoFrameAndWaitForRenderer(&sink); 108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track); 110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_refptr<media::VideoFrame> frame = 112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch media::VideoFrame::CreateBlackFrame( 113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch gfx::Size(MediaStreamVideoSource::kDefaultWidth, 114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch MediaStreamVideoSource::kDefaultHeight)); 115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mock_source()->DeliverVideoFrame(frame); 116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Wait for the IO thread to complete delivering frames. 117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) io_message_loop()->RunUntilIdle(); 118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(2, sink.number_of_frames()); 119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class CheckThreadHelper { 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public: 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CheckThreadHelper(base::Closure callback, bool* correct) 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : callback_(callback), 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) correct_(correct) { 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ~CheckThreadHelper() { 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *correct_ = thread_checker_.CalledOnValidThread(); 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback_.Run(); 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private: 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Closure callback_; 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool* correct_; 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::ThreadCheckerImpl thread_checker_; 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void CheckThreadVideoFrameReceiver( 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CheckThreadHelper* helper, 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const scoped_refptr<media::VideoFrame>& frame, 14246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const media::VideoCaptureFormat& format, 14346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const base::TimeTicks& estimated_capture_time) { 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Do nothing. 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Checks that the callback given to the track is reset on the right thread. 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(MediaStreamVideoTrackTest, ResetCallbackOnThread) { 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MockMediaStreamVideoSink sink; 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) blink::WebMediaStreamTrack track = CreateTrack(); 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::RunLoop run_loop; 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool correct = false; 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MediaStreamVideoSink::AddToVideoTrack( 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &sink, 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind( 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &CheckThreadVideoFrameReceiver, 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Owned(new CheckThreadHelper(run_loop.QuitClosure(), &correct))), 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) track); 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track); 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) run_loop.Run(); 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(correct) << "Not called on correct thread."; 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 165effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_F(MediaStreamVideoTrackTest, SetEnabled) { 166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch MockMediaStreamVideoSink sink; 167effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blink::WebMediaStreamTrack track = CreateTrack(); 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MediaStreamVideoSink::AddToVideoTrack( 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &sink, sink.GetDeliverFrameCB(), track); 170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 171effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch MediaStreamVideoTrack* video_track = 172effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch MediaStreamVideoTrack::GetVideoTrack(track); 173010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DeliverVideoFrameAndWaitForRenderer(&sink); 175effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(1, sink.number_of_frames()); 1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(kColorValue, *sink.last_frame()->data(media::VideoFrame::kYPlane)); 177effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 178effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch video_track->SetEnabled(false); 179effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_FALSE(sink.enabled()); 180010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DeliverVideoFrameAndWaitForRenderer(&sink); 1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(2, sink.number_of_frames()); 1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(kBlackValue, *sink.last_frame()->data(media::VideoFrame::kYPlane)); 184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 185effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch video_track->SetEnabled(true); 186effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_TRUE(sink.enabled()); 187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DeliverVideoFrameAndWaitForRenderer(&sink); 1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(3, sink.number_of_frames()); 1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(kColorValue, *sink.last_frame()->data(media::VideoFrame::kYPlane)); 190effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track); 191effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 192effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 193effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_F(MediaStreamVideoTrackTest, SourceStopped) { 194c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch MockMediaStreamVideoSink sink; 195effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blink::WebMediaStreamTrack track = CreateTrack(); 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MediaStreamVideoSink::AddToVideoTrack( 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &sink, sink.GetDeliverFrameCB(), track); 198effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive, sink.state()); 199effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 200effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch mock_source()->StopSource(); 201effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded, sink.state()); 202effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch MediaStreamVideoSink::RemoveFromVideoTrack(&sink, track); 203effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 204effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 2050529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(MediaStreamVideoTrackTest, StopLastTrack) { 2060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch MockMediaStreamVideoSink sink1; 2070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch blink::WebMediaStreamTrack track1 = CreateTrack(); 208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MediaStreamVideoSink::AddToVideoTrack( 209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &sink1, sink1.GetDeliverFrameCB(), track1); 2100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive, sink1.state()); 2110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive, 2130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch blink_source().readyState()); 2140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch MockMediaStreamVideoSink sink2; 2160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch blink::WebMediaStreamTrack track2 = CreateTrack(); 217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MediaStreamVideoSink::AddToVideoTrack( 218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &sink2, sink2.GetDeliverFrameCB(), track2); 2190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive, sink2.state()); 2200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch MediaStreamVideoTrack* native_track1 = 2220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch MediaStreamVideoTrack::GetVideoTrack(track1); 2230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch native_track1->Stop(); 2240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded, sink1.state()); 2250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive, 2260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch blink_source().readyState()); 2270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch MediaStreamVideoSink::RemoveFromVideoTrack(&sink1, track1); 2280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch MediaStreamVideoTrack* native_track2 = 2300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch MediaStreamVideoTrack::GetVideoTrack(track2); 2310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch native_track2->Stop(); 2320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded, sink2.state()); 2330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded, 2340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch blink_source().readyState()); 2350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch MediaStreamVideoSink::RemoveFromVideoTrack(&sink2, track2); 2360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 2370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 238effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} // namespace content 239