OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 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 #include "video/video_quality_test.h" | 10 #include "video/video_quality_test.h" |
11 | 11 |
12 #include <stdio.h> | 12 #include <stdio.h> |
13 #include <algorithm> | 13 #include <algorithm> |
14 #include <deque> | 14 #include <deque> |
15 #include <map> | 15 #include <map> |
16 #include <set> | 16 #include <set> |
17 #include <sstream> | 17 #include <sstream> |
18 #include <string> | 18 #include <string> |
19 #include <vector> | 19 #include <vector> |
20 | 20 |
| 21 #if defined(WEBRTC_ANDROID) |
| 22 #include "modules/video_coding/codecs/test/android_test_initializer.h" |
| 23 #include "sdk/android/src/jni/androidmediadecoder_jni.h" |
| 24 #include "sdk/android/src/jni/androidmediaencoder_jni.h" |
| 25 #elif defined(WEBRTC_IOS) |
| 26 #include "modules/video_coding/codecs/test/objc_codec_h264_test.h" |
| 27 #endif |
| 28 |
21 #include "api/optional.h" | 29 #include "api/optional.h" |
22 #include "call/call.h" | 30 #include "call/call.h" |
23 #include "common_video/libyuv/include/webrtc_libyuv.h" | 31 #include "common_video/libyuv/include/webrtc_libyuv.h" |
24 #include "logging/rtc_event_log/rtc_event_log.h" | 32 #include "logging/rtc_event_log/rtc_event_log.h" |
| 33 #include "media/engine/internalencoderfactory.h" |
| 34 #include "media/engine/videoencodersoftwarefallbackwrapper.h" |
25 #include "media/engine/webrtcvideoengine.h" | 35 #include "media/engine/webrtcvideoengine.h" |
26 #include "modules/audio_mixer/audio_mixer_impl.h" | 36 #include "modules/audio_mixer/audio_mixer_impl.h" |
27 #include "modules/rtp_rtcp/include/rtp_header_parser.h" | 37 #include "modules/rtp_rtcp/include/rtp_header_parser.h" |
28 #include "modules/rtp_rtcp/source/rtp_format.h" | 38 #include "modules/rtp_rtcp/source/rtp_format.h" |
29 #include "modules/rtp_rtcp/source/rtp_utility.h" | 39 #include "modules/rtp_rtcp/source/rtp_utility.h" |
30 #include "modules/video_coding/codecs/h264/include/h264.h" | 40 #include "modules/video_coding/codecs/h264/include/h264.h" |
31 #include "modules/video_coding/codecs/vp8/include/vp8.h" | 41 #include "modules/video_coding/codecs/vp8/include/vp8.h" |
32 #include "modules/video_coding/codecs/vp8/include/vp8_common_types.h" | 42 #include "modules/video_coding/codecs/vp8/include/vp8_common_types.h" |
33 #include "modules/video_coding/codecs/vp9/include/vp9.h" | 43 #include "modules/video_coding/codecs/vp9/include/vp9.h" |
34 #include "rtc_base/checks.h" | 44 #include "rtc_base/checks.h" |
(...skipping 1086 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1121 rtc::PlatformThread stats_polling_thread_; | 1131 rtc::PlatformThread stats_polling_thread_; |
1122 rtc::Event comparison_available_event_; | 1132 rtc::Event comparison_available_event_; |
1123 std::deque<FrameComparison> comparisons_ RTC_GUARDED_BY(comparison_lock_); | 1133 std::deque<FrameComparison> comparisons_ RTC_GUARDED_BY(comparison_lock_); |
1124 rtc::Event done_; | 1134 rtc::Event done_; |
1125 | 1135 |
1126 std::unique_ptr<test::RtpFileWriter> rtp_file_writer_; | 1136 std::unique_ptr<test::RtpFileWriter> rtp_file_writer_; |
1127 Clock* const clock_; | 1137 Clock* const clock_; |
1128 const int64_t start_ms_; | 1138 const int64_t start_ms_; |
1129 }; | 1139 }; |
1130 | 1140 |
1131 class Vp8EncoderFactory : public cricket::WebRtcVideoEncoderFactory { | |
1132 public: | |
1133 Vp8EncoderFactory() { | |
1134 supported_codecs_.push_back(cricket::VideoCodec("VP8")); | |
1135 } | |
1136 ~Vp8EncoderFactory() override { RTC_CHECK(live_encoders_.empty()); } | |
1137 | |
1138 const std::vector<cricket::VideoCodec>& supported_codecs() const override { | |
1139 return supported_codecs_; | |
1140 } | |
1141 | |
1142 VideoEncoder* CreateVideoEncoder(const cricket::VideoCodec& codec) override { | |
1143 VideoEncoder* encoder = VP8Encoder::Create(); | |
1144 live_encoders_.insert(encoder); | |
1145 return encoder; | |
1146 } | |
1147 | |
1148 void DestroyVideoEncoder(VideoEncoder* encoder) override { | |
1149 auto it = live_encoders_.find(encoder); | |
1150 RTC_CHECK(it != live_encoders_.end()); | |
1151 live_encoders_.erase(it); | |
1152 delete encoder; | |
1153 } | |
1154 | |
1155 private: | |
1156 std::vector<cricket::VideoCodec> supported_codecs_; | |
1157 std::set<VideoEncoder*> live_encoders_; | |
1158 }; | |
1159 | |
1160 VideoQualityTest::VideoQualityTest() | 1141 VideoQualityTest::VideoQualityTest() |
1161 : clock_(Clock::GetRealTimeClock()), receive_logs_(0), send_logs_(0) { | 1142 : clock_(Clock::GetRealTimeClock()), receive_logs_(0), send_logs_(0) { |
1162 payload_type_map_ = test::CallTest::payload_type_map_; | 1143 payload_type_map_ = test::CallTest::payload_type_map_; |
1163 RTC_DCHECK(payload_type_map_.find(kPayloadTypeH264) == | 1144 RTC_DCHECK(payload_type_map_.find(kPayloadTypeH264) == |
1164 payload_type_map_.end()); | 1145 payload_type_map_.end()); |
1165 RTC_DCHECK(payload_type_map_.find(kPayloadTypeVP8) == | 1146 RTC_DCHECK(payload_type_map_.find(kPayloadTypeVP8) == |
1166 payload_type_map_.end()); | 1147 payload_type_map_.end()); |
1167 RTC_DCHECK(payload_type_map_.find(kPayloadTypeVP9) == | 1148 RTC_DCHECK(payload_type_map_.find(kPayloadTypeVP9) == |
1168 payload_type_map_.end()); | 1149 payload_type_map_.end()); |
1169 payload_type_map_[kPayloadTypeH264] = webrtc::MediaType::VIDEO; | 1150 payload_type_map_[kPayloadTypeH264] = webrtc::MediaType::VIDEO; |
1170 payload_type_map_[kPayloadTypeVP8] = webrtc::MediaType::VIDEO; | 1151 payload_type_map_[kPayloadTypeVP8] = webrtc::MediaType::VIDEO; |
1171 payload_type_map_[kPayloadTypeVP9] = webrtc::MediaType::VIDEO; | 1152 payload_type_map_[kPayloadTypeVP9] = webrtc::MediaType::VIDEO; |
| 1153 |
| 1154 #if defined(WEBRTC_ANDROID) |
| 1155 InitializeAndroidObjects(); |
| 1156 #endif |
1172 } | 1157 } |
1173 | 1158 |
1174 VideoQualityTest::Params::Params() | 1159 VideoQualityTest::Params::Params() |
1175 : call({false, Call::Config::BitrateConfig(), 0}), | 1160 : call({false, Call::Config::BitrateConfig(), 0}), |
1176 video({false, 640, 480, 30, 50, 800, 800, false, "VP8", 1, -1, 0, false, | 1161 video({false, 640, 480, 30, 50, 800, 800, false, "VP8", false, false, 1, |
1177 false, ""}), | 1162 -1, 0, false, false, ""}), |
1178 audio({false, false, false}), | 1163 audio({false, false, false}), |
1179 screenshare({false, false, 10, 0}), | 1164 screenshare({false, false, 10, 0}), |
1180 analyzer({"", 0.0, 0.0, 0, "", ""}), | 1165 analyzer({"", 0.0, 0.0, 0, "", ""}), |
1181 pipe(), | 1166 pipe(), |
1182 ss({std::vector<VideoStream>(), 0, 0, -1, std::vector<SpatialLayer>()}), | 1167 ss({std::vector<VideoStream>(), 0, 0, -1, std::vector<SpatialLayer>()}), |
1183 logging({false, "", "", ""}) {} | 1168 logging({false, "", "", ""}) {} |
1184 | 1169 |
1185 VideoQualityTest::Params::~Params() = default; | 1170 VideoQualityTest::Params::~Params() = default; |
1186 | 1171 |
1187 void VideoQualityTest::TestBody() {} | 1172 void VideoQualityTest::TestBody() {} |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1406 | 1391 |
1407 void VideoQualityTest::SetupVideo(Transport* send_transport, | 1392 void VideoQualityTest::SetupVideo(Transport* send_transport, |
1408 Transport* recv_transport) { | 1393 Transport* recv_transport) { |
1409 if (params_.logging.logs) | 1394 if (params_.logging.logs) |
1410 trace_to_stderr_.reset(new test::TraceToStderr); | 1395 trace_to_stderr_.reset(new test::TraceToStderr); |
1411 | 1396 |
1412 size_t num_video_streams = params_.ss.streams.size(); | 1397 size_t num_video_streams = params_.ss.streams.size(); |
1413 size_t num_flexfec_streams = params_.video.flexfec ? 1 : 0; | 1398 size_t num_flexfec_streams = params_.video.flexfec ? 1 : 0; |
1414 CreateSendConfig(num_video_streams, 0, num_flexfec_streams, send_transport); | 1399 CreateSendConfig(num_video_streams, 0, num_flexfec_streams, send_transport); |
1415 | 1400 |
| 1401 if (params_.video.hw_encoder) { |
| 1402 #if defined(WEBRTC_ANDROID) |
| 1403 video_encoder_factory_.reset(new jni::MediaCodecVideoEncoderFactory()); |
| 1404 #elif defined(WEBRTC_IOS) |
| 1405 video_encoder_factory_ = CreateObjCEncoderFactory(); |
| 1406 #else |
| 1407 RTC_NOTREACHED() << "Only support HW encoder on Android and iOS."; |
| 1408 #endif |
| 1409 } else { |
| 1410 video_encoder_factory_.reset(new cricket::InternalEncoderFactory()); |
| 1411 } |
| 1412 |
| 1413 cricket::VideoCodec codec; |
1416 int payload_type; | 1414 int payload_type; |
1417 if (params_.video.codec == "H264") { | 1415 if (params_.video.codec == "H264") { |
1418 video_encoder_.reset(H264Encoder::Create(cricket::VideoCodec("H264"))); | 1416 // TODO(brandtr): Add support for high profile here. |
| 1417 codec = cricket::VideoCodec(cricket::kH264CodecName); |
| 1418 video_encoder_.reset(video_encoder_factory_->CreateVideoEncoder(codec)); |
1419 payload_type = kPayloadTypeH264; | 1419 payload_type = kPayloadTypeH264; |
1420 } else if (params_.video.codec == "VP8") { | 1420 } else if (params_.video.codec == "VP8") { |
| 1421 codec = cricket::VideoCodec(cricket::kVp8CodecName); |
1421 if (params_.screenshare.enabled && params_.ss.streams.size() > 1) { | 1422 if (params_.screenshare.enabled && params_.ss.streams.size() > 1) { |
1422 // Simulcast screenshare needs a simulcast encoder adapter to work, since | 1423 // Simulcast screenshare needs a simulcast encoder adapter to work, |
1423 // encoders usually can't natively do simulcast with different frame rates | 1424 // since encoders usually can't natively do simulcast with |
1424 // for the different layers. | 1425 // different frame rates for the different layers. |
1425 video_encoder_.reset( | 1426 video_encoder_.reset( |
1426 new SimulcastEncoderAdapter(new Vp8EncoderFactory())); | 1427 new SimulcastEncoderAdapter(video_encoder_factory_.get())); |
1427 } else { | 1428 } else { |
1428 video_encoder_.reset(VP8Encoder::Create()); | 1429 video_encoder_.reset(video_encoder_factory_->CreateVideoEncoder(codec)); |
1429 } | 1430 } |
1430 payload_type = kPayloadTypeVP8; | 1431 payload_type = kPayloadTypeVP8; |
1431 } else if (params_.video.codec == "VP9") { | 1432 } else if (params_.video.codec == "VP9") { |
1432 video_encoder_.reset(VP9Encoder::Create()); | 1433 codec = cricket::VideoCodec(cricket::kVp9CodecName); |
| 1434 video_encoder_.reset(video_encoder_factory_->CreateVideoEncoder(codec)); |
1433 payload_type = kPayloadTypeVP9; | 1435 payload_type = kPayloadTypeVP9; |
1434 } else { | 1436 } else { |
1435 RTC_NOTREACHED() << "Codec not supported!"; | 1437 RTC_NOTREACHED() << "Codec not supported!"; |
1436 return; | 1438 return; |
1437 } | 1439 } |
| 1440 |
| 1441 if (params_.video.sw_fallback_encoder) { |
| 1442 video_encoder_ = rtc::MakeUnique<VideoEncoderSoftwareFallbackWrapper>( |
| 1443 codec, std::move(video_encoder_)); |
| 1444 } |
| 1445 |
1438 video_send_config_.encoder_settings.encoder = video_encoder_.get(); | 1446 video_send_config_.encoder_settings.encoder = video_encoder_.get(); |
1439 video_send_config_.encoder_settings.payload_name = params_.video.codec; | 1447 video_send_config_.encoder_settings.payload_name = params_.video.codec; |
1440 video_send_config_.encoder_settings.payload_type = payload_type; | 1448 video_send_config_.encoder_settings.payload_type = payload_type; |
1441 video_send_config_.rtp.nack.rtp_history_ms = kNackRtpHistoryMs; | 1449 video_send_config_.rtp.nack.rtp_history_ms = kNackRtpHistoryMs; |
1442 video_send_config_.rtp.rtx.payload_type = kSendRtxPayloadType; | 1450 video_send_config_.rtp.rtx.payload_type = kSendRtxPayloadType; |
1443 for (size_t i = 0; i < num_video_streams; ++i) | 1451 for (size_t i = 0; i < num_video_streams; ++i) |
1444 video_send_config_.rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[i]); | 1452 video_send_config_.rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[i]); |
1445 | 1453 |
1446 video_send_config_.rtp.extensions.clear(); | 1454 video_send_config_.rtp.extensions.clear(); |
1447 if (params_.call.send_side_bwe) { | 1455 if (params_.call.send_side_bwe) { |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1961 test::kTransportSequenceNumberExtensionId)); | 1969 test::kTransportSequenceNumberExtensionId)); |
1962 audio_send_config_.min_bitrate_bps = kOpusMinBitrateBps; | 1970 audio_send_config_.min_bitrate_bps = kOpusMinBitrateBps; |
1963 audio_send_config_.max_bitrate_bps = kOpusBitrateFbBps; | 1971 audio_send_config_.max_bitrate_bps = kOpusBitrateFbBps; |
1964 } | 1972 } |
1965 audio_send_config_.send_codec_spec = | 1973 audio_send_config_.send_codec_spec = |
1966 rtc::Optional<AudioSendStream::Config::SendCodecSpec>( | 1974 rtc::Optional<AudioSendStream::Config::SendCodecSpec>( |
1967 {kAudioSendPayloadType, | 1975 {kAudioSendPayloadType, |
1968 {"OPUS", 48000, 2, | 1976 {"OPUS", 48000, 2, |
1969 {{"usedtx", (params_.audio.dtx ? "1" : "0")}, | 1977 {{"usedtx", (params_.audio.dtx ? "1" : "0")}, |
1970 {"stereo", "1"}}}}); | 1978 {"stereo", "1"}}}}); |
1971 audio_send_config_.encoder_factory = encoder_factory_; | 1979 audio_send_config_.encoder_factory = audio_encoder_factory_; |
1972 audio_send_stream_ = sender_call_->CreateAudioSendStream(audio_send_config_); | 1980 audio_send_stream_ = sender_call_->CreateAudioSendStream(audio_send_config_); |
1973 | 1981 |
1974 AudioReceiveStream::Config audio_config; | 1982 AudioReceiveStream::Config audio_config; |
1975 audio_config.rtp.local_ssrc = kReceiverLocalAudioSsrc; | 1983 audio_config.rtp.local_ssrc = kReceiverLocalAudioSsrc; |
1976 audio_config.rtcp_send_transport = transport; | 1984 audio_config.rtcp_send_transport = transport; |
1977 audio_config.voe_channel_id = receive_channel_id; | 1985 audio_config.voe_channel_id = receive_channel_id; |
1978 audio_config.rtp.remote_ssrc = audio_send_config_.rtp.ssrc; | 1986 audio_config.rtp.remote_ssrc = audio_send_config_.rtp.ssrc; |
1979 audio_config.rtp.transport_cc = params_.call.send_side_bwe; | 1987 audio_config.rtp.transport_cc = params_.call.send_side_bwe; |
1980 audio_config.rtp.extensions = audio_send_config_.rtp.extensions; | 1988 audio_config.rtp.extensions = audio_send_config_.rtp.extensions; |
1981 audio_config.decoder_factory = decoder_factory_; | 1989 audio_config.decoder_factory = audio_decoder_factory_; |
1982 audio_config.decoder_map = {{kAudioSendPayloadType, {"OPUS", 48000, 2}}}; | 1990 audio_config.decoder_map = {{kAudioSendPayloadType, {"OPUS", 48000, 2}}}; |
1983 if (params_.video.enabled && params_.audio.sync_video) | 1991 if (params_.video.enabled && params_.audio.sync_video) |
1984 audio_config.sync_group = kSyncGroup; | 1992 audio_config.sync_group = kSyncGroup; |
1985 | 1993 |
1986 *audio_receive_stream = | 1994 *audio_receive_stream = |
1987 receiver_call_->CreateAudioReceiveStream(audio_config); | 1995 receiver_call_->CreateAudioReceiveStream(audio_config); |
1988 } | 1996 } |
1989 | 1997 |
1990 void VideoQualityTest::RunWithRenderers(const Params& params) { | 1998 void VideoQualityTest::RunWithRenderers(const Params& params) { |
1991 std::unique_ptr<test::LayerFilteringTransport> send_transport; | 1999 std::unique_ptr<test::LayerFilteringTransport> send_transport; |
1992 std::unique_ptr<test::DirectTransport> recv_transport; | 2000 std::unique_ptr<test::DirectTransport> recv_transport; |
1993 ::VoiceEngineState voe; | 2001 ::VoiceEngineState voe; |
1994 std::unique_ptr<test::VideoRenderer> local_preview; | 2002 std::unique_ptr<test::VideoRenderer> local_preview; |
1995 std::vector<std::unique_ptr<test::VideoRenderer>> loopback_renderers; | 2003 std::vector<std::unique_ptr<test::VideoRenderer>> loopback_renderers; |
1996 AudioReceiveStream* audio_receive_stream = nullptr; | 2004 AudioReceiveStream* audio_receive_stream = nullptr; |
1997 | 2005 |
1998 task_queue_.SendTask([&]() { | 2006 task_queue_.SendTask([&]() { |
1999 params_ = params; | 2007 params_ = params; |
2000 CheckParams(); | 2008 CheckParams(); |
2001 | 2009 |
2002 // TODO(ivica): Remove bitrate_config and use the default Call::Config(), to | 2010 // TODO(ivica): Remove bitrate_config and use the default Call::Config(), to |
2003 // match the full stack tests. | 2011 // match the full stack tests. |
2004 Call::Config call_config(event_log_.get()); | 2012 Call::Config call_config(event_log_.get()); |
2005 call_config.bitrate_config = params_.call.call_bitrate_config; | 2013 call_config.bitrate_config = params_.call.call_bitrate_config; |
2006 | 2014 |
2007 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing( | 2015 rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing( |
2008 webrtc::AudioProcessing::Create()); | 2016 webrtc::AudioProcessing::Create()); |
2009 | 2017 |
2010 if (params_.audio.enabled) { | 2018 if (params_.audio.enabled) { |
2011 CreateVoiceEngine(&voe, audio_processing.get(), decoder_factory_); | 2019 CreateVoiceEngine(&voe, audio_processing.get(), audio_decoder_factory_); |
2012 AudioState::Config audio_state_config; | 2020 AudioState::Config audio_state_config; |
2013 audio_state_config.voice_engine = voe.voice_engine; | 2021 audio_state_config.voice_engine = voe.voice_engine; |
2014 audio_state_config.audio_mixer = AudioMixerImpl::Create(); | 2022 audio_state_config.audio_mixer = AudioMixerImpl::Create(); |
2015 audio_state_config.audio_processing = audio_processing; | 2023 audio_state_config.audio_processing = audio_processing; |
2016 call_config.audio_state = AudioState::Create(audio_state_config); | 2024 call_config.audio_state = AudioState::Create(audio_state_config); |
2017 } | 2025 } |
2018 | 2026 |
2019 CreateCalls(call_config, call_config); | 2027 CreateCalls(call_config, call_config); |
2020 | 2028 |
2021 // TODO(minyue): consider if this is a good transport even for audio only | 2029 // TODO(minyue): consider if this is a good transport even for audio only |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2180 if (!params_.logging.encoded_frame_base_path.empty()) { | 2188 if (!params_.logging.encoded_frame_base_path.empty()) { |
2181 std::ostringstream str; | 2189 std::ostringstream str; |
2182 str << receive_logs_++; | 2190 str << receive_logs_++; |
2183 std::string path = | 2191 std::string path = |
2184 params_.logging.encoded_frame_base_path + "." + str.str() + ".recv.ivf"; | 2192 params_.logging.encoded_frame_base_path + "." + str.str() + ".recv.ivf"; |
2185 stream->EnableEncodedFrameRecording(rtc::CreatePlatformFile(path), | 2193 stream->EnableEncodedFrameRecording(rtc::CreatePlatformFile(path), |
2186 100000000); | 2194 100000000); |
2187 } | 2195 } |
2188 } | 2196 } |
2189 } // namespace webrtc | 2197 } // namespace webrtc |
OLD | NEW |