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