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