1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// found in the LICENSE file. 4c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <string> 6c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 7010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/message_loop/message_loop.h" 8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/run_loop.h" 9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/strings/utf_string_conversions.h" 10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/child/child_process.h" 11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/renderer/media/media_stream.h" 12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/renderer/media/media_stream_video_track.h" 13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/renderer/media/mock_media_stream_registry.h" 14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/renderer/media/mock_media_stream_video_sink.h" 15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/renderer/media/webrtc/video_destination_handler.h" 16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/renderer/pepper/pepper_plugin_instance_impl.h" 17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/renderer/pepper/ppb_image_data_impl.h" 18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/test/ppapi_unittest.h" 19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "testing/gtest/include/gtest/gtest.h" 21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" 22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "third_party/WebKit/public/platform/WebString.h" 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/WebKit/public/web/WebHeap.h" 24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)using ::testing::_; 26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace content { 28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ACTION_P(RunClosure, closure) { 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) closure.Run(); 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstatic const std::string kTestStreamUrl = "stream_url"; 34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstatic const std::string kUnknownStreamUrl = "unknown_stream_url"; 35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass VideoDestinationHandlerTest : public PpapiUnittest { 37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch public: 38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VideoDestinationHandlerTest() 39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : child_process_(new ChildProcess()), 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) registry_(new MockMediaStreamRegistry()) { 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) registry_->Init(kTestStreamUrl); 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void TearDown() OVERRIDE { 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) registry_.reset(); 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blink::WebHeap::collectAllGarbageForTesting(); 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PpapiUnittest::TearDown(); 48c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::MessageLoop* io_message_loop() const { 51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return child_process_->io_message_loop(); 52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 54c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch protected: 55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<ChildProcess> child_process_; 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<MockMediaStreamRegistry> registry_; 57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}; 58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(VideoDestinationHandlerTest, Open) { 60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FrameWriterInterface* frame_writer = NULL; 61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Unknow url will return false. 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_FALSE(VideoDestinationHandler::Open(registry_.get(), 63c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch kUnknownStreamUrl, &frame_writer)); 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(VideoDestinationHandler::Open(registry_.get(), 65c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch kTestStreamUrl, &frame_writer)); 66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // The |frame_writer| is a proxy and is owned by whoever call Open. 67c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch delete frame_writer; 68c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 69c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 70c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(VideoDestinationHandlerTest, PutFrame) { 71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FrameWriterInterface* frame_writer = NULL; 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(VideoDestinationHandler::Open(registry_.get(), 73c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch kTestStreamUrl, &frame_writer)); 74c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ASSERT_TRUE(frame_writer); 75c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Verify the video track has been added. 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const blink::WebMediaStream test_stream = registry_->test_stream(); 78c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch blink::WebVector<blink::WebMediaStreamTrack> video_tracks; 79c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch test_stream.videoTracks(video_tracks); 80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ASSERT_EQ(1u, video_tracks.size()); 81c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 82c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Verify the native video track has been added. 83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch MediaStreamVideoTrack* native_track = 84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch MediaStreamVideoTrack::GetVideoTrack(video_tracks[0]); 85c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ASSERT_TRUE(native_track != NULL); 86c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 87c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch MockMediaStreamVideoSink sink; 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) native_track->AddSink(&sink, sink.GetDeliverFrameCB()); 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<PPB_ImageData_Impl> image( 90c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch new PPB_ImageData_Impl(instance()->pp_instance(), 91c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch PPB_ImageData_Impl::ForTest())); 92c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch image->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL, 640, 360, true); 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) { 94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::RunLoop run_loop; 95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Closure quit_closure = run_loop.QuitClosure(); 96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_CALL(sink, OnVideoFrame()).WillOnce( 98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RunClosure(quit_closure)); 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci frame_writer->PutFrame(image.get(), 10); 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) run_loop.Run(); 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 102c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // TODO(perkj): Verify that the track output I420 when 103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // https://codereview.chromium.org/213423006/ is landed. 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_EQ(1, sink.number_of_frames()); 105c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch native_track->RemoveSink(&sink); 106c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // The |frame_writer| is a proxy and is owned by whoever call Open. 108c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch delete frame_writer; 109c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 110c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 111c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} // namespace content 112