OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "base/at_exit.h" | 5 #include "base/at_exit.h" |
6 #include "base/bind.h" | 6 #include "base/bind.h" |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/files/memory_mapped_file.h" | 9 #include "base/files/memory_mapped_file.h" |
10 #include "base/memory/scoped_vector.h" | 10 #include "base/memory/scoped_vector.h" |
(...skipping 15 matching lines...) Expand all Loading... | |
26 #endif | 26 #endif |
27 | 27 |
28 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) | 28 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) |
29 #include "content/common/gpu/media/v4l2_video_encode_accelerator.h" | 29 #include "content/common/gpu/media/v4l2_video_encode_accelerator.h" |
30 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11) | 30 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11) |
31 #include "content/common/gpu/media/vaapi_video_encode_accelerator.h" | 31 #include "content/common/gpu/media/vaapi_video_encode_accelerator.h" |
32 #else | 32 #else |
33 #error The VideoEncodeAcceleratorUnittest is not supported on this platform. | 33 #error The VideoEncodeAcceleratorUnittest is not supported on this platform. |
34 #endif | 34 #endif |
35 | 35 |
36 #define ALIGN_64_BYTES(x) (((x) + 63) & ~63) | |
37 | |
36 using media::VideoEncodeAccelerator; | 38 using media::VideoEncodeAccelerator; |
37 | 39 |
38 namespace content { | 40 namespace content { |
39 namespace { | 41 namespace { |
40 | 42 |
41 const media::VideoFrame::Format kInputFormat = media::VideoFrame::I420; | 43 const media::VideoFrame::Format kInputFormat = media::VideoFrame::I420; |
42 | 44 |
43 // Arbitrarily chosen to add some depth to the pipeline. | 45 // Arbitrarily chosen to add some depth to the pipeline. |
44 const unsigned int kNumOutputBuffers = 4; | 46 const unsigned int kNumOutputBuffers = 4; |
45 const unsigned int kNumExtraInputFrames = 4; | 47 const unsigned int kNumExtraInputFrames = 4; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
89 // stream. | 91 // stream. |
90 // - |requested_subsequent_framerate| framerate to switch to in the middle | 92 // - |requested_subsequent_framerate| framerate to switch to in the middle |
91 // of the stream. | 93 // of the stream. |
92 // Bitrate is only forced for tests that test bitrate. | 94 // Bitrate is only forced for tests that test bitrate. |
93 const char* g_default_in_filename = "bear_320x192_40frames.yuv"; | 95 const char* g_default_in_filename = "bear_320x192_40frames.yuv"; |
94 const char* g_default_in_parameters = ":320:192:1:out.h264:200000"; | 96 const char* g_default_in_parameters = ":320:192:1:out.h264:200000"; |
95 base::FilePath::StringType* g_test_stream_data; | 97 base::FilePath::StringType* g_test_stream_data; |
96 | 98 |
97 struct TestStream { | 99 struct TestStream { |
98 TestStream() | 100 TestStream() |
99 : requested_bitrate(0), | 101 : default_requested_bitrate(0), |
100 requested_framerate(0), | 102 default_requested_framerate(0), |
101 requested_subsequent_bitrate(0), | 103 default_requested_subsequent_bitrate(0), |
102 requested_subsequent_framerate(0) {} | 104 default_requested_subsequent_framerate(0) {} |
103 ~TestStream() {} | 105 ~TestStream() {} |
104 | 106 |
105 gfx::Size size; | 107 gfx::Size size; |
108 | |
109 // Input file name and the file must be an I420 (YUV planar) raw stream. | |
110 std::string in_filename; | |
111 | |
112 // The memory mapped of |temp_file| | |
106 base::MemoryMappedFile input_file; | 113 base::MemoryMappedFile input_file; |
114 | |
115 // A temporary file used to prepare input buffers. | |
116 base::FilePath temp_file; | |
117 | |
118 std::string out_filename; | |
107 media::VideoCodecProfile requested_profile; | 119 media::VideoCodecProfile requested_profile; |
108 std::string out_filename; | 120 unsigned int default_requested_bitrate; |
wuchengli
2014/09/04 03:34:29
We really should not mix global variables and test
henryhsu
2014/09/04 08:06:19
Done.
| |
121 unsigned int default_requested_framerate; | |
122 unsigned int default_requested_subsequent_bitrate; | |
123 unsigned int default_requested_subsequent_framerate; | |
109 unsigned int requested_bitrate; | 124 unsigned int requested_bitrate; |
110 unsigned int requested_framerate; | 125 unsigned int requested_framerate; |
111 unsigned int requested_subsequent_bitrate; | 126 unsigned int requested_subsequent_bitrate; |
112 unsigned int requested_subsequent_framerate; | 127 unsigned int requested_subsequent_framerate; |
113 }; | 128 }; |
129 ScopedVector<TestStream> g_test_streams; | |
wuchengli
2014/09/04 03:34:29
This has indeterminate order of destruction. Use a
henryhsu
2014/09/04 08:06:19
Done.
| |
130 | |
131 static bool WriteFile(base::File *file, | |
132 const off_t offset, | |
133 const char* data, | |
134 size_t size) { | |
135 size_t write_bytes = 0; | |
wuchengli
2014/09/04 03:34:29
s/write_bytes/written_bytes/
henryhsu
2014/09/04 08:06:19
Done.
| |
136 while (write_bytes < size) { | |
137 int bytes = file->Write( | |
138 offset + write_bytes, data + write_bytes, size - write_bytes); | |
139 if (!bytes) return false; | |
wuchengli
2014/09/04 03:34:30
Should this be if (bytes == -1)?
The function com
henryhsu
2014/09/04 08:06:19
Done.
| |
140 write_bytes += bytes; | |
141 } | |
142 return true; | |
143 } | |
144 | |
145 // ARM performs CPU cache management with CPU cache line granularity. We thus | |
146 // need to ensure our buffers are CPU cache line-aligned (64 byte-aligned). | |
147 // Otherwise newer kernels will refuse to accept them, and on older kernels | |
148 // we'll be treating ourselves to random corruption. | |
149 // Since we are just mmapping and passing chunks of the input file, to ensure | |
150 // alignment, if the starting virtual addresses of YUV planes of the frames | |
151 // in it were not 64 byte-aligned, we'd have to prepare a memory with 64 | |
152 // byte-aligned starting address and make sure the addresses of YUV planes of | |
153 // each frame are 64 byte-aligned before sending to the encoder. | |
154 // Now we test resolutions different from coded size and prepare chunks before | |
155 // encoding to avoid performance impact. | |
156 // Use |visible_size| and |coded_size| to copy YUV data into memory from | |
wuchengli
2014/09/04 03:34:29
YUV data are copied to file directly. Use |visible
henryhsu
2014/09/04 08:06:19
Done.
| |
157 // |in_filename|. The copied result will be saved in |input_file|. Also | |
158 // calculate the byte size of an input frame and set it to |coded_buffer_size|. | |
159 // |temp_file| is used to prepare input buffers and will be deleted after test | |
160 // finished. | |
161 static void PrepareInputBuffers(const gfx::Size& visible_size, | |
162 const gfx::Size& coded_size, | |
163 const std::string in_filename, | |
164 base::MemoryMappedFile* input_file, | |
165 base::FilePath* temp_file, | |
166 size_t* coded_buffer_size) { | |
167 size_t input_num_planes = media::VideoFrame::NumPlanes(kInputFormat); | |
168 std::vector<size_t> padding_sizes(input_num_planes); | |
169 std::vector<size_t> coded_bpl(input_num_planes); | |
170 std::vector<size_t> visible_bpl(input_num_planes); | |
171 std::vector<size_t> visible_plane_rows(input_num_planes); | |
172 | |
173 // YUV plane starting address should be 64 bytes alignment. Calculate padding | |
174 // size for each plane, and frame allocation size for coded size. Also store | |
175 // bytes per line information of coded size and visible size. | |
176 *coded_buffer_size = 0; | |
177 for (off_t i = 0; i < input_num_planes; i++) { | |
178 size_t size = | |
179 media::VideoFrame::PlaneAllocationSize(kInputFormat, i, coded_size); | |
180 size_t padding_bytes = ALIGN_64_BYTES(size) - size; | |
181 *coded_buffer_size += ALIGN_64_BYTES(size); | |
182 | |
183 coded_bpl[i] = | |
184 media::VideoFrame::RowBytes(i, kInputFormat, coded_size.width()); | |
185 visible_bpl[i] = | |
186 media::VideoFrame::RowBytes(i, kInputFormat, visible_size.width()); | |
187 visible_plane_rows[i] = | |
188 media::VideoFrame::Rows(i, kInputFormat, visible_size.height()); | |
189 size_t padding_rows = | |
190 media::VideoFrame::Rows(i, kInputFormat, coded_size.height()) - | |
191 visible_plane_rows[i]; | |
192 padding_sizes[i] = padding_rows * coded_bpl[i] + padding_bytes; | |
193 } | |
194 | |
195 // Test case may have many encoders and memory should be prepared once. | |
196 if (input_file->IsValid()) | |
197 return; | |
198 | |
199 base::MemoryMappedFile src_file; | |
200 CHECK(base::CreateTemporaryFile(temp_file)); | |
201 CHECK(src_file.Initialize(base::FilePath(in_filename))); | |
202 | |
203 size_t visible_buffer_size = | |
204 media::VideoFrame::AllocationSize(kInputFormat, visible_size); | |
205 size_t num_frames = src_file.length() / visible_buffer_size; | |
206 uint32 flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE | | |
207 base::File::FLAG_READ; | |
208 | |
209 // Create a temporary file with coded_size length. | |
210 base::File file(*temp_file, flags); | |
wuchengli
2014/09/04 03:34:30
s/file/dest_file/ is more readable.
henryhsu
2014/09/04 08:06:19
Done.
| |
211 file.SetLength(*coded_buffer_size * num_frames); | |
212 | |
213 off_t src_offset = 0, dest_offset = 0; | |
214 while (src_offset < static_cast<off_t>(src_file.length())) { | |
215 for (off_t i = 0; i < input_num_planes; i++) { | |
216 #if defined(ARCH_CPU_ARMEL) | |
217 // Assert that each plane of frame starts at 64-byte boundary. | |
218 const uint8* ptr = input_file->data() + dest_offset; | |
wuchengli
2014/09/04 03:34:30
Is it valid to access data() before Initialize?
henryhsu
2014/09/04 08:06:19
IsValid function will check data_ != NULL.
wuchengli
2014/09/04 08:24:39
So if the code reaches here, data_ is NULL and you
| |
219 ASSERT_EQ(reinterpret_cast<off_t>(ptr) & 63, 0) | |
220 << "Planes of frame should be mapped at a 64 byte boundary"; | |
221 #endif | |
222 for (off_t j = 0; j < visible_plane_rows[i]; j++) { | |
223 const char* src = | |
224 reinterpret_cast<const char*>(src_file.data() + src_offset); | |
225 CHECK(WriteFile(&file, dest_offset, src, visible_bpl[i])); | |
226 src_offset += visible_bpl[i]; | |
227 dest_offset += coded_bpl[i]; | |
228 } | |
229 dest_offset += padding_sizes[i]; | |
230 } | |
231 } | |
232 CHECK(input_file->Initialize(file.Pass())); | |
233 } | |
114 | 234 |
115 // Parse |data| into its constituent parts, set the various output fields | 235 // Parse |data| into its constituent parts, set the various output fields |
116 // accordingly, read in video stream, and store them to |test_streams|. | 236 // accordingly, read in video stream, and store them to |test_streams|. |
117 static void ParseAndReadTestStreamData(const base::FilePath::StringType& data, | 237 static void ParseAndReadTestStreamData(const base::FilePath::StringType& data, |
118 ScopedVector<TestStream>* test_streams) { | 238 ScopedVector<TestStream>* test_streams) { |
119 // Split the string to individual test stream data. | 239 // Split the string to individual test stream data. |
120 std::vector<base::FilePath::StringType> test_streams_data; | 240 std::vector<base::FilePath::StringType> test_streams_data; |
121 base::SplitString(data, ';', &test_streams_data); | 241 base::SplitString(data, ';', &test_streams_data); |
122 CHECK_GE(test_streams_data.size(), 1U) << data; | 242 CHECK_GE(test_streams_data.size(), 1U) << data; |
123 | 243 |
124 // Parse each test stream data and read the input file. | 244 // Parse each test stream data and read the input file. |
125 for (size_t index = 0; index < test_streams_data.size(); ++index) { | 245 for (size_t index = 0; index < test_streams_data.size(); ++index) { |
126 std::vector<base::FilePath::StringType> fields; | 246 std::vector<base::FilePath::StringType> fields; |
127 base::SplitString(test_streams_data[index], ':', &fields); | 247 base::SplitString(test_streams_data[index], ':', &fields); |
128 CHECK_GE(fields.size(), 4U) << data; | 248 CHECK_GE(fields.size(), 4U) << data; |
129 CHECK_LE(fields.size(), 9U) << data; | 249 CHECK_LE(fields.size(), 9U) << data; |
130 TestStream* test_stream = new TestStream(); | 250 TestStream* test_stream = new TestStream(); |
131 | 251 |
132 base::FilePath::StringType filename = fields[0]; | 252 test_stream->in_filename = fields[0]; |
133 int width, height; | 253 int width, height; |
134 CHECK(base::StringToInt(fields[1], &width)); | 254 CHECK(base::StringToInt(fields[1], &width)); |
135 CHECK(base::StringToInt(fields[2], &height)); | 255 CHECK(base::StringToInt(fields[2], &height)); |
136 test_stream->size = gfx::Size(width, height); | 256 test_stream->size = gfx::Size(width, height); |
137 CHECK(!test_stream->size.IsEmpty()); | 257 CHECK(!test_stream->size.IsEmpty()); |
138 int profile; | 258 int profile; |
139 CHECK(base::StringToInt(fields[3], &profile)); | 259 CHECK(base::StringToInt(fields[3], &profile)); |
140 CHECK_GT(profile, media::VIDEO_CODEC_PROFILE_UNKNOWN); | 260 CHECK_GT(profile, media::VIDEO_CODEC_PROFILE_UNKNOWN); |
141 CHECK_LE(profile, media::VIDEO_CODEC_PROFILE_MAX); | 261 CHECK_LE(profile, media::VIDEO_CODEC_PROFILE_MAX); |
142 test_stream->requested_profile = | 262 test_stream->requested_profile = |
143 static_cast<media::VideoCodecProfile>(profile); | 263 static_cast<media::VideoCodecProfile>(profile); |
144 | 264 |
145 if (fields.size() >= 5 && !fields[4].empty()) | 265 if (fields.size() >= 5 && !fields[4].empty()) |
146 test_stream->out_filename = fields[4]; | 266 test_stream->out_filename = fields[4]; |
147 | 267 |
148 if (fields.size() >= 6 && !fields[5].empty()) | 268 if (fields.size() >= 6 && !fields[5].empty()) |
149 CHECK(base::StringToUint(fields[5], &test_stream->requested_bitrate)); | 269 CHECK(base::StringToUint( |
270 fields[5], &test_stream->default_requested_bitrate)); | |
150 | 271 |
151 if (fields.size() >= 7 && !fields[6].empty()) | 272 if (fields.size() >= 7 && !fields[6].empty()) |
152 CHECK(base::StringToUint(fields[6], &test_stream->requested_framerate)); | 273 CHECK(base::StringToUint( |
274 fields[6], &test_stream->default_requested_framerate)); | |
153 | 275 |
154 if (fields.size() >= 8 && !fields[7].empty()) { | 276 if (fields.size() >= 8 && !fields[7].empty()) { |
155 CHECK(base::StringToUint(fields[7], | 277 CHECK(base::StringToUint( |
156 &test_stream->requested_subsequent_bitrate)); | 278 fields[7], &test_stream->default_requested_subsequent_bitrate)); |
157 } | 279 } |
158 | 280 |
159 if (fields.size() >= 9 && !fields[8].empty()) { | 281 if (fields.size() >= 9 && !fields[8].empty()) { |
160 CHECK(base::StringToUint(fields[8], | 282 CHECK(base::StringToUint( |
161 &test_stream->requested_subsequent_framerate)); | 283 fields[8], &test_stream->default_requested_subsequent_framerate)); |
162 } | 284 } |
163 | 285 |
164 CHECK(test_stream->input_file.Initialize(base::FilePath(filename))); | |
165 test_streams->push_back(test_stream); | 286 test_streams->push_back(test_stream); |
166 } | 287 } |
167 } | 288 } |
168 | 289 |
169 // Set default parameters of |test_streams| and update the parameters according | 290 // Set default parameters of |test_streams| and update the parameters according |
170 // to |mid_stream_bitrate_switch| and |mid_stream_framerate_switch|. | 291 // to |mid_stream_bitrate_switch| and |mid_stream_framerate_switch|. |
171 static void UpdateTestStreamData(bool mid_stream_bitrate_switch, | 292 static void UpdateTestStreamData(bool mid_stream_bitrate_switch, |
172 bool mid_stream_framerate_switch, | 293 bool mid_stream_framerate_switch, |
173 ScopedVector<TestStream>* test_streams) { | 294 ScopedVector<TestStream>* test_streams) { |
174 for (size_t i = 0; i < test_streams->size(); i++) { | 295 for (size_t i = 0; i < test_streams->size(); i++) { |
175 TestStream* test_stream = (*test_streams)[i]; | 296 TestStream* test_stream = (*test_streams)[i]; |
176 // Use defaults for bitrate/framerate if they are not provided. | 297 // Use defaults for bitrate/framerate if they are not provided. |
177 if (test_stream->requested_bitrate == 0) | 298 if (test_stream->default_requested_bitrate == 0) |
178 test_stream->requested_bitrate = kDefaultBitrate; | 299 test_stream->requested_bitrate = kDefaultBitrate; |
300 else | |
301 test_stream->requested_bitrate = test_stream->default_requested_bitrate; | |
179 | 302 |
180 if (test_stream->requested_framerate == 0) | 303 if (test_stream->default_requested_framerate == 0) |
181 test_stream->requested_framerate = kDefaultFramerate; | 304 test_stream->requested_framerate = kDefaultFramerate; |
305 else | |
306 test_stream->requested_framerate = | |
307 test_stream->default_requested_framerate; | |
182 | 308 |
183 // If bitrate/framerate switch is requested, use the subsequent values if | 309 // If bitrate/framerate switch is requested, use the subsequent values if |
184 // provided, or, if not, calculate them from their initial values using | 310 // provided, or, if not, calculate them from their initial values using |
185 // the default ratios. | 311 // the default ratios. |
186 // Otherwise, if a switch is not requested, keep the initial values. | 312 // Otherwise, if a switch is not requested, keep the initial values. |
313 test_stream->requested_subsequent_bitrate = 0; | |
187 if (mid_stream_bitrate_switch) { | 314 if (mid_stream_bitrate_switch) { |
188 if (test_stream->requested_subsequent_bitrate == 0) { | 315 if (test_stream->default_requested_subsequent_bitrate == 0) |
189 test_stream->requested_subsequent_bitrate = | 316 test_stream->requested_subsequent_bitrate = |
190 test_stream->requested_bitrate * kDefaultSubsequentBitrateRatio; | 317 test_stream->requested_bitrate * kDefaultSubsequentBitrateRatio; |
191 } | 318 else |
319 test_stream->requested_subsequent_bitrate = | |
320 test_stream->default_requested_subsequent_bitrate; | |
192 } else { | 321 } else { |
193 test_stream->requested_subsequent_bitrate = | 322 test_stream->requested_subsequent_bitrate = |
194 test_stream->requested_bitrate; | 323 test_stream->requested_bitrate; |
195 } | 324 } |
196 if (test_stream->requested_subsequent_bitrate == 0) | 325 if (test_stream->requested_subsequent_bitrate == 0) |
197 test_stream->requested_subsequent_bitrate = 1; | 326 test_stream->requested_subsequent_bitrate = 1; |
198 | 327 |
328 test_stream->requested_subsequent_framerate = 0; | |
199 if (mid_stream_framerate_switch) { | 329 if (mid_stream_framerate_switch) { |
200 if (test_stream->requested_subsequent_framerate == 0) { | 330 if (test_stream->default_requested_subsequent_framerate == 0) |
201 test_stream->requested_subsequent_framerate = | 331 test_stream->requested_subsequent_framerate = |
202 test_stream->requested_framerate * kDefaultSubsequentFramerateRatio; | 332 test_stream->requested_framerate * kDefaultSubsequentFramerateRatio; |
203 } | 333 else |
334 test_stream->requested_subsequent_framerate = | |
335 test_stream->default_requested_subsequent_framerate; | |
204 } else { | 336 } else { |
205 test_stream->requested_subsequent_framerate = | 337 test_stream->requested_subsequent_framerate = |
206 test_stream->requested_framerate; | 338 test_stream->requested_framerate; |
207 } | 339 } |
208 if (test_stream->requested_subsequent_framerate == 0) | 340 if (test_stream->requested_subsequent_framerate == 0) |
209 test_stream->requested_subsequent_framerate = 1; | 341 test_stream->requested_subsequent_framerate = 1; |
210 } | 342 } |
211 } | 343 } |
212 | 344 |
213 enum ClientState { | 345 enum ClientState { |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
361 validator.reset(new VP8Validator(frame_cb)); | 493 validator.reset(new VP8Validator(frame_cb)); |
362 } else { | 494 } else { |
363 LOG(FATAL) << "Unsupported profile: " << profile; | 495 LOG(FATAL) << "Unsupported profile: " << profile; |
364 } | 496 } |
365 | 497 |
366 return validator.Pass(); | 498 return validator.Pass(); |
367 } | 499 } |
368 | 500 |
369 class VEAClient : public VideoEncodeAccelerator::Client { | 501 class VEAClient : public VideoEncodeAccelerator::Client { |
370 public: | 502 public: |
371 VEAClient(const TestStream& test_stream, | 503 VEAClient(TestStream& test_stream, |
372 ClientStateNotification<ClientState>* note, | 504 ClientStateNotification<ClientState>* note, |
373 bool save_to_file, | 505 bool save_to_file, |
374 unsigned int keyframe_period, | 506 unsigned int keyframe_period, |
375 bool force_bitrate, | 507 bool force_bitrate, |
376 bool test_perf); | 508 bool test_perf); |
377 virtual ~VEAClient(); | 509 virtual ~VEAClient(); |
378 void CreateEncoder(); | 510 void CreateEncoder(); |
379 void DestroyEncoder(); | 511 void DestroyEncoder(); |
380 | 512 |
381 // Return the number of encoded frames per second. | 513 // Return the number of encoded frames per second. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
423 // the performance test. | 555 // the performance test. |
424 void VerifyPerf(); | 556 void VerifyPerf(); |
425 | 557 |
426 // Prepare and return a frame wrapping the data at |position| bytes in | 558 // Prepare and return a frame wrapping the data at |position| bytes in |
427 // the input stream, ready to be sent to encoder. | 559 // the input stream, ready to be sent to encoder. |
428 scoped_refptr<media::VideoFrame> PrepareInputFrame(off_t position); | 560 scoped_refptr<media::VideoFrame> PrepareInputFrame(off_t position); |
429 | 561 |
430 ClientState state_; | 562 ClientState state_; |
431 scoped_ptr<VideoEncodeAccelerator> encoder_; | 563 scoped_ptr<VideoEncodeAccelerator> encoder_; |
432 | 564 |
433 const TestStream& test_stream_; | 565 TestStream& test_stream_; |
434 // Used to notify another thread about the state. VEAClient does not own this. | 566 // Used to notify another thread about the state. VEAClient does not own this. |
435 ClientStateNotification<ClientState>* note_; | 567 ClientStateNotification<ClientState>* note_; |
436 | 568 |
437 // Ids assigned to VideoFrames (start at 1 for easy comparison with | 569 // Ids assigned to VideoFrames (start at 1 for easy comparison with |
438 // num_encoded_frames_). | 570 // num_encoded_frames_). |
439 std::set<int32> inputs_at_client_; | 571 std::set<int32> inputs_at_client_; |
440 int32 next_input_id_; | 572 int32 next_input_id_; |
441 | 573 |
442 // Ids for output BitstreamBuffers. | 574 // Ids for output BitstreamBuffers. |
443 typedef std::map<int32, base::SharedMemory*> IdToSHM; | 575 typedef std::map<int32, base::SharedMemory*> IdToSHM; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
500 // The time when the encoding started. | 632 // The time when the encoding started. |
501 base::TimeTicks encode_start_time_; | 633 base::TimeTicks encode_start_time_; |
502 | 634 |
503 // The time when the last encoded frame is ready. | 635 // The time when the last encoded frame is ready. |
504 base::TimeTicks last_frame_ready_time_; | 636 base::TimeTicks last_frame_ready_time_; |
505 | 637 |
506 // All methods of this class should be run on the same thread. | 638 // All methods of this class should be run on the same thread. |
507 base::ThreadChecker thread_checker_; | 639 base::ThreadChecker thread_checker_; |
508 }; | 640 }; |
509 | 641 |
510 VEAClient::VEAClient(const TestStream& test_stream, | 642 VEAClient::VEAClient(TestStream& test_stream, |
511 ClientStateNotification<ClientState>* note, | 643 ClientStateNotification<ClientState>* note, |
512 bool save_to_file, | 644 bool save_to_file, |
513 unsigned int keyframe_period, | 645 unsigned int keyframe_period, |
514 bool force_bitrate, | 646 bool force_bitrate, |
515 bool test_perf) | 647 bool test_perf) |
516 : state_(CS_CREATED), | 648 : state_(CS_CREATED), |
517 test_stream_(test_stream), | 649 test_stream_(test_stream), |
518 note_(note), | 650 note_(note), |
519 next_input_id_(1), | 651 next_input_id_(1), |
520 next_output_buffer_id_(0), | 652 next_output_buffer_id_(0), |
(...skipping 24 matching lines...) Expand all Loading... | |
545 CHECK(validator_.get()); | 677 CHECK(validator_.get()); |
546 | 678 |
547 if (save_to_file_) { | 679 if (save_to_file_) { |
548 CHECK(!test_stream_.out_filename.empty()); | 680 CHECK(!test_stream_.out_filename.empty()); |
549 base::FilePath out_filename(test_stream_.out_filename); | 681 base::FilePath out_filename(test_stream_.out_filename); |
550 // This creates or truncates out_filename. | 682 // This creates or truncates out_filename. |
551 // Without it, AppendToFile() will not work. | 683 // Without it, AppendToFile() will not work. |
552 EXPECT_EQ(0, base::WriteFile(out_filename, NULL, 0)); | 684 EXPECT_EQ(0, base::WriteFile(out_filename, NULL, 0)); |
553 } | 685 } |
554 | 686 |
555 input_buffer_size_ = | |
556 media::VideoFrame::AllocationSize(kInputFormat, test_stream.size); | |
557 CHECK_GT(input_buffer_size_, 0UL); | |
558 | |
559 // Calculate the number of frames in the input stream by dividing its length | |
560 // in bytes by frame size in bytes. | |
561 CHECK_EQ(test_stream_.input_file.length() % input_buffer_size_, 0U) | |
562 << "Stream byte size is not a product of calculated frame byte size"; | |
563 num_frames_in_stream_ = test_stream_.input_file.length() / input_buffer_size_; | |
564 CHECK_GT(num_frames_in_stream_, 0UL); | |
565 CHECK_LE(num_frames_in_stream_, kMaxFrameNum); | |
566 | |
567 // We may need to loop over the stream more than once if more frames than | |
568 // provided is required for bitrate tests. | |
569 if (force_bitrate_ && num_frames_in_stream_ < kMinFramesForBitrateTests) { | |
570 DVLOG(1) << "Stream too short for bitrate test (" << num_frames_in_stream_ | |
571 << " frames), will loop it to reach " << kMinFramesForBitrateTests | |
572 << " frames"; | |
573 num_frames_to_encode_ = kMinFramesForBitrateTests; | |
574 } else { | |
575 num_frames_to_encode_ = num_frames_in_stream_; | |
576 } | |
577 | |
578 thread_checker_.DetachFromThread(); | 687 thread_checker_.DetachFromThread(); |
579 } | 688 } |
580 | 689 |
581 VEAClient::~VEAClient() { CHECK(!has_encoder()); } | 690 VEAClient::~VEAClient() { CHECK(!has_encoder()); } |
582 | 691 |
583 void VEAClient::CreateEncoder() { | 692 void VEAClient::CreateEncoder() { |
584 DCHECK(thread_checker_.CalledOnValidThread()); | 693 DCHECK(thread_checker_.CalledOnValidThread()); |
585 CHECK(!has_encoder()); | 694 CHECK(!has_encoder()); |
586 | 695 |
587 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) | 696 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
622 return num_encoded_frames_ / duration.InSecondsF(); | 731 return num_encoded_frames_ / duration.InSecondsF(); |
623 } | 732 } |
624 | 733 |
625 void VEAClient::RequireBitstreamBuffers(unsigned int input_count, | 734 void VEAClient::RequireBitstreamBuffers(unsigned int input_count, |
626 const gfx::Size& input_coded_size, | 735 const gfx::Size& input_coded_size, |
627 size_t output_size) { | 736 size_t output_size) { |
628 DCHECK(thread_checker_.CalledOnValidThread()); | 737 DCHECK(thread_checker_.CalledOnValidThread()); |
629 ASSERT_EQ(state_, CS_INITIALIZED); | 738 ASSERT_EQ(state_, CS_INITIALIZED); |
630 SetState(CS_ENCODING); | 739 SetState(CS_ENCODING); |
631 | 740 |
632 // TODO(posciak): For now we only support input streams that meet encoder | 741 PrepareInputBuffers(test_stream_.size, |
633 // size requirements exactly (i.e. coded size == visible size), so that we | 742 input_coded_size, |
634 // can simply mmap the stream file and feed the encoder directly with chunks | 743 test_stream_.in_filename, |
635 // of that, instead of memcpying from mmapped file into a separate set of | 744 &test_stream_.input_file, |
636 // input buffers that would meet the coded size and alignment requirements. | 745 &test_stream_.temp_file, |
637 // If/when this is changed, the ARM-specific alignment check below should be | 746 &input_buffer_size_); |
638 // redone as well. | 747 CHECK_GT(input_buffer_size_, 0UL); |
748 | |
749 // Calculate the number of frames in the input stream by dividing its length | |
750 // in bytes by frame size in bytes. | |
751 CHECK_EQ(test_stream_.input_file.length() % input_buffer_size_, 0U) | |
752 << "Stream byte size is not a product of calculated frame byte size"; | |
753 num_frames_in_stream_ = test_stream_.input_file.length() / input_buffer_size_; | |
754 CHECK_GT(num_frames_in_stream_, 0UL); | |
755 CHECK_LE(num_frames_in_stream_, kMaxFrameNum); | |
756 | |
757 // We may need to loop over the stream more than once if more frames than | |
758 // provided is required for bitrate tests. | |
759 if (force_bitrate_ && num_frames_in_stream_ < kMinFramesForBitrateTests) { | |
760 DVLOG(1) << "Stream too short for bitrate test (" << num_frames_in_stream_ | |
761 << " frames), will loop it to reach " << kMinFramesForBitrateTests | |
762 << " frames"; | |
763 num_frames_to_encode_ = kMinFramesForBitrateTests; | |
764 } else { | |
765 num_frames_to_encode_ = num_frames_in_stream_; | |
766 } | |
767 | |
639 input_coded_size_ = input_coded_size; | 768 input_coded_size_ = input_coded_size; |
640 ASSERT_EQ(input_coded_size_, test_stream_.size); | |
641 #if defined(ARCH_CPU_ARMEL) | |
642 // ARM performs CPU cache management with CPU cache line granularity. We thus | |
643 // need to ensure our buffers are CPU cache line-aligned (64 byte-aligned). | |
644 // Otherwise newer kernels will refuse to accept them, and on older kernels | |
645 // we'll be treating ourselves to random corruption. | |
646 // Since we are just mmapping and passing chunks of the input file, to ensure | |
647 // alignment, if the starting virtual addresses of the frames in it were not | |
648 // 64 byte-aligned, we'd have to use a separate set of input buffers and copy | |
649 // the frames into them before sending to the encoder. It would have been an | |
650 // overkill here though, because, for now at least, we only test resolutions | |
651 // that result in proper alignment, and it would have also interfered with | |
652 // performance testing. So just assert that the frame size is a multiple of | |
653 // 64 bytes. This ensures all frames start at 64-byte boundary, because | |
654 // MemoryMappedFile should be mmapp()ed at virtual page start as well. | |
655 ASSERT_EQ(input_buffer_size_ & 63, 0u) | |
656 << "Frame size has to be a multiple of 64 bytes"; | |
657 ASSERT_EQ(reinterpret_cast<off_t>(test_stream_.input_file.data()) & 63, 0) | |
658 << "Mapped file should be mapped at a 64 byte boundary"; | |
659 #endif | |
660 | |
661 num_required_input_buffers_ = input_count; | 769 num_required_input_buffers_ = input_count; |
662 ASSERT_GT(num_required_input_buffers_, 0UL); | 770 ASSERT_GT(num_required_input_buffers_, 0UL); |
663 | 771 |
664 output_buffer_size_ = output_size; | 772 output_buffer_size_ = output_size; |
665 ASSERT_GT(output_buffer_size_, 0UL); | 773 ASSERT_GT(output_buffer_size_, 0UL); |
666 | 774 |
667 for (unsigned int i = 0; i < kNumOutputBuffers; ++i) { | 775 for (unsigned int i = 0; i < kNumOutputBuffers; ++i) { |
668 base::SharedMemory* shm = new base::SharedMemory(); | 776 base::SharedMemory* shm = new base::SharedMemory(); |
669 CHECK(shm->CreateAndMapAnonymous(output_buffer_size_)); | 777 CHECK(shm->CreateAndMapAnonymous(output_buffer_size_)); |
670 output_shms_.push_back(shm); | 778 output_shms_.push_back(shm); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
736 void VEAClient::InputNoLongerNeededCallback(int32 input_id) { | 844 void VEAClient::InputNoLongerNeededCallback(int32 input_id) { |
737 std::set<int32>::iterator it = inputs_at_client_.find(input_id); | 845 std::set<int32>::iterator it = inputs_at_client_.find(input_id); |
738 ASSERT_NE(it, inputs_at_client_.end()); | 846 ASSERT_NE(it, inputs_at_client_.end()); |
739 inputs_at_client_.erase(it); | 847 inputs_at_client_.erase(it); |
740 FeedEncoderWithInputs(); | 848 FeedEncoderWithInputs(); |
741 } | 849 } |
742 | 850 |
743 scoped_refptr<media::VideoFrame> VEAClient::PrepareInputFrame(off_t position) { | 851 scoped_refptr<media::VideoFrame> VEAClient::PrepareInputFrame(off_t position) { |
744 CHECK_LE(position + input_buffer_size_, test_stream_.input_file.length()); | 852 CHECK_LE(position + input_buffer_size_, test_stream_.input_file.length()); |
745 | 853 |
746 uint8* frame_data = | 854 uint8* frame_data_y = |
747 const_cast<uint8*>(test_stream_.input_file.data() + position); | 855 const_cast<uint8*>(test_stream_.input_file.data() + position); |
856 uint8* frame_data_u = | |
857 frame_data_y + ALIGN_64_BYTES(media::VideoFrame::PlaneAllocationSize( | |
858 kInputFormat, 0, input_coded_size_)); | |
859 uint8* frame_data_v = | |
860 frame_data_u + ALIGN_64_BYTES(media::VideoFrame::PlaneAllocationSize( | |
861 kInputFormat, 1, input_coded_size_)); | |
748 | 862 |
749 CHECK_GT(current_framerate_, 0U); | 863 CHECK_GT(current_framerate_, 0U); |
750 scoped_refptr<media::VideoFrame> frame = | 864 scoped_refptr<media::VideoFrame> frame = |
751 media::VideoFrame::WrapExternalYuvData( | 865 media::VideoFrame::WrapExternalYuvData( |
752 kInputFormat, | 866 kInputFormat, |
753 input_coded_size_, | 867 input_coded_size_, |
754 gfx::Rect(test_stream_.size), | 868 gfx::Rect(test_stream_.size), |
755 test_stream_.size, | 869 test_stream_.size, |
756 input_coded_size_.width(), | 870 input_coded_size_.width(), |
757 input_coded_size_.width() / 2, | 871 input_coded_size_.width() / 2, |
758 input_coded_size_.width() / 2, | 872 input_coded_size_.width() / 2, |
759 frame_data, | 873 frame_data_y, |
760 frame_data + input_coded_size_.GetArea(), | 874 frame_data_u, |
761 frame_data + (input_coded_size_.GetArea() * 5 / 4), | 875 frame_data_v, |
762 base::TimeDelta().FromMilliseconds( | 876 base::TimeDelta().FromMilliseconds( |
763 next_input_id_ * base::Time::kMillisecondsPerSecond / | 877 next_input_id_ * base::Time::kMillisecondsPerSecond / |
764 current_framerate_), | 878 current_framerate_), |
765 media::BindToCurrentLoop( | 879 media::BindToCurrentLoop( |
766 base::Bind(&VEAClient::InputNoLongerNeededCallback, | 880 base::Bind(&VEAClient::InputNoLongerNeededCallback, |
767 base::Unretained(this), | 881 base::Unretained(this), |
768 next_input_id_))); | 882 next_input_id_))); |
769 | 883 |
770 CHECK(inputs_at_client_.insert(next_input_id_).second); | 884 CHECK(inputs_at_client_.insert(next_input_id_).second); |
771 ++next_input_id_; | 885 ++next_input_id_; |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
890 num_frames_since_last_check_ = 0; | 1004 num_frames_since_last_check_ = 0; |
891 encoded_stream_size_since_last_check_ = 0; | 1005 encoded_stream_size_since_last_check_ = 0; |
892 | 1006 |
893 if (force_bitrate_) { | 1007 if (force_bitrate_) { |
894 EXPECT_NEAR(bitrate, | 1008 EXPECT_NEAR(bitrate, |
895 current_requested_bitrate_, | 1009 current_requested_bitrate_, |
896 kBitrateTolerance * current_requested_bitrate_); | 1010 kBitrateTolerance * current_requested_bitrate_); |
897 } | 1011 } |
898 } | 1012 } |
899 | 1013 |
1014 class VideoEncodeAcceleratorEnvironment : public ::testing::Environment { | |
wuchengli
2014/09/04 03:34:29
s/VideoEncodeAcceleratorEnvironment/VideoEncodeAcc
henryhsu
2014/09/04 08:06:19
Done.
| |
1015 public: | |
1016 virtual void TearDown() { | |
1017 for (size_t i = 0; i < g_test_streams.size(); i++) | |
1018 base::DeleteFile(g_test_streams[i]->temp_file, false); | |
1019 } | |
1020 }; | |
1021 | |
900 // Test parameters: | 1022 // Test parameters: |
901 // - Number of concurrent encoders. | 1023 // - Number of concurrent encoders. |
902 // - If true, save output to file (provided an output filename was supplied). | 1024 // - If true, save output to file (provided an output filename was supplied). |
903 // - Force a keyframe every n frames. | 1025 // - Force a keyframe every n frames. |
904 // - Force bitrate; the actual required value is provided as a property | 1026 // - Force bitrate; the actual required value is provided as a property |
905 // of the input stream, because it depends on stream type/resolution/etc. | 1027 // of the input stream, because it depends on stream type/resolution/etc. |
906 // - If true, measure performance. | 1028 // - If true, measure performance. |
907 // - If true, switch bitrate mid-stream. | 1029 // - If true, switch bitrate mid-stream. |
908 // - If true, switch framerate mid-stream. | 1030 // - If true, switch framerate mid-stream. |
909 class VideoEncodeAcceleratorTest | 1031 class VideoEncodeAcceleratorTest |
910 : public ::testing::TestWithParam< | 1032 : public ::testing::TestWithParam< |
911 Tuple7<int, bool, int, bool, bool, bool, bool> > {}; | 1033 Tuple7<int, bool, int, bool, bool, bool, bool> > {}; |
912 | 1034 |
913 TEST_P(VideoEncodeAcceleratorTest, TestSimpleEncode) { | 1035 TEST_P(VideoEncodeAcceleratorTest, TestSimpleEncode) { |
914 const size_t num_concurrent_encoders = GetParam().a; | 1036 const size_t num_concurrent_encoders = GetParam().a; |
915 const bool save_to_file = GetParam().b; | 1037 const bool save_to_file = GetParam().b; |
916 const unsigned int keyframe_period = GetParam().c; | 1038 const unsigned int keyframe_period = GetParam().c; |
917 const bool force_bitrate = GetParam().d; | 1039 const bool force_bitrate = GetParam().d; |
918 const bool test_perf = GetParam().e; | 1040 const bool test_perf = GetParam().e; |
919 const bool mid_stream_bitrate_switch = GetParam().f; | 1041 const bool mid_stream_bitrate_switch = GetParam().f; |
920 const bool mid_stream_framerate_switch = GetParam().g; | 1042 const bool mid_stream_framerate_switch = GetParam().g; |
921 | 1043 |
922 // Initialize the test streams. | 1044 // Initialize the test streams. |
923 ScopedVector<TestStream> test_streams; | |
924 ParseAndReadTestStreamData(*g_test_stream_data, &test_streams); | |
925 UpdateTestStreamData( | 1045 UpdateTestStreamData( |
926 mid_stream_bitrate_switch, mid_stream_framerate_switch, &test_streams); | 1046 mid_stream_bitrate_switch, mid_stream_framerate_switch, &g_test_streams); |
927 | 1047 |
928 ScopedVector<ClientStateNotification<ClientState> > notes; | 1048 ScopedVector<ClientStateNotification<ClientState> > notes; |
929 ScopedVector<VEAClient> clients; | 1049 ScopedVector<VEAClient> clients; |
930 base::Thread encoder_thread("EncoderThread"); | 1050 base::Thread encoder_thread("EncoderThread"); |
931 ASSERT_TRUE(encoder_thread.Start()); | 1051 ASSERT_TRUE(encoder_thread.Start()); |
932 | 1052 |
933 // Create all encoders. | 1053 // Create all encoders. |
934 for (size_t i = 0; i < num_concurrent_encoders; i++) { | 1054 for (size_t i = 0; i < num_concurrent_encoders; i++) { |
935 size_t test_stream_index = i % test_streams.size(); | 1055 size_t test_stream_index = i % g_test_streams.size(); |
936 // Disregard save_to_file if we didn't get an output filename. | 1056 // Disregard save_to_file if we didn't get an output filename. |
937 bool encoder_save_to_file = | 1057 bool encoder_save_to_file = |
938 (save_to_file && | 1058 (save_to_file && |
939 !test_streams[test_stream_index]->out_filename.empty()); | 1059 !g_test_streams[test_stream_index]->out_filename.empty()); |
940 | 1060 |
941 notes.push_back(new ClientStateNotification<ClientState>()); | 1061 notes.push_back(new ClientStateNotification<ClientState>()); |
942 clients.push_back(new VEAClient(*test_streams[test_stream_index], | 1062 clients.push_back(new VEAClient(*g_test_streams[test_stream_index], |
943 notes.back(), | 1063 notes.back(), |
944 encoder_save_to_file, | 1064 encoder_save_to_file, |
945 keyframe_period, | 1065 keyframe_period, |
946 force_bitrate, | 1066 force_bitrate, |
947 test_perf)); | 1067 test_perf)); |
948 | 1068 |
949 encoder_thread.message_loop()->PostTask( | 1069 encoder_thread.message_loop()->PostTask( |
950 FROM_HERE, | 1070 FROM_HERE, |
951 base::Bind(&VEAClient::CreateEncoder, | 1071 base::Bind(&VEAClient::CreateEncoder, |
952 base::Unretained(clients.back()))); | 1072 base::Unretained(clients.back()))); |
(...skipping 15 matching lines...) Expand all Loading... | |
968 ASSERT_EQ(notes[i]->Wait(), state_transitions[state_no]); | 1088 ASSERT_EQ(notes[i]->Wait(), state_transitions[state_no]); |
969 | 1089 |
970 for (size_t i = 0; i < num_concurrent_encoders; ++i) { | 1090 for (size_t i = 0; i < num_concurrent_encoders; ++i) { |
971 encoder_thread.message_loop()->PostTask( | 1091 encoder_thread.message_loop()->PostTask( |
972 FROM_HERE, | 1092 FROM_HERE, |
973 base::Bind(&VEAClient::DestroyEncoder, base::Unretained(clients[i]))); | 1093 base::Bind(&VEAClient::DestroyEncoder, base::Unretained(clients[i]))); |
974 } | 1094 } |
975 | 1095 |
976 // This ensures all tasks have finished. | 1096 // This ensures all tasks have finished. |
977 encoder_thread.Stop(); | 1097 encoder_thread.Stop(); |
1098 | |
wuchengli
2014/09/04 03:34:29
remove blank line
henryhsu
2014/09/04 08:06:19
Done.
| |
978 } | 1099 } |
979 | 1100 |
980 INSTANTIATE_TEST_CASE_P( | 1101 INSTANTIATE_TEST_CASE_P( |
981 SimpleEncode, | 1102 SimpleEncode, |
982 VideoEncodeAcceleratorTest, | 1103 VideoEncodeAcceleratorTest, |
983 ::testing::Values(MakeTuple(1, true, 0, false, false, false, false))); | 1104 ::testing::Values(MakeTuple(1, true, 0, false, false, false, false))); |
984 | 1105 |
985 INSTANTIATE_TEST_CASE_P( | 1106 INSTANTIATE_TEST_CASE_P( |
986 EncoderPerf, | 1107 EncoderPerf, |
987 VideoEncodeAcceleratorTest, | 1108 VideoEncodeAcceleratorTest, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1021 // TODO(posciak): more tests: | 1142 // TODO(posciak): more tests: |
1022 // - async FeedEncoderWithOutput | 1143 // - async FeedEncoderWithOutput |
1023 // - out-of-order return of outputs to encoder | 1144 // - out-of-order return of outputs to encoder |
1024 // - multiple encoders + decoders | 1145 // - multiple encoders + decoders |
1025 // - mid-stream encoder_->Destroy() | 1146 // - mid-stream encoder_->Destroy() |
1026 | 1147 |
1027 } // namespace | 1148 } // namespace |
1028 } // namespace content | 1149 } // namespace content |
1029 | 1150 |
1030 int main(int argc, char** argv) { | 1151 int main(int argc, char** argv) { |
1152 testing::AddGlobalTestEnvironment( | |
1153 new content::VideoEncodeAcceleratorEnvironment); | |
1031 testing::InitGoogleTest(&argc, argv); // Removes gtest-specific args. | 1154 testing::InitGoogleTest(&argc, argv); // Removes gtest-specific args. |
1032 base::CommandLine::Init(argc, argv); | 1155 base::CommandLine::Init(argc, argv); |
1033 | 1156 |
1034 base::ShadowingAtExitManager at_exit_manager; | 1157 base::ShadowingAtExitManager at_exit_manager; |
1035 scoped_ptr<base::FilePath::StringType> test_stream_data( | 1158 scoped_ptr<base::FilePath::StringType> test_stream_data( |
1036 new base::FilePath::StringType( | 1159 new base::FilePath::StringType( |
1037 media::GetTestDataFilePath(content::g_default_in_filename).value() + | 1160 media::GetTestDataFilePath(content::g_default_in_filename).value() + |
1038 content::g_default_in_parameters)); | 1161 content::g_default_in_parameters)); |
1039 content::g_test_stream_data = test_stream_data.get(); | 1162 content::g_test_stream_data = test_stream_data.get(); |
1040 | 1163 |
(...skipping 10 matching lines...) Expand all Loading... | |
1051 it != switches.end(); | 1174 it != switches.end(); |
1052 ++it) { | 1175 ++it) { |
1053 if (it->first == "test_stream_data") { | 1176 if (it->first == "test_stream_data") { |
1054 test_stream_data->assign(it->second.c_str()); | 1177 test_stream_data->assign(it->second.c_str()); |
1055 continue; | 1178 continue; |
1056 } | 1179 } |
1057 if (it->first == "v" || it->first == "vmodule") | 1180 if (it->first == "v" || it->first == "vmodule") |
1058 continue; | 1181 continue; |
1059 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; | 1182 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; |
1060 } | 1183 } |
1061 | 1184 content::ParseAndReadTestStreamData(*content::g_test_stream_data, |
1185 &content::g_test_streams); | |
1062 return RUN_ALL_TESTS(); | 1186 return RUN_ALL_TESTS(); |
1063 } | 1187 } |
OLD | NEW |