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.
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
);
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);"
32 " video: { mandatory: { minWidth: 640, minHeight: 480 } }"
34 "navigator.getUserMedia ="
35 " navigator.getUserMedia || navigator.webkitGetUserMedia;"
36 "navigator.getUserMedia(constraints,"
37 " gotStream, function() {});";
40 TestMediaStreamVideoTrack::TestMediaStreamVideoTrack(TestingInstance
* instance
)
42 event_(instance_
->pp_instance()) {
45 bool TestMediaStreamVideoTrack::Init() {
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());
64 std::string
TestMediaStreamVideoTrack::TestCreate() {
66 instance_
->EvalScript(kJSCode
);
70 ASSERT_FALSE(video_track_
.is_null());
71 ASSERT_FALSE(video_track_
.HasEnded());
72 ASSERT_FALSE(video_track_
.GetId().empty());
76 ASSERT_TRUE(video_track_
.HasEnded());
77 video_track_
= pp::MediaStreamVideoTrack();
81 std::string
TestMediaStreamVideoTrack::TestGetFrame() {
83 instance_
->EvalScript(kJSCode
);
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
);
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
);
125 video_track_
.Close();
126 ASSERT_TRUE(video_track_
.HasEnded());
127 video_track_
= pp::MediaStreamVideoTrack();
131 std::string
TestMediaStreamVideoTrack::TestConfigure() {
133 instance_
->EvalScript(kJSCode
);
137 ASSERT_FALSE(video_track_
.is_null());
138 ASSERT_FALSE(video_track_
.HasEnded());
139 ASSERT_FALSE(video_track_
.GetId().empty());
144 int32_t expected_format
;
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
);
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
);
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
);
192 int32_t expect_width
;
193 int32_t expect_height
;
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
);
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
);
232 video_track_
.Close();
233 ASSERT_TRUE(video_track_
.HasEnded());
234 video_track_
= pp::MediaStreamVideoTrack();