OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 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 #include "base/bind.h" | |
6 #include "base/message_loop.h" | |
7 #include "base/synchronization/waitable_event.h" | |
8 #include "base/threading/thread.h" | |
9 #include "content/renderer/media/rtc_video_decoder.h" | |
10 #include "media/base/gmock_callback_support.h" | |
11 #include "media/filters/gpu_video_decoder.h" | |
12 #include "media/filters/mock_gpu_video_decoder_factories.h" | |
13 #include "media/video/mock_video_decode_accelerator.h" | |
14 #include "testing/gtest/include/gtest/gtest.h" | |
15 | |
16 using ::testing::_; | |
17 using ::testing::Invoke; | |
18 using ::testing::Return; | |
19 using ::testing::SaveArg; | |
20 using ::testing::WithArgs; | |
21 | |
22 namespace content { | |
23 | |
24 class RTCVideoDecoderTest : public ::testing::Test, | |
25 webrtc::DecodedImageCallback { | |
26 public: | |
27 RTCVideoDecoderTest() | |
28 : mock_gpu_factories_(new media::MockGpuVideoDecoderFactories), | |
29 vda_thread_("vda_thread"), | |
30 idle_waiter_(false, false) { | |
31 memset(&codec_, 0, sizeof(codec_)); | |
32 } | |
33 | |
34 virtual void SetUp() OVERRIDE { | |
35 ASSERT_TRUE(vda_thread_.Start()); | |
36 vda_loop_proxy_ = vda_thread_.message_loop_proxy(); | |
37 mock_vda_ = new media::MockVideoDecodeAccelerator; | |
38 EXPECT_CALL(*mock_gpu_factories_, GetMessageLoop()) | |
39 .WillRepeatedly(Return(vda_loop_proxy_)); | |
40 EXPECT_CALL(*mock_gpu_factories_, | |
41 CreateVideoDecodeAccelerator(media::VP8PROFILE_MAIN, _)) | |
42 .WillOnce(Return(mock_vda_)); | |
43 EXPECT_CALL(*mock_vda_, Destroy()); | |
44 rtc_decoder_ = RTCVideoDecoder::Create(mock_gpu_factories_); | |
45 } | |
46 | |
47 virtual void TearDown() OVERRIDE { | |
48 VLOG(2) << "TearDown"; | |
49 if (vda_thread_.IsRunning()) { | |
50 RunUntilIdle(); // Wait until all callbascks complete. | |
51 vda_loop_proxy_->DeleteSoon(FROM_HERE, rtc_decoder_.release()); | |
52 // Make sure the decoder is released before stopping the thread. | |
53 RunUntilIdle(); | |
54 vda_thread_.Stop(); | |
55 } else { | |
56 rtc_decoder_.reset(); | |
57 } | |
58 } | |
59 | |
60 virtual int32_t Decoded(webrtc::I420VideoFrame& decoded_image) OVERRIDE { | |
61 VLOG(2) << "Decoded"; | |
62 EXPECT_EQ(vda_loop_proxy_, base::MessageLoopProxy::current()); | |
63 return WEBRTC_VIDEO_CODEC_OK; | |
64 } | |
65 | |
66 void Initialize() { | |
67 VLOG(2) << "Initialize"; | |
68 codec_.codecType = webrtc::kVideoCodecVP8; | |
69 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->InitDecode(&codec_, 1)); | |
70 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | |
71 rtc_decoder_->RegisterDecodeCompleteCallback(this)); | |
72 } | |
73 | |
74 void NotifyResetDone() { | |
75 VLOG(2) << "NotifyResetDone"; | |
76 vda_loop_proxy_->PostTask(FROM_HERE, | |
77 base::Bind(&RTCVideoDecoder::NotifyResetDone, | |
78 base::Unretained(rtc_decoder_.get()))); | |
79 } | |
80 | |
81 void RunUntilIdle() { | |
82 VLOG(2) << "RunUntilIdle"; | |
83 vda_loop_proxy_->PostTask( | |
84 FROM_HERE, | |
85 base::Bind(&RTCVideoDecoderTest::NotifyIdle, base::Unretained(this))); | |
Ami GONE FROM CHROMIUM
2013/06/19 18:28:58
This is equal to
base::Bind(&WaitableEvent::Signa
wuchengli
2013/06/20 07:27:04
Done.
| |
86 idle_waiter_.Wait(); | |
87 } | |
88 | |
89 void NotifyIdle() { idle_waiter_.Signal(); } | |
90 | |
91 protected: | |
92 scoped_refptr<media::MockGpuVideoDecoderFactories> mock_gpu_factories_; | |
93 media::MockVideoDecodeAccelerator* mock_vda_; | |
94 scoped_ptr<RTCVideoDecoder> rtc_decoder_; | |
95 webrtc::VideoCodec codec_; | |
96 base::Thread vda_thread_; | |
97 | |
98 private: | |
99 scoped_refptr<base::MessageLoopProxy> vda_loop_proxy_; | |
100 | |
101 base::Lock lock_; | |
102 base::WaitableEvent idle_waiter_; | |
103 }; | |
104 | |
105 TEST_F(RTCVideoDecoderTest, InitDecodeReturnsErrorOnFeedbackMode) { | |
106 codec_.codecType = webrtc::kVideoCodecVP8; | |
107 codec_.codecSpecific.VP8.feedbackModeOn = true; | |
108 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, rtc_decoder_->InitDecode(&codec_, 1)); | |
109 } | |
110 | |
111 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorWithoutInitDecode) { | |
112 webrtc::EncodedImage input_image; | |
113 EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED, | |
114 rtc_decoder_->Decode(input_image, false, NULL, NULL, 0)); | |
115 } | |
116 | |
117 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnIncompleteFrame) { | |
118 Initialize(); | |
119 webrtc::EncodedImage input_image; | |
120 input_image._completeFrame = false; | |
121 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, | |
122 rtc_decoder_->Decode(input_image, false, NULL, NULL, 0)); | |
123 } | |
124 | |
125 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnMissingFrames) { | |
126 Initialize(); | |
127 webrtc::EncodedImage input_image; | |
128 input_image._completeFrame = true; | |
129 bool missingFrames = true; | |
130 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, | |
131 rtc_decoder_->Decode(input_image, missingFrames, NULL, NULL, 0)); | |
132 } | |
133 | |
134 TEST_F(RTCVideoDecoderTest, ResetReturnsOk) { | |
135 Initialize(); | |
136 EXPECT_CALL(*mock_vda_, Reset()) | |
137 .WillOnce(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone)); | |
138 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Reset()); | |
139 } | |
140 | |
141 TEST_F(RTCVideoDecoderTest, ReleaseReturnsOk) { | |
142 Initialize(); | |
143 EXPECT_CALL(*mock_vda_, Reset()) | |
144 .WillOnce(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone)); | |
145 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release()); | |
146 } | |
147 | |
148 TEST_F(RTCVideoDecoderTest, VdaThreadStops) { | |
149 EXPECT_CALL(*mock_gpu_factories_, Abort()); | |
150 vda_thread_.Stop(); | |
151 } | |
152 | |
153 } // content | |
OLD | NEW |