Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(565)

Side by Side Diff: content/common/gpu/media/jpeg_decode_accelerator_unittest.cc

Issue 1882373004: Migrate content/common/gpu/media code to media/gpu (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Squash and rebase Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 // This has to be included first.
6 // See http://code.google.com/p/googletest/issues/detail?id=371
7 #include "testing/gtest/include/gtest/gtest.h"
8
9 #include <stddef.h>
10 #include <stdint.h>
11 #include <string.h>
12
13 #include <memory>
14
15 #include "base/at_exit.h"
16 #include "base/bind.h"
17 #include "base/command_line.h"
18 #include "base/files/file_util.h"
19 #include "base/logging.h"
20 #include "base/macros.h"
21 #include "base/memory/scoped_vector.h"
22 #include "base/path_service.h"
23 #include "base/strings/string_piece.h"
24 #include "base/strings/string_split.h"
25 #include "base/thread_task_runner_handle.h"
26 #include "build/build_config.h"
27 #include "content/common/gpu/media/video_accelerator_unittest_helpers.h"
28 #include "media/base/test_data_util.h"
29 #include "media/filters/jpeg_parser.h"
30 #include "media/video/jpeg_decode_accelerator.h"
31 #include "third_party/libyuv/include/libyuv.h"
32 #include "ui/gfx/codec/jpeg_codec.h"
33
34 #if defined(OS_CHROMEOS)
35 #if defined(USE_V4L2_CODEC)
36 #include "content/common/gpu/media/v4l2_device.h"
37 #include "content/common/gpu/media/v4l2_jpeg_decode_accelerator.h"
38 #endif
39 #if defined(ARCH_CPU_X86_FAMILY)
40 #include "content/common/gpu/media/vaapi_jpeg_decode_accelerator.h"
41 #include "content/common/gpu/media/vaapi_wrapper.h"
42 #endif
43 #endif
44
45 using media::JpegDecodeAccelerator;
46
47 namespace content {
48 namespace {
49
50 // Default test image file.
51 const base::FilePath::CharType* kDefaultJpegFilename =
52 FILE_PATH_LITERAL("peach_pi-1280x720.jpg");
53 // Decide to save decode results to files or not. Output files will be saved
54 // in the same directory with unittest. File name is like input file but
55 // changing the extension to "yuv".
56 bool g_save_to_file = false;
57 // Threshold for mean absolute difference of hardware and software decode.
58 // Absolute difference is to calculate the difference between each pixel in two
59 // images. This is used for measuring of the similarity of two images.
60 const double kDecodeSimilarityThreshold = 1.0;
61
62 // Environment to create test data for all test cases.
63 class JpegDecodeAcceleratorTestEnvironment;
64 JpegDecodeAcceleratorTestEnvironment* g_env;
65
66 struct TestImageFile {
67 explicit TestImageFile(const base::FilePath::StringType& filename)
68 : filename(filename) {}
69
70 base::FilePath::StringType filename;
71
72 // The input content of |filename|.
73 std::string data_str;
74
75 media::JpegParseResult parse_result;
76 gfx::Size visible_size;
77 size_t output_size;
78 };
79
80 enum ClientState {
81 CS_CREATED,
82 CS_INITIALIZED,
83 CS_DECODE_PASS,
84 CS_ERROR,
85 };
86
87 class JpegClient : public JpegDecodeAccelerator::Client {
88 public:
89 JpegClient(const std::vector<TestImageFile*>& test_image_files,
90 ClientStateNotification<ClientState>* note);
91 ~JpegClient() override;
92 void CreateJpegDecoder();
93 void DestroyJpegDecoder();
94 void StartDecode(int32_t bitstream_buffer_id);
95
96 // JpegDecodeAccelerator::Client implementation.
97 void VideoFrameReady(int32_t bitstream_buffer_id) override;
98 void NotifyError(int32_t bitstream_buffer_id,
99 JpegDecodeAccelerator::Error error) override;
100
101 private:
102 void PrepareMemory(int32_t bitstream_buffer_id);
103 void SetState(ClientState new_state);
104 void SaveToFile(int32_t bitstream_buffer_id);
105 bool GetSoftwareDecodeResult(int32_t bitstream_buffer_id);
106
107 // Calculate mean absolute difference of hardware and software decode results
108 // to check the similarity.
109 double GetMeanAbsoluteDifference(int32_t bitstream_buffer_id);
110
111 // JpegClient doesn't own |test_image_files_|.
112 const std::vector<TestImageFile*>& test_image_files_;
113
114 std::unique_ptr<JpegDecodeAccelerator> decoder_;
115 ClientState state_;
116
117 // Used to notify another thread about the state. JpegClient does not own
118 // this.
119 ClientStateNotification<ClientState>* note_;
120
121 // Mapped memory of input file.
122 std::unique_ptr<base::SharedMemory> in_shm_;
123 // Mapped memory of output buffer from hardware decoder.
124 std::unique_ptr<base::SharedMemory> hw_out_shm_;
125 // Mapped memory of output buffer from software decoder.
126 std::unique_ptr<base::SharedMemory> sw_out_shm_;
127
128 DISALLOW_COPY_AND_ASSIGN(JpegClient);
129 };
130
131 JpegClient::JpegClient(const std::vector<TestImageFile*>& test_image_files,
132 ClientStateNotification<ClientState>* note)
133 : test_image_files_(test_image_files), state_(CS_CREATED), note_(note) {
134 }
135
136 JpegClient::~JpegClient() {
137 }
138
139 void JpegClient::CreateJpegDecoder() {
140 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
141 decoder_.reset(
142 new VaapiJpegDecodeAccelerator(base::ThreadTaskRunnerHandle::Get()));
143 #elif defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC)
144 scoped_refptr<V4L2Device> device =
145 V4L2Device::Create(V4L2Device::kJpegDecoder);
146 if (!device.get()) {
147 LOG(ERROR) << "V4L2Device::Create failed";
148 SetState(CS_ERROR);
149 return;
150 }
151 decoder_.reset(new V4L2JpegDecodeAccelerator(
152 device, base::ThreadTaskRunnerHandle::Get()));
153 #else
154 #error The JpegDecodeAccelerator is not supported on this platform.
155 #endif
156 if (!decoder_->Initialize(this)) {
157 LOG(ERROR) << "JpegDecodeAccelerator::Initialize() failed";
158 SetState(CS_ERROR);
159 return;
160 }
161 SetState(CS_INITIALIZED);
162 }
163
164 void JpegClient::DestroyJpegDecoder() {
165 decoder_.reset();
166 }
167
168 void JpegClient::VideoFrameReady(int32_t bitstream_buffer_id) {
169 if (!GetSoftwareDecodeResult(bitstream_buffer_id)) {
170 SetState(CS_ERROR);
171 return;
172 }
173 if (g_save_to_file) {
174 SaveToFile(bitstream_buffer_id);
175 }
176
177 double difference = GetMeanAbsoluteDifference(bitstream_buffer_id);
178 if (difference <= kDecodeSimilarityThreshold) {
179 SetState(CS_DECODE_PASS);
180 } else {
181 LOG(ERROR) << "The mean absolute difference between software and hardware "
182 "decode is " << difference;
183 SetState(CS_ERROR);
184 }
185 }
186
187 void JpegClient::NotifyError(int32_t bitstream_buffer_id,
188 JpegDecodeAccelerator::Error error) {
189 LOG(ERROR) << "Notifying of error " << error << " for buffer id "
190 << bitstream_buffer_id;
191 SetState(CS_ERROR);
192 }
193
194 void JpegClient::PrepareMemory(int32_t bitstream_buffer_id) {
195 TestImageFile* image_file = test_image_files_[bitstream_buffer_id];
196
197 size_t input_size = image_file->data_str.size();
198 if (!in_shm_.get() || input_size > in_shm_->mapped_size()) {
199 in_shm_.reset(new base::SharedMemory);
200 LOG_ASSERT(in_shm_->CreateAndMapAnonymous(input_size));
201 }
202 memcpy(in_shm_->memory(), image_file->data_str.data(), input_size);
203
204 if (!hw_out_shm_.get() ||
205 image_file->output_size > hw_out_shm_->mapped_size()) {
206 hw_out_shm_.reset(new base::SharedMemory);
207 LOG_ASSERT(hw_out_shm_->CreateAndMapAnonymous(image_file->output_size));
208 }
209 memset(hw_out_shm_->memory(), 0, image_file->output_size);
210
211 if (!sw_out_shm_.get() ||
212 image_file->output_size > sw_out_shm_->mapped_size()) {
213 sw_out_shm_.reset(new base::SharedMemory);
214 LOG_ASSERT(sw_out_shm_->CreateAndMapAnonymous(image_file->output_size));
215 }
216 memset(sw_out_shm_->memory(), 0, image_file->output_size);
217 }
218
219 void JpegClient::SetState(ClientState new_state) {
220 DVLOG(2) << "Changing state " << state_ << "->" << new_state;
221 note_->Notify(new_state);
222 state_ = new_state;
223 }
224
225 void JpegClient::SaveToFile(int32_t bitstream_buffer_id) {
226 TestImageFile* image_file = test_image_files_[bitstream_buffer_id];
227
228 base::FilePath in_filename(image_file->filename);
229 base::FilePath out_filename = in_filename.ReplaceExtension(".yuv");
230 int size = base::checked_cast<int>(image_file->output_size);
231 ASSERT_EQ(size,
232 base::WriteFile(out_filename,
233 static_cast<char*>(hw_out_shm_->memory()), size));
234 }
235
236 double JpegClient::GetMeanAbsoluteDifference(int32_t bitstream_buffer_id) {
237 TestImageFile* image_file = test_image_files_[bitstream_buffer_id];
238
239 double total_difference = 0;
240 uint8_t* hw_ptr = static_cast<uint8_t*>(hw_out_shm_->memory());
241 uint8_t* sw_ptr = static_cast<uint8_t*>(sw_out_shm_->memory());
242 for (size_t i = 0; i < image_file->output_size; i++)
243 total_difference += std::abs(hw_ptr[i] - sw_ptr[i]);
244 return total_difference / image_file->output_size;
245 }
246
247 void JpegClient::StartDecode(int32_t bitstream_buffer_id) {
248 DCHECK_LT(static_cast<size_t>(bitstream_buffer_id), test_image_files_.size());
249 TestImageFile* image_file = test_image_files_[bitstream_buffer_id];
250
251 PrepareMemory(bitstream_buffer_id);
252
253 base::SharedMemoryHandle dup_handle;
254 dup_handle = base::SharedMemory::DuplicateHandle(in_shm_->handle());
255 media::BitstreamBuffer bitstream_buffer(bitstream_buffer_id, dup_handle,
256 image_file->data_str.size());
257 scoped_refptr<media::VideoFrame> out_frame_ =
258 media::VideoFrame::WrapExternalSharedMemory(
259 media::PIXEL_FORMAT_I420,
260 image_file->visible_size,
261 gfx::Rect(image_file->visible_size),
262 image_file->visible_size,
263 static_cast<uint8_t*>(hw_out_shm_->memory()),
264 image_file->output_size,
265 hw_out_shm_->handle(),
266 0,
267 base::TimeDelta());
268 LOG_ASSERT(out_frame_.get());
269 decoder_->Decode(bitstream_buffer, out_frame_);
270 }
271
272 bool JpegClient::GetSoftwareDecodeResult(int32_t bitstream_buffer_id) {
273 media::VideoPixelFormat format = media::PIXEL_FORMAT_I420;
274 TestImageFile* image_file = test_image_files_[bitstream_buffer_id];
275
276 uint8_t* yplane = static_cast<uint8_t*>(sw_out_shm_->memory());
277 uint8_t* uplane =
278 yplane +
279 media::VideoFrame::PlaneSize(format, media::VideoFrame::kYPlane,
280 image_file->visible_size).GetArea();
281 uint8_t* vplane =
282 uplane +
283 media::VideoFrame::PlaneSize(format, media::VideoFrame::kUPlane,
284 image_file->visible_size).GetArea();
285 int yplane_stride = image_file->visible_size.width();
286 int uv_plane_stride = yplane_stride / 2;
287
288 if (libyuv::ConvertToI420(
289 static_cast<uint8_t*>(in_shm_->memory()),
290 image_file->data_str.size(),
291 yplane,
292 yplane_stride,
293 uplane,
294 uv_plane_stride,
295 vplane,
296 uv_plane_stride,
297 0,
298 0,
299 image_file->visible_size.width(),
300 image_file->visible_size.height(),
301 image_file->visible_size.width(),
302 image_file->visible_size.height(),
303 libyuv::kRotate0,
304 libyuv::FOURCC_MJPG) != 0) {
305 LOG(ERROR) << "Software decode " << image_file->filename << " failed.";
306 return false;
307 }
308 return true;
309 }
310
311 class JpegDecodeAcceleratorTestEnvironment : public ::testing::Environment {
312 public:
313 JpegDecodeAcceleratorTestEnvironment(
314 const base::FilePath::CharType* jpeg_filenames) {
315 user_jpeg_filenames_ =
316 jpeg_filenames ? jpeg_filenames: kDefaultJpegFilename;
317 }
318 void SetUp() override;
319 void TearDown() override;
320
321 // Create all black test image with |width| and |height| size.
322 bool CreateTestJpegImage(int width, int height, base::FilePath* filename);
323
324 // Read image from |filename| to |image_data|.
325 void ReadTestJpegImage(base::FilePath& filename, TestImageFile* image_data);
326
327 // Parsed data of |test_1280x720_jpeg_file_|.
328 std::unique_ptr<TestImageFile> image_data_1280x720_black_;
329 // Parsed data of |test_640x368_jpeg_file_|.
330 std::unique_ptr<TestImageFile> image_data_640x368_black_;
331 // Parsed data of |test_640x360_jpeg_file_|.
332 std::unique_ptr<TestImageFile> image_data_640x360_black_;
333 // Parsed data of "peach_pi-1280x720.jpg".
334 std::unique_ptr<TestImageFile> image_data_1280x720_default_;
335 // Parsed data of failure image.
336 std::unique_ptr<TestImageFile> image_data_invalid_;
337 // Parsed data from command line.
338 ScopedVector<TestImageFile> image_data_user_;
339
340 private:
341 const base::FilePath::CharType* user_jpeg_filenames_;
342
343 // Used for InputSizeChange test case. The image size should be smaller than
344 // |kDefaultJpegFilename|.
345 base::FilePath test_1280x720_jpeg_file_;
346 // Used for ResolutionChange test case.
347 base::FilePath test_640x368_jpeg_file_;
348 // Used for testing some drivers which will align the output resolution to a
349 // multiple of 16. 640x360 will be aligned to 640x368.
350 base::FilePath test_640x360_jpeg_file_;
351 };
352
353 void JpegDecodeAcceleratorTestEnvironment::SetUp() {
354 ASSERT_TRUE(CreateTestJpegImage(1280, 720, &test_1280x720_jpeg_file_));
355 ASSERT_TRUE(CreateTestJpegImage(640, 368, &test_640x368_jpeg_file_));
356 ASSERT_TRUE(CreateTestJpegImage(640, 360, &test_640x360_jpeg_file_));
357
358 image_data_1280x720_black_.reset(
359 new TestImageFile(test_1280x720_jpeg_file_.value()));
360 ASSERT_NO_FATAL_FAILURE(ReadTestJpegImage(test_1280x720_jpeg_file_,
361 image_data_1280x720_black_.get()));
362
363 image_data_640x368_black_.reset(
364 new TestImageFile(test_640x368_jpeg_file_.value()));
365 ASSERT_NO_FATAL_FAILURE(ReadTestJpegImage(test_640x368_jpeg_file_,
366 image_data_640x368_black_.get()));
367
368 image_data_640x360_black_.reset(
369 new TestImageFile(test_640x360_jpeg_file_.value()));
370 ASSERT_NO_FATAL_FAILURE(ReadTestJpegImage(test_640x360_jpeg_file_,
371 image_data_640x360_black_.get()));
372
373 base::FilePath default_jpeg_file =
374 media::GetTestDataFilePath(kDefaultJpegFilename);
375 image_data_1280x720_default_.reset(new TestImageFile(kDefaultJpegFilename));
376 ASSERT_NO_FATAL_FAILURE(
377 ReadTestJpegImage(default_jpeg_file, image_data_1280x720_default_.get()));
378
379 image_data_invalid_.reset(new TestImageFile("failure.jpg"));
380 image_data_invalid_->data_str.resize(100, 0);
381 image_data_invalid_->visible_size.SetSize(1280, 720);
382 image_data_invalid_->output_size = media::VideoFrame::AllocationSize(
383 media::PIXEL_FORMAT_I420, image_data_invalid_->visible_size);
384
385 // |user_jpeg_filenames_| may include many files and use ';' as delimiter.
386 std::vector<base::FilePath::StringType> filenames = base::SplitString(
387 user_jpeg_filenames_, base::FilePath::StringType(1, ';'),
388 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
389 for (const auto& filename : filenames) {
390 base::FilePath input_file = media::GetTestDataFilePath(filename);
391 TestImageFile* image_data = new TestImageFile(filename);
392 ASSERT_NO_FATAL_FAILURE(ReadTestJpegImage(input_file, image_data));
393 image_data_user_.push_back(image_data);
394 }
395 }
396
397 void JpegDecodeAcceleratorTestEnvironment::TearDown() {
398 base::DeleteFile(test_1280x720_jpeg_file_, false);
399 base::DeleteFile(test_640x368_jpeg_file_, false);
400 base::DeleteFile(test_640x360_jpeg_file_, false);
401 }
402
403 bool JpegDecodeAcceleratorTestEnvironment::CreateTestJpegImage(
404 int width,
405 int height,
406 base::FilePath* filename) {
407 const int kBytesPerPixel = 3;
408 const int kJpegQuality = 100;
409 std::vector<unsigned char> input_buffer(width * height * kBytesPerPixel);
410 std::vector<unsigned char> encoded;
411 if (!gfx::JPEGCodec::Encode(&input_buffer[0], gfx::JPEGCodec::FORMAT_RGB,
412 width, height, width * kBytesPerPixel,
413 kJpegQuality, &encoded)) {
414 return false;
415 }
416
417 LOG_ASSERT(base::CreateTemporaryFile(filename));
418 EXPECT_TRUE(base::AppendToFile(
419 *filename, reinterpret_cast<char*>(&encoded[0]), encoded.size()));
420 return true;
421 }
422
423 void JpegDecodeAcceleratorTestEnvironment::ReadTestJpegImage(
424 base::FilePath& input_file, TestImageFile* image_data) {
425 ASSERT_TRUE(base::ReadFileToString(input_file, &image_data->data_str));
426
427 ASSERT_TRUE(media::ParseJpegPicture(
428 reinterpret_cast<const uint8_t*>(image_data->data_str.data()),
429 image_data->data_str.size(),
430 &image_data->parse_result));
431 image_data->visible_size.SetSize(
432 image_data->parse_result.frame_header.visible_width,
433 image_data->parse_result.frame_header.visible_height);
434 image_data->output_size = media::VideoFrame::AllocationSize(
435 media::PIXEL_FORMAT_I420, image_data->visible_size);
436 }
437
438 class JpegDecodeAcceleratorTest : public ::testing::Test {
439 protected:
440 JpegDecodeAcceleratorTest() {}
441
442 void TestDecode(size_t num_concurrent_decoders);
443
444 // The elements of |test_image_files_| are owned by
445 // JpegDecodeAcceleratorTestEnvironment.
446 std::vector<TestImageFile*> test_image_files_;
447 std::vector<ClientState> expected_status_;
448
449 protected:
450 DISALLOW_COPY_AND_ASSIGN(JpegDecodeAcceleratorTest);
451 };
452
453 void JpegDecodeAcceleratorTest::TestDecode(size_t num_concurrent_decoders) {
454 LOG_ASSERT(test_image_files_.size() == expected_status_.size());
455 base::Thread decoder_thread("DecoderThread");
456 ASSERT_TRUE(decoder_thread.Start());
457
458 ScopedVector<ClientStateNotification<ClientState>> notes;
459 ScopedVector<JpegClient> clients;
460
461 for (size_t i = 0; i < num_concurrent_decoders; i++) {
462 notes.push_back(new ClientStateNotification<ClientState>());
463 clients.push_back(new JpegClient(test_image_files_, notes.back()));
464 decoder_thread.task_runner()->PostTask(
465 FROM_HERE, base::Bind(&JpegClient::CreateJpegDecoder,
466 base::Unretained(clients.back())));
467 ASSERT_EQ(notes[i]->Wait(), CS_INITIALIZED);
468 }
469
470 for (size_t index = 0; index < test_image_files_.size(); index++) {
471 for (size_t i = 0; i < num_concurrent_decoders; i++) {
472 decoder_thread.task_runner()->PostTask(
473 FROM_HERE, base::Bind(&JpegClient::StartDecode,
474 base::Unretained(clients[i]),
475 index));
476 }
477 for (size_t i = 0; i < num_concurrent_decoders; i++) {
478 ASSERT_EQ(notes[i]->Wait(), expected_status_[index]);
479 }
480 }
481
482 for (size_t i = 0; i < num_concurrent_decoders; i++) {
483 decoder_thread.task_runner()->PostTask(
484 FROM_HERE, base::Bind(&JpegClient::DestroyJpegDecoder,
485 base::Unretained(clients[i])));
486 }
487 decoder_thread.Stop();
488 }
489
490 TEST_F(JpegDecodeAcceleratorTest, SimpleDecode) {
491 for (const auto& image : g_env->image_data_user_) {
492 test_image_files_.push_back(image);
493 expected_status_.push_back(CS_DECODE_PASS);
494 }
495 TestDecode(1);
496 }
497
498 TEST_F(JpegDecodeAcceleratorTest, MultipleDecoders) {
499 for (const auto& image : g_env->image_data_user_) {
500 test_image_files_.push_back(image);
501 expected_status_.push_back(CS_DECODE_PASS);
502 }
503 TestDecode(3);
504 }
505
506 TEST_F(JpegDecodeAcceleratorTest, InputSizeChange) {
507 // The size of |image_data_1280x720_black_| is smaller than
508 // |image_data_1280x720_default_|.
509 test_image_files_.push_back(g_env->image_data_1280x720_black_.get());
510 test_image_files_.push_back(g_env->image_data_1280x720_default_.get());
511 test_image_files_.push_back(g_env->image_data_1280x720_black_.get());
512 for (size_t i = 0; i < test_image_files_.size(); i++)
513 expected_status_.push_back(CS_DECODE_PASS);
514 TestDecode(1);
515 }
516
517 TEST_F(JpegDecodeAcceleratorTest, ResolutionChange) {
518 test_image_files_.push_back(g_env->image_data_640x368_black_.get());
519 test_image_files_.push_back(g_env->image_data_1280x720_default_.get());
520 test_image_files_.push_back(g_env->image_data_640x368_black_.get());
521 for (size_t i = 0; i < test_image_files_.size(); i++)
522 expected_status_.push_back(CS_DECODE_PASS);
523 TestDecode(1);
524 }
525
526 TEST_F(JpegDecodeAcceleratorTest, CodedSizeAlignment) {
527 test_image_files_.push_back(g_env->image_data_640x360_black_.get());
528 expected_status_.push_back(CS_DECODE_PASS);
529 TestDecode(1);
530 }
531
532 TEST_F(JpegDecodeAcceleratorTest, FailureJpeg) {
533 test_image_files_.push_back(g_env->image_data_invalid_.get());
534 expected_status_.push_back(CS_ERROR);
535 TestDecode(1);
536 }
537
538 TEST_F(JpegDecodeAcceleratorTest, KeepDecodeAfterFailure) {
539 test_image_files_.push_back(g_env->image_data_invalid_.get());
540 test_image_files_.push_back(g_env->image_data_1280x720_default_.get());
541 expected_status_.push_back(CS_ERROR);
542 expected_status_.push_back(CS_DECODE_PASS);
543 TestDecode(1);
544 }
545
546 } // namespace
547 } // namespace content
548
549 int main(int argc, char** argv) {
550 testing::InitGoogleTest(&argc, argv);
551 base::CommandLine::Init(argc, argv);
552 base::ShadowingAtExitManager at_exit_manager;
553
554 // Needed to enable DVLOG through --vmodule.
555 logging::LoggingSettings settings;
556 settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
557 LOG_ASSERT(logging::InitLogging(settings));
558
559 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
560 DCHECK(cmd_line);
561
562 const base::FilePath::CharType* jpeg_filenames = nullptr;
563 base::CommandLine::SwitchMap switches = cmd_line->GetSwitches();
564 for (base::CommandLine::SwitchMap::const_iterator it = switches.begin();
565 it != switches.end(); ++it) {
566 // jpeg_filenames can include one or many files and use ';' as delimiter.
567 if (it->first == "jpeg_filenames") {
568 jpeg_filenames = it->second.c_str();
569 continue;
570 }
571 if (it->first == "save_to_file") {
572 content::g_save_to_file = true;
573 continue;
574 }
575 if (it->first == "v" || it->first == "vmodule")
576 continue;
577 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second;
578 }
579 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
580 content::VaapiWrapper::PreSandboxInitialization();
581 #endif
582
583 content::g_env =
584 reinterpret_cast<content::JpegDecodeAcceleratorTestEnvironment*>(
585 testing::AddGlobalTestEnvironment(
586 new content::JpegDecodeAcceleratorTestEnvironment(
587 jpeg_filenames)));
588
589 return RUN_ALL_TESTS();
590 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698