1a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// found in the LICENSE file.
4a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)//
5a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Tests PPB_VideoDestination_Private interface.
6a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
7a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "ppapi/tests/test_video_destination.h"
8a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
9a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include <algorithm>
10a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include <limits>
11a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include <string>
12a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ppapi/c/private/ppb_testing_private.h"
14a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "ppapi/cpp/completion_callback.h"
15a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "ppapi/cpp/instance.h"
16a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "ppapi/cpp/private/video_destination_private.h"
17a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "ppapi/cpp/private/video_frame_private.h"
18a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "ppapi/cpp/var.h"
19a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "ppapi/tests/test_utils.h"
20a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "ppapi/tests/testing_instance.h"
21a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
22a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)REGISTER_TEST_CASE(VideoDestination);
23a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
24a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)namespace {
25a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
26a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const PP_Resource kInvalidResource = 0;
27a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)const PP_Instance kInvalidInstance = 0;
28a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
29a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
30a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
31a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)TestVideoDestination::TestVideoDestination(TestingInstance* instance)
32a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    : TestCase(instance),
33a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      ppb_video_destination_private_interface_(NULL),
34a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      ppb_core_interface_(NULL),
35a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      event_(instance_->pp_instance()) {
36a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
37a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
38a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)bool TestVideoDestination::Init() {
39a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ppb_video_destination_private_interface_ =
40a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      static_cast<const PPB_VideoDestination_Private*>(
41a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          pp::Module::Get()->GetBrowserInterface(
42a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)              PPB_VIDEODESTINATION_PRIVATE_INTERFACE));
43a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!ppb_video_destination_private_interface_)
44a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    instance_->AppendError(
45a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        "PPB_VideoDestination_Private interface not available");
46a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
47a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ppb_core_interface_ = static_cast<const PPB_Core*>(
48a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE));
49a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!ppb_core_interface_)
50a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    instance_->AppendError("PPB_Core interface not available");
51a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
52a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return
53a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      ppb_video_destination_private_interface_ &&
54a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      ppb_core_interface_;
55a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
56a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
57a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)TestVideoDestination::~TestVideoDestination() {
58a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
59a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
60a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void TestVideoDestination::RunTests(const std::string& filter) {
61a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  RUN_TEST(Create, filter);
62a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  RUN_TEST(PutFrame, filter);
63a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
64a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
65a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void TestVideoDestination::HandleMessage(const pp::Var& message_data) {
66a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (message_data.AsString().find("blob:") == 0) {
67a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    stream_url_ = message_data.AsString();
68a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    event_.Signal();
69a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
70a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
71a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
72a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)std::string TestVideoDestination::TestCreate() {
73a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  PP_Resource video_destination;
74a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Creating a destination from an invalid instance returns an invalid
75a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // resource.
76a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  video_destination =
77a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      ppb_video_destination_private_interface_->Create(kInvalidInstance);
78a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_EQ(kInvalidResource, video_destination);
79a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_FALSE(
80a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      ppb_video_destination_private_interface_->IsVideoDestination(
81a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          video_destination));
82a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
83a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Creating a destination from a valid instance returns a valid resource.
84a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  video_destination =
85a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      ppb_video_destination_private_interface_->Create(
86a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          instance_->pp_instance());
87a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_NE(kInvalidResource, video_destination);
88a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_TRUE(
89a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      ppb_video_destination_private_interface_->IsVideoDestination(
90a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          video_destination));
91a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
92a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ppb_core_interface_->ReleaseResource(video_destination);
93a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Once released, the resource shouldn't be a video destination.
94a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_FALSE(
95a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      ppb_video_destination_private_interface_->IsVideoDestination(
96a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          video_destination));
97a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
98a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  PASS();
99a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
100a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
101a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)std::string TestVideoDestination::TestPutFrame() {
102a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  std::string js_code;
103a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  js_code += "var test_stream = new webkitMediaStream([]);"
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             "var url = URL.createObjectURL(test_stream);"
105a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)             "var plugin = document.getElementById('plugin');"
106a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)             "plugin.postMessage(url);";
107a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  instance_->EvalScript(js_code);
108a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  event_.Wait();
109a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
110a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  pp::VideoDestination_Private video_destination(instance_);
111a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  TestCompletionCallback cc1(instance_->pp_instance(), false);
112a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  cc1.WaitForResult(video_destination.Open(stream_url_, cc1.GetCallback()));
113a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_EQ(PP_OK, cc1.result());
114a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
115a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  pp::ImageData image_data(instance_,
116a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                           PP_IMAGEDATAFORMAT_BGRA_PREMUL,
117a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                           pp::Size(640, 480),
118a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                           false /* init_to_zero */);
119a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  pp::VideoFrame_Private video_frame(image_data,
120a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                     0.0 /* timestamp */);
121a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_EQ(PP_OK, video_destination.PutFrame(video_frame));
122a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
123a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  video_destination.Close();
124a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
125a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  PASS();
126a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
127a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
128