Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ppapi / tests / test_media_stream_video_track.cc
blobb4f01863ce69b4b298f01935bced81084432fc4a
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 //
5 // Tests PPB_MediaStreamVideoTrack interface.
7 #include "ppapi/tests/test_media_stream_video_track.h"
9 #include "ppapi/c/private/ppb_testing_private.h"
10 #include "ppapi/cpp/completion_callback.h"
11 #include "ppapi/cpp/instance.h"
12 #include "ppapi/cpp/var.h"
13 #include "ppapi/cpp/video_frame.h"
14 #include "ppapi/tests/test_utils.h"
15 #include "ppapi/tests/testing_instance.h"
17 REGISTER_TEST_CASE(MediaStreamVideoTrack);
19 namespace {
21 const int32_t kTimes = 3;
22 const int32_t kDefaultWidth = 640;
23 const int32_t kDefaultHeight = 480;
24 const char kJSCode[] =
25 "function gotStream(stream) {"
26 " var track = stream.getVideoTracks()[0];"
27 " var plugin = document.getElementById('plugin');"
28 " plugin.postMessage(track);"
29 "}"
30 "var constraints = {"
31 " audio: false,"
32 " video: { mandatory: { minWidth: 640, minHeight: 480 } }"
33 "};"
34 "navigator.getUserMedia ="
35 " navigator.getUserMedia || navigator.webkitGetUserMedia;"
36 "navigator.getUserMedia(constraints,"
37 " gotStream, function() {});";
40 TestMediaStreamVideoTrack::TestMediaStreamVideoTrack(TestingInstance* instance)
41 : TestCase(instance),
42 event_(instance_->pp_instance()) {
45 bool TestMediaStreamVideoTrack::Init() {
46 return true;
49 TestMediaStreamVideoTrack::~TestMediaStreamVideoTrack() {
52 void TestMediaStreamVideoTrack::RunTests(const std::string& filter) {
53 RUN_TEST(Create, filter);
54 RUN_TEST(GetFrame, filter);
55 RUN_TEST(Configure, filter);
58 void TestMediaStreamVideoTrack::HandleMessage(const pp::Var& message) {
59 if (message.is_resource())
60 video_track_ = pp::MediaStreamVideoTrack(message.AsResource());
61 event_.Signal();
64 std::string TestMediaStreamVideoTrack::TestCreate() {
65 // Create a track.
66 instance_->EvalScript(kJSCode);
67 event_.Wait();
68 event_.Reset();
70 ASSERT_FALSE(video_track_.is_null());
71 ASSERT_FALSE(video_track_.HasEnded());
72 ASSERT_FALSE(video_track_.GetId().empty());
74 // Close the track.
75 video_track_.Close();
76 ASSERT_TRUE(video_track_.HasEnded());
77 video_track_ = pp::MediaStreamVideoTrack();
78 PASS();
81 std::string TestMediaStreamVideoTrack::TestGetFrame() {
82 // Create a track.
83 instance_->EvalScript(kJSCode);
84 event_.Wait();
85 event_.Reset();
87 ASSERT_FALSE(video_track_.is_null());
88 ASSERT_FALSE(video_track_.HasEnded());
89 ASSERT_FALSE(video_track_.GetId().empty());
91 PP_TimeDelta timestamp = 0.0;
93 // Get |kTimes| frames.
94 for (int i = 0; i < kTimes; ++i) {
95 TestCompletionCallbackWithOutput<pp::VideoFrame> cc(
96 instance_->pp_instance(), false);
97 cc.WaitForResult(video_track_.GetFrame(cc.GetCallback()));
98 ASSERT_EQ(PP_OK, cc.result());
99 pp::VideoFrame frame = cc.output();
100 ASSERT_FALSE(frame.is_null());
101 ASSERT_TRUE(frame.GetFormat() == PP_VIDEOFRAME_FORMAT_YV12 ||
102 frame.GetFormat() == PP_VIDEOFRAME_FORMAT_I420);
104 pp::Size size;
105 ASSERT_TRUE(frame.GetSize(&size));
106 ASSERT_EQ(size.width(), kDefaultWidth);
107 ASSERT_EQ(size.height(), kDefaultHeight);
109 ASSERT_GE(frame.GetTimestamp(), timestamp);
110 timestamp = frame.GetTimestamp();
112 ASSERT_GT(frame.GetDataBufferSize(), 0U);
113 ASSERT_TRUE(frame.GetDataBuffer() != NULL);
115 video_track_.RecycleFrame(frame);
117 // A recycled frame should be invalidated.
118 ASSERT_EQ(frame.GetFormat(), PP_VIDEOFRAME_FORMAT_UNKNOWN);
119 ASSERT_FALSE(frame.GetSize(&size));
120 ASSERT_EQ(frame.GetDataBufferSize(), 0U);
121 ASSERT_TRUE(frame.GetDataBuffer() == NULL);
124 // Close the track.
125 video_track_.Close();
126 ASSERT_TRUE(video_track_.HasEnded());
127 video_track_ = pp::MediaStreamVideoTrack();
128 PASS();
131 std::string TestMediaStreamVideoTrack::TestConfigure() {
132 // Create a track.
133 instance_->EvalScript(kJSCode);
134 event_.Wait();
135 event_.Reset();
137 ASSERT_FALSE(video_track_.is_null());
138 ASSERT_FALSE(video_track_.HasEnded());
139 ASSERT_FALSE(video_track_.GetId().empty());
141 // Configure format.
142 struct {
143 int32_t format;
144 int32_t expected_format;
145 } formats[] = {
146 { PP_VIDEOFRAME_FORMAT_BGRA, PP_VIDEOFRAME_FORMAT_BGRA }, // To RGBA.
147 { PP_VIDEOFRAME_FORMAT_I420, PP_VIDEOFRAME_FORMAT_I420 }, // To I420.
148 { PP_VIDEOFRAME_FORMAT_YV12, PP_VIDEOFRAME_FORMAT_YV12 }, // To YV12.
149 { PP_VIDEOFRAME_FORMAT_BGRA, PP_VIDEOFRAME_FORMAT_BGRA }, // To RGBA.
150 { PP_VIDEOFRAME_FORMAT_UNKNOWN, PP_VIDEOFRAME_FORMAT_YV12 }, // To default.
152 for (size_t i = 0; i < sizeof(formats) / sizeof(formats[0]); ++i) {
153 TestCompletionCallback cc1(instance_->pp_instance(), false);
154 int32_t attrib_list[] = {
155 PP_MEDIASTREAMVIDEOTRACK_ATTRIB_FORMAT, formats[i].format,
156 PP_MEDIASTREAMVIDEOTRACK_ATTRIB_NONE,
158 cc1.WaitForResult(video_track_.Configure(attrib_list, cc1.GetCallback()));
159 ASSERT_EQ(PP_OK, cc1.result());
161 for (int j = 0; j < kTimes; ++j) {
162 TestCompletionCallbackWithOutput<pp::VideoFrame> cc2(
163 instance_->pp_instance(), false);
164 cc2.WaitForResult(video_track_.GetFrame(cc2.GetCallback()));
165 ASSERT_EQ(PP_OK, cc2.result());
166 pp::VideoFrame frame = cc2.output();
167 ASSERT_FALSE(frame.is_null());
168 if (formats[i].format != PP_VIDEOFRAME_FORMAT_UNKNOWN) {
169 ASSERT_EQ(frame.GetFormat(), formats[i].expected_format);
170 } else {
171 // Both YV12 and I420 are acceptable as default YUV formats.
172 ASSERT_TRUE(frame.GetFormat() == PP_VIDEOFRAME_FORMAT_YV12 ||
173 frame.GetFormat() == PP_VIDEOFRAME_FORMAT_I420);
176 pp::Size size;
177 ASSERT_TRUE(frame.GetSize(&size));
178 ASSERT_EQ(size.width(), kDefaultWidth);
179 ASSERT_EQ(size.height(), kDefaultHeight);
181 ASSERT_GT(frame.GetDataBufferSize(), 0U);
182 ASSERT_TRUE(frame.GetDataBuffer() != NULL);
184 video_track_.RecycleFrame(frame);
188 // Configure size.
189 struct {
190 int32_t width;
191 int32_t height;
192 int32_t expect_width;
193 int32_t expect_height;
194 } sizes[] = {
195 { 72, 72, 72, 72 }, // To 72x27.
196 { 1024, 768, 1024, 768 }, // To 1024x768.
197 { 0, 0, kDefaultWidth, kDefaultHeight }, // To default.
199 for (size_t i = 0; i < sizeof(sizes) / sizeof(sizes[0]); ++i) {
200 TestCompletionCallback cc1(instance_->pp_instance(), false);
201 int32_t attrib_list[] = {
202 PP_MEDIASTREAMVIDEOTRACK_ATTRIB_WIDTH, sizes[i].width,
203 PP_MEDIASTREAMVIDEOTRACK_ATTRIB_HEIGHT, sizes[i].height,
204 PP_MEDIASTREAMVIDEOTRACK_ATTRIB_NONE,
206 cc1.WaitForResult(video_track_.Configure(attrib_list, cc1.GetCallback()));
207 ASSERT_EQ(PP_OK, cc1.result());
209 for (int j = 0; j < kTimes; ++j) {
210 TestCompletionCallbackWithOutput<pp::VideoFrame> cc2(
211 instance_->pp_instance(), false);
212 cc2.WaitForResult(video_track_.GetFrame(cc2.GetCallback()));
213 ASSERT_EQ(PP_OK, cc2.result());
214 pp::VideoFrame frame = cc2.output();
215 ASSERT_FALSE(frame.is_null());
216 ASSERT_TRUE(frame.GetFormat() == PP_VIDEOFRAME_FORMAT_YV12 ||
217 frame.GetFormat() == PP_VIDEOFRAME_FORMAT_I420);
219 pp::Size size;
220 ASSERT_TRUE(frame.GetSize(&size));
221 ASSERT_EQ(size.width(), sizes[i].expect_width);
222 ASSERT_EQ(size.height(), sizes[i].expect_height);
224 ASSERT_GT(frame.GetDataBufferSize(), 0U);
225 ASSERT_TRUE(frame.GetDataBuffer() != NULL);
227 video_track_.RecycleFrame(frame);
231 // Close the track.
232 video_track_.Close();
233 ASSERT_TRUE(video_track_.HasEnded());
234 video_track_ = pp::MediaStreamVideoTrack();
235 PASS();