OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTEST_H
_ | 11 #ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTEST_H
_ |
12 #define WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTEST_H
_ | 12 #define WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTEST_H
_ |
13 | 13 |
14 #include <math.h> | 14 #include <math.h> |
15 | 15 |
16 #include <memory> | 16 #include <memory> |
17 #include <string> | 17 #include <string> |
18 | 18 |
| 19 #if defined(WEBRTC_ANDROID) |
| 20 #include "webrtc/modules/video_coding/codecs/test/android_test_initializer.h" |
| 21 #include "webrtc/sdk/android/src/jni/androidmediadecoder_jni.h" |
| 22 #include "webrtc/sdk/android/src/jni/androidmediaencoder_jni.h" |
| 23 #elif defined(WEBRTC_IOS) |
| 24 #include "webrtc/sdk/objc/Framework/Classes/h264_video_toolbox_decoder.h" |
| 25 #include "webrtc/sdk/objc/Framework/Classes/h264_video_toolbox_encoder.h" |
| 26 #endif |
| 27 |
| 28 #include "webrtc/media/engine/webrtcvideodecoderfactory.h" |
| 29 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" |
19 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h" | 30 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h" |
20 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" | 31 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" |
21 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" | 32 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" |
22 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" | 33 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" |
23 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" | 34 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" |
24 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h" | 35 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h" |
25 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" | 36 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" |
26 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 37 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
27 #include "webrtc/modules/video_coding/include/video_coding.h" | 38 #include "webrtc/modules/video_coding/include/video_coding.h" |
28 #include "webrtc/test/gtest.h" | 39 #include "webrtc/test/gtest.h" |
(...skipping 14 matching lines...) Expand all Loading... |
43 const int kBaseKeyFrameInterval = 3000; | 54 const int kBaseKeyFrameInterval = 3000; |
44 | 55 |
45 // Default sequence is foreman (CIF): may be better to use VGA for resize test. | 56 // Default sequence is foreman (CIF): may be better to use VGA for resize test. |
46 const int kCifWidth = 352; | 57 const int kCifWidth = 352; |
47 const int kCifHeight = 288; | 58 const int kCifHeight = 288; |
48 const char kFilenameForemanCif[] = "foreman_cif"; | 59 const char kFilenameForemanCif[] = "foreman_cif"; |
49 | 60 |
50 // Codec and network settings. | 61 // Codec and network settings. |
51 struct CodecConfigPars { | 62 struct CodecConfigPars { |
52 VideoCodecType codec_type; | 63 VideoCodecType codec_type; |
| 64 bool hw_codec; |
53 float packet_loss; | 65 float packet_loss; |
54 int num_temporal_layers; | 66 int num_temporal_layers; |
55 int key_frame_interval; | 67 int key_frame_interval; |
56 bool error_concealment_on; | 68 bool error_concealment_on; |
57 bool denoising_on; | 69 bool denoising_on; |
58 bool frame_dropper_on; | 70 bool frame_dropper_on; |
59 bool spatial_resize_on; | 71 bool spatial_resize_on; |
60 int width; | 72 int width; |
61 int height; | 73 int height; |
62 std::string filename; | 74 std::string filename; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 // writes it to the output directory. After completion, quality metrics | 122 // writes it to the output directory. After completion, quality metrics |
111 // (PSNR and SSIM) and rate control metrics are computed to verify that the | 123 // (PSNR and SSIM) and rate control metrics are computed to verify that the |
112 // quality and encoder response is acceptable. The rate control tests allow us | 124 // quality and encoder response is acceptable. The rate control tests allow us |
113 // to verify the behavior for changing bitrate, changing frame rate, frame | 125 // to verify the behavior for changing bitrate, changing frame rate, frame |
114 // dropping/spatial resize, and temporal layers. The limits for the rate | 126 // dropping/spatial resize, and temporal layers. The limits for the rate |
115 // control metrics are set to be fairly conservative, so failure should only | 127 // control metrics are set to be fairly conservative, so failure should only |
116 // happen when some significant regression or breakdown occurs. | 128 // happen when some significant regression or breakdown occurs. |
117 class VideoProcessorIntegrationTest : public testing::Test { | 129 class VideoProcessorIntegrationTest : public testing::Test { |
118 protected: | 130 protected: |
119 std::unique_ptr<VideoEncoder> encoder_; | 131 std::unique_ptr<VideoEncoder> encoder_; |
| 132 std::unique_ptr<cricket::WebRtcVideoEncoderFactory> external_encoder_factory_; |
120 std::unique_ptr<VideoDecoder> decoder_; | 133 std::unique_ptr<VideoDecoder> decoder_; |
| 134 std::unique_ptr<cricket::WebRtcVideoDecoderFactory> external_decoder_factory_; |
121 std::unique_ptr<test::FrameReader> frame_reader_; | 135 std::unique_ptr<test::FrameReader> frame_reader_; |
122 std::unique_ptr<test::FrameWriter> frame_writer_; | 136 std::unique_ptr<test::FrameWriter> frame_writer_; |
123 test::PacketReader packet_reader_; | 137 test::PacketReader packet_reader_; |
124 std::unique_ptr<test::PacketManipulator> packet_manipulator_; | 138 std::unique_ptr<test::PacketManipulator> packet_manipulator_; |
125 test::Stats stats_; | 139 test::Stats stats_; |
126 test::TestConfig config_; | 140 test::TestConfig config_; |
127 VideoCodec codec_settings_; | 141 VideoCodec codec_settings_; |
| 142 // Must be destroyed before |encoder_| and |decoder_|. |
128 std::unique_ptr<test::VideoProcessor> processor_; | 143 std::unique_ptr<test::VideoProcessor> processor_; |
129 TemporalLayersFactory tl_factory_; | 144 TemporalLayersFactory tl_factory_; |
130 | 145 |
131 // Quantities defined/updated for every encoder rate update. | 146 // Quantities defined/updated for every encoder rate update. |
132 // Some quantities defined per temporal layer (at most 3 layers in this test). | 147 // Some quantities defined per temporal layer (at most 3 layers in this test). |
133 int num_frames_per_update_[3]; | 148 int num_frames_per_update_[3]; |
134 float sum_frame_size_mismatch_[3]; | 149 float sum_frame_size_mismatch_[3]; |
135 float sum_encoded_frame_size_[3]; | 150 float sum_encoded_frame_size_[3]; |
136 float encoding_bitrate_[3]; | 151 float encoding_bitrate_[3]; |
137 float per_frame_bandwidth_[3]; | 152 float per_frame_bandwidth_[3]; |
138 float bit_rate_layer_[3]; | 153 float bit_rate_layer_[3]; |
139 float frame_rate_layer_[3]; | 154 float frame_rate_layer_[3]; |
140 int num_frames_total_; | 155 int num_frames_total_; |
141 float sum_encoded_frame_size_total_; | 156 float sum_encoded_frame_size_total_; |
142 float encoding_bitrate_total_; | 157 float encoding_bitrate_total_; |
143 float perc_encoding_rate_mismatch_; | 158 float perc_encoding_rate_mismatch_; |
144 int num_frames_to_hit_target_; | 159 int num_frames_to_hit_target_; |
145 bool encoding_rate_within_target_; | 160 bool encoding_rate_within_target_; |
146 int bit_rate_; | 161 int bit_rate_; |
147 int frame_rate_; | 162 int frame_rate_; |
148 int layer_; | 163 int layer_; |
149 float target_size_key_frame_initial_; | 164 float target_size_key_frame_initial_; |
150 float target_size_key_frame_; | 165 float target_size_key_frame_; |
151 float sum_key_frame_size_mismatch_; | 166 float sum_key_frame_size_mismatch_; |
152 int num_key_frames_; | 167 int num_key_frames_; |
153 float start_bitrate_; | 168 float start_bitrate_; |
154 | 169 |
155 // Codec and network settings. | 170 // Codec and network settings. |
156 VideoCodecType codec_type_; | 171 VideoCodecType codec_type_; |
| 172 bool hw_codec_; |
157 float packet_loss_; | 173 float packet_loss_; |
158 int num_temporal_layers_; | 174 int num_temporal_layers_; |
159 int key_frame_interval_; | 175 int key_frame_interval_; |
160 bool error_concealment_on_; | 176 bool error_concealment_on_; |
161 bool denoising_on_; | 177 bool denoising_on_; |
162 bool frame_dropper_on_; | 178 bool frame_dropper_on_; |
163 bool spatial_resize_on_; | 179 bool spatial_resize_on_; |
164 | 180 |
165 VideoProcessorIntegrationTest() {} | 181 VideoProcessorIntegrationTest() { |
166 virtual ~VideoProcessorIntegrationTest() {} | 182 #if defined(WEBRTC_ANDROID) |
| 183 InitializeAndroidObjects(); |
| 184 |
| 185 external_encoder_factory_.reset( |
| 186 new webrtc_jni::MediaCodecVideoEncoderFactory()); |
| 187 external_decoder_factory_.reset( |
| 188 new webrtc_jni::MediaCodecVideoDecoderFactory()); |
| 189 #endif |
| 190 } |
| 191 virtual ~VideoProcessorIntegrationTest() { |
| 192 #if defined(WEBRTC_ANDROID) |
| 193 FreeAndroidObjects(); |
| 194 #endif |
| 195 } |
167 | 196 |
168 void SetUpCodecConfig(const std::string& filename, | 197 void SetUpCodecConfig(const std::string& filename, |
169 int width, | 198 int width, |
170 int height, | 199 int height, |
171 bool verbose_logging) { | 200 bool verbose_logging) { |
172 if (codec_type_ == kVideoCodecH264) { | 201 if (hw_codec_) { |
173 encoder_.reset(H264Encoder::Create(cricket::VideoCodec("H264"))); | 202 #if defined(WEBRTC_ANDROID) |
174 decoder_.reset(H264Decoder::Create()); | 203 // In general, external codecs should be destroyed by the factories that |
175 VideoCodingModule::Codec(kVideoCodecH264, &codec_settings_); | 204 // allocated them. For the particular case of the Android |
176 } else if (codec_type_ == kVideoCodecVP8) { | 205 // MediaCodecVideo{En,De}coderFactory's, however, it turns out that it is |
177 encoder_.reset(VP8Encoder::Create()); | 206 // fine for the std::unique_ptr to destroy the owned codec directly. |
178 decoder_.reset(VP8Decoder::Create()); | 207 if (codec_type_ == kVideoCodecH264) { |
179 VideoCodingModule::Codec(kVideoCodecVP8, &codec_settings_); | 208 encoder_.reset(external_encoder_factory_->CreateVideoEncoder( |
180 } else if (codec_type_ == kVideoCodecVP9) { | 209 cricket::VideoCodec(cricket::kH264CodecName))); |
181 encoder_.reset(VP9Encoder::Create()); | 210 decoder_.reset( |
182 decoder_.reset(VP9Decoder::Create()); | 211 external_decoder_factory_->CreateVideoDecoder(kVideoCodecH264)); |
183 VideoCodingModule::Codec(kVideoCodecVP9, &codec_settings_); | 212 } else if (codec_type_ == kVideoCodecVP8) { |
| 213 encoder_.reset(external_encoder_factory_->CreateVideoEncoder( |
| 214 cricket::VideoCodec(cricket::kVp8CodecName))); |
| 215 decoder_.reset( |
| 216 external_decoder_factory_->CreateVideoDecoder(kVideoCodecVP8)); |
| 217 } else if (codec_type_ == kVideoCodecVP9) { |
| 218 encoder_.reset(external_encoder_factory_->CreateVideoEncoder( |
| 219 cricket::VideoCodec(cricket::kVp9CodecName))); |
| 220 decoder_.reset( |
| 221 external_decoder_factory_->CreateVideoDecoder(kVideoCodecVP9)); |
| 222 } |
| 223 #elif defined(WEBRTC_IOS) |
| 224 RTC_DCHECK_EQ(kVideoCodecH264, codec_type_) |
| 225 << "iOS HW codecs only support H264."; |
| 226 encoder_.reset(new H264VideoToolboxEncoder( |
| 227 cricket::VideoCodec(cricket::kH264CodecName))); |
| 228 decoder_.reset(new H264VideoToolboxDecoder()); |
| 229 #else |
| 230 RTC_NOTREACHED() << "Only support HW codecs on Android and iOS."; |
| 231 #endif |
| 232 RTC_DCHECK(encoder_) << "HW encoder not successfully created."; |
| 233 RTC_DCHECK(decoder_) << "HW decoder not successfully created."; |
| 234 } else { |
| 235 // SW codecs. |
| 236 if (codec_type_ == kVideoCodecH264) { |
| 237 encoder_.reset( |
| 238 H264Encoder::Create(cricket::VideoCodec(cricket::kH264CodecName))); |
| 239 decoder_.reset(H264Decoder::Create()); |
| 240 } else if (codec_type_ == kVideoCodecVP8) { |
| 241 encoder_.reset(VP8Encoder::Create()); |
| 242 decoder_.reset(VP8Decoder::Create()); |
| 243 } else if (codec_type_ == kVideoCodecVP9) { |
| 244 encoder_.reset(VP9Encoder::Create()); |
| 245 decoder_.reset(VP9Decoder::Create()); |
| 246 } |
184 } | 247 } |
185 | 248 |
| 249 VideoCodingModule::Codec(codec_type_, &codec_settings_); |
| 250 |
186 // Configure input filename. | 251 // Configure input filename. |
187 config_.input_filename = test::ResourcePath(filename, "yuv"); | 252 config_.input_filename = test::ResourcePath(filename, "yuv"); |
188 if (verbose_logging) | 253 if (verbose_logging) |
189 printf("Filename: %s\n", filename.c_str()); | 254 printf("Filename: %s\n", filename.c_str()); |
190 // Generate an output filename in a safe way. | 255 // Generate an output filename in a safe way. |
191 config_.output_filename = test::TempFilename( | 256 config_.output_filename = test::TempFilename( |
192 test::OutputPath(), "videoprocessor_integrationtest"); | 257 test::OutputPath(), "videoprocessor_integrationtest"); |
193 config_.frame_length_in_bytes = CalcBufferSize(kI420, width, height); | 258 config_.frame_length_in_bytes = CalcBufferSize(kI420, width, height); |
194 config_.verbose = verbose_logging; | 259 config_.verbose = verbose_logging; |
195 // Only allow encoder/decoder to use single core, for predictability. | 260 // Only allow encoder/decoder to use single core, for predictability. |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 } | 492 } |
428 } | 493 } |
429 | 494 |
430 // Processes all frames in the clip and verifies the result. | 495 // Processes all frames in the clip and verifies the result. |
431 void ProcessFramesAndVerify(QualityMetrics quality_metrics, | 496 void ProcessFramesAndVerify(QualityMetrics quality_metrics, |
432 RateProfile rate_profile, | 497 RateProfile rate_profile, |
433 CodecConfigPars process, | 498 CodecConfigPars process, |
434 RateControlMetrics* rc_metrics) { | 499 RateControlMetrics* rc_metrics) { |
435 // Codec/config settings. | 500 // Codec/config settings. |
436 codec_type_ = process.codec_type; | 501 codec_type_ = process.codec_type; |
| 502 hw_codec_ = process.hw_codec; |
437 start_bitrate_ = rate_profile.target_bit_rate[0]; | 503 start_bitrate_ = rate_profile.target_bit_rate[0]; |
438 packet_loss_ = process.packet_loss; | 504 packet_loss_ = process.packet_loss; |
439 key_frame_interval_ = process.key_frame_interval; | 505 key_frame_interval_ = process.key_frame_interval; |
440 num_temporal_layers_ = process.num_temporal_layers; | 506 num_temporal_layers_ = process.num_temporal_layers; |
441 error_concealment_on_ = process.error_concealment_on; | 507 error_concealment_on_ = process.error_concealment_on; |
442 denoising_on_ = process.denoising_on; | 508 denoising_on_ = process.denoising_on; |
443 frame_dropper_on_ = process.frame_dropper_on; | 509 frame_dropper_on_ = process.frame_dropper_on; |
444 spatial_resize_on_ = process.spatial_resize_on; | 510 spatial_resize_on_ = process.spatial_resize_on; |
445 SetUpCodecConfig(process.filename, process.width, process.height, | 511 SetUpCodecConfig(process.filename, process.width, process.height, |
446 process.verbose_logging); | 512 process.verbose_logging); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 int frame_rate, | 603 int frame_rate, |
538 int frame_index_rate_update) { | 604 int frame_index_rate_update) { |
539 rate_profile->target_bit_rate[update_index] = bit_rate; | 605 rate_profile->target_bit_rate[update_index] = bit_rate; |
540 rate_profile->input_frame_rate[update_index] = frame_rate; | 606 rate_profile->input_frame_rate[update_index] = frame_rate; |
541 rate_profile->frame_index_rate_update[update_index] = | 607 rate_profile->frame_index_rate_update[update_index] = |
542 frame_index_rate_update; | 608 frame_index_rate_update; |
543 } | 609 } |
544 | 610 |
545 static void SetCodecParameters(CodecConfigPars* process_settings, | 611 static void SetCodecParameters(CodecConfigPars* process_settings, |
546 VideoCodecType codec_type, | 612 VideoCodecType codec_type, |
| 613 bool hw_codec, |
547 float packet_loss, | 614 float packet_loss, |
548 int key_frame_interval, | 615 int key_frame_interval, |
549 int num_temporal_layers, | 616 int num_temporal_layers, |
550 bool error_concealment_on, | 617 bool error_concealment_on, |
551 bool denoising_on, | 618 bool denoising_on, |
552 bool frame_dropper_on, | 619 bool frame_dropper_on, |
553 bool spatial_resize_on, | 620 bool spatial_resize_on, |
554 int width, | 621 int width, |
555 int height, | 622 int height, |
556 const std::string& filename, | 623 const std::string& filename, |
557 bool verbose_logging) { | 624 bool verbose_logging) { |
558 process_settings->codec_type = codec_type; | 625 process_settings->codec_type = codec_type; |
| 626 process_settings->hw_codec = hw_codec; |
559 process_settings->packet_loss = packet_loss; | 627 process_settings->packet_loss = packet_loss; |
560 process_settings->key_frame_interval = key_frame_interval; | 628 process_settings->key_frame_interval = key_frame_interval; |
561 process_settings->num_temporal_layers = num_temporal_layers, | 629 process_settings->num_temporal_layers = num_temporal_layers, |
562 process_settings->error_concealment_on = error_concealment_on; | 630 process_settings->error_concealment_on = error_concealment_on; |
563 process_settings->denoising_on = denoising_on; | 631 process_settings->denoising_on = denoising_on; |
564 process_settings->frame_dropper_on = frame_dropper_on; | 632 process_settings->frame_dropper_on = frame_dropper_on; |
565 process_settings->spatial_resize_on = spatial_resize_on; | 633 process_settings->spatial_resize_on = spatial_resize_on; |
566 process_settings->width = width; | 634 process_settings->width = width; |
567 process_settings->height = height; | 635 process_settings->height = height; |
568 process_settings->filename = filename; | 636 process_settings->filename = filename; |
569 process_settings->verbose_logging = verbose_logging; | 637 process_settings->verbose_logging = verbose_logging; |
570 } | 638 } |
571 | 639 |
572 static void SetCodecParameters(CodecConfigPars* process_settings, | 640 static void SetCodecParameters(CodecConfigPars* process_settings, |
573 VideoCodecType codec_type, | 641 VideoCodecType codec_type, |
| 642 bool hw_codec, |
574 float packet_loss, | 643 float packet_loss, |
575 int key_frame_interval, | 644 int key_frame_interval, |
576 int num_temporal_layers, | 645 int num_temporal_layers, |
577 bool error_concealment_on, | 646 bool error_concealment_on, |
578 bool denoising_on, | 647 bool denoising_on, |
579 bool frame_dropper_on, | 648 bool frame_dropper_on, |
580 bool spatial_resize_on) { | 649 bool spatial_resize_on) { |
581 SetCodecParameters(process_settings, codec_type, packet_loss, | 650 SetCodecParameters(process_settings, codec_type, hw_codec, packet_loss, |
582 key_frame_interval, num_temporal_layers, | 651 key_frame_interval, num_temporal_layers, |
583 error_concealment_on, denoising_on, frame_dropper_on, | 652 error_concealment_on, denoising_on, frame_dropper_on, |
584 spatial_resize_on, kCifWidth, kCifHeight, | 653 spatial_resize_on, kCifWidth, kCifHeight, |
585 kFilenameForemanCif, false /* verbose_logging */); | 654 kFilenameForemanCif, false /* verbose_logging */); |
586 } | 655 } |
587 | 656 |
588 static void SetQualityMetrics(QualityMetrics* quality_metrics, | 657 static void SetQualityMetrics(QualityMetrics* quality_metrics, |
589 double minimum_avg_psnr, | 658 double minimum_avg_psnr, |
590 double minimum_min_psnr, | 659 double minimum_min_psnr, |
591 double minimum_avg_ssim, | 660 double minimum_avg_ssim, |
(...skipping 23 matching lines...) Expand all Loading... |
615 rc_metrics[update_index].max_time_hit_target = max_time_hit_target; | 684 rc_metrics[update_index].max_time_hit_target = max_time_hit_target; |
616 rc_metrics[update_index].num_spatial_resizes = num_spatial_resizes; | 685 rc_metrics[update_index].num_spatial_resizes = num_spatial_resizes; |
617 rc_metrics[update_index].num_key_frames = num_key_frames; | 686 rc_metrics[update_index].num_key_frames = num_key_frames; |
618 } | 687 } |
619 }; | 688 }; |
620 | 689 |
621 } // namespace test | 690 } // namespace test |
622 } // namespace webrtc | 691 } // namespace webrtc |
623 | 692 |
624 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES
T_H_ | 693 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES
T_H_ |
OLD | NEW |