OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <cstdlib> | 5 #include <cstdlib> |
6 #include <vector> | |
7 | 6 |
8 #include "base/bind.h" | 7 #include "base/bind.h" |
9 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
10 #include "base/synchronization/condition_variable.h" | 9 #include "base/synchronization/condition_variable.h" |
11 #include "base/synchronization/lock.h" | 10 #include "base/synchronization/lock.h" |
12 #include "base/time/time.h" | 11 #include "base/time/time.h" |
13 #include "media/cast/cast_config.h" | 12 #include "media/cast/cast_config.h" |
14 #include "media/cast/receiver/video_decoder.h" | 13 #include "media/cast/receiver/video_decoder.h" |
15 #include "media/cast/sender/vp8_encoder.h" | 14 #include "media/cast/sender/vp8_encoder.h" |
16 #include "media/cast/test/utility/default_config.h" | 15 #include "media/cast/test/utility/default_config.h" |
17 #include "media/cast/test/utility/standalone_cast_environment.h" | 16 #include "media/cast/test/utility/standalone_cast_environment.h" |
18 #include "media/cast/test/utility/video_utility.h" | 17 #include "media/cast/test/utility/video_utility.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
20 | 19 |
21 namespace media { | 20 namespace media { |
22 namespace cast { | 21 namespace cast { |
23 | 22 |
24 namespace { | 23 namespace { |
25 | 24 |
26 const int kStartingWidth = 360; | 25 const int kWidth = 360; |
27 const int kStartingHeight = 240; | 26 const int kHeight = 240; |
28 const int kFrameRate = 10; | 27 const int kFrameRate = 10; |
29 | 28 |
30 VideoSenderConfig GetVideoSenderConfigForTest() { | 29 VideoSenderConfig GetVideoSenderConfigForTest() { |
31 VideoSenderConfig config = GetDefaultVideoSenderConfig(); | 30 VideoSenderConfig config = GetDefaultVideoSenderConfig(); |
| 31 config.width = kWidth; |
| 32 config.height = kHeight; |
32 config.max_frame_rate = kFrameRate; | 33 config.max_frame_rate = kFrameRate; |
33 return config; | 34 return config; |
34 } | 35 } |
35 | 36 |
36 } // namespace | 37 } // namespace |
37 | 38 |
38 class VideoDecoderTest : public ::testing::TestWithParam<Codec> { | 39 class VideoDecoderTest : public ::testing::TestWithParam<Codec> { |
39 public: | 40 public: |
40 VideoDecoderTest() | 41 VideoDecoderTest() |
41 : cast_environment_(new StandaloneCastEnvironment()), | 42 : cast_environment_(new StandaloneCastEnvironment()), |
42 vp8_encoder_(GetVideoSenderConfigForTest()), | 43 vp8_encoder_(GetVideoSenderConfigForTest()), |
43 cond_(&lock_) { | 44 cond_(&lock_) { |
44 vp8_encoder_.Initialize(); | 45 vp8_encoder_.Initialize(); |
45 } | 46 } |
46 | 47 |
47 virtual ~VideoDecoderTest() { | 48 virtual ~VideoDecoderTest() { |
48 // Make sure all threads have stopped before the environment goes away. | 49 // Make sure all threads have stopped before the environment goes away. |
49 cast_environment_->Shutdown(); | 50 cast_environment_->Shutdown(); |
50 } | 51 } |
51 | 52 |
52 protected: | 53 protected: |
53 void SetUp() override { | 54 void SetUp() override { |
54 video_decoder_.reset(new VideoDecoder(cast_environment_, GetParam())); | 55 video_decoder_.reset(new VideoDecoder(cast_environment_, GetParam())); |
55 CHECK_EQ(STATUS_VIDEO_INITIALIZED, video_decoder_->InitializationResult()); | 56 CHECK_EQ(STATUS_VIDEO_INITIALIZED, video_decoder_->InitializationResult()); |
56 | 57 |
57 next_frame_size_ = gfx::Size(kStartingWidth, kStartingHeight); | |
58 next_frame_timestamp_ = base::TimeDelta(); | 58 next_frame_timestamp_ = base::TimeDelta(); |
59 last_frame_id_ = 0; | 59 last_frame_id_ = 0; |
60 seen_a_decoded_frame_ = false; | 60 seen_a_decoded_frame_ = false; |
61 | 61 |
62 total_video_frames_feed_in_ = 0; | 62 total_video_frames_feed_in_ = 0; |
63 total_video_frames_decoded_ = 0; | 63 total_video_frames_decoded_ = 0; |
64 } | 64 } |
65 | 65 |
66 void SetNextFrameSize(const gfx::Size& size) { | |
67 next_frame_size_ = size; | |
68 } | |
69 | |
70 // Called from the unit test thread to create another EncodedFrame and push it | 66 // Called from the unit test thread to create another EncodedFrame and push it |
71 // into the decoding pipeline. | 67 // into the decoding pipeline. |
72 void FeedMoreVideo(int num_dropped_frames) { | 68 void FeedMoreVideo(int num_dropped_frames) { |
73 // Prepare a simulated EncodedFrame to feed into the VideoDecoder. | 69 // Prepare a simulated EncodedFrame to feed into the VideoDecoder. |
74 | 70 |
| 71 const gfx::Size frame_size(kWidth, kHeight); |
75 const scoped_refptr<VideoFrame> video_frame = | 72 const scoped_refptr<VideoFrame> video_frame = |
76 VideoFrame::CreateFrame(VideoFrame::YV12, | 73 VideoFrame::CreateFrame(VideoFrame::YV12, |
77 next_frame_size_, | 74 frame_size, |
78 gfx::Rect(next_frame_size_), | 75 gfx::Rect(frame_size), |
79 next_frame_size_, | 76 frame_size, |
80 next_frame_timestamp_); | 77 next_frame_timestamp_); |
81 const base::TimeTicks reference_time = | |
82 base::TimeTicks::UnixEpoch() + next_frame_timestamp_; | |
83 next_frame_timestamp_ += base::TimeDelta::FromSeconds(1) / kFrameRate; | 78 next_frame_timestamp_ += base::TimeDelta::FromSeconds(1) / kFrameRate; |
84 PopulateVideoFrame(video_frame.get(), 0); | 79 PopulateVideoFrame(video_frame.get(), 0); |
85 | 80 |
86 // Encode |frame| into |encoded_frame->data|. | 81 // Encode |frame| into |encoded_frame->data|. |
87 scoped_ptr<EncodedFrame> encoded_frame(new EncodedFrame()); | 82 scoped_ptr<EncodedFrame> encoded_frame( |
| 83 new EncodedFrame()); |
88 // Test only supports VP8, currently. | 84 // Test only supports VP8, currently. |
89 CHECK_EQ(CODEC_VIDEO_VP8, GetParam()); | 85 CHECK_EQ(CODEC_VIDEO_VP8, GetParam()); |
90 vp8_encoder_.Encode(video_frame, reference_time, encoded_frame.get()); | 86 vp8_encoder_.Encode(video_frame, base::TimeTicks(), encoded_frame.get()); |
91 // Rewrite frame IDs for testing purposes. | 87 // Rewrite frame IDs for testing purposes. |
92 encoded_frame->frame_id = last_frame_id_ + 1 + num_dropped_frames; | 88 encoded_frame->frame_id = last_frame_id_ + 1 + num_dropped_frames; |
93 if (encoded_frame->dependency == EncodedFrame::KEY) | 89 if (last_frame_id_ == 0) |
94 encoded_frame->referenced_frame_id = encoded_frame->frame_id; | 90 encoded_frame->referenced_frame_id = encoded_frame->frame_id; |
95 else | 91 else |
96 encoded_frame->referenced_frame_id = encoded_frame->frame_id - 1; | 92 encoded_frame->referenced_frame_id = encoded_frame->frame_id - 1; |
97 last_frame_id_ = encoded_frame->frame_id; | 93 last_frame_id_ = encoded_frame->frame_id; |
98 ASSERT_EQ(reference_time, encoded_frame->reference_time); | |
99 | 94 |
100 { | 95 { |
101 base::AutoLock auto_lock(lock_); | 96 base::AutoLock auto_lock(lock_); |
102 ++total_video_frames_feed_in_; | 97 ++total_video_frames_feed_in_; |
103 } | 98 } |
104 | 99 |
105 cast_environment_->PostTask( | 100 cast_environment_->PostTask( |
106 CastEnvironment::MAIN, | 101 CastEnvironment::MAIN, |
107 FROM_HERE, | 102 FROM_HERE, |
108 base::Bind(&VideoDecoder::DecodeFrame, | 103 base::Bind(&VideoDecoder::DecodeFrame, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 // TODO(miu): Once we start using VideoFrame::timestamp_, check that here. | 141 // TODO(miu): Once we start using VideoFrame::timestamp_, check that here. |
147 | 142 |
148 // Signal the main test thread that more video was decoded. | 143 // Signal the main test thread that more video was decoded. |
149 base::AutoLock auto_lock(lock_); | 144 base::AutoLock auto_lock(lock_); |
150 ++total_video_frames_decoded_; | 145 ++total_video_frames_decoded_; |
151 cond_.Signal(); | 146 cond_.Signal(); |
152 } | 147 } |
153 | 148 |
154 const scoped_refptr<StandaloneCastEnvironment> cast_environment_; | 149 const scoped_refptr<StandaloneCastEnvironment> cast_environment_; |
155 scoped_ptr<VideoDecoder> video_decoder_; | 150 scoped_ptr<VideoDecoder> video_decoder_; |
156 gfx::Size next_frame_size_; | |
157 base::TimeDelta next_frame_timestamp_; | 151 base::TimeDelta next_frame_timestamp_; |
158 uint32 last_frame_id_; | 152 uint32 last_frame_id_; |
159 bool seen_a_decoded_frame_; | 153 bool seen_a_decoded_frame_; |
160 | 154 |
161 Vp8Encoder vp8_encoder_; | 155 Vp8Encoder vp8_encoder_; |
162 | 156 |
163 base::Lock lock_; | 157 base::Lock lock_; |
164 base::ConditionVariable cond_; | 158 base::ConditionVariable cond_; |
165 int total_video_frames_feed_in_; | 159 int total_video_frames_feed_in_; |
166 int total_video_frames_decoded_; | 160 int total_video_frames_decoded_; |
(...skipping 18 matching lines...) Expand all Loading... |
185 next_drop_at *= 2; | 179 next_drop_at *= 2; |
186 i += num_dropped; | 180 i += num_dropped; |
187 FeedMoreVideo(num_dropped); | 181 FeedMoreVideo(num_dropped); |
188 } else { | 182 } else { |
189 FeedMoreVideo(0); | 183 FeedMoreVideo(0); |
190 } | 184 } |
191 } | 185 } |
192 WaitForAllVideoToBeDecoded(); | 186 WaitForAllVideoToBeDecoded(); |
193 } | 187 } |
194 | 188 |
195 TEST_P(VideoDecoderTest, DecodesFramesOfVaryingSizes) { | 189 INSTANTIATE_TEST_CASE_P(VideoDecoderTestScenarios, |
196 std::vector<gfx::Size> frame_sizes; | |
197 frame_sizes.push_back(gfx::Size(1280, 720)); | |
198 frame_sizes.push_back(gfx::Size(640, 360)); // Shrink both dimensions. | |
199 frame_sizes.push_back(gfx::Size(300, 200)); // Shrink both dimensions again. | |
200 frame_sizes.push_back(gfx::Size(200, 300)); // Same area. | |
201 frame_sizes.push_back(gfx::Size(600, 400)); // Grow both dimensions. | |
202 frame_sizes.push_back(gfx::Size(638, 400)); // Shrink only one dimension. | |
203 frame_sizes.push_back(gfx::Size(638, 398)); // Shrink the other dimension. | |
204 frame_sizes.push_back(gfx::Size(320, 180)); // Shrink both dimensions again. | |
205 frame_sizes.push_back(gfx::Size(322, 180)); // Grow only one dimension. | |
206 frame_sizes.push_back(gfx::Size(322, 182)); // Grow the other dimension. | |
207 frame_sizes.push_back(gfx::Size(1920, 1080)); // Grow both dimensions again. | |
208 | |
209 // Encode one frame at each size. | |
210 for (const auto& frame_size : frame_sizes) { | |
211 SetNextFrameSize(frame_size); | |
212 FeedMoreVideo(0); | |
213 } | |
214 | |
215 // Encode 10 frames at each size. | |
216 for (const auto& frame_size : frame_sizes) { | |
217 SetNextFrameSize(frame_size); | |
218 const int kNumFrames = 10; | |
219 for (int i = 0; i < kNumFrames; ++i) | |
220 FeedMoreVideo(0); | |
221 } | |
222 | |
223 WaitForAllVideoToBeDecoded(); | |
224 } | |
225 | |
226 INSTANTIATE_TEST_CASE_P(, | |
227 VideoDecoderTest, | 190 VideoDecoderTest, |
228 ::testing::Values(CODEC_VIDEO_VP8)); | 191 ::testing::Values(CODEC_VIDEO_VP8)); |
229 | 192 |
230 } // namespace cast | 193 } // namespace cast |
231 } // namespace media | 194 } // namespace media |
OLD | NEW |