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/files/file_util.h" | 8 #include "base/files/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" |
11 #include "base/numerics/safe_conversions.h" | 11 #include "base/numerics/safe_conversions.h" |
12 #include "base/process/process_handle.h" | 12 #include "base/process/process_handle.h" |
13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
14 #include "base/strings/string_split.h" | 14 #include "base/strings/string_split.h" |
15 #include "base/sys_byteorder.h" | 15 #include "base/sys_byteorder.h" |
16 #include "base/time/time.h" | 16 #include "base/time/time.h" |
17 #include "content/common/gpu/media/video_accelerator_unittest_helpers.h" | 17 #include "content/common/gpu/media/video_accelerator_unittest_helpers.h" |
18 #include "media/base/bind_to_current_loop.h" | 18 #include "media/base/bind_to_current_loop.h" |
19 #include "media/base/bitstream_buffer.h" | 19 #include "media/base/bitstream_buffer.h" |
20 #include "media/base/test_data_util.h" | 20 #include "media/base/test_data_util.h" |
21 #include "media/filters/h264_parser.h" | 21 #include "media/filters/h264_parser.h" |
| 22 #include "media/video/fake_video_encode_accelerator.h" |
22 #include "media/video/video_encode_accelerator.h" | 23 #include "media/video/video_encode_accelerator.h" |
23 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
24 | 25 |
25 #if defined(USE_X11) | 26 #if defined(USE_X11) |
26 #include "ui/gfx/x/x11_types.h" | 27 #include "ui/gfx/x/x11_types.h" |
27 #endif | 28 #endif |
28 | 29 |
29 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) | 30 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) |
30 #include "content/common/gpu/media/v4l2_video_encode_accelerator.h" | 31 #include "content/common/gpu/media/v4l2_video_encode_accelerator.h" |
31 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11) | 32 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11) |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 // parameters if a specific subsequent parameter is required): | 91 // parameters if a specific subsequent parameter is required): |
91 // - |requested_bitrate| requested bitrate in bits per second. | 92 // - |requested_bitrate| requested bitrate in bits per second. |
92 // - |requested_framerate| requested initial framerate. | 93 // - |requested_framerate| requested initial framerate. |
93 // - |requested_subsequent_bitrate| bitrate to switch to in the middle of the | 94 // - |requested_subsequent_bitrate| bitrate to switch to in the middle of the |
94 // stream. | 95 // stream. |
95 // - |requested_subsequent_framerate| framerate to switch to in the middle | 96 // - |requested_subsequent_framerate| framerate to switch to in the middle |
96 // of the stream. | 97 // of the stream. |
97 // Bitrate is only forced for tests that test bitrate. | 98 // Bitrate is only forced for tests that test bitrate. |
98 const char* g_default_in_filename = "bear_320x192_40frames.yuv"; | 99 const char* g_default_in_filename = "bear_320x192_40frames.yuv"; |
99 const char* g_default_in_parameters = ":320:192:1:out.h264:200000"; | 100 const char* g_default_in_parameters = ":320:192:1:out.h264:200000"; |
| 101 |
| 102 // Enabled by including a --fake_encoder flag to the command line invoking the |
| 103 // test. |
| 104 bool g_fake_encoder = false; |
| 105 |
100 // Environment to store test stream data for all test cases. | 106 // Environment to store test stream data for all test cases. |
101 class VideoEncodeAcceleratorTestEnvironment; | 107 class VideoEncodeAcceleratorTestEnvironment; |
102 VideoEncodeAcceleratorTestEnvironment* g_env; | 108 VideoEncodeAcceleratorTestEnvironment* g_env; |
103 | 109 |
104 struct IvfFileHeader { | 110 struct IvfFileHeader { |
105 char signature[4]; // signature: 'DKIF' | 111 char signature[4]; // signature: 'DKIF' |
106 uint16_t version; // version (should be 0) | 112 uint16_t version; // version (should be 0) |
107 uint16_t header_size; // size of header in bytes | 113 uint16_t header_size; // size of header in bytes |
108 uint32_t fourcc; // codec FourCC (e.g., 'VP80') | 114 uint32_t fourcc; // codec FourCC (e.g., 'VP80') |
109 uint16_t width; // width in pixels | 115 uint16_t width; // width in pixels |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 // no simple way to detect this. We'd need to parse the frames and go through | 483 // no simple way to detect this. We'd need to parse the frames and go through |
478 // partition numbers/sizes. For now assume one frame per buffer. | 484 // partition numbers/sizes. For now assume one frame per buffer. |
479 } | 485 } |
480 | 486 |
481 // static | 487 // static |
482 scoped_ptr<StreamValidator> StreamValidator::Create( | 488 scoped_ptr<StreamValidator> StreamValidator::Create( |
483 media::VideoCodecProfile profile, | 489 media::VideoCodecProfile profile, |
484 const FrameFoundCallback& frame_cb) { | 490 const FrameFoundCallback& frame_cb) { |
485 scoped_ptr<StreamValidator> validator; | 491 scoped_ptr<StreamValidator> validator; |
486 | 492 |
487 if (IsH264(profile)) { | 493 if (g_fake_encoder) { |
| 494 validator.reset(NULL); |
| 495 } else if (IsH264(profile)) { |
488 validator.reset(new H264Validator(frame_cb)); | 496 validator.reset(new H264Validator(frame_cb)); |
489 } else if (IsVP8(profile)) { | 497 } else if (IsVP8(profile)) { |
490 validator.reset(new VP8Validator(frame_cb)); | 498 validator.reset(new VP8Validator(frame_cb)); |
491 } else { | 499 } else { |
492 LOG(FATAL) << "Unsupported profile: " << profile; | 500 LOG(FATAL) << "Unsupported profile: " << profile; |
493 } | 501 } |
494 | 502 |
495 return validator.Pass(); | 503 return validator.Pass(); |
496 } | 504 } |
497 | 505 |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 requested_framerate_(0), | 696 requested_framerate_(0), |
689 requested_subsequent_bitrate_(0), | 697 requested_subsequent_bitrate_(0), |
690 requested_subsequent_framerate_(0) { | 698 requested_subsequent_framerate_(0) { |
691 if (keyframe_period_) | 699 if (keyframe_period_) |
692 CHECK_LT(kMaxKeyframeDelay, keyframe_period_); | 700 CHECK_LT(kMaxKeyframeDelay, keyframe_period_); |
693 | 701 |
694 validator_ = StreamValidator::Create( | 702 validator_ = StreamValidator::Create( |
695 test_stream_->requested_profile, | 703 test_stream_->requested_profile, |
696 base::Bind(&VEAClient::HandleEncodedFrame, base::Unretained(this))); | 704 base::Bind(&VEAClient::HandleEncodedFrame, base::Unretained(this))); |
697 | 705 |
698 CHECK(validator_.get()); | 706 |
| 707 CHECK(g_fake_encoder || validator_.get()); |
699 | 708 |
700 if (save_to_file_) { | 709 if (save_to_file_) { |
701 CHECK(!test_stream_->out_filename.empty()); | 710 CHECK(!test_stream_->out_filename.empty()); |
702 base::FilePath out_filename(test_stream_->out_filename); | 711 base::FilePath out_filename(test_stream_->out_filename); |
703 // This creates or truncates out_filename. | 712 // This creates or truncates out_filename. |
704 // Without it, AppendToFile() will not work. | 713 // Without it, AppendToFile() will not work. |
705 EXPECT_EQ(0, base::WriteFile(out_filename, NULL, 0)); | 714 EXPECT_EQ(0, base::WriteFile(out_filename, NULL, 0)); |
706 } | 715 } |
707 | 716 |
708 // Initialize the parameters of the test streams. | 717 // Initialize the parameters of the test streams. |
709 UpdateTestStreamData(mid_stream_bitrate_switch, mid_stream_framerate_switch); | 718 UpdateTestStreamData(mid_stream_bitrate_switch, mid_stream_framerate_switch); |
710 | 719 |
711 thread_checker_.DetachFromThread(); | 720 thread_checker_.DetachFromThread(); |
712 } | 721 } |
713 | 722 |
714 VEAClient::~VEAClient() { CHECK(!has_encoder()); } | 723 VEAClient::~VEAClient() { CHECK(!has_encoder()); } |
715 | 724 |
716 void VEAClient::CreateEncoder() { | 725 void VEAClient::CreateEncoder() { |
717 DCHECK(thread_checker_.CalledOnValidThread()); | 726 DCHECK(thread_checker_.CalledOnValidThread()); |
718 CHECK(!has_encoder()); | 727 CHECK(!has_encoder()); |
719 | 728 |
| 729 |
| 730 if (g_fake_encoder) { |
| 731 encoder_.reset( |
| 732 new media::FakeVideoEncodeAccelerator( |
| 733 base::MessageLoopProxy::current())); |
| 734 } else { |
720 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) | 735 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) |
721 scoped_ptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kEncoder); | 736 scoped_ptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kEncoder); |
722 encoder_.reset(new V4L2VideoEncodeAccelerator(device.Pass())); | 737 encoder_.reset(new V4L2VideoEncodeAccelerator(device.Pass())); |
723 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11) | 738 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) && defined(USE_X11) |
724 encoder_.reset(new VaapiVideoEncodeAccelerator(gfx::GetXDisplay())); | 739 encoder_.reset(new VaapiVideoEncodeAccelerator(gfx::GetXDisplay())); |
725 #endif | 740 #endif |
| 741 } |
726 | 742 |
727 SetState(CS_ENCODER_SET); | 743 SetState(CS_ENCODER_SET); |
728 | 744 |
729 DVLOG(1) << "Profile: " << test_stream_->requested_profile | 745 DVLOG(1) << "Profile: " << test_stream_->requested_profile |
730 << ", initial bitrate: " << requested_bitrate_; | 746 << ", initial bitrate: " << requested_bitrate_; |
731 if (!encoder_->Initialize(kInputFormat, | 747 if (!encoder_->Initialize(kInputFormat, |
732 test_stream_->visible_size, | 748 test_stream_->visible_size, |
733 test_stream_->requested_profile, | 749 test_stream_->requested_profile, |
734 requested_bitrate_, | 750 requested_bitrate_, |
735 this)) { | 751 this)) { |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 base::SharedMemory* shm = it->second; | 867 base::SharedMemory* shm = it->second; |
852 output_buffers_at_client_.erase(it); | 868 output_buffers_at_client_.erase(it); |
853 | 869 |
854 if (state_ == CS_FINISHED) | 870 if (state_ == CS_FINISHED) |
855 return; | 871 return; |
856 | 872 |
857 encoded_stream_size_since_last_check_ += payload_size; | 873 encoded_stream_size_since_last_check_ += payload_size; |
858 | 874 |
859 const uint8* stream_ptr = static_cast<const uint8*>(shm->memory()); | 875 const uint8* stream_ptr = static_cast<const uint8*>(shm->memory()); |
860 if (payload_size > 0) { | 876 if (payload_size > 0) { |
861 validator_->ProcessStreamBuffer(stream_ptr, payload_size); | 877 if (validator_) { |
| 878 validator_->ProcessStreamBuffer(stream_ptr, payload_size); |
| 879 } else { |
| 880 HandleEncodedFrame(key_frame); |
| 881 } |
862 | 882 |
863 if (save_to_file_) { | 883 if (save_to_file_) { |
864 if (IsVP8(test_stream_->requested_profile)) | 884 if (IsVP8(test_stream_->requested_profile)) |
865 WriteIvfFrameHeader(num_encoded_frames_ - 1, payload_size); | 885 WriteIvfFrameHeader(num_encoded_frames_ - 1, payload_size); |
866 | 886 |
867 EXPECT_TRUE(base::AppendToFile( | 887 EXPECT_TRUE(base::AppendToFile( |
868 base::FilePath::FromUTF8Unsafe(test_stream_->out_filename), | 888 base::FilePath::FromUTF8Unsafe(test_stream_->out_filename), |
869 static_cast<char*>(shm->memory()), | 889 static_cast<char*>(shm->memory()), |
870 base::checked_cast<int>(payload_size))); | 890 base::checked_cast<int>(payload_size))); |
871 } | 891 } |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1276 for (base::CommandLine::SwitchMap::const_iterator it = switches.begin(); | 1296 for (base::CommandLine::SwitchMap::const_iterator it = switches.begin(); |
1277 it != switches.end(); | 1297 it != switches.end(); |
1278 ++it) { | 1298 ++it) { |
1279 if (it->first == "test_stream_data") { | 1299 if (it->first == "test_stream_data") { |
1280 test_stream_data->assign(it->second.c_str()); | 1300 test_stream_data->assign(it->second.c_str()); |
1281 continue; | 1301 continue; |
1282 } | 1302 } |
1283 if (it->first == "num_frames_to_encode") { | 1303 if (it->first == "num_frames_to_encode") { |
1284 std::string input(it->second.begin(), it->second.end()); | 1304 std::string input(it->second.begin(), it->second.end()); |
1285 CHECK(base::StringToInt(input, &content::g_num_frames_to_encode)); | 1305 CHECK(base::StringToInt(input, &content::g_num_frames_to_encode)); |
| 1306 if (it->first == "fake_encoder") { |
| 1307 content::g_fake_encoder = true; |
1286 continue; | 1308 continue; |
1287 } | 1309 } |
1288 if (it->first == "v" || it->first == "vmodule") | 1310 if (it->first == "v" || it->first == "vmodule") |
1289 continue; | 1311 continue; |
1290 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; | 1312 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; |
1291 } | 1313 } |
1292 | 1314 |
1293 content::g_env = | 1315 content::g_env = |
1294 reinterpret_cast<content::VideoEncodeAcceleratorTestEnvironment*>( | 1316 reinterpret_cast<content::VideoEncodeAcceleratorTestEnvironment*>( |
1295 testing::AddGlobalTestEnvironment( | 1317 testing::AddGlobalTestEnvironment( |
1296 new content::VideoEncodeAcceleratorTestEnvironment( | 1318 new content::VideoEncodeAcceleratorTestEnvironment( |
1297 test_stream_data.Pass()))); | 1319 test_stream_data.Pass()))); |
1298 | 1320 |
1299 return RUN_ALL_TESTS(); | 1321 return RUN_ALL_TESTS(); |
1300 } | 1322 } |
OLD | NEW |