1 // Copyright 2015 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 #include "base/run_loop.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "content/child/child_process.h"
8 #include "content/renderer/media/media_recorder_handler.h"
9 #include "content/renderer/media/mock_media_stream_registry.h"
10 #include "media/base/video_frame.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/WebKit/public/platform/WebMediaRecorderHandlerClient.h"
14 #include "third_party/WebKit/public/platform/WebString.h"
17 using ::testing::AtLeast
;
18 using ::testing::InSequence
;
20 using ::testing::Mock
;
22 using blink::WebString
;
26 ACTION_P(RunClosure
, closure
) {
30 static const std::string kTestStreamUrl
= "stream_url";
31 static const std::string kTestVideoTrackId
= "video_track_id";
33 class MediaRecorderHandlerTest
34 : public testing::Test
35 , public blink::WebMediaRecorderHandlerClient
{
37 MediaRecorderHandlerTest()
38 : media_recorder_handler_(new MediaRecorderHandler()) {
39 EXPECT_FALSE(media_recorder_handler_
->recording_
);
41 registry_
.Init(kTestStreamUrl
);
42 registry_
.AddVideoTrack(kTestVideoTrackId
);
45 MOCK_METHOD3(writeData
, void(const char*, size_t, bool));
46 MOCK_METHOD1(failOutOfMemory
, void(const WebString
& message
));
47 MOCK_METHOD1(failIllegalStreamModification
, void(const WebString
& message
));
48 MOCK_METHOD1(failOtherRecordingError
, void(const WebString
& message
));
50 bool recording() const { return media_recorder_handler_
->recording_
; }
51 bool hasVideoRecorders() const {
52 return !media_recorder_handler_
->video_recorders_
.empty();
55 void OnVideoFrameForTesting(const scoped_refptr
<media::VideoFrame
>& frame
) {
56 media_recorder_handler_
->OnVideoFrameForTesting(frame
,
57 base::TimeTicks::Now());
60 // The Class under test. Needs to be scoped_ptr to force its destruction.
61 scoped_ptr
<MediaRecorderHandler
> media_recorder_handler_
;
63 // A ChildProcess and a MessageLoopForUI are both needed to fool the Tracks
64 // and Sources in |registry_| into believing they are on the right threads.
65 const base::MessageLoopForUI message_loop_
;
66 const ChildProcess child_process_
;
67 MockMediaStreamRegistry registry_
;
70 DISALLOW_COPY_AND_ASSIGN(MediaRecorderHandlerTest
);
73 // Checks that canSupportMimeType() works as expected.
74 // TODO(mcasas): revisit this when canSupportMimeType() is fully implemented.
75 TEST_F(MediaRecorderHandlerTest
, CanSupportMimeType
) {
76 const WebString
good_mime_type(base::UTF8ToUTF16("video/vp8"));
77 EXPECT_TRUE(media_recorder_handler_
->canSupportMimeType(good_mime_type
));
79 const WebString
bad_mime_type(base::UTF8ToUTF16("video/unsupportedcodec"));
80 EXPECT_FALSE(media_recorder_handler_
->canSupportMimeType(bad_mime_type
));
82 const WebString
empty_mime_type(base::UTF8ToUTF16(""));
83 EXPECT_TRUE(media_recorder_handler_
->canSupportMimeType(empty_mime_type
));
86 // Checks that the initialization-destruction sequence works fine.
87 TEST_F(MediaRecorderHandlerTest
, InitializeStartStop
) {
88 const WebString
mime_type(base::UTF8ToUTF16(""));
89 EXPECT_TRUE(media_recorder_handler_
->initialize(this,
90 registry_
.test_stream(),
92 EXPECT_FALSE(recording());
93 EXPECT_FALSE(hasVideoRecorders());
95 EXPECT_TRUE(media_recorder_handler_
->start());
96 EXPECT_TRUE(recording());
97 EXPECT_TRUE(hasVideoRecorders());
99 media_recorder_handler_
->stop();
100 EXPECT_FALSE(recording());
101 EXPECT_FALSE(hasVideoRecorders());
103 // Expect a last call on destruction.
104 EXPECT_CALL(*this, writeData(_
, _
, true)).Times(1);
105 media_recorder_handler_
.reset();
108 // Sends 2 frames and expect them as WebM contained encoded data in writeData().
109 TEST_F(MediaRecorderHandlerTest
, EncodeVideoFrames
) {
110 const WebString
mime_type(base::UTF8ToUTF16("video/vp8"));
111 EXPECT_TRUE(media_recorder_handler_
->initialize(this, registry_
.test_stream(),
113 EXPECT_TRUE(media_recorder_handler_
->start());
116 const scoped_refptr
<media::VideoFrame
> video_frame
=
117 media::VideoFrame::CreateBlackFrame(gfx::Size(160, 80));
120 base::RunLoop run_loop
;
121 base::Closure quit_closure
= run_loop
.QuitClosure();
122 // writeData() is pinged a number of times as the WebM header is written;
123 // the last time it is called it has the encoded data.
124 const size_t kEncodedDataSize
= 52;
125 EXPECT_CALL(*this, writeData(_
, Lt(kEncodedDataSize
), false))
127 EXPECT_CALL(*this, writeData(_
, kEncodedDataSize
, false))
129 .WillOnce(RunClosure(quit_closure
));
131 OnVideoFrameForTesting(video_frame
);
136 base::RunLoop run_loop
;
137 base::Closure quit_closure
= run_loop
.QuitClosure();
138 // The second time around writeData() is called a number of times to write
139 // the WebM frame header, and then is pinged with the encoded data.
140 const size_t kSecondEncodedDataSize
= 32;
141 EXPECT_CALL(*this, writeData(_
, Lt(kSecondEncodedDataSize
), false))
143 EXPECT_CALL(*this, writeData(_
, kSecondEncodedDataSize
, false))
145 .WillOnce(RunClosure(quit_closure
));
147 OnVideoFrameForTesting(video_frame
);
151 media_recorder_handler_
->stop();
153 // Expect a last call on destruction, with size 0 and |lastInSlice| true.
154 EXPECT_CALL(*this, writeData(nullptr, 0, true)).Times(1);
155 media_recorder_handler_
.reset();
158 } // namespace content