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 <inttypes.h> | 5 #include <inttypes.h> |
6 #include <stddef.h> | 6 #include <stddef.h> |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 #include <algorithm> | 8 #include <algorithm> |
9 #include <queue> | 9 #include <queue> |
10 #include <string> | 10 #include <string> |
(...skipping 10 matching lines...) Expand all Loading... |
21 #include "base/numerics/safe_conversions.h" | 21 #include "base/numerics/safe_conversions.h" |
22 #include "base/process/process_handle.h" | 22 #include "base/process/process_handle.h" |
23 #include "base/strings/string_number_conversions.h" | 23 #include "base/strings/string_number_conversions.h" |
24 #include "base/strings/string_split.h" | 24 #include "base/strings/string_split.h" |
25 #include "base/strings/stringprintf.h" | 25 #include "base/strings/stringprintf.h" |
26 #include "base/threading/thread.h" | 26 #include "base/threading/thread.h" |
27 #include "base/threading/thread_checker.h" | 27 #include "base/threading/thread_checker.h" |
28 #include "base/time/time.h" | 28 #include "base/time/time.h" |
29 #include "base/timer/timer.h" | 29 #include "base/timer/timer.h" |
30 #include "build/build_config.h" | 30 #include "build/build_config.h" |
31 #include "content/common/gpu/media/video_accelerator_unittest_helpers.h" | |
32 #include "media/base/bind_to_current_loop.h" | 31 #include "media/base/bind_to_current_loop.h" |
33 #include "media/base/bitstream_buffer.h" | 32 #include "media/base/bitstream_buffer.h" |
34 #include "media/base/cdm_context.h" | 33 #include "media/base/cdm_context.h" |
35 #include "media/base/decoder_buffer.h" | 34 #include "media/base/decoder_buffer.h" |
36 #include "media/base/media_util.h" | 35 #include "media/base/media_util.h" |
37 #include "media/base/test_data_util.h" | 36 #include "media/base/test_data_util.h" |
38 #include "media/base/video_decoder.h" | 37 #include "media/base/video_decoder.h" |
39 #include "media/base/video_frame.h" | 38 #include "media/base/video_frame.h" |
40 #include "media/filters/ffmpeg_glue.h" | 39 #include "media/filters/ffmpeg_glue.h" |
41 #include "media/filters/ffmpeg_video_decoder.h" | 40 #include "media/filters/ffmpeg_video_decoder.h" |
42 #include "media/filters/h264_parser.h" | 41 #include "media/filters/h264_parser.h" |
43 #include "media/filters/ivf_parser.h" | 42 #include "media/filters/ivf_parser.h" |
| 43 #include "media/gpu/video_accelerator_unittest_helpers.h" |
44 #include "media/video/fake_video_encode_accelerator.h" | 44 #include "media/video/fake_video_encode_accelerator.h" |
45 #include "media/video/video_encode_accelerator.h" | 45 #include "media/video/video_encode_accelerator.h" |
46 #include "testing/gtest/include/gtest/gtest.h" | 46 #include "testing/gtest/include/gtest/gtest.h" |
47 | 47 |
48 #if defined(OS_CHROMEOS) | 48 #if defined(OS_CHROMEOS) |
49 #if defined(ARCH_CPU_ARMEL) || (defined(USE_OZONE) && defined(USE_V4L2_CODEC)) | 49 #if defined(ARCH_CPU_ARMEL) || (defined(USE_OZONE) && defined(USE_V4L2_CODEC)) |
50 #include "content/common/gpu/media/v4l2_video_encode_accelerator.h" | 50 #include "media/gpu/v4l2_video_encode_accelerator.h" |
51 #endif | 51 #endif |
52 #if defined(ARCH_CPU_X86_FAMILY) | 52 #if defined(ARCH_CPU_X86_FAMILY) |
53 #include "content/common/gpu/media/vaapi_video_encode_accelerator.h" | 53 #include "media/gpu/vaapi_video_encode_accelerator.h" |
54 #include "content/common/gpu/media/vaapi_wrapper.h" | 54 #include "media/gpu/vaapi_wrapper.h" |
55 // Status has been defined as int in Xlib.h. | 55 // Status has been defined as int in Xlib.h. |
56 #undef Status | 56 #undef Status |
57 #endif // defined(ARCH_CPU_X86_FAMILY) | 57 #endif // defined(ARCH_CPU_X86_FAMILY) |
58 #elif defined(OS_MACOSX) | 58 #elif defined(OS_MACOSX) |
59 #include "content/common/gpu/media/vt_video_encode_accelerator_mac.h" | 59 #include "media/gpu/vt_video_encode_accelerator_mac.h" |
60 #else | 60 #else |
61 #error The VideoEncodeAcceleratorUnittest is not supported on this platform. | 61 #error The VideoEncodeAcceleratorUnittest is not supported on this platform. |
62 #endif | 62 #endif |
63 | 63 |
64 using media::VideoEncodeAccelerator; | 64 using media::VideoEncodeAccelerator; |
65 | 65 |
66 namespace content { | 66 namespace media { |
67 namespace { | 67 namespace { |
68 | 68 |
69 const media::VideoPixelFormat kInputFormat = media::PIXEL_FORMAT_I420; | 69 const media::VideoPixelFormat kInputFormat = media::PIXEL_FORMAT_I420; |
70 | 70 |
71 // The absolute differences between original frame and decoded frame usually | 71 // The absolute differences between original frame and decoded frame usually |
72 // ranges aroud 1 ~ 7. So we pick 10 as an extreme value to detect abnormal | 72 // ranges aroud 1 ~ 7. So we pick 10 as an extreme value to detect abnormal |
73 // decoded frames. | 73 // decoded frames. |
74 const double kDecodeSimilarityThreshold = 10.0; | 74 const double kDecodeSimilarityThreshold = 10.0; |
75 | 75 |
76 // Arbitrarily chosen to add some depth to the pipeline. | 76 // Arbitrarily chosen to add some depth to the pipeline. |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 test_stream->mapped_aligned_in_file.Initialize(std::move(dest_file))); | 320 test_stream->mapped_aligned_in_file.Initialize(std::move(dest_file))); |
321 // Assert that memory mapped of file starts at 64 byte boundary. So each | 321 // Assert that memory mapped of file starts at 64 byte boundary. So each |
322 // plane of frames also start at 64 byte boundary. | 322 // plane of frames also start at 64 byte boundary. |
323 | 323 |
324 ASSERT_EQ( | 324 ASSERT_EQ( |
325 reinterpret_cast<off_t>(test_stream->mapped_aligned_in_file.data()) & 63, | 325 reinterpret_cast<off_t>(test_stream->mapped_aligned_in_file.data()) & 63, |
326 0) | 326 0) |
327 << "File should be mapped at a 64 byte boundary"; | 327 << "File should be mapped at a 64 byte boundary"; |
328 | 328 |
329 LOG_ASSERT(test_stream->mapped_aligned_in_file.length() % | 329 LOG_ASSERT(test_stream->mapped_aligned_in_file.length() % |
330 test_stream->aligned_buffer_size == 0U) | 330 test_stream->aligned_buffer_size == |
| 331 0U) |
331 << "Stream byte size is not a product of calculated frame byte size"; | 332 << "Stream byte size is not a product of calculated frame byte size"; |
332 LOG_ASSERT(test_stream->num_frames > 0UL); | 333 LOG_ASSERT(test_stream->num_frames > 0UL); |
333 } | 334 } |
334 | 335 |
335 // Parse |data| into its constituent parts, set the various output fields | 336 // Parse |data| into its constituent parts, set the various output fields |
336 // accordingly, read in video stream, and store them to |test_streams|. | 337 // accordingly, read in video stream, and store them to |test_streams|. |
337 static void ParseAndReadTestStreamData(const base::FilePath::StringType& data, | 338 static void ParseAndReadTestStreamData(const base::FilePath::StringType& data, |
338 ScopedVector<TestStream>* test_streams) { | 339 ScopedVector<TestStream>* test_streams) { |
339 // Split the string to individual test stream data. | 340 // Split the string to individual test stream data. |
340 std::vector<base::FilePath::StringType> test_streams_data = base::SplitString( | 341 std::vector<base::FilePath::StringType> test_streams_data = |
341 data, base::FilePath::StringType(1, ';'), | 342 base::SplitString(data, base::FilePath::StringType(1, ';'), |
342 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | 343 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
343 LOG_ASSERT(test_streams_data.size() >= 1U) << data; | 344 LOG_ASSERT(test_streams_data.size() >= 1U) << data; |
344 | 345 |
345 // Parse each test stream data and read the input file. | 346 // Parse each test stream data and read the input file. |
346 for (size_t index = 0; index < test_streams_data.size(); ++index) { | 347 for (size_t index = 0; index < test_streams_data.size(); ++index) { |
347 std::vector<base::FilePath::StringType> fields = base::SplitString( | 348 std::vector<base::FilePath::StringType> fields = base::SplitString( |
348 test_streams_data[index], base::FilePath::StringType(1, ':'), | 349 test_streams_data[index], base::FilePath::StringType(1, ':'), |
349 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | 350 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
350 LOG_ASSERT(fields.size() >= 4U) << data; | 351 LOG_ASSERT(fields.size() >= 4U) << data; |
351 LOG_ASSERT(fields.size() <= 9U) << data; | 352 LOG_ASSERT(fields.size() <= 9U) << data; |
352 TestStream* test_stream = new TestStream(); | 353 TestStream* test_stream = new TestStream(); |
(...skipping 11 matching lines...) Expand all Loading... |
364 LOG_ASSERT(result); | 365 LOG_ASSERT(result); |
365 LOG_ASSERT(profile > media::VIDEO_CODEC_PROFILE_UNKNOWN); | 366 LOG_ASSERT(profile > media::VIDEO_CODEC_PROFILE_UNKNOWN); |
366 LOG_ASSERT(profile <= media::VIDEO_CODEC_PROFILE_MAX); | 367 LOG_ASSERT(profile <= media::VIDEO_CODEC_PROFILE_MAX); |
367 test_stream->requested_profile = | 368 test_stream->requested_profile = |
368 static_cast<media::VideoCodecProfile>(profile); | 369 static_cast<media::VideoCodecProfile>(profile); |
369 | 370 |
370 if (fields.size() >= 5 && !fields[4].empty()) | 371 if (fields.size() >= 5 && !fields[4].empty()) |
371 test_stream->out_filename = fields[4]; | 372 test_stream->out_filename = fields[4]; |
372 | 373 |
373 if (fields.size() >= 6 && !fields[5].empty()) | 374 if (fields.size() >= 6 && !fields[5].empty()) |
374 LOG_ASSERT(base::StringToUint(fields[5], | 375 LOG_ASSERT( |
375 &test_stream->requested_bitrate)); | 376 base::StringToUint(fields[5], &test_stream->requested_bitrate)); |
376 | 377 |
377 if (fields.size() >= 7 && !fields[6].empty()) | 378 if (fields.size() >= 7 && !fields[6].empty()) |
378 LOG_ASSERT(base::StringToUint(fields[6], | 379 LOG_ASSERT( |
379 &test_stream->requested_framerate)); | 380 base::StringToUint(fields[6], &test_stream->requested_framerate)); |
380 | 381 |
381 if (fields.size() >= 8 && !fields[7].empty()) { | 382 if (fields.size() >= 8 && !fields[7].empty()) { |
382 LOG_ASSERT(base::StringToUint(fields[7], | 383 LOG_ASSERT(base::StringToUint( |
383 &test_stream->requested_subsequent_bitrate)); | 384 fields[7], &test_stream->requested_subsequent_bitrate)); |
384 } | 385 } |
385 | 386 |
386 if (fields.size() >= 9 && !fields[8].empty()) { | 387 if (fields.size() >= 9 && !fields[8].empty()) { |
387 LOG_ASSERT(base::StringToUint(fields[8], | 388 LOG_ASSERT(base::StringToUint( |
388 &test_stream->requested_subsequent_framerate)); | 389 fields[8], &test_stream->requested_subsequent_framerate)); |
389 } | 390 } |
390 test_streams->push_back(test_stream); | 391 test_streams->push_back(test_stream); |
391 } | 392 } |
392 } | 393 } |
393 | 394 |
394 // Basic test environment shared across multiple test cases. We only need to | 395 // Basic test environment shared across multiple test cases. We only need to |
395 // setup it once for all test cases. | 396 // setup it once for all test cases. |
396 // It helps | 397 // It helps |
397 // - maintain test stream data and other test settings. | 398 // - maintain test stream data and other test settings. |
398 // - clean up temporary aligned files. | 399 // - clean up temporary aligned files. |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 ASSERT_EQ(media::H264Parser::kOk, result); | 538 ASSERT_EQ(media::H264Parser::kOk, result); |
538 | 539 |
539 bool keyframe = false; | 540 bool keyframe = false; |
540 | 541 |
541 switch (nalu.nal_unit_type) { | 542 switch (nalu.nal_unit_type) { |
542 case media::H264NALU::kIDRSlice: | 543 case media::H264NALU::kIDRSlice: |
543 ASSERT_TRUE(seen_sps_); | 544 ASSERT_TRUE(seen_sps_); |
544 ASSERT_TRUE(seen_pps_); | 545 ASSERT_TRUE(seen_pps_); |
545 seen_idr_ = true; | 546 seen_idr_ = true; |
546 keyframe = true; | 547 keyframe = true; |
547 // fallthrough | 548 // fallthrough |
548 case media::H264NALU::kNonIDRSlice: { | 549 case media::H264NALU::kNonIDRSlice: { |
549 ASSERT_TRUE(seen_idr_); | 550 ASSERT_TRUE(seen_idr_); |
550 if (!frame_cb_.Run(keyframe)) | 551 if (!frame_cb_.Run(keyframe)) |
551 return; | 552 return; |
552 break; | 553 break; |
553 } | 554 } |
554 | 555 |
555 case media::H264NALU::kSPS: { | 556 case media::H264NALU::kSPS: { |
556 int sps_id; | 557 int sps_id; |
557 ASSERT_EQ(media::H264Parser::kOk, h264_parser_.ParseSPS(&sps_id)); | 558 ASSERT_EQ(media::H264Parser::kOk, h264_parser_.ParseSPS(&sps_id)); |
(...skipping 11 matching lines...) Expand all Loading... |
569 | 570 |
570 default: | 571 default: |
571 break; | 572 break; |
572 } | 573 } |
573 } | 574 } |
574 } | 575 } |
575 | 576 |
576 class VP8Validator : public StreamValidator { | 577 class VP8Validator : public StreamValidator { |
577 public: | 578 public: |
578 explicit VP8Validator(const FrameFoundCallback& frame_cb) | 579 explicit VP8Validator(const FrameFoundCallback& frame_cb) |
579 : StreamValidator(frame_cb), | 580 : StreamValidator(frame_cb), seen_keyframe_(false) {} |
580 seen_keyframe_(false) {} | |
581 | 581 |
582 void ProcessStreamBuffer(const uint8_t* stream, size_t size) override; | 582 void ProcessStreamBuffer(const uint8_t* stream, size_t size) override; |
583 | 583 |
584 private: | 584 private: |
585 // Have we already got a keyframe in the stream? | 585 // Have we already got a keyframe in the stream? |
586 bool seen_keyframe_; | 586 bool seen_keyframe_; |
587 }; | 587 }; |
588 | 588 |
589 void VP8Validator::ProcessStreamBuffer(const uint8_t* stream, size_t size) { | 589 void VP8Validator::ProcessStreamBuffer(const uint8_t* stream, size_t size) { |
590 bool keyframe = !(stream[0] & 0x01); | 590 bool keyframe = !(stream[0] & 0x01); |
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1042 // Without it, AppendToFile() will not work. | 1042 // Without it, AppendToFile() will not work. |
1043 EXPECT_EQ(0, base::WriteFile(out_filename, NULL, 0)); | 1043 EXPECT_EQ(0, base::WriteFile(out_filename, NULL, 0)); |
1044 } | 1044 } |
1045 | 1045 |
1046 // Initialize the parameters of the test streams. | 1046 // Initialize the parameters of the test streams. |
1047 UpdateTestStreamData(mid_stream_bitrate_switch, mid_stream_framerate_switch); | 1047 UpdateTestStreamData(mid_stream_bitrate_switch, mid_stream_framerate_switch); |
1048 | 1048 |
1049 thread_checker_.DetachFromThread(); | 1049 thread_checker_.DetachFromThread(); |
1050 } | 1050 } |
1051 | 1051 |
1052 VEAClient::~VEAClient() { LOG_ASSERT(!has_encoder()); } | 1052 VEAClient::~VEAClient() { |
| 1053 LOG_ASSERT(!has_encoder()); |
| 1054 } |
1053 | 1055 |
1054 std::unique_ptr<media::VideoEncodeAccelerator> VEAClient::CreateFakeVEA() { | 1056 std::unique_ptr<media::VideoEncodeAccelerator> VEAClient::CreateFakeVEA() { |
1055 std::unique_ptr<media::VideoEncodeAccelerator> encoder; | 1057 std::unique_ptr<media::VideoEncodeAccelerator> encoder; |
1056 if (g_fake_encoder) { | 1058 if (g_fake_encoder) { |
1057 encoder.reset(new media::FakeVideoEncodeAccelerator( | 1059 encoder.reset(new media::FakeVideoEncodeAccelerator( |
1058 scoped_refptr<base::SingleThreadTaskRunner>( | 1060 scoped_refptr<base::SingleThreadTaskRunner>( |
1059 base::ThreadTaskRunnerHandle::Get()))); | 1061 base::ThreadTaskRunnerHandle::Get()))); |
1060 } | 1062 } |
1061 return encoder; | 1063 return encoder; |
1062 } | 1064 } |
1063 | 1065 |
1064 std::unique_ptr<media::VideoEncodeAccelerator> VEAClient::CreateV4L2VEA() { | 1066 std::unique_ptr<media::VideoEncodeAccelerator> VEAClient::CreateV4L2VEA() { |
1065 std::unique_ptr<media::VideoEncodeAccelerator> encoder; | 1067 std::unique_ptr<media::VideoEncodeAccelerator> encoder; |
1066 #if defined(OS_CHROMEOS) && (defined(ARCH_CPU_ARMEL) || \ | 1068 #if defined(OS_CHROMEOS) && (defined(ARCH_CPU_ARMEL) || \ |
1067 (defined(USE_OZONE) && defined(USE_V4L2_CODEC))) | 1069 (defined(USE_OZONE) && defined(USE_V4L2_CODEC))) |
1068 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kEncoder); | 1070 scoped_refptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kEncoder); |
1069 if (device) | 1071 if (device) |
1070 encoder.reset(new V4L2VideoEncodeAccelerator(device)); | 1072 encoder.reset(new V4L2VideoEncodeAccelerator(device)); |
1071 #endif | 1073 #endif |
1072 return encoder; | 1074 return encoder; |
1073 } | 1075 } |
1074 | 1076 |
1075 std::unique_ptr<media::VideoEncodeAccelerator> VEAClient::CreateVaapiVEA() { | 1077 std::unique_ptr<media::VideoEncodeAccelerator> VEAClient::CreateVaapiVEA() { |
1076 std::unique_ptr<media::VideoEncodeAccelerator> encoder; | 1078 std::unique_ptr<media::VideoEncodeAccelerator> encoder; |
1077 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) | 1079 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) |
(...skipping 18 matching lines...) Expand all Loading... |
1096 CreateFakeVEA(), CreateV4L2VEA(), CreateVaapiVEA(), CreateVTVEA()}; | 1098 CreateFakeVEA(), CreateV4L2VEA(), CreateVaapiVEA(), CreateVTVEA()}; |
1097 | 1099 |
1098 DVLOG(1) << "Profile: " << test_stream_->requested_profile | 1100 DVLOG(1) << "Profile: " << test_stream_->requested_profile |
1099 << ", initial bitrate: " << requested_bitrate_; | 1101 << ", initial bitrate: " << requested_bitrate_; |
1100 | 1102 |
1101 for (size_t i = 0; i < arraysize(encoders); ++i) { | 1103 for (size_t i = 0; i < arraysize(encoders); ++i) { |
1102 if (!encoders[i]) | 1104 if (!encoders[i]) |
1103 continue; | 1105 continue; |
1104 encoder_ = std::move(encoders[i]); | 1106 encoder_ = std::move(encoders[i]); |
1105 SetState(CS_ENCODER_SET); | 1107 SetState(CS_ENCODER_SET); |
1106 if (encoder_->Initialize(kInputFormat, | 1108 if (encoder_->Initialize(kInputFormat, test_stream_->visible_size, |
1107 test_stream_->visible_size, | |
1108 test_stream_->requested_profile, | 1109 test_stream_->requested_profile, |
1109 requested_bitrate_, | 1110 requested_bitrate_, this)) { |
1110 this)) { | |
1111 SetStreamParameters(requested_bitrate_, requested_framerate_); | 1111 SetStreamParameters(requested_bitrate_, requested_framerate_); |
1112 SetState(CS_INITIALIZED); | 1112 SetState(CS_INITIALIZED); |
1113 | 1113 |
1114 if (verify_output_ && !g_fake_encoder) | 1114 if (verify_output_ && !g_fake_encoder) |
1115 quality_validator_.reset(new VideoFrameQualityValidator( | 1115 quality_validator_.reset(new VideoFrameQualityValidator( |
1116 test_stream_->requested_profile, | 1116 test_stream_->requested_profile, |
1117 base::Bind(&VEAClient::DecodeCompleted, base::Unretained(this)), | 1117 base::Bind(&VEAClient::DecodeCompleted, base::Unretained(this)), |
1118 base::Bind(&VEAClient::DecodeFailed, base::Unretained(this)))); | 1118 base::Bind(&VEAClient::DecodeFailed, base::Unretained(this)))); |
1119 return; | 1119 return; |
1120 } | 1120 } |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1350 } | 1350 } |
1351 | 1351 |
1352 scoped_refptr<media::VideoFrame> VEAClient::PrepareInputFrame( | 1352 scoped_refptr<media::VideoFrame> VEAClient::PrepareInputFrame( |
1353 off_t position, | 1353 off_t position, |
1354 int32_t* input_id) { | 1354 int32_t* input_id) { |
1355 CHECK_LE(position + test_stream_->aligned_buffer_size, | 1355 CHECK_LE(position + test_stream_->aligned_buffer_size, |
1356 test_stream_->mapped_aligned_in_file.length()); | 1356 test_stream_->mapped_aligned_in_file.length()); |
1357 | 1357 |
1358 scoped_refptr<media::VideoFrame> frame = CreateFrame(position); | 1358 scoped_refptr<media::VideoFrame> frame = CreateFrame(position); |
1359 EXPECT_TRUE(frame); | 1359 EXPECT_TRUE(frame); |
1360 frame->AddDestructionObserver( | 1360 frame->AddDestructionObserver(media::BindToCurrentLoop( |
1361 media::BindToCurrentLoop( | 1361 base::Bind(&VEAClient::InputNoLongerNeededCallback, |
1362 base::Bind(&VEAClient::InputNoLongerNeededCallback, | 1362 base::Unretained(this), next_input_id_))); |
1363 base::Unretained(this), | |
1364 next_input_id_))); | |
1365 | 1363 |
1366 LOG_ASSERT(inputs_at_client_.insert(next_input_id_).second); | 1364 LOG_ASSERT(inputs_at_client_.insert(next_input_id_).second); |
1367 | 1365 |
1368 *input_id = next_input_id_++; | 1366 *input_id = next_input_id_++; |
1369 return frame; | 1367 return frame; |
1370 } | 1368 } |
1371 | 1369 |
1372 void VEAClient::OnInputTimer() { | 1370 void VEAClient::OnInputTimer() { |
1373 if (!has_encoder() || state_ != CS_ENCODING) | 1371 if (!has_encoder() || state_ != CS_ENCODING) |
1374 input_timer_.reset(); | 1372 input_timer_.reset(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1422 void VEAClient::FeedEncoderWithOutput(base::SharedMemory* shm) { | 1420 void VEAClient::FeedEncoderWithOutput(base::SharedMemory* shm) { |
1423 if (!has_encoder()) | 1421 if (!has_encoder()) |
1424 return; | 1422 return; |
1425 | 1423 |
1426 if (state_ != CS_ENCODING) | 1424 if (state_ != CS_ENCODING) |
1427 return; | 1425 return; |
1428 | 1426 |
1429 base::SharedMemoryHandle dup_handle; | 1427 base::SharedMemoryHandle dup_handle; |
1430 LOG_ASSERT(shm->ShareToProcess(base::GetCurrentProcessHandle(), &dup_handle)); | 1428 LOG_ASSERT(shm->ShareToProcess(base::GetCurrentProcessHandle(), &dup_handle)); |
1431 | 1429 |
1432 media::BitstreamBuffer bitstream_buffer( | 1430 media::BitstreamBuffer bitstream_buffer(next_output_buffer_id_++, dup_handle, |
1433 next_output_buffer_id_++, dup_handle, output_buffer_size_); | 1431 output_buffer_size_); |
1434 LOG_ASSERT(output_buffers_at_client_.insert( | 1432 LOG_ASSERT(output_buffers_at_client_ |
1435 std::make_pair(bitstream_buffer.id(), shm)).second); | 1433 .insert(std::make_pair(bitstream_buffer.id(), shm)) |
| 1434 .second); |
1436 encoder_->UseOutputBitstreamBuffer(bitstream_buffer); | 1435 encoder_->UseOutputBitstreamBuffer(bitstream_buffer); |
1437 } | 1436 } |
1438 | 1437 |
1439 bool VEAClient::HandleEncodedFrame(bool keyframe) { | 1438 bool VEAClient::HandleEncodedFrame(bool keyframe) { |
1440 // This would be a bug in the test, which should not ignore false | 1439 // This would be a bug in the test, which should not ignore false |
1441 // return value from this method. | 1440 // return value from this method. |
1442 LOG_ASSERT(num_encoded_frames_ <= num_frames_to_encode_); | 1441 LOG_ASSERT(num_encoded_frames_ <= num_frames_to_encode_); |
1443 | 1442 |
1444 last_frame_ready_time_ = base::TimeTicks::Now(); | 1443 last_frame_ready_time_ = base::TimeTicks::Now(); |
1445 | 1444 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1519 if (test_perf_) | 1518 if (test_perf_) |
1520 EXPECT_GE(frames_per_second(), kMinPerfFPS); | 1519 EXPECT_GE(frames_per_second(), kMinPerfFPS); |
1521 } | 1520 } |
1522 | 1521 |
1523 void VEAClient::VerifyStreamProperties() { | 1522 void VEAClient::VerifyStreamProperties() { |
1524 LOG_ASSERT(num_frames_since_last_check_ > 0UL); | 1523 LOG_ASSERT(num_frames_since_last_check_ > 0UL); |
1525 LOG_ASSERT(encoded_stream_size_since_last_check_ > 0UL); | 1524 LOG_ASSERT(encoded_stream_size_since_last_check_ > 0UL); |
1526 unsigned int bitrate = encoded_stream_size_since_last_check_ * 8 * | 1525 unsigned int bitrate = encoded_stream_size_since_last_check_ * 8 * |
1527 current_framerate_ / num_frames_since_last_check_; | 1526 current_framerate_ / num_frames_since_last_check_; |
1528 DVLOG(1) << "Current chunk's bitrate: " << bitrate | 1527 DVLOG(1) << "Current chunk's bitrate: " << bitrate |
1529 << " (expected: " << current_requested_bitrate_ | 1528 << " (expected: " << current_requested_bitrate_ << " @ " |
1530 << " @ " << current_framerate_ << " FPS," | 1529 << current_framerate_ << " FPS," |
1531 << " num frames in chunk: " << num_frames_since_last_check_; | 1530 << " num frames in chunk: " << num_frames_since_last_check_; |
1532 | 1531 |
1533 num_frames_since_last_check_ = 0; | 1532 num_frames_since_last_check_ = 0; |
1534 encoded_stream_size_since_last_check_ = 0; | 1533 encoded_stream_size_since_last_check_ = 0; |
1535 | 1534 |
1536 if (force_bitrate_) { | 1535 if (force_bitrate_) { |
1537 EXPECT_NEAR(bitrate, | 1536 EXPECT_NEAR(bitrate, current_requested_bitrate_, |
1538 current_requested_bitrate_, | |
1539 kBitrateTolerance * current_requested_bitrate_); | 1537 kBitrateTolerance * current_requested_bitrate_); |
1540 } | 1538 } |
1541 | 1539 |
1542 // All requested keyframes should've been provided. Allow the last requested | 1540 // All requested keyframes should've been provided. Allow the last requested |
1543 // frame to remain undelivered if we haven't reached the maximum frame number | 1541 // frame to remain undelivered if we haven't reached the maximum frame number |
1544 // by which it should have arrived. | 1542 // by which it should have arrived. |
1545 if (num_encoded_frames_ < next_keyframe_at_ + kMaxKeyframeDelay) | 1543 if (num_encoded_frames_ < next_keyframe_at_ + kMaxKeyframeDelay) |
1546 EXPECT_LE(num_keyframes_requested_, 1UL); | 1544 EXPECT_LE(num_keyframes_requested_, 1UL); |
1547 else | 1545 else |
1548 EXPECT_EQ(num_keyframes_requested_, 0UL); | 1546 EXPECT_EQ(num_keyframes_requested_, 0UL); |
1549 } | 1547 } |
1550 | 1548 |
1551 void VEAClient::WriteIvfFileHeader() { | 1549 void VEAClient::WriteIvfFileHeader() { |
1552 media::IvfFileHeader header = {}; | 1550 media::IvfFileHeader header = {}; |
1553 | 1551 |
1554 memcpy(header.signature, media::kIvfHeaderSignature, | 1552 memcpy(header.signature, media::kIvfHeaderSignature, |
1555 sizeof(header.signature)); | 1553 sizeof(header.signature)); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1601 size_t num_concurrent_encoders = base::get<0>(GetParam()); | 1599 size_t num_concurrent_encoders = base::get<0>(GetParam()); |
1602 const bool save_to_file = base::get<1>(GetParam()); | 1600 const bool save_to_file = base::get<1>(GetParam()); |
1603 const unsigned int keyframe_period = base::get<2>(GetParam()); | 1601 const unsigned int keyframe_period = base::get<2>(GetParam()); |
1604 const bool force_bitrate = base::get<3>(GetParam()); | 1602 const bool force_bitrate = base::get<3>(GetParam()); |
1605 const bool test_perf = base::get<4>(GetParam()); | 1603 const bool test_perf = base::get<4>(GetParam()); |
1606 const bool mid_stream_bitrate_switch = base::get<5>(GetParam()); | 1604 const bool mid_stream_bitrate_switch = base::get<5>(GetParam()); |
1607 const bool mid_stream_framerate_switch = base::get<6>(GetParam()); | 1605 const bool mid_stream_framerate_switch = base::get<6>(GetParam()); |
1608 const bool verify_output = | 1606 const bool verify_output = |
1609 base::get<7>(GetParam()) || g_env->verify_all_output(); | 1607 base::get<7>(GetParam()) || g_env->verify_all_output(); |
1610 | 1608 |
1611 ScopedVector<ClientStateNotification<ClientState> > notes; | 1609 ScopedVector<ClientStateNotification<ClientState>> notes; |
1612 ScopedVector<VEAClient> clients; | 1610 ScopedVector<VEAClient> clients; |
1613 base::Thread encoder_thread("EncoderThread"); | 1611 base::Thread encoder_thread("EncoderThread"); |
1614 ASSERT_TRUE(encoder_thread.Start()); | 1612 ASSERT_TRUE(encoder_thread.Start()); |
1615 | 1613 |
1616 if (g_env->test_streams_.size() > 1) | 1614 if (g_env->test_streams_.size() > 1) |
1617 num_concurrent_encoders = g_env->test_streams_.size(); | 1615 num_concurrent_encoders = g_env->test_streams_.size(); |
1618 | 1616 |
1619 // Create all encoders. | 1617 // Create all encoders. |
1620 for (size_t i = 0; i < num_concurrent_encoders; i++) { | 1618 for (size_t i = 0; i < num_concurrent_encoders; i++) { |
1621 size_t test_stream_index = i % g_env->test_streams_.size(); | 1619 size_t test_stream_index = i % g_env->test_streams_.size(); |
1622 // Disregard save_to_file if we didn't get an output filename. | 1620 // Disregard save_to_file if we didn't get an output filename. |
1623 bool encoder_save_to_file = | 1621 bool encoder_save_to_file = |
1624 (save_to_file && | 1622 (save_to_file && |
1625 !g_env->test_streams_[test_stream_index]->out_filename.empty()); | 1623 !g_env->test_streams_[test_stream_index]->out_filename.empty()); |
1626 | 1624 |
1627 notes.push_back(new ClientStateNotification<ClientState>()); | 1625 notes.push_back(new ClientStateNotification<ClientState>()); |
1628 clients.push_back(new VEAClient( | 1626 clients.push_back(new VEAClient( |
1629 g_env->test_streams_[test_stream_index], notes.back(), | 1627 g_env->test_streams_[test_stream_index], notes.back(), |
1630 encoder_save_to_file, keyframe_period, force_bitrate, test_perf, | 1628 encoder_save_to_file, keyframe_period, force_bitrate, test_perf, |
1631 mid_stream_bitrate_switch, mid_stream_framerate_switch, verify_output)); | 1629 mid_stream_bitrate_switch, mid_stream_framerate_switch, verify_output)); |
1632 | 1630 |
1633 encoder_thread.message_loop()->PostTask( | 1631 encoder_thread.message_loop()->PostTask( |
1634 FROM_HERE, | 1632 FROM_HERE, base::Bind(&VEAClient::CreateEncoder, |
1635 base::Bind(&VEAClient::CreateEncoder, | 1633 base::Unretained(clients.back()))); |
1636 base::Unretained(clients.back()))); | |
1637 } | 1634 } |
1638 | 1635 |
1639 // All encoders must pass through states in this order. | 1636 // All encoders must pass through states in this order. |
1640 enum ClientState state_transitions[] = { | 1637 enum ClientState state_transitions[] = { |
1641 CS_ENCODER_SET, CS_INITIALIZED, CS_ENCODING, CS_FINISHED, CS_VALIDATED}; | 1638 CS_ENCODER_SET, CS_INITIALIZED, CS_ENCODING, CS_FINISHED, CS_VALIDATED}; |
1642 | 1639 |
1643 // Wait for all encoders to go through all states and finish. | 1640 // Wait for all encoders to go through all states and finish. |
1644 // Do this by waiting for all encoders to advance to state n before checking | 1641 // Do this by waiting for all encoders to advance to state n before checking |
1645 // state n+1, to verify that they are able to operate concurrently. | 1642 // state n+1, to verify that they are able to operate concurrently. |
1646 // It also simulates the real-world usage better, as the main thread, on which | 1643 // It also simulates the real-world usage better, as the main thread, on which |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1729 base::MakeTuple(3, false, 0, false, false, false, false, false))); | 1726 base::MakeTuple(3, false, 0, false, false, false, false, false))); |
1730 #endif | 1727 #endif |
1731 | 1728 |
1732 // TODO(posciak): more tests: | 1729 // TODO(posciak): more tests: |
1733 // - async FeedEncoderWithOutput | 1730 // - async FeedEncoderWithOutput |
1734 // - out-of-order return of outputs to encoder | 1731 // - out-of-order return of outputs to encoder |
1735 // - multiple encoders + decoders | 1732 // - multiple encoders + decoders |
1736 // - mid-stream encoder_->Destroy() | 1733 // - mid-stream encoder_->Destroy() |
1737 | 1734 |
1738 } // namespace | 1735 } // namespace |
1739 } // namespace content | 1736 } // namespace media |
1740 | 1737 |
1741 int main(int argc, char** argv) { | 1738 int main(int argc, char** argv) { |
1742 testing::InitGoogleTest(&argc, argv); // Removes gtest-specific args. | 1739 testing::InitGoogleTest(&argc, argv); // Removes gtest-specific args. |
1743 base::CommandLine::Init(argc, argv); | 1740 base::CommandLine::Init(argc, argv); |
1744 | 1741 |
1745 base::ShadowingAtExitManager at_exit_manager; | 1742 base::ShadowingAtExitManager at_exit_manager; |
1746 base::MessageLoop main_loop; | 1743 base::MessageLoop main_loop; |
1747 | 1744 |
1748 std::unique_ptr<base::FilePath::StringType> test_stream_data( | 1745 std::unique_ptr<base::FilePath::StringType> test_stream_data( |
1749 new base::FilePath::StringType( | 1746 new base::FilePath::StringType( |
1750 media::GetTestDataFilePath(content::g_default_in_filename).value() + | 1747 media::GetTestDataFilePath(media::g_default_in_filename).value() + |
1751 content::g_default_in_parameters)); | 1748 media::g_default_in_parameters)); |
1752 | 1749 |
1753 // Needed to enable DVLOG through --vmodule. | 1750 // Needed to enable DVLOG through --vmodule. |
1754 logging::LoggingSettings settings; | 1751 logging::LoggingSettings settings; |
1755 settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; | 1752 settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; |
1756 LOG_ASSERT(logging::InitLogging(settings)); | 1753 LOG_ASSERT(logging::InitLogging(settings)); |
1757 | 1754 |
1758 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); | 1755 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); |
1759 DCHECK(cmd_line); | 1756 DCHECK(cmd_line); |
1760 | 1757 |
1761 bool run_at_fps = false; | 1758 bool run_at_fps = false; |
1762 bool needs_encode_latency = false; | 1759 bool needs_encode_latency = false; |
1763 bool verify_all_output = false; | 1760 bool verify_all_output = false; |
1764 base::FilePath log_path; | 1761 base::FilePath log_path; |
1765 | 1762 |
1766 base::CommandLine::SwitchMap switches = cmd_line->GetSwitches(); | 1763 base::CommandLine::SwitchMap switches = cmd_line->GetSwitches(); |
1767 for (base::CommandLine::SwitchMap::const_iterator it = switches.begin(); | 1764 for (base::CommandLine::SwitchMap::const_iterator it = switches.begin(); |
1768 it != switches.end(); | 1765 it != switches.end(); ++it) { |
1769 ++it) { | |
1770 if (it->first == "test_stream_data") { | 1766 if (it->first == "test_stream_data") { |
1771 test_stream_data->assign(it->second.c_str()); | 1767 test_stream_data->assign(it->second.c_str()); |
1772 continue; | 1768 continue; |
1773 } | 1769 } |
1774 // Output machine-readable logs with fixed formats to a file. | 1770 // Output machine-readable logs with fixed formats to a file. |
1775 if (it->first == "output_log") { | 1771 if (it->first == "output_log") { |
1776 log_path = base::FilePath( | 1772 log_path = base::FilePath( |
1777 base::FilePath::StringType(it->second.begin(), it->second.end())); | 1773 base::FilePath::StringType(it->second.begin(), it->second.end())); |
1778 continue; | 1774 continue; |
1779 } | 1775 } |
1780 if (it->first == "num_frames_to_encode") { | 1776 if (it->first == "num_frames_to_encode") { |
1781 std::string input(it->second.begin(), it->second.end()); | 1777 std::string input(it->second.begin(), it->second.end()); |
1782 LOG_ASSERT(base::StringToInt(input, &content::g_num_frames_to_encode)); | 1778 LOG_ASSERT(base::StringToInt(input, &media::g_num_frames_to_encode)); |
1783 continue; | 1779 continue; |
1784 } | 1780 } |
1785 if (it->first == "measure_latency") { | 1781 if (it->first == "measure_latency") { |
1786 needs_encode_latency = true; | 1782 needs_encode_latency = true; |
1787 continue; | 1783 continue; |
1788 } | 1784 } |
1789 if (it->first == "fake_encoder") { | 1785 if (it->first == "fake_encoder") { |
1790 content::g_fake_encoder = true; | 1786 media::g_fake_encoder = true; |
1791 continue; | 1787 continue; |
1792 } | 1788 } |
1793 if (it->first == "run_at_fps") { | 1789 if (it->first == "run_at_fps") { |
1794 run_at_fps = true; | 1790 run_at_fps = true; |
1795 continue; | 1791 continue; |
1796 } | 1792 } |
1797 if (it->first == "verify_all_output") { | 1793 if (it->first == "verify_all_output") { |
1798 verify_all_output = true; | 1794 verify_all_output = true; |
1799 continue; | 1795 continue; |
1800 } | 1796 } |
1801 if (it->first == "v" || it->first == "vmodule") | 1797 if (it->first == "v" || it->first == "vmodule") |
1802 continue; | 1798 continue; |
1803 if (it->first == "ozone-platform" || it->first == "ozone-use-surfaceless") | 1799 if (it->first == "ozone-platform" || it->first == "ozone-use-surfaceless") |
1804 continue; | 1800 continue; |
1805 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; | 1801 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; |
1806 } | 1802 } |
1807 | 1803 |
1808 if (needs_encode_latency && !run_at_fps) { | 1804 if (needs_encode_latency && !run_at_fps) { |
1809 // Encode latency can only be measured with --run_at_fps. Otherwise, we get | 1805 // Encode latency can only be measured with --run_at_fps. Otherwise, we get |
1810 // skewed results since it may queue too many frames at once with the same | 1806 // skewed results since it may queue too many frames at once with the same |
1811 // encode start time. | 1807 // encode start time. |
1812 LOG(FATAL) << "--measure_latency requires --run_at_fps enabled to work."; | 1808 LOG(FATAL) << "--measure_latency requires --run_at_fps enabled to work."; |
1813 } | 1809 } |
1814 | 1810 |
1815 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) | 1811 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) |
1816 content::VaapiWrapper::PreSandboxInitialization(); | 1812 media::VaapiWrapper::PreSandboxInitialization(); |
1817 #endif | 1813 #endif |
1818 | 1814 |
1819 content::g_env = | 1815 media::g_env = |
1820 reinterpret_cast<content::VideoEncodeAcceleratorTestEnvironment*>( | 1816 reinterpret_cast<media::VideoEncodeAcceleratorTestEnvironment*>( |
1821 testing::AddGlobalTestEnvironment( | 1817 testing::AddGlobalTestEnvironment( |
1822 new content::VideoEncodeAcceleratorTestEnvironment( | 1818 new media::VideoEncodeAcceleratorTestEnvironment( |
1823 std::move(test_stream_data), log_path, run_at_fps, | 1819 std::move(test_stream_data), log_path, run_at_fps, |
1824 needs_encode_latency, verify_all_output))); | 1820 needs_encode_latency, verify_all_output))); |
1825 | 1821 |
1826 return RUN_ALL_TESTS(); | 1822 return RUN_ALL_TESTS(); |
1827 } | 1823 } |
OLD | NEW |