summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/api
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /third_party/libwebrtc/api
parentInitial commit. (diff)
downloadthunderbird-upstream.tar.xz
thunderbird-upstream.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--third_party/libwebrtc/api/BUILD.gn1559
-rw-r--r--third_party/libwebrtc/api/DEPS346
-rw-r--r--third_party/libwebrtc/api/OWNERS14
-rw-r--r--third_party/libwebrtc/api/README.md27
-rw-r--r--third_party/libwebrtc/api/adaptation/BUILD.gn23
-rw-r--r--third_party/libwebrtc/api/adaptation/DEPS7
-rw-r--r--third_party/libwebrtc/api/adaptation/resource.cc33
-rw-r--r--third_party/libwebrtc/api/adaptation/resource.h67
-rw-r--r--third_party/libwebrtc/api/adaptation/resource_adaptation_api_gn/moz.build221
-rw-r--r--third_party/libwebrtc/api/array_view.h330
-rw-r--r--third_party/libwebrtc/api/array_view_gn/moz.build205
-rw-r--r--third_party/libwebrtc/api/array_view_unittest.cc630
-rw-r--r--third_party/libwebrtc/api/async_dns_resolver.h104
-rw-r--r--third_party/libwebrtc/api/async_resolver_factory.h32
-rw-r--r--third_party/libwebrtc/api/audio/BUILD.gn111
-rw-r--r--third_party/libwebrtc/api/audio/OWNERS2
-rw-r--r--third_party/libwebrtc/api/audio/aec3_config_gn/moz.build221
-rw-r--r--third_party/libwebrtc/api/audio/aec3_factory_gn/moz.build233
-rw-r--r--third_party/libwebrtc/api/audio/audio_frame.cc140
-rw-r--r--third_party/libwebrtc/api/audio/audio_frame.h173
-rw-r--r--third_party/libwebrtc/api/audio/audio_frame_api_gn/moz.build226
-rw-r--r--third_party/libwebrtc/api/audio/audio_frame_processor.h43
-rw-r--r--third_party/libwebrtc/api/audio/audio_frame_processor_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/audio/audio_mixer.h80
-rw-r--r--third_party/libwebrtc/api/audio/audio_mixer_api_gn/moz.build209
-rw-r--r--third_party/libwebrtc/api/audio/channel_layout.cc282
-rw-r--r--third_party/libwebrtc/api/audio/channel_layout.h165
-rw-r--r--third_party/libwebrtc/api/audio/echo_canceller3_config.cc278
-rw-r--r--third_party/libwebrtc/api/audio/echo_canceller3_config.h250
-rw-r--r--third_party/libwebrtc/api/audio/echo_canceller3_config_json.cc772
-rw-r--r--third_party/libwebrtc/api/audio/echo_canceller3_config_json.h45
-rw-r--r--third_party/libwebrtc/api/audio/echo_canceller3_factory.cc32
-rw-r--r--third_party/libwebrtc/api/audio/echo_canceller3_factory.h41
-rw-r--r--third_party/libwebrtc/api/audio/echo_control.h75
-rw-r--r--third_party/libwebrtc/api/audio/echo_control_gn/moz.build205
-rw-r--r--third_party/libwebrtc/api/audio/echo_detector_creator.cc21
-rw-r--r--third_party/libwebrtc/api/audio/echo_detector_creator.h26
-rw-r--r--third_party/libwebrtc/api/audio/test/BUILD.gn30
-rw-r--r--third_party/libwebrtc/api/audio/test/audio_frame_unittest.cc136
-rw-r--r--third_party/libwebrtc/api/audio/test/echo_canceller3_config_json_unittest.cc93
-rw-r--r--third_party/libwebrtc/api/audio/test/echo_canceller3_config_unittest.cc46
-rw-r--r--third_party/libwebrtc/api/audio_codecs/BUILD.gn144
-rw-r--r--third_party/libwebrtc/api/audio_codecs/L16/BUILD.gn55
-rw-r--r--third_party/libwebrtc/api/audio_codecs/L16/audio_decoder_L16.cc49
-rw-r--r--third_party/libwebrtc/api/audio_codecs/L16/audio_decoder_L16.h49
-rw-r--r--third_party/libwebrtc/api/audio_codecs/L16/audio_decoder_L16_gn/moz.build225
-rw-r--r--third_party/libwebrtc/api/audio_codecs/L16/audio_encoder_L16.cc76
-rw-r--r--third_party/libwebrtc/api/audio_codecs/L16/audio_encoder_L16.h54
-rw-r--r--third_party/libwebrtc/api/audio_codecs/L16/audio_encoder_L16_gn/moz.build225
-rw-r--r--third_party/libwebrtc/api/audio_codecs/OWNERS3
-rw-r--r--third_party/libwebrtc/api/audio_codecs/audio_codec_pair_id.cc91
-rw-r--r--third_party/libwebrtc/api/audio_codecs/audio_codec_pair_id.h74
-rw-r--r--third_party/libwebrtc/api/audio_codecs/audio_codecs_api_gn/moz.build228
-rw-r--r--third_party/libwebrtc/api/audio_codecs/audio_decoder.cc170
-rw-r--r--third_party/libwebrtc/api/audio_codecs/audio_decoder.h195
-rw-r--r--third_party/libwebrtc/api/audio_codecs/audio_decoder_factory.h53
-rw-r--r--third_party/libwebrtc/api/audio_codecs/audio_decoder_factory_template.h145
-rw-r--r--third_party/libwebrtc/api/audio_codecs/audio_encoder.cc114
-rw-r--r--third_party/libwebrtc/api/audio_codecs/audio_encoder.h260
-rw-r--r--third_party/libwebrtc/api/audio_codecs/audio_encoder_factory.h62
-rw-r--r--third_party/libwebrtc/api/audio_codecs/audio_encoder_factory_template.h163
-rw-r--r--third_party/libwebrtc/api/audio_codecs/audio_format.cc86
-rw-r--r--third_party/libwebrtc/api/audio_codecs/audio_format.h133
-rw-r--r--third_party/libwebrtc/api/audio_codecs/builtin_audio_decoder_factory.cc68
-rw-r--r--third_party/libwebrtc/api/audio_codecs/builtin_audio_decoder_factory.h28
-rw-r--r--third_party/libwebrtc/api/audio_codecs/builtin_audio_decoder_factory_gn/moz.build234
-rw-r--r--third_party/libwebrtc/api/audio_codecs/builtin_audio_encoder_factory.cc74
-rw-r--r--third_party/libwebrtc/api/audio_codecs/builtin_audio_encoder_factory.h28
-rw-r--r--third_party/libwebrtc/api/audio_codecs/builtin_audio_encoder_factory_gn/moz.build234
-rw-r--r--third_party/libwebrtc/api/audio_codecs/g711/BUILD.gn55
-rw-r--r--third_party/libwebrtc/api/audio_codecs/g711/audio_decoder_g711.cc67
-rw-r--r--third_party/libwebrtc/api/audio_codecs/g711/audio_decoder_g711.h49
-rw-r--r--third_party/libwebrtc/api/audio_codecs/g711/audio_decoder_g711_gn/moz.build225
-rw-r--r--third_party/libwebrtc/api/audio_codecs/g711/audio_encoder_g711.cc95
-rw-r--r--third_party/libwebrtc/api/audio_codecs/g711/audio_encoder_g711.h54
-rw-r--r--third_party/libwebrtc/api/audio_codecs/g711/audio_encoder_g711_gn/moz.build225
-rw-r--r--third_party/libwebrtc/api/audio_codecs/g722/BUILD.gn62
-rw-r--r--third_party/libwebrtc/api/audio_codecs/g722/audio_decoder_g722.cc56
-rw-r--r--third_party/libwebrtc/api/audio_codecs/g722/audio_decoder_g722.h43
-rw-r--r--third_party/libwebrtc/api/audio_codecs/g722/audio_decoder_g722_gn/moz.build225
-rw-r--r--third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722.cc74
-rw-r--r--third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722.h44
-rw-r--r--third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722_config.h29
-rw-r--r--third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722_config_gn/moz.build209
-rw-r--r--third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722_gn/moz.build225
-rw-r--r--third_party/libwebrtc/api/audio_codecs/ilbc/BUILD.gn58
-rw-r--r--third_party/libwebrtc/api/audio_codecs/ilbc/audio_decoder_ilbc.cc42
-rw-r--r--third_party/libwebrtc/api/audio_codecs/ilbc/audio_decoder_ilbc.h39
-rw-r--r--third_party/libwebrtc/api/audio_codecs/ilbc/audio_decoder_ilbc_gn/moz.build232
-rw-r--r--third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc.cc88
-rw-r--r--third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc.h43
-rw-r--r--third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc_config.h28
-rw-r--r--third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc_config_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc_gn/moz.build232
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/BUILD.gn110
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_multi_channel_opus.cc71
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_multi_channel_opus.h42
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_multi_channel_opus_config.h66
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_multiopus_gn/moz.build226
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_opus.cc86
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_opus.h44
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_opus_config_gn/moz.build209
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_opus_gn/moz.build233
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multi_channel_opus.cc75
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multi_channel_opus.h43
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multi_channel_opus_config.cc106
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multi_channel_opus_config.h66
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multiopus_gn/moz.build226
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus.cc44
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus.h44
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus_config.cc75
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus_config.h74
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus_config_gn/moz.build222
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus_gn/moz.build233
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus_audio_decoder_factory.cc49
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus_audio_decoder_factory.h26
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus_audio_encoder_factory.cc54
-rw-r--r--third_party/libwebrtc/api/audio_codecs/opus_audio_encoder_factory.h26
-rw-r--r--third_party/libwebrtc/api/audio_codecs/test/BUILD.gn39
-rw-r--r--third_party/libwebrtc/api/audio_codecs/test/audio_decoder_factory_template_unittest.cc222
-rw-r--r--third_party/libwebrtc/api/audio_codecs/test/audio_encoder_factory_template_unittest.cc224
-rw-r--r--third_party/libwebrtc/api/audio_options.cc107
-rw-r--r--third_party/libwebrtc/api/audio_options.h80
-rw-r--r--third_party/libwebrtc/api/audio_options_api_gn/moz.build221
-rw-r--r--third_party/libwebrtc/api/bitrate_allocation_gn/moz.build205
-rw-r--r--third_party/libwebrtc/api/call/audio_sink.h48
-rw-r--r--third_party/libwebrtc/api/call/bitrate_allocation.h45
-rw-r--r--third_party/libwebrtc/api/call/call_factory_interface.h38
-rw-r--r--third_party/libwebrtc/api/call/transport.cc23
-rw-r--r--third_party/libwebrtc/api/call/transport.h54
-rw-r--r--third_party/libwebrtc/api/call_api_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/callfactory_api_gn/moz.build216
-rw-r--r--third_party/libwebrtc/api/candidate.cc167
-rw-r--r--third_party/libwebrtc/api/candidate.h222
-rw-r--r--third_party/libwebrtc/api/create_peerconnection_factory.cc83
-rw-r--r--third_party/libwebrtc/api/create_peerconnection_factory.h57
-rw-r--r--third_party/libwebrtc/api/crypto/BUILD.gn49
-rw-r--r--third_party/libwebrtc/api/crypto/crypto_options.cc89
-rw-r--r--third_party/libwebrtc/api/crypto/crypto_options.h72
-rw-r--r--third_party/libwebrtc/api/crypto/frame_decryptor_interface.h76
-rw-r--r--third_party/libwebrtc/api/crypto/frame_decryptor_interface_gn/moz.build205
-rw-r--r--third_party/libwebrtc/api/crypto/frame_encryptor_interface.h54
-rw-r--r--third_party/libwebrtc/api/crypto/frame_encryptor_interface_gn/moz.build205
-rw-r--r--third_party/libwebrtc/api/crypto/options_gn/moz.build217
-rw-r--r--third_party/libwebrtc/api/crypto_params.h43
-rw-r--r--third_party/libwebrtc/api/data_channel_interface.cc47
-rw-r--r--third_party/libwebrtc/api/data_channel_interface.h202
-rw-r--r--third_party/libwebrtc/api/dtls_transport_interface.cc73
-rw-r--r--third_party/libwebrtc/api/dtls_transport_interface.h124
-rw-r--r--third_party/libwebrtc/api/dtmf_sender_interface.h125
-rw-r--r--third_party/libwebrtc/api/fec_controller.h92
-rw-r--r--third_party/libwebrtc/api/fec_controller_api_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/fec_controller_override.h28
-rw-r--r--third_party/libwebrtc/api/field_trials.cc107
-rw-r--r--third_party/libwebrtc/api/field_trials.h59
-rw-r--r--third_party/libwebrtc/api/field_trials_registry.cc31
-rw-r--r--third_party/libwebrtc/api/field_trials_registry.h54
-rw-r--r--third_party/libwebrtc/api/field_trials_registry_gn/moz.build221
-rw-r--r--third_party/libwebrtc/api/field_trials_unittest.cc152
-rw-r--r--third_party/libwebrtc/api/field_trials_view.h49
-rw-r--r--third_party/libwebrtc/api/field_trials_view_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/frame_transformer_factory.cc33
-rw-r--r--third_party/libwebrtc/api/frame_transformer_factory.h39
-rw-r--r--third_party/libwebrtc/api/frame_transformer_interface.h115
-rw-r--r--third_party/libwebrtc/api/frame_transformer_interface_gn/moz.build216
-rw-r--r--third_party/libwebrtc/api/function_view.h130
-rw-r--r--third_party/libwebrtc/api/function_view_gn/moz.build205
-rw-r--r--third_party/libwebrtc/api/function_view_unittest.cc176
-rw-r--r--third_party/libwebrtc/api/g3doc/index.md51
-rw-r--r--third_party/libwebrtc/api/g3doc/threading_design.md74
-rw-r--r--third_party/libwebrtc/api/ice_transport_factory.cc67
-rw-r--r--third_party/libwebrtc/api/ice_transport_factory.h47
-rw-r--r--third_party/libwebrtc/api/ice_transport_interface.h157
-rw-r--r--third_party/libwebrtc/api/jsep.cc57
-rw-r--r--third_party/libwebrtc/api/jsep.h253
-rw-r--r--third_party/libwebrtc/api/jsep_ice_candidate.cc76
-rw-r--r--third_party/libwebrtc/api/jsep_ice_candidate.h90
-rw-r--r--third_party/libwebrtc/api/jsep_session_description.h91
-rw-r--r--third_party/libwebrtc/api/legacy_stats_types.cc845
-rw-r--r--third_party/libwebrtc/api/legacy_stats_types.h455
-rw-r--r--third_party/libwebrtc/api/libjingle_logging_api_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/libjingle_peerconnection_api_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/make_ref_counted.h119
-rw-r--r--third_party/libwebrtc/api/make_ref_counted_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/media_stream_interface.cc38
-rw-r--r--third_party/libwebrtc/api/media_stream_interface.h376
-rw-r--r--third_party/libwebrtc/api/media_stream_interface_gn/moz.build225
-rw-r--r--third_party/libwebrtc/api/media_stream_track.h64
-rw-r--r--third_party/libwebrtc/api/media_types.cc37
-rw-r--r--third_party/libwebrtc/api/media_types.h44
-rw-r--r--third_party/libwebrtc/api/metronome/BUILD.gn19
-rw-r--r--third_party/libwebrtc/api/metronome/metronome.cc19
-rw-r--r--third_party/libwebrtc/api/metronome/metronome.h47
-rw-r--r--third_party/libwebrtc/api/metronome/metronome_gn/moz.build205
-rw-r--r--third_party/libwebrtc/api/metronome/test/BUILD.gn30
-rw-r--r--third_party/libwebrtc/api/metronome/test/fake_metronome.cc72
-rw-r--r--third_party/libwebrtc/api/metronome/test/fake_metronome.h69
-rw-r--r--third_party/libwebrtc/api/neteq/BUILD.gn95
-rw-r--r--third_party/libwebrtc/api/neteq/DEPS14
-rw-r--r--third_party/libwebrtc/api/neteq/OWNERS3
-rw-r--r--third_party/libwebrtc/api/neteq/custom_neteq_factory.cc34
-rw-r--r--third_party/libwebrtc/api/neteq/custom_neteq_factory.h44
-rw-r--r--third_party/libwebrtc/api/neteq/default_neteq_controller_factory.cc25
-rw-r--r--third_party/libwebrtc/api/neteq/default_neteq_controller_factory.h34
-rw-r--r--third_party/libwebrtc/api/neteq/default_neteq_controller_factory_gn/moz.build232
-rw-r--r--third_party/libwebrtc/api/neteq/neteq.cc37
-rw-r--r--third_party/libwebrtc/api/neteq/neteq.h322
-rw-r--r--third_party/libwebrtc/api/neteq/neteq_api_gn/moz.build232
-rw-r--r--third_party/libwebrtc/api/neteq/neteq_controller.h197
-rw-r--r--third_party/libwebrtc/api/neteq/neteq_controller_api_gn/moz.build216
-rw-r--r--third_party/libwebrtc/api/neteq/neteq_controller_factory.h32
-rw-r--r--third_party/libwebrtc/api/neteq/neteq_factory.h37
-rw-r--r--third_party/libwebrtc/api/neteq/tick_timer.cc25
-rw-r--r--third_party/libwebrtc/api/neteq/tick_timer.h112
-rw-r--r--third_party/libwebrtc/api/neteq/tick_timer_gn/moz.build221
-rw-r--r--third_party/libwebrtc/api/neteq/tick_timer_unittest.cc135
-rw-r--r--third_party/libwebrtc/api/network_state_predictor.h56
-rw-r--r--third_party/libwebrtc/api/network_state_predictor_api_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/notifier.h68
-rw-r--r--third_party/libwebrtc/api/numerics/BUILD.gn41
-rw-r--r--third_party/libwebrtc/api/numerics/DEPS6
-rw-r--r--third_party/libwebrtc/api/numerics/samples_stats_counter.cc101
-rw-r--r--third_party/libwebrtc/api/numerics/samples_stats_counter.h126
-rw-r--r--third_party/libwebrtc/api/numerics/samples_stats_counter_unittest.cc221
-rw-r--r--third_party/libwebrtc/api/packet_socket_factory.h100
-rw-r--r--third_party/libwebrtc/api/peer_connection_interface.cc108
-rw-r--r--third_party/libwebrtc/api/peer_connection_interface.h1696
-rw-r--r--third_party/libwebrtc/api/priority.h26
-rw-r--r--third_party/libwebrtc/api/priority_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/ref_counted_base.h98
-rw-r--r--third_party/libwebrtc/api/refcountedbase_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/rtc_error.cc80
-rw-r--r--third_party/libwebrtc/api/rtc_error.h331
-rw-r--r--third_party/libwebrtc/api/rtc_error_gn/moz.build225
-rw-r--r--third_party/libwebrtc/api/rtc_error_unittest.cc242
-rw-r--r--third_party/libwebrtc/api/rtc_event_log/BUILD.gn48
-rw-r--r--third_party/libwebrtc/api/rtc_event_log/rtc_event.cc19
-rw-r--r--third_party/libwebrtc/api/rtc_event_log/rtc_event.h88
-rw-r--r--third_party/libwebrtc/api/rtc_event_log/rtc_event_log.cc21
-rw-r--r--third_party/libwebrtc/api/rtc_event_log/rtc_event_log.h69
-rw-r--r--third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory.cc48
-rw-r--r--third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory.h39
-rw-r--r--third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory_interface.h35
-rw-r--r--third_party/libwebrtc/api/rtc_event_log/rtc_event_log_gn/moz.build226
-rw-r--r--third_party/libwebrtc/api/rtc_event_log_output.h44
-rw-r--r--third_party/libwebrtc/api/rtc_event_log_output_file.cc85
-rw-r--r--third_party/libwebrtc/api/rtc_event_log_output_file.h58
-rw-r--r--third_party/libwebrtc/api/rtc_event_log_output_file_unittest.cc167
-rw-r--r--third_party/libwebrtc/api/rtp_headers.cc55
-rw-r--r--third_party/libwebrtc/api/rtp_headers.h193
-rw-r--r--third_party/libwebrtc/api/rtp_headers_gn/moz.build225
-rw-r--r--third_party/libwebrtc/api/rtp_packet_info.cc56
-rw-r--r--third_party/libwebrtc/api/rtp_packet_info.h117
-rw-r--r--third_party/libwebrtc/api/rtp_packet_info_gn/moz.build225
-rw-r--r--third_party/libwebrtc/api/rtp_packet_info_unittest.cc218
-rw-r--r--third_party/libwebrtc/api/rtp_packet_infos.h131
-rw-r--r--third_party/libwebrtc/api/rtp_packet_infos_unittest.cc113
-rw-r--r--third_party/libwebrtc/api/rtp_parameters.cc295
-rw-r--r--third_party/libwebrtc/api/rtp_parameters.h719
-rw-r--r--third_party/libwebrtc/api/rtp_parameters_gn/moz.build222
-rw-r--r--third_party/libwebrtc/api/rtp_parameters_unittest.cc303
-rw-r--r--third_party/libwebrtc/api/rtp_receiver_interface.cc44
-rw-r--r--third_party/libwebrtc/api/rtp_receiver_interface.h123
-rw-r--r--third_party/libwebrtc/api/rtp_sender_interface.cc22
-rw-r--r--third_party/libwebrtc/api/rtp_sender_interface.h123
-rw-r--r--third_party/libwebrtc/api/rtp_sender_interface_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/rtp_sender_setparameters_callback.cc27
-rw-r--r--third_party/libwebrtc/api/rtp_sender_setparameters_callback.h28
-rw-r--r--third_party/libwebrtc/api/rtp_sender_setparameters_callback_gn/moz.build225
-rw-r--r--third_party/libwebrtc/api/rtp_transceiver_direction.h27
-rw-r--r--third_party/libwebrtc/api/rtp_transceiver_direction_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/rtp_transceiver_interface.cc60
-rw-r--r--third_party/libwebrtc/api/rtp_transceiver_interface.h178
-rw-r--r--third_party/libwebrtc/api/scoped_refptr.h222
-rw-r--r--third_party/libwebrtc/api/scoped_refptr_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/scoped_refptr_unittest.cc111
-rw-r--r--third_party/libwebrtc/api/sctp_transport_interface.cc32
-rw-r--r--third_party/libwebrtc/api/sctp_transport_interface.h92
-rw-r--r--third_party/libwebrtc/api/sequence_checker.h126
-rw-r--r--third_party/libwebrtc/api/sequence_checker_gn/moz.build205
-rw-r--r--third_party/libwebrtc/api/sequence_checker_unittest.cc224
-rw-r--r--third_party/libwebrtc/api/set_local_description_observer_interface.h30
-rw-r--r--third_party/libwebrtc/api/set_remote_description_observer_interface.h31
-rw-r--r--third_party/libwebrtc/api/simulated_network_api_gn/moz.build205
-rw-r--r--third_party/libwebrtc/api/stats/OWNERS2
-rw-r--r--third_party/libwebrtc/api/stats/rtc_stats.h580
-rw-r--r--third_party/libwebrtc/api/stats/rtc_stats_collector_callback.h30
-rw-r--r--third_party/libwebrtc/api/stats/rtc_stats_report.h144
-rw-r--r--third_party/libwebrtc/api/stats/rtcstats_objects.h722
-rw-r--r--third_party/libwebrtc/api/task_queue/BUILD.gn166
-rw-r--r--third_party/libwebrtc/api/task_queue/DEPS14
-rw-r--r--third_party/libwebrtc/api/task_queue/default_task_queue_factory.h25
-rw-r--r--third_party/libwebrtc/api/task_queue/default_task_queue_factory_gcd.cc23
-rw-r--r--third_party/libwebrtc/api/task_queue/default_task_queue_factory_libevent.cc23
-rw-r--r--third_party/libwebrtc/api/task_queue/default_task_queue_factory_stdlib.cc23
-rw-r--r--third_party/libwebrtc/api/task_queue/default_task_queue_factory_stdlib_or_libevent_experiment.cc38
-rw-r--r--third_party/libwebrtc/api/task_queue/default_task_queue_factory_unittest.cc24
-rw-r--r--third_party/libwebrtc/api/task_queue/default_task_queue_factory_win.cc23
-rw-r--r--third_party/libwebrtc/api/task_queue/pending_task_safety_flag.cc57
-rw-r--r--third_party/libwebrtc/api/task_queue/pending_task_safety_flag.h168
-rw-r--r--third_party/libwebrtc/api/task_queue/pending_task_safety_flag_gn/moz.build221
-rw-r--r--third_party/libwebrtc/api/task_queue/pending_task_safety_flag_unittest.cc188
-rw-r--r--third_party/libwebrtc/api/task_queue/task_queue_base.cc81
-rw-r--r--third_party/libwebrtc/api/task_queue/task_queue_base.h156
-rw-r--r--third_party/libwebrtc/api/task_queue/task_queue_factory.h35
-rw-r--r--third_party/libwebrtc/api/task_queue/task_queue_gn/moz.build221
-rw-r--r--third_party/libwebrtc/api/task_queue/task_queue_test.cc333
-rw-r--r--third_party/libwebrtc/api/task_queue/task_queue_test.h41
-rw-r--r--third_party/libwebrtc/api/task_queue/test/BUILD.gn20
-rw-r--r--third_party/libwebrtc/api/task_queue/test/mock_task_queue_base.h37
-rw-r--r--third_party/libwebrtc/api/test/DEPS39
-rw-r--r--third_party/libwebrtc/api/test/OWNERS5
-rw-r--r--third_party/libwebrtc/api/test/audio_quality_analyzer_interface.h44
-rw-r--r--third_party/libwebrtc/api/test/audioproc_float.cc44
-rw-r--r--third_party/libwebrtc/api/test/audioproc_float.h71
-rw-r--r--third_party/libwebrtc/api/test/compile_all_headers.cc53
-rw-r--r--third_party/libwebrtc/api/test/create_frame_generator.cc101
-rw-r--r--third_party/libwebrtc/api/test/create_frame_generator.h85
-rw-r--r--third_party/libwebrtc/api/test/create_network_emulation_manager.cc27
-rw-r--r--third_party/libwebrtc/api/test/create_network_emulation_manager.h28
-rw-r--r--third_party/libwebrtc/api/test/create_peer_connection_quality_test_frame_generator.cc103
-rw-r--r--third_party/libwebrtc/api/test/create_peer_connection_quality_test_frame_generator.h44
-rw-r--r--third_party/libwebrtc/api/test/create_peerconnection_quality_test_fixture.cc36
-rw-r--r--third_party/libwebrtc/api/test/create_peerconnection_quality_test_fixture.h43
-rw-r--r--third_party/libwebrtc/api/test/create_simulcast_test_fixture.cc31
-rw-r--r--third_party/libwebrtc/api/test/create_simulcast_test_fixture.h32
-rw-r--r--third_party/libwebrtc/api/test/create_time_controller.cc53
-rw-r--r--third_party/libwebrtc/api/test/create_time_controller.h34
-rw-r--r--third_party/libwebrtc/api/test/create_time_controller_unittest.cc76
-rw-r--r--third_party/libwebrtc/api/test/create_video_codec_tester.cc27
-rw-r--r--third_party/libwebrtc/api/test/create_video_codec_tester.h26
-rw-r--r--third_party/libwebrtc/api/test/create_video_quality_test_fixture.cc40
-rw-r--r--third_party/libwebrtc/api/test/create_video_quality_test_fixture.h31
-rw-r--r--third_party/libwebrtc/api/test/create_videocodec_test_fixture.cc38
-rw-r--r--third_party/libwebrtc/api/test/create_videocodec_test_fixture.h34
-rw-r--r--third_party/libwebrtc/api/test/fake_frame_decryptor.cc71
-rw-r--r--third_party/libwebrtc/api/test/fake_frame_decryptor.h70
-rw-r--r--third_party/libwebrtc/api/test/fake_frame_encryptor.cc66
-rw-r--r--third_party/libwebrtc/api/test/fake_frame_encryptor.h69
-rw-r--r--third_party/libwebrtc/api/test/frame_generator_interface.cc34
-rw-r--r--third_party/libwebrtc/api/test/frame_generator_interface.h51
-rw-r--r--third_party/libwebrtc/api/test/metrics/BUILD.gn281
-rw-r--r--third_party/libwebrtc/api/test/metrics/DEPS14
-rw-r--r--third_party/libwebrtc/api/test/metrics/chrome_perf_dashboard_metrics_exporter.cc146
-rw-r--r--third_party/libwebrtc/api/test/metrics/chrome_perf_dashboard_metrics_exporter.h41
-rw-r--r--third_party/libwebrtc/api/test/metrics/chrome_perf_dashboard_metrics_exporter_test.cc248
-rw-r--r--third_party/libwebrtc/api/test/metrics/global_metrics_logger_and_exporter.cc42
-rw-r--r--third_party/libwebrtc/api/test/metrics/global_metrics_logger_and_exporter.h32
-rw-r--r--third_party/libwebrtc/api/test/metrics/global_metrics_logger_and_exporter_test.cc131
-rw-r--r--third_party/libwebrtc/api/test/metrics/metric.cc48
-rw-r--r--third_party/libwebrtc/api/test/metrics/metric.h96
-rw-r--r--third_party/libwebrtc/api/test/metrics/metrics_accumulator.cc132
-rw-r--r--third_party/libwebrtc/api/test/metrics/metrics_accumulator.h99
-rw-r--r--third_party/libwebrtc/api/test/metrics/metrics_accumulator_test.cc315
-rw-r--r--third_party/libwebrtc/api/test/metrics/metrics_exporter.h33
-rw-r--r--third_party/libwebrtc/api/test/metrics/metrics_logger.cc114
-rw-r--r--third_party/libwebrtc/api/test/metrics/metrics_logger.h112
-rw-r--r--third_party/libwebrtc/api/test/metrics/metrics_logger_test.cc326
-rw-r--r--third_party/libwebrtc/api/test/metrics/metrics_set_proto_file_exporter.cc157
-rw-r--r--third_party/libwebrtc/api/test/metrics/metrics_set_proto_file_exporter.h54
-rw-r--r--third_party/libwebrtc/api/test/metrics/metrics_set_proto_file_exporter_test.cc151
-rw-r--r--third_party/libwebrtc/api/test/metrics/print_result_proxy_metrics_exporter.cc157
-rw-r--r--third_party/libwebrtc/api/test/metrics/print_result_proxy_metrics_exporter.h32
-rw-r--r--third_party/libwebrtc/api/test/metrics/print_result_proxy_metrics_exporter_test.cc177
-rw-r--r--third_party/libwebrtc/api/test/metrics/proto/metric.proto87
-rw-r--r--third_party/libwebrtc/api/test/metrics/stdout_metrics_exporter.cc101
-rw-r--r--third_party/libwebrtc/api/test/metrics/stdout_metrics_exporter.h41
-rw-r--r--third_party/libwebrtc/api/test/metrics/stdout_metrics_exporter_test.cc211
-rw-r--r--third_party/libwebrtc/api/test/mock_async_dns_resolver.h62
-rw-r--r--third_party/libwebrtc/api/test/mock_audio_mixer.h29
-rw-r--r--third_party/libwebrtc/api/test/mock_audio_sink.h44
-rw-r--r--third_party/libwebrtc/api/test/mock_data_channel.h61
-rw-r--r--third_party/libwebrtc/api/test/mock_dtmf_sender.h56
-rw-r--r--third_party/libwebrtc/api/test/mock_encoder_selector.h42
-rw-r--r--third_party/libwebrtc/api/test/mock_fec_controller_override.h26
-rw-r--r--third_party/libwebrtc/api/test/mock_frame_decryptor.h40
-rw-r--r--third_party/libwebrtc/api/test/mock_frame_encryptor.h39
-rw-r--r--third_party/libwebrtc/api/test/mock_media_stream_interface.h134
-rw-r--r--third_party/libwebrtc/api/test/mock_packet_socket_factory.h49
-rw-r--r--third_party/libwebrtc/api/test/mock_peer_connection_factory_interface.h81
-rw-r--r--third_party/libwebrtc/api/test/mock_peerconnectioninterface.h213
-rw-r--r--third_party/libwebrtc/api/test/mock_rtp_transceiver.h87
-rw-r--r--third_party/libwebrtc/api/test/mock_rtpreceiver.h58
-rw-r--r--third_party/libwebrtc/api/test/mock_rtpsender.h78
-rw-r--r--third_party/libwebrtc/api/test/mock_session_description_interface.h56
-rw-r--r--third_party/libwebrtc/api/test/mock_transformable_video_frame.h42
-rw-r--r--third_party/libwebrtc/api/test/mock_video_bitrate_allocator.h28
-rw-r--r--third_party/libwebrtc/api/test/mock_video_bitrate_allocator_factory.h34
-rw-r--r--third_party/libwebrtc/api/test/mock_video_decoder.h70
-rw-r--r--third_party/libwebrtc/api/test/mock_video_decoder_factory.h40
-rw-r--r--third_party/libwebrtc/api/test/mock_video_encoder.h73
-rw-r--r--third_party/libwebrtc/api/test/mock_video_encoder_factory.h42
-rw-r--r--third_party/libwebrtc/api/test/mock_video_track.h69
-rw-r--r--third_party/libwebrtc/api/test/neteq_simulator.cc26
-rw-r--r--third_party/libwebrtc/api/test/neteq_simulator.h82
-rw-r--r--third_party/libwebrtc/api/test/neteq_simulator_factory.cc71
-rw-r--r--third_party/libwebrtc/api/test/neteq_simulator_factory.h71
-rw-r--r--third_party/libwebrtc/api/test/network_emulation/BUILD.gn52
-rw-r--r--third_party/libwebrtc/api/test/network_emulation/DEPS7
-rw-r--r--third_party/libwebrtc/api/test/network_emulation/create_cross_traffic.cc39
-rw-r--r--third_party/libwebrtc/api/test/network_emulation/create_cross_traffic.h37
-rw-r--r--third_party/libwebrtc/api/test/network_emulation/cross_traffic.h85
-rw-r--r--third_party/libwebrtc/api/test/network_emulation/network_emulation_interfaces.cc46
-rw-r--r--third_party/libwebrtc/api/test/network_emulation/network_emulation_interfaces.h311
-rw-r--r--third_party/libwebrtc/api/test/network_emulation_manager.cc122
-rw-r--r--third_party/libwebrtc/api/test/network_emulation_manager.h357
-rw-r--r--third_party/libwebrtc/api/test/pclf/BUILD.gn114
-rw-r--r--third_party/libwebrtc/api/test/pclf/DEPS13
-rw-r--r--third_party/libwebrtc/api/test/pclf/media_configuration.cc314
-rw-r--r--third_party/libwebrtc/api/test/pclf/media_configuration.h484
-rw-r--r--third_party/libwebrtc/api/test/pclf/media_quality_test_params.h189
-rw-r--r--third_party/libwebrtc/api/test/pclf/peer_configurer.cc245
-rw-r--r--third_party/libwebrtc/api/test/pclf/peer_configurer.h200
-rw-r--r--third_party/libwebrtc/api/test/peer_network_dependencies.h32
-rw-r--r--third_party/libwebrtc/api/test/peerconnection_quality_test_fixture.h142
-rw-r--r--third_party/libwebrtc/api/test/peerconnection_quality_test_fixture_unittest.cc142
-rw-r--r--third_party/libwebrtc/api/test/simulated_network.h139
-rw-r--r--third_party/libwebrtc/api/test/simulcast_test_fixture.h45
-rw-r--r--third_party/libwebrtc/api/test/stats_observer_interface.h35
-rw-r--r--third_party/libwebrtc/api/test/test_dependency_factory.cc54
-rw-r--r--third_party/libwebrtc/api/test/test_dependency_factory.h48
-rw-r--r--third_party/libwebrtc/api/test/time_controller.cc43
-rw-r--r--third_party/libwebrtc/api/test/time_controller.h89
-rw-r--r--third_party/libwebrtc/api/test/track_id_stream_info_map.h44
-rw-r--r--third_party/libwebrtc/api/test/video/BUILD.gn31
-rw-r--r--third_party/libwebrtc/api/test/video/function_video_decoder_factory.h65
-rw-r--r--third_party/libwebrtc/api/test/video/function_video_encoder_factory.h60
-rw-r--r--third_party/libwebrtc/api/test/video/video_frame_writer.h37
-rw-r--r--third_party/libwebrtc/api/test/video_codec_tester.h134
-rw-r--r--third_party/libwebrtc/api/test/video_quality_analyzer_interface.h165
-rw-r--r--third_party/libwebrtc/api/test/video_quality_test_fixture.h143
-rw-r--r--third_party/libwebrtc/api/test/videocodec_test_fixture.h177
-rw-r--r--third_party/libwebrtc/api/test/videocodec_test_stats.cc121
-rw-r--r--third_party/libwebrtc/api/test/videocodec_test_stats.h156
-rw-r--r--third_party/libwebrtc/api/transport/BUILD.gn167
-rw-r--r--third_party/libwebrtc/api/transport/DEPS7
-rw-r--r--third_party/libwebrtc/api/transport/OWNERS2
-rw-r--r--third_party/libwebrtc/api/transport/bitrate_settings.cc19
-rw-r--r--third_party/libwebrtc/api/transport/bitrate_settings.h50
-rw-r--r--third_party/libwebrtc/api/transport/bitrate_settings_gn/moz.build217
-rw-r--r--third_party/libwebrtc/api/transport/data_channel_transport_interface.h125
-rw-r--r--third_party/libwebrtc/api/transport/datagram_transport_interface_gn/moz.build209
-rw-r--r--third_party/libwebrtc/api/transport/enums.h49
-rw-r--r--third_party/libwebrtc/api/transport/field_trial_based_config.cc18
-rw-r--r--third_party/libwebrtc/api/transport/field_trial_based_config.h26
-rw-r--r--third_party/libwebrtc/api/transport/field_trial_based_config_gn/moz.build225
-rw-r--r--third_party/libwebrtc/api/transport/goog_cc_factory.cc65
-rw-r--r--third_party/libwebrtc/api/transport/goog_cc_factory.h61
-rw-r--r--third_party/libwebrtc/api/transport/goog_cc_gn/moz.build232
-rw-r--r--third_party/libwebrtc/api/transport/network_control.h140
-rw-r--r--third_party/libwebrtc/api/transport/network_control_gn/moz.build225
-rw-r--r--third_party/libwebrtc/api/transport/network_types.cc106
-rw-r--r--third_party/libwebrtc/api/transport/network_types.h278
-rw-r--r--third_party/libwebrtc/api/transport/rtp/BUILD.gn37
-rw-r--r--third_party/libwebrtc/api/transport/rtp/dependency_descriptor.cc54
-rw-r--r--third_party/libwebrtc/api/transport/rtp/dependency_descriptor.h129
-rw-r--r--third_party/libwebrtc/api/transport/rtp/dependency_descriptor_gn/moz.build221
-rw-r--r--third_party/libwebrtc/api/transport/rtp/rtp_source.h111
-rw-r--r--third_party/libwebrtc/api/transport/rtp/rtp_source_gn/moz.build209
-rw-r--r--third_party/libwebrtc/api/transport/sctp_transport_factory_interface.h42
-rw-r--r--third_party/libwebrtc/api/transport/stun.cc1515
-rw-r--r--third_party/libwebrtc/api/transport/stun.h798
-rw-r--r--third_party/libwebrtc/api/transport/stun_types_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/transport/stun_unittest.cc1882
-rw-r--r--third_party/libwebrtc/api/transport/test/create_feedback_generator.cc23
-rw-r--r--third_party/libwebrtc/api/transport/test/create_feedback_generator.h21
-rw-r--r--third_party/libwebrtc/api/transport/test/feedback_generator_interface.h37
-rw-r--r--third_party/libwebrtc/api/transport/test/mock_network_control.h35
-rw-r--r--third_party/libwebrtc/api/transport_api_gn/moz.build217
-rw-r--r--third_party/libwebrtc/api/turn_customizer.h46
-rw-r--r--third_party/libwebrtc/api/uma_metrics.h194
-rw-r--r--third_party/libwebrtc/api/units/BUILD.gn111
-rw-r--r--third_party/libwebrtc/api/units/OWNERS1
-rw-r--r--third_party/libwebrtc/api/units/data_rate.cc34
-rw-r--r--third_party/libwebrtc/api/units/data_rate.h155
-rw-r--r--third_party/libwebrtc/api/units/data_rate_gn/moz.build221
-rw-r--r--third_party/libwebrtc/api/units/data_rate_unittest.cc197
-rw-r--r--third_party/libwebrtc/api/units/data_size.cc30
-rw-r--r--third_party/libwebrtc/api/units/data_size.h66
-rw-r--r--third_party/libwebrtc/api/units/data_size_gn/moz.build221
-rw-r--r--third_party/libwebrtc/api/units/data_size_unittest.cc110
-rw-r--r--third_party/libwebrtc/api/units/frequency.cc29
-rw-r--r--third_party/libwebrtc/api/units/frequency.h101
-rw-r--r--third_party/libwebrtc/api/units/frequency_gn/moz.build221
-rw-r--r--third_party/libwebrtc/api/units/frequency_unittest.cc161
-rw-r--r--third_party/libwebrtc/api/units/time_delta.cc36
-rw-r--r--third_party/libwebrtc/api/units/time_delta.h110
-rw-r--r--third_party/libwebrtc/api/units/time_delta_gn/moz.build221
-rw-r--r--third_party/libwebrtc/api/units/time_delta_unittest.cc237
-rw-r--r--third_party/libwebrtc/api/units/timestamp.cc34
-rw-r--r--third_party/libwebrtc/api/units/timestamp.h139
-rw-r--r--third_party/libwebrtc/api/units/timestamp_gn/moz.build221
-rw-r--r--third_party/libwebrtc/api/units/timestamp_unittest.cc162
-rw-r--r--third_party/libwebrtc/api/video/BUILD.gn421
-rw-r--r--third_party/libwebrtc/api/video/DEPS77
-rw-r--r--third_party/libwebrtc/api/video/OWNERS5
-rw-r--r--third_party/libwebrtc/api/video/builtin_video_bitrate_allocator_factory.cc50
-rw-r--r--third_party/libwebrtc/api/video/builtin_video_bitrate_allocator_factory.h25
-rw-r--r--third_party/libwebrtc/api/video/builtin_video_bitrate_allocator_factory_gn/moz.build233
-rw-r--r--third_party/libwebrtc/api/video/color_space.cc187
-rw-r--r--third_party/libwebrtc/api/video/color_space.h178
-rw-r--r--third_party/libwebrtc/api/video/encoded_frame.cc33
-rw-r--r--third_party/libwebrtc/api/video/encoded_frame.h74
-rw-r--r--third_party/libwebrtc/api/video/encoded_frame_gn/moz.build232
-rw-r--r--third_party/libwebrtc/api/video/encoded_image.cc99
-rw-r--r--third_party/libwebrtc/api/video/encoded_image.h226
-rw-r--r--third_party/libwebrtc/api/video/encoded_image_gn/moz.build225
-rw-r--r--third_party/libwebrtc/api/video/frame_buffer.cc332
-rw-r--r--third_party/libwebrtc/api/video/frame_buffer.h110
-rw-r--r--third_party/libwebrtc/api/video/frame_buffer_gn/moz.build232
-rw-r--r--third_party/libwebrtc/api/video/frame_buffer_unittest.cc393
-rw-r--r--third_party/libwebrtc/api/video/hdr_metadata.cc21
-rw-r--r--third_party/libwebrtc/api/video/hdr_metadata.h105
-rw-r--r--third_party/libwebrtc/api/video/i010_buffer.cc213
-rw-r--r--third_party/libwebrtc/api/video/i010_buffer.h84
-rw-r--r--third_party/libwebrtc/api/video/i210_buffer.cc211
-rw-r--r--third_party/libwebrtc/api/video/i210_buffer.h84
-rw-r--r--third_party/libwebrtc/api/video/i410_buffer.cc221
-rw-r--r--third_party/libwebrtc/api/video/i410_buffer.h104
-rw-r--r--third_party/libwebrtc/api/video/i420_buffer.cc232
-rw-r--r--third_party/libwebrtc/api/video/i420_buffer.h118
-rw-r--r--third_party/libwebrtc/api/video/i422_buffer.cc237
-rw-r--r--third_party/libwebrtc/api/video/i422_buffer.h114
-rw-r--r--third_party/libwebrtc/api/video/i444_buffer.cc211
-rw-r--r--third_party/libwebrtc/api/video/i444_buffer.h104
-rw-r--r--third_party/libwebrtc/api/video/nv12_buffer.cc155
-rw-r--r--third_party/libwebrtc/api/video/nv12_buffer.h85
-rw-r--r--third_party/libwebrtc/api/video/recordable_encoded_frame.h61
-rw-r--r--third_party/libwebrtc/api/video/recordable_encoded_frame_gn/moz.build209
-rw-r--r--third_party/libwebrtc/api/video/render_resolution.h46
-rw-r--r--third_party/libwebrtc/api/video/render_resolution_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/video/resolution.h38
-rw-r--r--third_party/libwebrtc/api/video/resolution_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/video/rtp_video_frame_assembler.cc340
-rw-r--r--third_party/libwebrtc/api/video/rtp_video_frame_assembler.h76
-rw-r--r--third_party/libwebrtc/api/video/rtp_video_frame_assembler_unittests.cc583
-rw-r--r--third_party/libwebrtc/api/video/test/BUILD.gn56
-rw-r--r--third_party/libwebrtc/api/video/test/color_space_unittest.cc74
-rw-r--r--third_party/libwebrtc/api/video/test/i210_buffer_unittest.cc126
-rw-r--r--third_party/libwebrtc/api/video/test/i410_buffer_unittest.cc120
-rw-r--r--third_party/libwebrtc/api/video/test/i422_buffer_unittest.cc128
-rw-r--r--third_party/libwebrtc/api/video/test/i444_buffer_unittest.cc112
-rw-r--r--third_party/libwebrtc/api/video/test/mock_recordable_encoded_frame.h34
-rw-r--r--third_party/libwebrtc/api/video/test/nv12_buffer_unittest.cc119
-rw-r--r--third_party/libwebrtc/api/video/test/video_adaptation_counters_unittest.cc32
-rw-r--r--third_party/libwebrtc/api/video/test/video_bitrate_allocation_unittest.cc64
-rw-r--r--third_party/libwebrtc/api/video/test/video_frame_matchers.h34
-rw-r--r--third_party/libwebrtc/api/video/video_adaptation_counters.cc42
-rw-r--r--third_party/libwebrtc/api/video/video_adaptation_counters.h46
-rw-r--r--third_party/libwebrtc/api/video/video_adaptation_gn/moz.build221
-rw-r--r--third_party/libwebrtc/api/video/video_adaptation_reason.h20
-rw-r--r--third_party/libwebrtc/api/video/video_bitrate_allocation.cc185
-rw-r--r--third_party/libwebrtc/api/video/video_bitrate_allocation.h96
-rw-r--r--third_party/libwebrtc/api/video/video_bitrate_allocation_gn/moz.build221
-rw-r--r--third_party/libwebrtc/api/video/video_bitrate_allocator.cc54
-rw-r--r--third_party/libwebrtc/api/video/video_bitrate_allocator.h60
-rw-r--r--third_party/libwebrtc/api/video/video_bitrate_allocator_factory.h33
-rw-r--r--third_party/libwebrtc/api/video/video_bitrate_allocator_factory_gn/moz.build209
-rw-r--r--third_party/libwebrtc/api/video/video_bitrate_allocator_gn/moz.build221
-rw-r--r--third_party/libwebrtc/api/video/video_codec_constants.h24
-rw-r--r--third_party/libwebrtc/api/video/video_codec_constants_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/video/video_codec_type.h29
-rw-r--r--third_party/libwebrtc/api/video/video_content_type.cc93
-rw-r--r--third_party/libwebrtc/api/video/video_content_type.h39
-rw-r--r--third_party/libwebrtc/api/video/video_frame.cc317
-rw-r--r--third_party/libwebrtc/api/video/video_frame.h302
-rw-r--r--third_party/libwebrtc/api/video/video_frame_buffer.cc242
-rw-r--r--third_party/libwebrtc/api/video/video_frame_buffer.h325
-rw-r--r--third_party/libwebrtc/api/video/video_frame_gn/moz.build236
-rw-r--r--third_party/libwebrtc/api/video/video_frame_i010_gn/moz.build232
-rw-r--r--third_party/libwebrtc/api/video/video_frame_metadata.cc139
-rw-r--r--third_party/libwebrtc/api/video/video_frame_metadata.h112
-rw-r--r--third_party/libwebrtc/api/video/video_frame_metadata_gn/moz.build225
-rw-r--r--third_party/libwebrtc/api/video/video_frame_type.h26
-rw-r--r--third_party/libwebrtc/api/video/video_frame_type_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/video/video_layers_allocation.h77
-rw-r--r--third_party/libwebrtc/api/video/video_layers_allocation_gn/moz.build205
-rw-r--r--third_party/libwebrtc/api/video/video_rotation.h26
-rw-r--r--third_party/libwebrtc/api/video/video_rtp_headers_gn/moz.build228
-rw-r--r--third_party/libwebrtc/api/video/video_sink_interface.h39
-rw-r--r--third_party/libwebrtc/api/video/video_source_interface.cc19
-rw-r--r--third_party/libwebrtc/api/video/video_source_interface.h130
-rw-r--r--third_party/libwebrtc/api/video/video_stream_decoder.h57
-rw-r--r--third_party/libwebrtc/api/video/video_stream_decoder_create.cc32
-rw-r--r--third_party/libwebrtc/api/video/video_stream_decoder_create.h37
-rw-r--r--third_party/libwebrtc/api/video/video_stream_decoder_create_unittest.cc46
-rw-r--r--third_party/libwebrtc/api/video/video_stream_encoder_gn/moz.build209
-rw-r--r--third_party/libwebrtc/api/video/video_stream_encoder_settings.h60
-rw-r--r--third_party/libwebrtc/api/video/video_timing.cc101
-rw-r--r--third_party/libwebrtc/api/video/video_timing.h132
-rw-r--r--third_party/libwebrtc/api/video_codecs/BUILD.gn314
-rw-r--r--third_party/libwebrtc/api/video_codecs/OWNERS4
-rw-r--r--third_party/libwebrtc/api/video_codecs/av1_profile.cc69
-rw-r--r--third_party/libwebrtc/api/video_codecs/av1_profile.h57
-rw-r--r--third_party/libwebrtc/api/video_codecs/bitstream_parser.h37
-rw-r--r--third_party/libwebrtc/api/video_codecs/bitstream_parser_api_gn/moz.build205
-rw-r--r--third_party/libwebrtc/api/video_codecs/builtin_video_decoder_factory.cc23
-rw-r--r--third_party/libwebrtc/api/video_codecs/builtin_video_decoder_factory.h27
-rw-r--r--third_party/libwebrtc/api/video_codecs/builtin_video_encoder_factory.cc71
-rw-r--r--third_party/libwebrtc/api/video_codecs/builtin_video_encoder_factory.h28
-rw-r--r--third_party/libwebrtc/api/video_codecs/h264_profile_level_id.cc256
-rw-r--r--third_party/libwebrtc/api/video_codecs/h264_profile_level_id.h92
-rw-r--r--third_party/libwebrtc/api/video_codecs/rtc_software_fallback_wrappers_gn/moz.build234
-rw-r--r--third_party/libwebrtc/api/video_codecs/scalability_mode.cc91
-rw-r--r--third_party/libwebrtc/api/video_codecs/scalability_mode.h111
-rw-r--r--third_party/libwebrtc/api/video_codecs/scalability_mode_gn/moz.build221
-rw-r--r--third_party/libwebrtc/api/video_codecs/scalability_mode_helper.cc37
-rw-r--r--third_party/libwebrtc/api/video_codecs/scalability_mode_helper.h31
-rw-r--r--third_party/libwebrtc/api/video_codecs/sdp_video_format.cc171
-rw-r--r--third_party/libwebrtc/api/video_codecs/sdp_video_format.h75
-rw-r--r--third_party/libwebrtc/api/video_codecs/simulcast_stream.cc37
-rw-r--r--third_party/libwebrtc/api/video_codecs/simulcast_stream.h39
-rw-r--r--third_party/libwebrtc/api/video_codecs/spatial_layer.cc25
-rw-r--r--third_party/libwebrtc/api/video_codecs/spatial_layer.h32
-rw-r--r--third_party/libwebrtc/api/video_codecs/test/BUILD.gn81
-rw-r--r--third_party/libwebrtc/api/video_codecs/test/builtin_video_encoder_factory_unittest.cc39
-rw-r--r--third_party/libwebrtc/api/video_codecs/test/h264_profile_level_id_unittest.cc171
-rw-r--r--third_party/libwebrtc/api/video_codecs/test/sdp_video_format_unittest.cc103
-rw-r--r--third_party/libwebrtc/api/video_codecs/test/video_decoder_factory_template_tests.cc123
-rw-r--r--third_party/libwebrtc/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc305
-rw-r--r--third_party/libwebrtc/api/video_codecs/test/video_encoder_factory_template_tests.cc172
-rw-r--r--third_party/libwebrtc/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc1055
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_codec.cc155
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_codec.h200
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_codecs_api_gn/moz.build235
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_decoder.cc65
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_decoder.h136
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_decoder_factory.h69
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_decoder_factory_template.h95
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_dav1d_adapter.h34
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h33
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h32
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_open_h264_adapter.h44
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_decoder_software_fallback_wrapper.cc284
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_decoder_software_fallback_wrapper.h31
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_encoder.cc345
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_encoder.h426
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_encoder_factory.h127
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_encoder_factory_template.h135
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h43
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h46
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h36
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_encoder_factory_template_open_h264_adapter.h50
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_encoder_software_fallback_wrapper.cc519
-rw-r--r--third_party/libwebrtc/api/video_codecs/video_encoder_software_fallback_wrapper.h47
-rw-r--r--third_party/libwebrtc/api/video_codecs/vp8_frame_buffer_controller.h192
-rw-r--r--third_party/libwebrtc/api/video_codecs/vp8_frame_config.cc78
-rw-r--r--third_party/libwebrtc/api/video_codecs/vp8_frame_config.h110
-rw-r--r--third_party/libwebrtc/api/video_codecs/vp8_temporal_layers.cc108
-rw-r--r--third_party/libwebrtc/api/video_codecs/vp8_temporal_layers.h77
-rw-r--r--third_party/libwebrtc/api/video_codecs/vp8_temporal_layers_factory.cc59
-rw-r--r--third_party/libwebrtc/api/video_codecs/vp8_temporal_layers_factory.h34
-rw-r--r--third_party/libwebrtc/api/video_codecs/vp8_temporal_layers_factory_gn/moz.build232
-rw-r--r--third_party/libwebrtc/api/video_codecs/vp9_profile.cc73
-rw-r--r--third_party/libwebrtc/api/video_codecs/vp9_profile.h54
-rw-r--r--third_party/libwebrtc/api/video_track_source_constraints.h32
-rw-r--r--third_party/libwebrtc/api/video_track_source_constraints_gn/moz.build201
-rw-r--r--third_party/libwebrtc/api/video_track_source_proxy_factory.h29
-rw-r--r--third_party/libwebrtc/api/voip/BUILD.gn85
-rw-r--r--third_party/libwebrtc/api/voip/DEPS10
-rw-r--r--third_party/libwebrtc/api/voip/test/compile_all_headers.cc14
-rw-r--r--third_party/libwebrtc/api/voip/test/mock_voip_engine.h124
-rw-r--r--third_party/libwebrtc/api/voip/test/voip_engine_factory_unittest.cc51
-rw-r--r--third_party/libwebrtc/api/voip/voip_base.h114
-rw-r--r--third_party/libwebrtc/api/voip/voip_codec.h56
-rw-r--r--third_party/libwebrtc/api/voip/voip_dtmf.h74
-rw-r--r--third_party/libwebrtc/api/voip/voip_engine.h99
-rw-r--r--third_party/libwebrtc/api/voip/voip_engine_factory.cc37
-rw-r--r--third_party/libwebrtc/api/voip/voip_engine_factory.h68
-rw-r--r--third_party/libwebrtc/api/voip/voip_network.h46
-rw-r--r--third_party/libwebrtc/api/voip/voip_statistics.h98
-rw-r--r--third_party/libwebrtc/api/voip/voip_volume_control.h64
-rw-r--r--third_party/libwebrtc/api/webrtc_key_value_config.h17
-rw-r--r--third_party/libwebrtc/api/wrapping_async_dns_resolver.cc31
-rw-r--r--third_party/libwebrtc/api/wrapping_async_dns_resolver.h131
675 files changed, 88073 insertions, 0 deletions
diff --git a/third_party/libwebrtc/api/BUILD.gn b/third_party/libwebrtc/api/BUILD.gn
new file mode 100644
index 0000000000..7c16b45e05
--- /dev/null
+++ b/third_party/libwebrtc/api/BUILD.gn
@@ -0,0 +1,1559 @@
+# Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../webrtc.gni")
+if (is_android) {
+ import("//build/config/android/config.gni")
+ import("//build/config/android/rules.gni")
+}
+
+group("api") {
+ visibility = [ "*" ]
+ deps = []
+
+ if (!build_with_mozilla) {
+ deps += [ ":libjingle_peerconnection_api" ]
+ }
+}
+
+rtc_source_set("call_api") {
+ visibility = [ "*" ]
+ sources = [ "call/audio_sink.h" ]
+}
+
+rtc_source_set("callfactory_api") {
+ visibility = [ "*" ]
+ sources = [ "call/call_factory_interface.h" ]
+ deps = [
+ "../call:rtp_interfaces",
+ "../rtc_base/system:rtc_export",
+ ]
+}
+
+if (!build_with_chromium && !build_with_mozilla) {
+ rtc_library("create_peerconnection_factory") {
+ visibility = [ "*" ]
+ allow_poison = [ "default_task_queue" ]
+ sources = [
+ "create_peerconnection_factory.cc",
+ "create_peerconnection_factory.h",
+ ]
+ deps = [
+ ":callfactory_api",
+ ":libjingle_peerconnection_api",
+ ":scoped_refptr",
+ "../api/rtc_event_log:rtc_event_log_factory",
+ "../media:rtc_audio_video",
+ "../media:rtc_media_base",
+ "../modules/audio_device:audio_device_api",
+ "../modules/audio_processing:api",
+ "../pc:peer_connection_factory",
+ "../pc:webrtc_sdp",
+ "../rtc_base:threading",
+ "../stats:rtc_stats",
+ "audio:audio_mixer_api",
+ "audio_codecs:audio_codecs_api",
+ "task_queue:default_task_queue_factory",
+ "transport:field_trial_based_config",
+ "video_codecs:video_codecs_api",
+ ]
+ }
+}
+
+rtc_library("rtp_headers") {
+ visibility = [ "*" ]
+ sources = [
+ "rtp_headers.cc",
+ "rtp_headers.h",
+ ]
+ deps = [
+ ":array_view",
+ "units:timestamp",
+ "video:video_rtp_headers",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_library("rtp_packet_info") {
+ visibility = [ "*" ]
+ sources = [
+ "rtp_packet_info.cc",
+ "rtp_packet_info.h",
+ "rtp_packet_infos.h",
+ ]
+ deps = [
+ ":array_view",
+ ":make_ref_counted",
+ ":refcountedbase",
+ ":rtp_headers",
+ ":scoped_refptr",
+ "../rtc_base/system:rtc_export",
+ "units:time_delta",
+ "units:timestamp",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_source_set("video_track_source_constraints") {
+ visibility = [ "*" ]
+ sources = [ "video_track_source_constraints.h" ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_library("media_stream_interface") {
+ visibility = [ "*" ]
+ sources = [
+ "media_stream_interface.cc",
+ "media_stream_interface.h",
+ "media_stream_track.h",
+ "notifier.h",
+ ]
+ deps = [
+ ":audio_options_api",
+ ":make_ref_counted",
+ ":rtp_parameters",
+ ":scoped_refptr",
+ ":sequence_checker",
+ ":video_track_source_constraints",
+ "../modules/audio_processing:audio_processing_statistics",
+ "../rtc_base:checks",
+ "../rtc_base:refcount",
+ "../rtc_base/system:no_unique_address",
+ "../rtc_base/system:rtc_export",
+ "video:recordable_encoded_frame",
+ "video:video_frame",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
+rtc_library("candidate") {
+ visibility = [ "*" ]
+
+ sources = [
+ "candidate.cc",
+ "candidate.h",
+ ]
+ deps = [
+ "../rtc_base:checks",
+ "../rtc_base:ip_address",
+ "../rtc_base:logging",
+ "../rtc_base:network_constants",
+ "../rtc_base:socket_address",
+ "../rtc_base:ssl",
+ "../rtc_base:stringutils",
+ "../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
+}
+
+rtc_source_set("turn_customizer") {
+ visibility = [ "*" ]
+ sources = [ "turn_customizer.h" ]
+ deps = [ "transport:stun_types" ]
+}
+
+rtc_source_set("ice_transport_interface") {
+ visibility = [ "*" ]
+
+ sources = [ "ice_transport_interface.h" ]
+ deps = [
+ ":async_dns_resolver",
+ ":packet_socket_factory",
+ ":rtc_error",
+ ":scoped_refptr",
+ "../rtc_base:refcount",
+ "rtc_event_log:rtc_event_log",
+ ]
+}
+
+rtc_library("dtls_transport_interface") {
+# Previously, Mozilla has tried to limit including this dep, but as
+# upstream changes, it requires whack-a-mole. Making it an empty
+# definition has the same effect, but only requires one change.
+if (!build_with_mozilla) {
+ visibility = [ "*" ]
+
+ sources = [
+ "dtls_transport_interface.cc",
+ "dtls_transport_interface.h",
+ ]
+ deps = [
+ ":ice_transport_interface",
+ ":rtc_error",
+ ":scoped_refptr",
+ "../rtc_base:refcount",
+ "../rtc_base:ssl",
+ "../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+}
+
+rtc_library("dtmf_sender_interface") {
+ visibility = [ "*" ]
+
+ sources = [ "dtmf_sender_interface.h" ]
+ deps = [
+ ":media_stream_interface",
+ "../rtc_base:refcount",
+ ]
+}
+
+rtc_library("rtp_sender_interface") {
+# Previously, Mozilla has tried to limit including this dep, but as
+# upstream changes, it requires whack-a-mole. Making it an empty
+# definition has the same effect, but only requires one change.
+if (!build_with_mozilla) {
+ visibility = [ "*" ]
+
+ sources = [
+ "rtp_sender_interface.cc",
+ "rtp_sender_interface.h",
+ ]
+ deps = [
+ ":dtls_transport_interface",
+ ":dtmf_sender_interface",
+ ":frame_transformer_interface",
+ ":media_stream_interface",
+ ":rtp_parameters",
+ ":rtp_sender_setparameters_callback",
+ ":scoped_refptr",
+ "../rtc_base:checks",
+ "../rtc_base:refcount",
+ "../rtc_base/system:rtc_export",
+ "crypto:frame_encryptor_interface",
+ "video_codecs:video_codecs_api",
+ ]
+}
+}
+
+rtc_library("rtp_sender_setparameters_callback") {
+ visibility = [ "*" ]
+
+ sources = [
+ "rtp_sender_setparameters_callback.cc",
+ "rtp_sender_setparameters_callback.h",
+ ]
+ deps = [
+ ":rtc_error",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/functional:any_invocable" ]
+}
+
+rtc_library("libjingle_peerconnection_api") {
+if (!build_with_mozilla) {
+ visibility = [ "*" ]
+ cflags = []
+ sources = [
+ "crypto_params.h",
+ "data_channel_interface.cc",
+ "data_channel_interface.h",
+ "jsep.cc",
+ "jsep.h",
+ "jsep_ice_candidate.cc",
+ "jsep_ice_candidate.h",
+ "jsep_session_description.h",
+ "legacy_stats_types.cc",
+ "legacy_stats_types.h",
+ "peer_connection_interface.cc",
+ "peer_connection_interface.h",
+ "rtp_receiver_interface.cc",
+ "rtp_receiver_interface.h",
+ "rtp_transceiver_interface.cc",
+ "rtp_transceiver_interface.h",
+ "sctp_transport_interface.cc",
+ "sctp_transport_interface.h",
+ "set_local_description_observer_interface.h",
+ "set_remote_description_observer_interface.h",
+ "uma_metrics.h",
+ "video_track_source_proxy_factory.h",
+
+ # Remove when downstream has been updated
+ "dtmf_sender_interface.h",
+ "rtp_sender_interface.h",
+ ]
+ public_deps = [ # no-presubmit-check TODO(webrtc:8603)
+ # Remove when downstream has been updated
+ ":dtmf_sender_interface",
+ ":rtp_sender_interface",
+ ]
+ deps = [
+ ":array_view",
+ ":async_dns_resolver",
+ ":audio_options_api",
+ ":callfactory_api",
+ ":candidate",
+ ":dtls_transport_interface",
+ ":fec_controller_api",
+ ":field_trials",
+ ":field_trials_view",
+ ":frame_transformer_interface",
+ ":ice_transport_interface",
+ ":libjingle_logging_api",
+ ":make_ref_counted",
+ ":media_stream_interface",
+ ":network_state_predictor_api",
+ ":packet_socket_factory",
+ ":priority",
+ ":rtc_error",
+ ":rtc_stats_api",
+ ":rtp_packet_info",
+ ":rtp_parameters",
+ ":rtp_sender_interface",
+ ":rtp_transceiver_direction",
+ ":scoped_refptr",
+ ":sequence_checker",
+ ":turn_customizer",
+ "../call:rtp_interfaces",
+ "../p2p:rtc_p2p",
+ "../rtc_base:copy_on_write_buffer",
+ "../rtc_base:logging",
+ "../rtc_base:network",
+ "../rtc_base:network_constants",
+ "../rtc_base:refcount",
+ "../rtc_base:rtc_certificate_generator",
+ "../rtc_base:ssl",
+ "../rtc_base:stringutils",
+ "adaptation:resource_adaptation_api",
+ "audio:audio_mixer_api",
+ "audio_codecs:audio_codecs_api",
+ "crypto:frame_decryptor_interface",
+ "crypto:frame_encryptor_interface",
+ "crypto:options",
+ "metronome",
+ "neteq:neteq_api",
+ "rtc_event_log",
+ "task_queue",
+ "transport:bitrate_settings",
+ "transport:enums",
+ "transport:network_control",
+ "transport:sctp_transport_factory_interface",
+ "transport/rtp:rtp_source",
+ "units:data_rate",
+ "units:timestamp",
+ "video:encoded_image",
+ "video:video_bitrate_allocator_factory",
+ "video:video_frame",
+ "video:video_rtp_headers",
+ "video_codecs:video_codecs_api",
+
+ # Basically, don't add stuff here. You might break sensitive downstream
+ # targets like pnacl. API should not depend on anything outside of this
+ # file, really. All these should arguably go away in time.
+ "../media:rtc_media_base",
+ "../media:rtc_media_config",
+ "../modules/audio_processing:audio_processing_statistics",
+ "../rtc_base:checks",
+ "../rtc_base:ip_address",
+ "../rtc_base:socket_address",
+ "../rtc_base:threading",
+ "../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/algorithm:container",
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ "//third_party/abseil-cpp/absl/functional:any_invocable",
+ "//third_party/abseil-cpp/absl/memory",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+}
+
+rtc_source_set("frame_transformer_interface") {
+ visibility = [ "*" ]
+ sources = [ "frame_transformer_interface.h" ]
+ deps = [
+ ":make_ref_counted",
+ ":scoped_refptr",
+ "../rtc_base:refcount",
+ "video:encoded_frame",
+ "video:video_frame_metadata",
+ ]
+}
+
+rtc_library("rtc_error") {
+ visibility = [ "*" ]
+ sources = [
+ "rtc_error.cc",
+ "rtc_error.h",
+ ]
+ deps = [
+ "../rtc_base:checks",
+ "../rtc_base:logging",
+ "../rtc_base:macromagic",
+ "../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_source_set("packet_socket_factory") {
+ visibility = [ "*" ]
+ sources = [
+ "async_resolver_factory.h",
+ "packet_socket_factory.h",
+ ]
+ deps = [
+ ":async_dns_resolver",
+ ":wrapping_async_dns_resolver",
+ "../rtc_base:async_packet_socket",
+ "../rtc_base:async_resolver_interface",
+ "../rtc_base:proxy_info",
+ "../rtc_base:socket_address",
+ "../rtc_base/system:rtc_export",
+ ]
+}
+
+rtc_source_set("async_dns_resolver") {
+ visibility = [ "*" ]
+ sources = [ "async_dns_resolver.h" ]
+ deps = [
+ "../rtc_base:checks",
+ "../rtc_base:socket_address",
+ "../rtc_base/system:rtc_export",
+ ]
+}
+
+rtc_source_set("wrapping_async_dns_resolver") {
+ visibility = [
+ ":*",
+ "../p2p:rtc_p2p",
+ ]
+ sources = [
+ "wrapping_async_dns_resolver.cc",
+ "wrapping_async_dns_resolver.h",
+ ]
+ deps = [
+ ":async_dns_resolver",
+ ":sequence_checker",
+ "../rtc_base:async_resolver_interface",
+ "../rtc_base:checks",
+ "../rtc_base:macromagic",
+ "../rtc_base:socket_address",
+ "../rtc_base:threading",
+ "../rtc_base/third_party/sigslot",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/memory" ]
+}
+
+rtc_source_set("scoped_refptr") {
+ visibility = [ "*" ]
+ sources = [ "scoped_refptr.h" ]
+}
+
+rtc_source_set("make_ref_counted") {
+ visibility = [ "*" ]
+ sources = [ "make_ref_counted.h" ]
+ deps = [ "../rtc_base:refcount" ]
+}
+
+rtc_source_set("video_quality_test_fixture_api") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/video_quality_test_fixture.h" ]
+ deps = [
+ ":fec_controller_api",
+ ":libjingle_peerconnection_api",
+ ":network_state_predictor_api",
+ ":rtp_parameters",
+ ":simulated_network_api",
+ "../call:fake_network",
+ "../call:rtp_interfaces",
+ "../test:test_common",
+ "../test:video_test_common",
+ "../video/config:encoder_config",
+ "transport:bitrate_settings",
+ "transport:network_control",
+ "video_codecs:video_codecs_api",
+ ]
+}
+
+rtc_source_set("video_quality_analyzer_api") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/video_quality_analyzer_interface.h" ]
+
+ deps = [
+ ":array_view",
+ ":stats_observer_interface",
+ "video:encoded_image",
+ "video:video_frame",
+ "video:video_rtp_headers",
+ "video_codecs:video_codecs_api",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
+rtc_source_set("track_id_stream_info_map") {
+ visibility = [ "*" ]
+ sources = [ "test/track_id_stream_info_map.h" ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
+}
+
+rtc_source_set("rtp_transceiver_direction") {
+ visibility = [ "*" ]
+ sources = [ "rtp_transceiver_direction.h" ]
+}
+
+rtc_source_set("priority") {
+ visibility = [ "*" ]
+ sources = [ "priority.h" ]
+}
+
+rtc_library("rtp_parameters") {
+ visibility = [ "*" ]
+ sources = [
+ "media_types.cc",
+ "media_types.h",
+ "rtp_parameters.cc",
+ "rtp_parameters.h",
+ ]
+ deps = [
+ ":array_view",
+ ":priority",
+ ":rtp_transceiver_direction",
+ "../rtc_base:checks",
+ "../rtc_base:stringutils",
+ "../rtc_base/system:rtc_export",
+ "video:resolution",
+ "video_codecs:scalability_mode",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/container:inlined_vector",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
+if (is_android) {
+ java_cpp_enum("priority_enums") {
+ sources = [ "priority.h" ]
+ }
+}
+
+rtc_source_set("audio_quality_analyzer_api") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/audio_quality_analyzer_interface.h" ]
+
+ deps = [
+ ":stats_observer_interface",
+ ":track_id_stream_info_map",
+ ]
+}
+
+rtc_source_set("stats_observer_interface") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/stats_observer_interface.h" ]
+
+ deps = [ ":rtc_stats_api" ]
+
+ absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
+}
+
+rtc_source_set("peer_network_dependencies") {
+ visibility = [ "*" ]
+ sources = [ "test/peer_network_dependencies.h" ]
+ deps = [
+ ":packet_socket_factory",
+ "../rtc_base:network",
+ "../rtc_base:threading",
+ ]
+}
+
+rtc_source_set("peer_connection_quality_test_fixture_api") {
+if (!build_with_mozilla) {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/peerconnection_quality_test_fixture.h" ]
+
+ deps = [
+ ":array_view",
+ ":audio_quality_analyzer_api",
+ ":callfactory_api",
+ ":fec_controller_api",
+ ":frame_generator_api",
+ ":function_view",
+ ":libjingle_peerconnection_api",
+ ":media_stream_interface",
+ ":network_state_predictor_api",
+ ":packet_socket_factory",
+ ":peer_network_dependencies",
+ ":rtp_parameters",
+ ":simulated_network_api",
+ ":stats_observer_interface",
+ ":track_id_stream_info_map",
+ ":video_quality_analyzer_api",
+ "../media:media_constants",
+ "../media:rtc_media_base",
+ "../modules/audio_processing:api",
+ "../rtc_base:checks",
+ "../rtc_base:network",
+ "../rtc_base:rtc_certificate_generator",
+ "../rtc_base:ssl",
+ "../rtc_base:stringutils",
+ "../rtc_base:threading",
+ "../test:fileutils",
+ "audio:audio_mixer_api",
+ "rtc_event_log",
+ "task_queue",
+ "test/pclf:media_configuration",
+ "test/pclf:media_quality_test_params",
+ "test/pclf:peer_configurer",
+ "test/video:video_frame_writer",
+ "transport:network_control",
+ "units:time_delta",
+ "video:video_frame",
+ "video_codecs:video_codecs_api",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ "//third_party/abseil-cpp/absl/memory",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+}
+
+rtc_source_set("frame_generator_api") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/frame_generator_interface.cc",
+ "test/frame_generator_interface.h",
+ ]
+
+ deps = [
+ ":scoped_refptr",
+ "video:video_frame",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_library("test_dependency_factory") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/test_dependency_factory.cc",
+ "test/test_dependency_factory.h",
+ ]
+ deps = [
+ ":video_quality_test_fixture_api",
+ "../rtc_base:checks",
+ "../rtc_base:platform_thread_types",
+ ]
+}
+
+if (rtc_include_tests) {
+ # TODO(srte): Move to network_emulation sub directory.
+ rtc_library("create_network_emulation_manager") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/create_network_emulation_manager.cc",
+ "test/create_network_emulation_manager.h",
+ ]
+ deps = [
+ ":network_emulation_manager_api",
+ "../test/network:emulated_network",
+ ]
+ }
+
+ if (!build_with_chromium) {
+ rtc_library("create_video_quality_test_fixture_api") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/create_video_quality_test_fixture.cc",
+ "test/create_video_quality_test_fixture.h",
+ ]
+ deps = [
+ ":fec_controller_api",
+ ":network_state_predictor_api",
+ ":scoped_refptr",
+ ":video_quality_test_fixture_api",
+ "../video:video_quality_test",
+ ]
+ }
+
+ rtc_library("create_peerconnection_quality_test_fixture") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/create_peerconnection_quality_test_fixture.cc",
+ "test/create_peerconnection_quality_test_fixture.h",
+ ]
+
+ deps = [
+ ":audio_quality_analyzer_api",
+ ":peer_connection_quality_test_fixture_api",
+ ":time_controller",
+ ":video_quality_analyzer_api",
+ "../test/pc/e2e:peerconnection_quality_test",
+ "test/metrics:global_metrics_logger_and_exporter",
+ ]
+ }
+ }
+}
+
+rtc_library("create_frame_generator") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/create_frame_generator.cc",
+ "test/create_frame_generator.h",
+ ]
+ deps = [
+ ":frame_generator_api",
+ "../rtc_base:checks",
+ "../system_wrappers",
+ "../test:frame_generator_impl",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+if (!build_with_mozilla) {
+rtc_library("create_peer_connection_quality_test_frame_generator") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/create_peer_connection_quality_test_frame_generator.cc",
+ "test/create_peer_connection_quality_test_frame_generator.h",
+ ]
+ deps = [
+ ":create_frame_generator",
+ ":frame_generator_api",
+ "../rtc_base:checks",
+ "../test:fileutils",
+ "test/pclf:media_configuration",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+}
+
+rtc_source_set("libjingle_logging_api") {
+ visibility = [ "*" ]
+ sources = [ "rtc_event_log_output.h" ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/strings:strings" ]
+}
+
+rtc_library("rtc_event_log_output_file") {
+ visibility = [ "*" ]
+ sources = [
+ "rtc_event_log_output_file.cc",
+ "rtc_event_log_output_file.h",
+ ]
+
+ deps = [
+ ":libjingle_logging_api",
+ "../rtc_base:checks",
+ "../rtc_base:logging",
+ "../rtc_base/system:file_wrapper",
+ "rtc_event_log",
+ ]
+}
+
+rtc_source_set("rtc_stats_api") {
+ visibility = [ "*" ]
+ cflags = []
+ sources = [
+ "stats/rtc_stats.h",
+ "stats/rtc_stats_collector_callback.h",
+ "stats/rtc_stats_report.h",
+ "stats/rtcstats_objects.h",
+ ]
+
+ deps = [
+ ":make_ref_counted",
+ ":scoped_refptr",
+ "../api:refcountedbase",
+ "../rtc_base:checks",
+ "../rtc_base:refcount",
+ "../rtc_base/system:rtc_export",
+ "units:timestamp",
+ ]
+
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_library("audio_options_api") {
+ visibility = [ "*" ]
+ sources = [
+ "audio_options.cc",
+ "audio_options.h",
+ ]
+
+ deps = [
+ ":array_view",
+ "../rtc_base:stringutils",
+ "../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_library("transport_api") {
+ visibility = [ "*" ]
+ sources = [
+ "call/transport.cc",
+ "call/transport.h",
+ ]
+ deps = [
+ ":refcountedbase",
+ ":scoped_refptr",
+ ]
+}
+
+rtc_source_set("bitrate_allocation") {
+ visibility = [ "*" ]
+ sources = [ "call/bitrate_allocation.h" ]
+ deps = [
+ "units:data_rate",
+ "units:time_delta",
+ ]
+}
+
+# TODO(srte): Move to network_emulation sub directory.
+rtc_source_set("simulated_network_api") {
+ visibility = [ "*" ]
+ sources = [ "test/simulated_network.h" ]
+ deps = [
+ "../rtc_base:macromagic",
+ "../rtc_base:random",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+# TODO(srte): Move to network_emulation sub directory.
+rtc_source_set("network_emulation_manager_api") {
+ visibility = [ "*" ]
+ sources = [
+ "test/network_emulation_manager.cc",
+ "test/network_emulation_manager.h",
+ ]
+ deps = [
+ ":array_view",
+ ":packet_socket_factory",
+ ":peer_network_dependencies",
+ ":simulated_network_api",
+ ":time_controller",
+ "../call:simulated_network",
+ "../rtc_base:checks",
+ "../rtc_base:network",
+ "../rtc_base:network_constants",
+ "../rtc_base:threading",
+ "test/network_emulation",
+ "units:data_rate",
+ "units:data_size",
+ "units:timestamp",
+ ]
+}
+
+rtc_source_set("time_controller") {
+ visibility = [ "*" ]
+ sources = [
+ "test/time_controller.cc",
+ "test/time_controller.h",
+ ]
+
+ deps = [
+ "../rtc_base:threading",
+ "../rtc_base/synchronization:yield_policy",
+ "../system_wrappers",
+ "task_queue",
+ "units:time_delta",
+ "units:timestamp",
+ ]
+}
+
+rtc_source_set("fec_controller_api") {
+ visibility = [ "*" ]
+ sources = [
+ "fec_controller.h",
+ "fec_controller_override.h",
+ ]
+
+ deps = [
+ "../modules:module_fec_api",
+ "video:video_frame_type",
+ ]
+}
+
+rtc_source_set("network_state_predictor_api") {
+ visibility = [ "*" ]
+ sources = [ "network_state_predictor.h" ]
+}
+
+rtc_source_set("array_view") {
+ visibility = [ "*" ]
+ sources = [ "array_view.h" ]
+ deps = [
+ "../rtc_base:checks",
+ "../rtc_base:type_traits",
+ ]
+}
+
+rtc_source_set("refcountedbase") {
+ visibility = [ "*" ]
+ sources = [ "ref_counted_base.h" ]
+ deps = [
+ "../rtc_base:macromagic",
+ "../rtc_base:refcount",
+ ]
+}
+
+if (!build_with_mozilla) {
+rtc_library("ice_transport_factory") {
+ visibility = [ "*" ]
+ sources = [
+ "ice_transport_factory.cc",
+ "ice_transport_factory.h",
+ ]
+ deps = [
+ ":ice_transport_interface",
+ ":libjingle_peerconnection_api",
+ ":make_ref_counted",
+ ":packet_socket_factory",
+ ":scoped_refptr",
+ "../p2p:rtc_p2p",
+ "../rtc_base:threading",
+ "../rtc_base/system:rtc_export",
+ "rtc_event_log:rtc_event_log",
+ ]
+}
+}
+
+rtc_library("neteq_simulator_api") {
+ visibility = [ "*" ]
+ sources = [
+ "test/neteq_simulator.cc",
+ "test/neteq_simulator.h",
+ ]
+}
+
+rtc_source_set("function_view") {
+ visibility = [ "*" ]
+ sources = [ "function_view.h" ]
+ deps = [ "../rtc_base:checks" ]
+}
+
+rtc_source_set("sequence_checker") {
+ visibility = [ "*" ]
+ sources = [ "sequence_checker.h" ]
+ deps = [
+ "../rtc_base:checks",
+ "../rtc_base:macromagic",
+ "../rtc_base/synchronization:sequence_checker_internal",
+ ]
+}
+
+if (rtc_include_tests) {
+ if (rtc_enable_protobuf && !build_with_chromium) {
+ rtc_library("audioproc_f_api") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/audioproc_float.cc",
+ "test/audioproc_float.h",
+ ]
+
+ deps = [
+ "../modules/audio_processing",
+ "../modules/audio_processing:api",
+ "../modules/audio_processing:audioproc_f_impl",
+ ]
+ }
+
+ rtc_library("neteq_simulator_factory") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/neteq_simulator_factory.cc",
+ "test/neteq_simulator_factory.h",
+ ]
+ deps = [
+ ":neteq_simulator_api",
+ "../modules/audio_coding:neteq_test_factory",
+ "../rtc_base:checks",
+ "neteq:neteq_api",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/flags:flag",
+ "//third_party/abseil-cpp/absl/flags:parse",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+ }
+ }
+
+ rtc_source_set("simulcast_test_fixture_api") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/simulcast_test_fixture.h" ]
+ }
+
+ rtc_library("create_simulcast_test_fixture_api") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/create_simulcast_test_fixture.cc",
+ "test/create_simulcast_test_fixture.h",
+ ]
+ deps = [
+ ":simulcast_test_fixture_api",
+ "../modules/video_coding:simulcast_test_fixture_impl",
+ "video_codecs:video_codecs_api",
+ ]
+ }
+
+ rtc_library("videocodec_test_stats_api") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/videocodec_test_stats.cc",
+ "test/videocodec_test_stats.h",
+ ]
+ deps = [
+ "../api/units:data_rate",
+ "../api/units:frequency",
+ "../rtc_base:stringutils",
+ "video:video_frame_type",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+ }
+
+ rtc_library("videocodec_test_fixture_api") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/videocodec_test_fixture.h" ]
+ deps = [
+ ":videocodec_test_stats_api",
+ "../modules/video_coding:video_codec_interface",
+ "video_codecs:video_codecs_api",
+ ]
+ }
+
+ rtc_library("video_codec_tester_api") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/video_codec_tester.h" ]
+ deps = [
+ ":videocodec_test_stats_api",
+ "../modules/video_coding/svc:scalability_mode_util",
+ "video:encoded_image",
+ "video:resolution",
+ "video:video_frame",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/functional:any_invocable",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+ }
+
+ rtc_library("create_videocodec_test_fixture_api") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/create_videocodec_test_fixture.cc",
+ "test/create_videocodec_test_fixture.h",
+ ]
+ deps = [
+ ":videocodec_test_fixture_api",
+ "../modules/video_coding:video_codecs_test_framework",
+ "../modules/video_coding:videocodec_test_impl",
+ "video_codecs:video_codecs_api",
+ ]
+ }
+
+ rtc_library("create_video_codec_tester_api") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/create_video_codec_tester.cc",
+ "test/create_video_codec_tester.h",
+ ]
+ deps = [
+ ":video_codec_tester_api",
+ "../modules/video_coding:videocodec_test_impl",
+ ]
+ }
+
+ rtc_source_set("mock_audio_mixer") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_audio_mixer.h" ]
+
+ deps = [
+ "../test:test_support",
+ "audio:audio_mixer_api",
+ ]
+ }
+
+ rtc_source_set("mock_audio_sink") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_audio_sink.h" ]
+
+ deps = [
+ "../api:media_stream_interface",
+ "../test:test_support",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+ }
+
+ rtc_source_set("mock_data_channel") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_data_channel.h" ]
+
+ deps = [
+ ":libjingle_peerconnection_api",
+ "../test:test_support",
+ ]
+ }
+
+ rtc_source_set("mock_dtmf_sender") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_dtmf_sender.h" ]
+
+ deps = [
+ ":dtmf_sender_interface",
+ ":libjingle_peerconnection_api",
+ "../test:test_support",
+ ]
+ }
+
+ rtc_source_set("mock_fec_controller_override") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_fec_controller_override.h" ]
+ deps = [
+ ":fec_controller_api",
+ "../test:test_support",
+ ]
+ }
+
+ rtc_library("mock_frame_encryptor") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_frame_encryptor.h" ]
+ deps = [
+ # For api/crypto/frame_encryptor_interface.h
+ ":libjingle_peerconnection_api",
+ "../test:test_support",
+ "crypto:frame_encryptor_interface",
+ ]
+ }
+
+ rtc_library("mock_frame_decryptor") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_frame_decryptor.h" ]
+ deps = [
+ ":libjingle_peerconnection_api",
+ "../test:test_support",
+ "crypto:frame_decryptor_interface",
+ ]
+ }
+
+ rtc_library("mock_encoder_selector") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_encoder_selector.h" ]
+ deps = [
+ ":libjingle_peerconnection_api",
+ "../api/video_codecs:video_codecs_api",
+ "../test:test_support",
+ ]
+ }
+
+ rtc_library("fake_frame_encryptor") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/fake_frame_encryptor.cc",
+ "test/fake_frame_encryptor.h",
+ ]
+ deps = [
+ ":array_view",
+ ":libjingle_peerconnection_api",
+ ":make_ref_counted",
+ ":rtp_parameters",
+ "../rtc_base:checks",
+ "../rtc_base:refcount",
+ "crypto:frame_encryptor_interface",
+ ]
+ }
+
+ rtc_library("fake_frame_decryptor") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/fake_frame_decryptor.cc",
+ "test/fake_frame_decryptor.h",
+ ]
+ deps = [
+ ":array_view",
+ ":libjingle_peerconnection_api",
+ ":make_ref_counted",
+ ":rtp_parameters",
+ "../rtc_base:checks",
+ "crypto:frame_decryptor_interface",
+ ]
+ }
+
+ rtc_source_set("mock_media_stream_interface") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_media_stream_interface.h" ]
+
+ deps = [
+ ":media_stream_interface",
+ "../test:test_support",
+ ]
+ }
+
+ rtc_source_set("mock_packet_socket_factory") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_packet_socket_factory.h" ]
+
+ deps = [
+ ":packet_socket_factory",
+ "../test:test_support",
+ ]
+ }
+
+ rtc_source_set("mock_peerconnectioninterface") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_peerconnectioninterface.h" ]
+
+ deps = [
+ ":libjingle_peerconnection_api",
+ "../api:scoped_refptr",
+ "../rtc_base:refcount",
+ "../test:test_support",
+ ]
+ }
+
+ rtc_source_set("mock_peer_connection_factory_interface") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_peer_connection_factory_interface.h" ]
+
+ deps = [
+ ":libjingle_peerconnection_api",
+ "../test:test_support",
+ ]
+ }
+
+ rtc_source_set("mock_session_description_interface") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_session_description_interface.h" ]
+ deps = [
+ ":libjingle_peerconnection_api",
+ "../test:test_support",
+ ]
+ }
+
+ rtc_source_set("mock_async_dns_resolver") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_async_dns_resolver.h" ]
+ deps = [
+ ":async_dns_resolver",
+ "../test:test_support",
+ ]
+ }
+
+ rtc_source_set("mock_rtp") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/mock_rtp_transceiver.h",
+ "test/mock_rtpreceiver.h",
+ "test/mock_rtpsender.h",
+ ]
+
+ deps = [
+ ":libjingle_peerconnection_api",
+ ":rtp_sender_interface",
+ "../api/crypto:frame_decryptor_interface",
+ "../test:test_support",
+ ]
+ }
+
+ rtc_source_set("mock_transformable_video_frame") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_transformable_video_frame.h" ]
+
+ deps = [
+ ":frame_transformer_interface",
+ "../test:test_support",
+ ]
+ }
+
+ rtc_source_set("mock_video_bitrate_allocator") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_video_bitrate_allocator.h" ]
+
+ deps = [
+ "../api/video:video_bitrate_allocator",
+ "../test:test_support",
+ ]
+ }
+
+ rtc_source_set("mock_video_bitrate_allocator_factory") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_video_bitrate_allocator_factory.h" ]
+
+ deps = [
+ "../api/video:video_bitrate_allocator_factory",
+ "../test:test_support",
+ ]
+ }
+
+ rtc_source_set("mock_video_codec_factory") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/mock_video_decoder_factory.h",
+ "test/mock_video_encoder_factory.h",
+ ]
+
+ deps = [
+ "../api/video_codecs:video_codecs_api",
+ "../test:test_support",
+ ]
+ }
+
+ rtc_library("mock_video_decoder") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_video_decoder.h" ]
+
+ deps = [
+ "../api/video_codecs:video_codecs_api",
+ "../test:test_support",
+ ]
+ }
+
+ rtc_library("mock_video_encoder") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_video_encoder.h" ]
+
+ deps = [
+ "../api/video_codecs:video_codecs_api",
+ "../test:test_support",
+ ]
+ }
+
+ rtc_library("mock_video_track") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "test/mock_video_track.h" ]
+
+ deps = [
+ "../api:media_stream_interface",
+ "../api:scoped_refptr",
+ "../rtc_base:refcount",
+ "../test:test_support",
+ ]
+ }
+
+ rtc_library("create_time_controller") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test/create_time_controller.cc",
+ "test/create_time_controller.h",
+ ]
+
+ deps = [
+ ":callfactory_api",
+ ":time_controller",
+ "../call",
+ "../call:call_interfaces",
+ "../call:rtp_interfaces",
+ "../test/time_controller",
+ ]
+ }
+
+ rtc_library("rtc_api_unittests") {
+ testonly = true
+
+ sources = [
+ "array_view_unittest.cc",
+ "field_trials_unittest.cc",
+ "function_view_unittest.cc",
+ "rtc_error_unittest.cc",
+ "rtc_event_log_output_file_unittest.cc",
+ "rtp_packet_info_unittest.cc",
+ "rtp_packet_infos_unittest.cc",
+ "rtp_parameters_unittest.cc",
+ "scoped_refptr_unittest.cc",
+ "sequence_checker_unittest.cc",
+ "test/create_time_controller_unittest.cc",
+ "test/peerconnection_quality_test_fixture_unittest.cc",
+ ]
+
+ deps = [
+ ":array_view",
+ ":create_time_controller",
+ ":field_trials",
+ ":field_trials_view",
+ ":function_view",
+ ":libjingle_peerconnection_api",
+ ":peer_connection_quality_test_fixture_api",
+ ":rtc_error",
+ ":rtc_event_log_output_file",
+ ":rtp_packet_info",
+ ":rtp_parameters",
+ ":scoped_refptr",
+ ":sequence_checker",
+ ":time_controller",
+ "../rtc_base:buffer",
+ "../rtc_base:checks",
+ "../rtc_base:gunit_helpers",
+ "../rtc_base:platform_thread",
+ "../rtc_base:rtc_event",
+ "../rtc_base:rtc_task_queue",
+ "../rtc_base:task_queue_for_test",
+ "../rtc_base/containers:flat_set",
+ "../rtc_base/task_utils:repeating_task",
+ "../system_wrappers:field_trial",
+ "../test:field_trial",
+ "../test:fileutils",
+ "../test:rtc_expect_death",
+ "../test:test_support",
+ "task_queue:task_queue_default_factory_unittests",
+ "test/pclf:media_configuration",
+ "test/video:video_frame_writer",
+ "transport:field_trial_based_config",
+ "units:time_delta",
+ "units:timestamp",
+ "units:units_unittests",
+ "video:frame_buffer_unittest",
+ "video:rtp_video_frame_assembler_unittests",
+ "video:video_unittests",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+ }
+
+ rtc_library("compile_all_headers") {
+ testonly = true
+
+ sources = [ "test/compile_all_headers.cc" ]
+
+ deps = [
+ ":fake_frame_decryptor",
+ ":fake_frame_encryptor",
+ ":mock_async_dns_resolver",
+ ":mock_audio_mixer",
+ ":mock_audio_sink",
+ ":mock_data_channel",
+ ":mock_dtmf_sender",
+ ":mock_frame_decryptor",
+ ":mock_frame_encryptor",
+ ":mock_media_stream_interface",
+ ":mock_packet_socket_factory",
+ ":mock_peer_connection_factory_interface",
+ ":mock_peerconnectioninterface",
+ ":mock_rtp",
+ ":mock_session_description_interface",
+ ":mock_transformable_video_frame",
+ ":mock_video_bitrate_allocator",
+ ":mock_video_bitrate_allocator_factory",
+ ":mock_video_codec_factory",
+ ":mock_video_decoder",
+ ":mock_video_encoder",
+ ":mock_video_track",
+ ":rtc_api_unittests",
+ "units:units_unittests",
+ ]
+ }
+}
+
+rtc_source_set("field_trials_registry") {
+ visibility = [ "*" ]
+ sources = [
+ "field_trials_registry.cc",
+ "field_trials_registry.h",
+ ]
+ deps = [
+ ":field_trials_view",
+ "../experiments:registered_field_trials",
+ "../rtc_base:checks",
+ "../rtc_base/containers:flat_set",
+ "../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/algorithm:container",
+ "//third_party/abseil-cpp/absl/strings",
+ ]
+}
+
+rtc_source_set("field_trials_view") {
+ visibility = [ "*" ]
+ sources = [ "field_trials_view.h" ]
+ deps = [ "../rtc_base/system:rtc_export" ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
+}
+
+rtc_source_set("webrtc_key_value_config") {
+ visibility = [ "*" ]
+ sources = [ "webrtc_key_value_config.h" ]
+ deps = [ ":field_trials_view" ]
+}
+
+rtc_library("field_trials") {
+ visibility = [ "*" ]
+ sources = [
+ "field_trials.cc",
+ "field_trials.h",
+ ]
+ deps = [
+ ":field_trials_registry",
+ "../rtc_base:checks",
+ "../rtc_base/containers:flat_map",
+ "../system_wrappers:field_trial",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
+}
+
+rtc_library("frame_transformer_factory") {
+ visibility = [ "*" ]
+ sources = [
+ "frame_transformer_factory.cc",
+ "frame_transformer_factory.h",
+ ]
+ deps = [
+ ":frame_transformer_interface",
+ ":scoped_refptr",
+ "../modules/rtp_rtcp",
+ "../rtc_base:refcount",
+ "video:encoded_frame",
+ "video:video_frame_metadata",
+ ]
+}
diff --git a/third_party/libwebrtc/api/DEPS b/third_party/libwebrtc/api/DEPS
new file mode 100644
index 0000000000..bcfd705741
--- /dev/null
+++ b/third_party/libwebrtc/api/DEPS
@@ -0,0 +1,346 @@
+# This is supposed to be a complete list of top-level directories,
+# excepting only api/ itself.
+include_rules = [
+ "-audio",
+ "-base",
+ "-build",
+ "-buildtools",
+ "-build_overrides",
+ "-call",
+ "-common_audio",
+ "-common_video",
+ "-data",
+ "-examples",
+ "-experiments",
+ "-g3doc",
+ "-ios",
+ "-infra",
+ "-logging",
+ "-media",
+ "-net",
+ "-modules",
+ "-out",
+ "-p2p",
+ "-pc",
+ "-resources",
+ "-rtc_base",
+ "-rtc_tools",
+ "-sdk",
+ "-stats",
+ "-style-guide",
+ "-system_wrappers",
+ "-test",
+ "-testing",
+ "-third_party",
+ "-tools",
+ "-tools_webrtc",
+ "-video",
+ "-external/webrtc/webrtc", # Android platform build.
+ "-libyuv",
+ "-common_types.h",
+ "-WebRTC",
+]
+
+specific_include_rules = {
+ # Some internal headers are allowed even in API headers:
+
+ "call_factory_interface\.h": [
+ "+call/rtp_transport_controller_send_factory_interface.h",
+ ],
+
+ ".*\.h": [
+ "+rtc_base/checks.h",
+ "+rtc_base/system/rtc_export.h",
+ "+rtc_base/system/rtc_export_template.h",
+ "+rtc_base/units/unit_base.h",
+ ],
+
+ "array_view\.h": [
+ "+rtc_base/type_traits.h",
+ ],
+
+ # Needed because AudioEncoderOpus is in the wrong place for
+ # backwards compatibilty reasons. See
+ # https://bugs.chromium.org/p/webrtc/issues/detail?id=7847
+ "audio_encoder_opus\.h": [
+ "+modules/audio_coding/codecs/opus/audio_encoder_opus.h",
+ ],
+
+ "async_resolver_factory\.h": [
+ "+rtc_base/async_resolver_interface.h",
+ ],
+
+ "async_dns_resolver\.h": [
+ "+rtc_base/socket_address.h",
+ ],
+
+ "candidate\.h": [
+ "+rtc_base/network_constants.h",
+ "+rtc_base/socket_address.h",
+ ],
+
+ "data_channel_interface\.h": [
+ "+rtc_base/copy_on_write_buffer.h",
+ "+rtc_base/ref_count.h",
+ ],
+
+ "data_channel_transport_interface\.h": [
+ "+rtc_base/copy_on_write_buffer.h",
+ ],
+
+ "dtls_transport_interface\.h": [
+ "+rtc_base/ref_count.h",
+ "+rtc_base/ssl_certificate.h",
+ ],
+
+ "dtmf_sender_interface\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "fec_controller\.h": [
+ "+modules/include/module_fec_types.h",
+ ],
+
+ "frame_transformer_interface\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "ice_transport_interface\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "jsep\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "media_stream_interface\.h": [
+ "+modules/audio_processing/include/audio_processing_statistics.h",
+ "+rtc_base/ref_count.h",
+ ],
+
+ "packet_socket_factory\.h": [
+ "+rtc_base/proxy_info.h",
+ "+rtc_base/async_packet_socket.h",
+ ],
+
+ "peer_connection_interface\.h": [
+ "+call/rtp_transport_controller_send_factory_interface.h",
+ "+media/base/media_config.h",
+ "+media/base/media_engine.h",
+ "+p2p/base/port.h",
+ "+p2p/base/port_allocator.h",
+ "+rtc_base/network.h",
+ "+rtc_base/network_constants.h",
+ "+rtc_base/network_monitor_factory.h",
+ "+rtc_base/ref_count.h",
+ "+rtc_base/rtc_certificate.h",
+ "+rtc_base/rtc_certificate_generator.h",
+ "+rtc_base/socket_address.h",
+ "+rtc_base/ssl_certificate.h",
+ "+rtc_base/ssl_stream_adapter.h",
+ "+rtc_base/thread.h",
+ ],
+
+ "proxy\.h": [
+ "+rtc_base/event.h",
+ "+rtc_base/message_handler.h", # Inherits from it.
+ "+rtc_base/thread.h",
+ ],
+
+ "ref_counted_base\.h": [
+ "+rtc_base/ref_count.h",
+ "+rtc_base/ref_counter.h",
+ ],
+
+ "rtc_error\.h": [
+ "+rtc_base/logging.h",
+ ],
+ "rtc_event_log_output_file.h": [
+ # For private member and constructor.
+ "+rtc_base/system/file_wrapper.h",
+ ],
+ "rtp_receiver_interface\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "rtp_sender_interface\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "rtp_transceiver_interface\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "sctp_transport_interface\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "set_local_description_observer_interface\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+ "set_remote_description_observer_interface\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "legacy_stats_types\.h": [
+ "+rtc_base/ref_count.h",
+ "+rtc_base/thread_checker.h",
+ ],
+
+ "uma_metrics\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "audio_mixer\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "audio_decoder\.h": [
+ "+rtc_base/buffer.h",
+ ],
+
+ "audio_decoder_factory\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "audio_encoder\.h": [
+ "+rtc_base/buffer.h",
+ ],
+
+ "audio_encoder_factory\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "frame_decryptor_interface\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "frame_encryptor_interface\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "rtc_stats_collector_callback\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "rtc_stats_report\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "audioproc_float\.h": [
+ "+modules/audio_processing/include/audio_processing.h",
+ ],
+
+ "echo_detector_creator\.h": [
+ "+modules/audio_processing/include/audio_processing.h",
+ ],
+
+ "fake_metronome\.h": [
+ "+rtc_base/synchronization/mutex.h",
+ "+rtc_base/task_queue.h",
+ "+rtc_base/task_utils/repeating_task.h",
+ "+rtc_base/thread_annotations.h",
+ ],
+
+ "make_ref_counted\.h": [
+ "+rtc_base/ref_counted_object.h",
+ ],
+
+ "mock.*\.h": [
+ "+test/gmock.h",
+ ],
+
+ "mock_peerconnectioninterface\.h": [
+ "+rtc_base/ref_counted_object.h",
+ ],
+
+ "mock_video_track\.h": [
+ "+rtc_base/ref_counted_object.h",
+ ],
+
+ "notifier\.h": [
+ "+rtc_base/system/no_unique_address.h",
+ ],
+
+ "simulated_network\.h": [
+ "+rtc_base/random.h",
+ "+rtc_base/thread_annotations.h",
+ ],
+
+ "test_dependency_factory\.h": [
+ "+rtc_base/thread_checker.h",
+ ],
+
+ "time_controller\.h": [
+ "+rtc_base/thread.h",
+ ],
+
+ "videocodec_test_fixture\.h": [
+ "+modules/video_coding/include/video_codec_interface.h"
+ ],
+
+ "video_encoder_config\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "sequence_checker\.h": [
+ "+rtc_base/synchronization/sequence_checker_internal.h",
+ "+rtc_base/thread_annotations.h",
+ ],
+
+ "wrapping_async_dns_resolver\.h": [
+ "+rtc_base/async_resolver.h",
+ "+rtc_base/async_resolver_interface.h",
+ "+rtc_base/socket_address.h",
+ "+rtc_base/third_party/sigslot/sigslot.h",
+ "+rtc_base/thread_annotations.h",
+ ],
+
+ "video_encoder_factory_template.*\.h": [
+ "+modules/video_coding",
+ ],
+
+ "video_decoder_factory_template.*\.h": [
+ "+modules/video_coding",
+ ],
+
+ "field_trials\.h": [
+ "+rtc_base/containers/flat_map.h",
+ ],
+
+ "video_track_source_proxy_factory.h": [
+ "+rtc_base/thread.h",
+ ],
+
+ "field_trials_registry\.h": [
+ "+rtc_base/containers/flat_set.h",
+ ],
+
+ # .cc files in api/ should not be restricted in what they can #include,
+ # so we re-add all the top-level directories here. (That's because .h
+ # files leak their #includes to whoever's #including them, but .cc files
+ # do not since no one #includes them.)
+ ".*\.cc": [
+ "+audio",
+ "+call",
+ "+common_audio",
+ "+common_video",
+ "+examples",
+ "+experiments",
+ "+logging",
+ "+media",
+ "+modules",
+ "+p2p",
+ "+pc",
+ "+rtc_base",
+ "+rtc_tools",
+ "+sdk",
+ "+stats",
+ "+system_wrappers",
+ "+test",
+ "+tools",
+ "+tools_webrtc",
+ "+video",
+ "+third_party",
+ ],
+}
diff --git a/third_party/libwebrtc/api/OWNERS b/third_party/libwebrtc/api/OWNERS
new file mode 100644
index 0000000000..383ac8a3ed
--- /dev/null
+++ b/third_party/libwebrtc/api/OWNERS
@@ -0,0 +1,14 @@
+hta@webrtc.org
+magjed@webrtc.org
+perkj@webrtc.org
+tommi@webrtc.org
+
+# For approvals that absolutely must be done on US Pacific time
+deadbeef@webrtc.org
+tkchin@webrtc.org
+
+per-file peer_connection*=hbos@webrtc.org
+
+per-file DEPS=mbonadei@webrtc.org
+
+per-file uma_metrics.h=kron@webrtc.org
diff --git a/third_party/libwebrtc/api/README.md b/third_party/libwebrtc/api/README.md
new file mode 100644
index 0000000000..7153cb57c4
--- /dev/null
+++ b/third_party/libwebrtc/api/README.md
@@ -0,0 +1,27 @@
+<!-- go/cmark -->
+<!--* freshness: {owner: 'hta' reviewed: '2021-01-01'} *-->
+
+# How to write code in the `api/` directory
+
+Mostly, just follow the regular [style guide](/g3doc/style-guide.md), but:
+
+* Note that `api/` code is not exempt from the “`.h` and `.cc` files come in
+ pairs” rule, so if you declare something in `api/path/to/foo.h`, it should be
+ defined in `api/path/to/foo.cc`.
+* Headers in `api/` should, if possible, not `#include` headers outside `api/`.
+ It’s not always possible to avoid this, but be aware that it adds to a small
+ mountain of technical debt that we’re trying to shrink.
+* `.cc` files in `api/`, on the other hand, are free to `#include` headers
+ outside `api/`.
+
+That is, the preferred way for `api/` code to access non-`api/` code is to call
+it from a `.cc` file, so that users of our API headers won’t transitively
+`#include` non-public headers.
+
+For headers in `api/` that need to refer to non-public types, forward
+declarations are often a lesser evil than including non-public header files. The
+usual [rules](/g3doc/style-guide.md#forward-declarations) still apply, though.
+
+`.cc` files in `api/` should preferably be kept reasonably small. If a
+substantial implementation is needed, consider putting it with our non-public
+code, and just call it from the `api/` `.cc` file.
diff --git a/third_party/libwebrtc/api/adaptation/BUILD.gn b/third_party/libwebrtc/api/adaptation/BUILD.gn
new file mode 100644
index 0000000000..839ad2c24b
--- /dev/null
+++ b/third_party/libwebrtc/api/adaptation/BUILD.gn
@@ -0,0 +1,23 @@
+# Copyright(c) 2020 The WebRTC project authors.All Rights Reserved.
+#
+# Use of this source code is governed by a BSD - style license
+# that can be found in the LICENSE file in the root of the source
+# tree.An additional intellectual property rights grant can be found
+# in the file PATENTS.All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../webrtc.gni")
+
+rtc_source_set("resource_adaptation_api") {
+ visibility = [ "*" ]
+ sources = [
+ "resource.cc",
+ "resource.h",
+ ]
+ deps = [
+ "../../api:scoped_refptr",
+ "../../rtc_base:checks",
+ "../../rtc_base:refcount",
+ "../../rtc_base/system:rtc_export",
+ ]
+}
diff --git a/third_party/libwebrtc/api/adaptation/DEPS b/third_party/libwebrtc/api/adaptation/DEPS
new file mode 100644
index 0000000000..734e152497
--- /dev/null
+++ b/third_party/libwebrtc/api/adaptation/DEPS
@@ -0,0 +1,7 @@
+specific_include_rules = {
+ "resource\.h": [
+ # ref_count.h is a public_deps of rtc_base:refcount. Necessary because of
+ # rtc::RefCountInterface.
+ "+rtc_base/ref_count.h",
+ ],
+} \ No newline at end of file
diff --git a/third_party/libwebrtc/api/adaptation/resource.cc b/third_party/libwebrtc/api/adaptation/resource.cc
new file mode 100644
index 0000000000..dac03fe019
--- /dev/null
+++ b/third_party/libwebrtc/api/adaptation/resource.cc
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/adaptation/resource.h"
+
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+const char* ResourceUsageStateToString(ResourceUsageState usage_state) {
+ switch (usage_state) {
+ case ResourceUsageState::kOveruse:
+ return "kOveruse";
+ case ResourceUsageState::kUnderuse:
+ return "kUnderuse";
+ }
+ RTC_CHECK_NOTREACHED();
+}
+
+ResourceListener::~ResourceListener() {}
+
+Resource::Resource() {}
+
+Resource::~Resource() {}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/adaptation/resource.h b/third_party/libwebrtc/api/adaptation/resource.h
new file mode 100644
index 0000000000..7d7c70b3eb
--- /dev/null
+++ b/third_party/libwebrtc/api/adaptation/resource.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_ADAPTATION_RESOURCE_H_
+#define API_ADAPTATION_RESOURCE_H_
+
+#include <string>
+
+#include "api/scoped_refptr.h"
+#include "rtc_base/ref_count.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+class Resource;
+
+enum class ResourceUsageState {
+ // Action is needed to minimze the load on this resource.
+ kOveruse,
+ // Increasing the load on this resource is desired, if possible.
+ kUnderuse,
+};
+
+RTC_EXPORT const char* ResourceUsageStateToString(
+ ResourceUsageState usage_state);
+
+class RTC_EXPORT ResourceListener {
+ public:
+ virtual ~ResourceListener();
+
+ virtual void OnResourceUsageStateMeasured(
+ rtc::scoped_refptr<Resource> resource,
+ ResourceUsageState usage_state) = 0;
+};
+
+// A Resource monitors an implementation-specific resource. It may report
+// kOveruse or kUnderuse when resource usage is high or low enough that we
+// should perform some sort of mitigation to fulfil the resource's constraints.
+//
+// The methods on this interface are invoked on the adaptation task queue.
+// Resource usage measurements may be performed on an any task queue.
+//
+// The Resource is reference counted to prevent use-after-free when posting
+// between task queues. As such, the implementation MUST NOT make any
+// assumptions about which task queue Resource is destructed on.
+class RTC_EXPORT Resource : public rtc::RefCountInterface {
+ public:
+ Resource();
+ // Destruction may happen on any task queue.
+ ~Resource() override;
+
+ virtual std::string Name() const = 0;
+ // The `listener` may be informed of resource usage measurements on any task
+ // queue, but not after this method is invoked with the null argument.
+ virtual void SetResourceListener(ResourceListener* listener) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_ADAPTATION_RESOURCE_H_
diff --git a/third_party/libwebrtc/api/adaptation/resource_adaptation_api_gn/moz.build b/third_party/libwebrtc/api/adaptation/resource_adaptation_api_gn/moz.build
new file mode 100644
index 0000000000..aa958f7042
--- /dev/null
+++ b/third_party/libwebrtc/api/adaptation/resource_adaptation_api_gn/moz.build
@@ -0,0 +1,221 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/adaptation/resource.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("resource_adaptation_api_gn")
diff --git a/third_party/libwebrtc/api/array_view.h b/third_party/libwebrtc/api/array_view.h
new file mode 100644
index 0000000000..2d68f1650f
--- /dev/null
+++ b/third_party/libwebrtc/api/array_view.h
@@ -0,0 +1,330 @@
+/*
+ * Copyright 2015 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_ARRAY_VIEW_H_
+#define API_ARRAY_VIEW_H_
+
+#include <algorithm>
+#include <array>
+#include <iterator>
+#include <type_traits>
+
+#include "rtc_base/checks.h"
+#include "rtc_base/type_traits.h"
+
+namespace rtc {
+
+// tl;dr: rtc::ArrayView is the same thing as gsl::span from the Guideline
+// Support Library.
+//
+// Many functions read from or write to arrays. The obvious way to do this is
+// to use two arguments, a pointer to the first element and an element count:
+//
+// bool Contains17(const int* arr, size_t size) {
+// for (size_t i = 0; i < size; ++i) {
+// if (arr[i] == 17)
+// return true;
+// }
+// return false;
+// }
+//
+// This is flexible, since it doesn't matter how the array is stored (C array,
+// std::vector, rtc::Buffer, ...), but it's error-prone because the caller has
+// to correctly specify the array length:
+//
+// Contains17(arr, arraysize(arr)); // C array
+// Contains17(arr.data(), arr.size()); // std::vector
+// Contains17(arr, size); // pointer + size
+// ...
+//
+// It's also kind of messy to have two separate arguments for what is
+// conceptually a single thing.
+//
+// Enter rtc::ArrayView<T>. It contains a T pointer (to an array it doesn't
+// own) and a count, and supports the basic things you'd expect, such as
+// indexing and iteration. It allows us to write our function like this:
+//
+// bool Contains17(rtc::ArrayView<const int> arr) {
+// for (auto e : arr) {
+// if (e == 17)
+// return true;
+// }
+// return false;
+// }
+//
+// And even better, because a bunch of things will implicitly convert to
+// ArrayView, we can call it like this:
+//
+// Contains17(arr); // C array
+// Contains17(arr); // std::vector
+// Contains17(rtc::ArrayView<int>(arr, size)); // pointer + size
+// Contains17(nullptr); // nullptr -> empty ArrayView
+// ...
+//
+// ArrayView<T> stores both a pointer and a size, but you may also use
+// ArrayView<T, N>, which has a size that's fixed at compile time (which means
+// it only has to store the pointer).
+//
+// One important point is that ArrayView<T> and ArrayView<const T> are
+// different types, which allow and don't allow mutation of the array elements,
+// respectively. The implicit conversions work just like you'd hope, so that
+// e.g. vector<int> will convert to either ArrayView<int> or ArrayView<const
+// int>, but const vector<int> will convert only to ArrayView<const int>.
+// (ArrayView itself can be the source type in such conversions, so
+// ArrayView<int> will convert to ArrayView<const int>.)
+//
+// Note: ArrayView is tiny (just a pointer and a count if variable-sized, just
+// a pointer if fix-sized) and trivially copyable, so it's probably cheaper to
+// pass it by value than by const reference.
+
+namespace array_view_internal {
+
+// Magic constant for indicating that the size of an ArrayView is variable
+// instead of fixed.
+enum : std::ptrdiff_t { kArrayViewVarSize = -4711 };
+
+// Base class for ArrayViews of fixed nonzero size.
+template <typename T, std::ptrdiff_t Size>
+class ArrayViewBase {
+ static_assert(Size > 0, "ArrayView size must be variable or non-negative");
+
+ public:
+ ArrayViewBase(T* data, size_t size) : data_(data) {}
+
+ static constexpr size_t size() { return Size; }
+ static constexpr bool empty() { return false; }
+ T* data() const { return data_; }
+
+ protected:
+ static constexpr bool fixed_size() { return true; }
+
+ private:
+ T* data_;
+};
+
+// Specialized base class for ArrayViews of fixed zero size.
+template <typename T>
+class ArrayViewBase<T, 0> {
+ public:
+ explicit ArrayViewBase(T* data, size_t size) {}
+
+ static constexpr size_t size() { return 0; }
+ static constexpr bool empty() { return true; }
+ T* data() const { return nullptr; }
+
+ protected:
+ static constexpr bool fixed_size() { return true; }
+};
+
+// Specialized base class for ArrayViews of variable size.
+template <typename T>
+class ArrayViewBase<T, array_view_internal::kArrayViewVarSize> {
+ public:
+ ArrayViewBase(T* data, size_t size)
+ : data_(size == 0 ? nullptr : data), size_(size) {}
+
+ size_t size() const { return size_; }
+ bool empty() const { return size_ == 0; }
+ T* data() const { return data_; }
+
+ protected:
+ static constexpr bool fixed_size() { return false; }
+
+ private:
+ T* data_;
+ size_t size_;
+};
+
+} // namespace array_view_internal
+
+template <typename T,
+ std::ptrdiff_t Size = array_view_internal::kArrayViewVarSize>
+class ArrayView final : public array_view_internal::ArrayViewBase<T, Size> {
+ public:
+ using value_type = T;
+ using const_iterator = const T*;
+
+ // Construct an ArrayView from a pointer and a length.
+ template <typename U>
+ ArrayView(U* data, size_t size)
+ : array_view_internal::ArrayViewBase<T, Size>::ArrayViewBase(data, size) {
+ RTC_DCHECK_EQ(size == 0 ? nullptr : data, this->data());
+ RTC_DCHECK_EQ(size, this->size());
+ RTC_DCHECK_EQ(!this->data(),
+ this->size() == 0); // data is null iff size == 0.
+ }
+
+ // Construct an empty ArrayView. Note that fixed-size ArrayViews of size > 0
+ // cannot be empty.
+ ArrayView() : ArrayView(nullptr, 0) {}
+ ArrayView(std::nullptr_t) // NOLINT
+ : ArrayView() {}
+ ArrayView(std::nullptr_t, size_t size)
+ : ArrayView(static_cast<T*>(nullptr), size) {
+ static_assert(Size == 0 || Size == array_view_internal::kArrayViewVarSize,
+ "");
+ RTC_DCHECK_EQ(0, size);
+ }
+
+ // Construct an ArrayView from a C-style array.
+ template <typename U, size_t N>
+ ArrayView(U (&array)[N]) // NOLINT
+ : ArrayView(array, N) {
+ static_assert(Size == N || Size == array_view_internal::kArrayViewVarSize,
+ "Array size must match ArrayView size");
+ }
+
+ // (Only if size is fixed.) Construct a fixed size ArrayView<T, N> from a
+ // non-const std::array instance. For an ArrayView with variable size, the
+ // used ctor is ArrayView(U& u) instead.
+ template <typename U,
+ size_t N,
+ typename std::enable_if<
+ Size == static_cast<std::ptrdiff_t>(N)>::type* = nullptr>
+ ArrayView(std::array<U, N>& u) // NOLINT
+ : ArrayView(u.data(), u.size()) {}
+
+ // (Only if size is fixed.) Construct a fixed size ArrayView<T, N> where T is
+ // const from a const(expr) std::array instance. For an ArrayView with
+ // variable size, the used ctor is ArrayView(U& u) instead.
+ template <typename U,
+ size_t N,
+ typename std::enable_if<
+ Size == static_cast<std::ptrdiff_t>(N)>::type* = nullptr>
+ ArrayView(const std::array<U, N>& u) // NOLINT
+ : ArrayView(u.data(), u.size()) {}
+
+ // (Only if size is fixed.) Construct an ArrayView from any type U that has a
+ // static constexpr size() method whose return value is equal to Size, and a
+ // data() method whose return value converts implicitly to T*. In particular,
+ // this means we allow conversion from ArrayView<T, N> to ArrayView<const T,
+ // N>, but not the other way around. We also don't allow conversion from
+ // ArrayView<T> to ArrayView<T, N>, or from ArrayView<T, M> to ArrayView<T,
+ // N> when M != N.
+ template <
+ typename U,
+ typename std::enable_if<Size != array_view_internal::kArrayViewVarSize &&
+ HasDataAndSize<U, T>::value>::type* = nullptr>
+ ArrayView(U& u) // NOLINT
+ : ArrayView(u.data(), u.size()) {
+ static_assert(U::size() == Size, "Sizes must match exactly");
+ }
+ template <
+ typename U,
+ typename std::enable_if<Size != array_view_internal::kArrayViewVarSize &&
+ HasDataAndSize<U, T>::value>::type* = nullptr>
+ ArrayView(const U& u) // NOLINT(runtime/explicit)
+ : ArrayView(u.data(), u.size()) {
+ static_assert(U::size() == Size, "Sizes must match exactly");
+ }
+
+ // (Only if size is variable.) Construct an ArrayView from any type U that
+ // has a size() method whose return value converts implicitly to size_t, and
+ // a data() method whose return value converts implicitly to T*. In
+ // particular, this means we allow conversion from ArrayView<T> to
+ // ArrayView<const T>, but not the other way around. Other allowed
+ // conversions include
+ // ArrayView<T, N> to ArrayView<T> or ArrayView<const T>,
+ // std::vector<T> to ArrayView<T> or ArrayView<const T>,
+ // const std::vector<T> to ArrayView<const T>,
+ // rtc::Buffer to ArrayView<uint8_t> or ArrayView<const uint8_t>, and
+ // const rtc::Buffer to ArrayView<const uint8_t>.
+ template <
+ typename U,
+ typename std::enable_if<Size == array_view_internal::kArrayViewVarSize &&
+ HasDataAndSize<U, T>::value>::type* = nullptr>
+ ArrayView(U& u) // NOLINT
+ : ArrayView(u.data(), u.size()) {}
+ template <
+ typename U,
+ typename std::enable_if<Size == array_view_internal::kArrayViewVarSize &&
+ HasDataAndSize<U, T>::value>::type* = nullptr>
+ ArrayView(const U& u) // NOLINT(runtime/explicit)
+ : ArrayView(u.data(), u.size()) {}
+
+ // Indexing and iteration. These allow mutation even if the ArrayView is
+ // const, because the ArrayView doesn't own the array. (To prevent mutation,
+ // use a const element type.)
+ T& operator[](size_t idx) const {
+ RTC_DCHECK_LT(idx, this->size());
+ RTC_DCHECK(this->data());
+ return this->data()[idx];
+ }
+ T* begin() const { return this->data(); }
+ T* end() const { return this->data() + this->size(); }
+ const T* cbegin() const { return this->data(); }
+ const T* cend() const { return this->data() + this->size(); }
+ std::reverse_iterator<T*> rbegin() const {
+ return std::make_reverse_iterator(end());
+ }
+ std::reverse_iterator<T*> rend() const {
+ return std::make_reverse_iterator(begin());
+ }
+ std::reverse_iterator<const T*> crbegin() const {
+ return std::make_reverse_iterator(cend());
+ }
+ std::reverse_iterator<const T*> crend() const {
+ return std::make_reverse_iterator(cbegin());
+ }
+
+ ArrayView<T> subview(size_t offset, size_t size) const {
+ return offset < this->size()
+ ? ArrayView<T>(this->data() + offset,
+ std::min(size, this->size() - offset))
+ : ArrayView<T>();
+ }
+ ArrayView<T> subview(size_t offset) const {
+ return subview(offset, this->size());
+ }
+};
+
+// Comparing two ArrayViews compares their (pointer,size) pairs; it does *not*
+// dereference the pointers.
+template <typename T, std::ptrdiff_t Size1, std::ptrdiff_t Size2>
+bool operator==(const ArrayView<T, Size1>& a, const ArrayView<T, Size2>& b) {
+ return a.data() == b.data() && a.size() == b.size();
+}
+template <typename T, std::ptrdiff_t Size1, std::ptrdiff_t Size2>
+bool operator!=(const ArrayView<T, Size1>& a, const ArrayView<T, Size2>& b) {
+ return !(a == b);
+}
+
+// Variable-size ArrayViews are the size of two pointers; fixed-size ArrayViews
+// are the size of one pointer. (And as a special case, fixed-size ArrayViews
+// of size 0 require no storage.)
+static_assert(sizeof(ArrayView<int>) == 2 * sizeof(int*), "");
+static_assert(sizeof(ArrayView<int, 17>) == sizeof(int*), "");
+static_assert(std::is_empty<ArrayView<int, 0>>::value, "");
+
+template <typename T>
+inline ArrayView<T> MakeArrayView(T* data, size_t size) {
+ return ArrayView<T>(data, size);
+}
+
+// Only for primitive types that have the same size and aligment.
+// Allow reinterpret cast of the array view to another primitive type of the
+// same size.
+// Template arguments order is (U, T, Size) to allow deduction of the template
+// arguments in client calls: reinterpret_array_view<target_type>(array_view).
+template <typename U, typename T, std::ptrdiff_t Size>
+inline ArrayView<U, Size> reinterpret_array_view(ArrayView<T, Size> view) {
+ static_assert(sizeof(U) == sizeof(T) && alignof(U) == alignof(T),
+ "ArrayView reinterpret_cast is only supported for casting "
+ "between views that represent the same chunk of memory.");
+ static_assert(
+ std::is_fundamental<T>::value && std::is_fundamental<U>::value,
+ "ArrayView reinterpret_cast is only supported for casting between "
+ "fundamental types.");
+ return ArrayView<U, Size>(reinterpret_cast<U*>(view.data()), view.size());
+}
+
+} // namespace rtc
+
+#endif // API_ARRAY_VIEW_H_
diff --git a/third_party/libwebrtc/api/array_view_gn/moz.build b/third_party/libwebrtc/api/array_view_gn/moz.build
new file mode 100644
index 0000000000..e453cb8585
--- /dev/null
+++ b/third_party/libwebrtc/api/array_view_gn/moz.build
@@ -0,0 +1,205 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("array_view_gn")
diff --git a/third_party/libwebrtc/api/array_view_unittest.cc b/third_party/libwebrtc/api/array_view_unittest.cc
new file mode 100644
index 0000000000..97267df006
--- /dev/null
+++ b/third_party/libwebrtc/api/array_view_unittest.cc
@@ -0,0 +1,630 @@
+/*
+ * Copyright 2015 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/array_view.h"
+
+#include <algorithm>
+#include <array>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "rtc_base/buffer.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/gunit.h"
+#include "test/gmock.h"
+
+namespace rtc {
+
+namespace {
+
+using ::testing::ElementsAre;
+using ::testing::IsEmpty;
+
+template <typename T>
+size_t Call(ArrayView<T> av) {
+ return av.size();
+}
+
+template <typename T, size_t N>
+void CallFixed(ArrayView<T, N> av) {}
+
+} // namespace
+
+TEST(ArrayViewDeathTest, TestConstructFromPtrAndArray) {
+ char arr[] = "Arrr!";
+ const char carr[] = "Carrr!";
+ EXPECT_EQ(6u, Call<const char>(arr));
+ EXPECT_EQ(7u, Call<const char>(carr));
+ EXPECT_EQ(6u, Call<char>(arr));
+ // Call<char>(carr); // Compile error, because can't drop const.
+ // Call<int>(arr); // Compile error, because incompatible types.
+ ArrayView<int*> x;
+ EXPECT_EQ(0u, x.size());
+ EXPECT_EQ(nullptr, x.data());
+ ArrayView<char> y = arr;
+ EXPECT_EQ(6u, y.size());
+ EXPECT_EQ(arr, y.data());
+ ArrayView<char, 6> yf = arr;
+ static_assert(yf.size() == 6, "");
+ EXPECT_EQ(arr, yf.data());
+ ArrayView<const char> z(arr + 1, 3);
+ EXPECT_EQ(3u, z.size());
+ EXPECT_EQ(arr + 1, z.data());
+ ArrayView<const char, 3> zf(arr + 1, 3);
+ static_assert(zf.size() == 3, "");
+ EXPECT_EQ(arr + 1, zf.data());
+ ArrayView<const char> w(arr, 2);
+ EXPECT_EQ(2u, w.size());
+ EXPECT_EQ(arr, w.data());
+ ArrayView<const char, 2> wf(arr, 2);
+ static_assert(wf.size() == 2, "");
+ EXPECT_EQ(arr, wf.data());
+ ArrayView<char> q(arr, 0);
+ EXPECT_EQ(0u, q.size());
+ EXPECT_EQ(nullptr, q.data());
+ ArrayView<char, 0> qf(arr, 0);
+ static_assert(qf.size() == 0, "");
+ EXPECT_EQ(nullptr, qf.data());
+#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
+ // DCHECK error (nullptr with nonzero size).
+ EXPECT_DEATH(ArrayView<int>(static_cast<int*>(nullptr), 5), "");
+#endif
+ // These are compile errors, because incompatible types.
+ // ArrayView<int> m = arr;
+ // ArrayView<float> n(arr + 2, 2);
+}
+
+TEST(ArrayViewTest, TestCopyConstructorVariableLvalue) {
+ char arr[] = "Arrr!";
+ ArrayView<char> x = arr;
+ EXPECT_EQ(6u, x.size());
+ EXPECT_EQ(arr, x.data());
+ ArrayView<char> y = x; // Copy non-const -> non-const.
+ EXPECT_EQ(6u, y.size());
+ EXPECT_EQ(arr, y.data());
+ ArrayView<const char> z = x; // Copy non-const -> const.
+ EXPECT_EQ(6u, z.size());
+ EXPECT_EQ(arr, z.data());
+ ArrayView<const char> w = z; // Copy const -> const.
+ EXPECT_EQ(6u, w.size());
+ EXPECT_EQ(arr, w.data());
+ // ArrayView<char> v = z; // Compile error, because can't drop const.
+}
+
+TEST(ArrayViewTest, TestCopyConstructorVariableRvalue) {
+ char arr[] = "Arrr!";
+ ArrayView<char> x = arr;
+ EXPECT_EQ(6u, x.size());
+ EXPECT_EQ(arr, x.data());
+ ArrayView<char> y = std::move(x); // Copy non-const -> non-const.
+ EXPECT_EQ(6u, y.size());
+ EXPECT_EQ(arr, y.data());
+ ArrayView<const char> z = std::move(x); // Copy non-const -> const.
+ EXPECT_EQ(6u, z.size());
+ EXPECT_EQ(arr, z.data());
+ ArrayView<const char> w = std::move(z); // Copy const -> const.
+ EXPECT_EQ(6u, w.size());
+ EXPECT_EQ(arr, w.data());
+ // ArrayView<char> v = std::move(z); // Error, because can't drop const.
+}
+
+TEST(ArrayViewTest, TestCopyConstructorFixedLvalue) {
+ char arr[] = "Arrr!";
+ ArrayView<char, 6> x = arr;
+ static_assert(x.size() == 6, "");
+ EXPECT_EQ(arr, x.data());
+
+ // Copy fixed -> fixed.
+ ArrayView<char, 6> y = x; // Copy non-const -> non-const.
+ static_assert(y.size() == 6, "");
+ EXPECT_EQ(arr, y.data());
+ ArrayView<const char, 6> z = x; // Copy non-const -> const.
+ static_assert(z.size() == 6, "");
+ EXPECT_EQ(arr, z.data());
+ ArrayView<const char, 6> w = z; // Copy const -> const.
+ static_assert(w.size() == 6, "");
+ EXPECT_EQ(arr, w.data());
+ // ArrayView<char, 6> v = z; // Compile error, because can't drop const.
+
+ // Copy fixed -> variable.
+ ArrayView<char> yv = x; // Copy non-const -> non-const.
+ EXPECT_EQ(6u, yv.size());
+ EXPECT_EQ(arr, yv.data());
+ ArrayView<const char> zv = x; // Copy non-const -> const.
+ EXPECT_EQ(6u, zv.size());
+ EXPECT_EQ(arr, zv.data());
+ ArrayView<const char> wv = z; // Copy const -> const.
+ EXPECT_EQ(6u, wv.size());
+ EXPECT_EQ(arr, wv.data());
+ // ArrayView<char> vv = z; // Compile error, because can't drop const.
+}
+
+TEST(ArrayViewTest, TestCopyConstructorFixedRvalue) {
+ char arr[] = "Arrr!";
+ ArrayView<char, 6> x = arr;
+ static_assert(x.size() == 6, "");
+ EXPECT_EQ(arr, x.data());
+
+ // Copy fixed -> fixed.
+ ArrayView<char, 6> y = std::move(x); // Copy non-const -> non-const.
+ static_assert(y.size() == 6, "");
+ EXPECT_EQ(arr, y.data());
+ ArrayView<const char, 6> z = std::move(x); // Copy non-const -> const.
+ static_assert(z.size() == 6, "");
+ EXPECT_EQ(arr, z.data());
+ ArrayView<const char, 6> w = std::move(z); // Copy const -> const.
+ static_assert(w.size() == 6, "");
+ EXPECT_EQ(arr, w.data());
+ // ArrayView<char, 6> v = std::move(z); // Error, because can't drop const.
+
+ // Copy fixed -> variable.
+ ArrayView<char> yv = std::move(x); // Copy non-const -> non-const.
+ EXPECT_EQ(6u, yv.size());
+ EXPECT_EQ(arr, yv.data());
+ ArrayView<const char> zv = std::move(x); // Copy non-const -> const.
+ EXPECT_EQ(6u, zv.size());
+ EXPECT_EQ(arr, zv.data());
+ ArrayView<const char> wv = std::move(z); // Copy const -> const.
+ EXPECT_EQ(6u, wv.size());
+ EXPECT_EQ(arr, wv.data());
+ // ArrayView<char> vv = std::move(z); // Error, because can't drop const.
+}
+
+TEST(ArrayViewTest, TestCopyAssignmentVariableLvalue) {
+ char arr[] = "Arrr!";
+ ArrayView<char> x(arr);
+ EXPECT_EQ(6u, x.size());
+ EXPECT_EQ(arr, x.data());
+ ArrayView<char> y;
+ y = x; // Copy non-const -> non-const.
+ EXPECT_EQ(6u, y.size());
+ EXPECT_EQ(arr, y.data());
+ ArrayView<const char> z;
+ z = x; // Copy non-const -> const.
+ EXPECT_EQ(6u, z.size());
+ EXPECT_EQ(arr, z.data());
+ ArrayView<const char> w;
+ w = z; // Copy const -> const.
+ EXPECT_EQ(6u, w.size());
+ EXPECT_EQ(arr, w.data());
+ // ArrayView<char> v;
+ // v = z; // Compile error, because can't drop const.
+}
+
+TEST(ArrayViewTest, TestCopyAssignmentVariableRvalue) {
+ char arr[] = "Arrr!";
+ ArrayView<char> x(arr);
+ EXPECT_EQ(6u, x.size());
+ EXPECT_EQ(arr, x.data());
+ ArrayView<char> y;
+ y = std::move(x); // Copy non-const -> non-const.
+ EXPECT_EQ(6u, y.size());
+ EXPECT_EQ(arr, y.data());
+ ArrayView<const char> z;
+ z = std::move(x); // Copy non-const -> const.
+ EXPECT_EQ(6u, z.size());
+ EXPECT_EQ(arr, z.data());
+ ArrayView<const char> w;
+ w = std::move(z); // Copy const -> const.
+ EXPECT_EQ(6u, w.size());
+ EXPECT_EQ(arr, w.data());
+ // ArrayView<char> v;
+ // v = std::move(z); // Compile error, because can't drop const.
+}
+
+TEST(ArrayViewTest, TestCopyAssignmentFixedLvalue) {
+ char arr[] = "Arrr!";
+ char init[] = "Init!";
+ ArrayView<char, 6> x(arr);
+ EXPECT_EQ(arr, x.data());
+
+ // Copy fixed -> fixed.
+ ArrayView<char, 6> y(init);
+ y = x; // Copy non-const -> non-const.
+ EXPECT_EQ(arr, y.data());
+ ArrayView<const char, 6> z(init);
+ z = x; // Copy non-const -> const.
+ EXPECT_EQ(arr, z.data());
+ ArrayView<const char, 6> w(init);
+ w = z; // Copy const -> const.
+ EXPECT_EQ(arr, w.data());
+ // ArrayView<char, 6> v(init);
+ // v = z; // Compile error, because can't drop const.
+
+ // Copy fixed -> variable.
+ ArrayView<char> yv;
+ yv = x; // Copy non-const -> non-const.
+ EXPECT_EQ(6u, yv.size());
+ EXPECT_EQ(arr, yv.data());
+ ArrayView<const char> zv;
+ zv = x; // Copy non-const -> const.
+ EXPECT_EQ(6u, zv.size());
+ EXPECT_EQ(arr, zv.data());
+ ArrayView<const char> wv;
+ wv = z; // Copy const -> const.
+ EXPECT_EQ(6u, wv.size());
+ EXPECT_EQ(arr, wv.data());
+ // ArrayView<char> v;
+ // v = z; // Compile error, because can't drop const.
+}
+
+TEST(ArrayViewTest, TestCopyAssignmentFixedRvalue) {
+ char arr[] = "Arrr!";
+ char init[] = "Init!";
+ ArrayView<char, 6> x(arr);
+ EXPECT_EQ(arr, x.data());
+
+ // Copy fixed -> fixed.
+ ArrayView<char, 6> y(init);
+ y = std::move(x); // Copy non-const -> non-const.
+ EXPECT_EQ(arr, y.data());
+ ArrayView<const char, 6> z(init);
+ z = std::move(x); // Copy non-const -> const.
+ EXPECT_EQ(arr, z.data());
+ ArrayView<const char, 6> w(init);
+ w = std::move(z); // Copy const -> const.
+ EXPECT_EQ(arr, w.data());
+ // ArrayView<char, 6> v(init);
+ // v = std::move(z); // Compile error, because can't drop const.
+
+ // Copy fixed -> variable.
+ ArrayView<char> yv;
+ yv = std::move(x); // Copy non-const -> non-const.
+ EXPECT_EQ(6u, yv.size());
+ EXPECT_EQ(arr, yv.data());
+ ArrayView<const char> zv;
+ zv = std::move(x); // Copy non-const -> const.
+ EXPECT_EQ(6u, zv.size());
+ EXPECT_EQ(arr, zv.data());
+ ArrayView<const char> wv;
+ wv = std::move(z); // Copy const -> const.
+ EXPECT_EQ(6u, wv.size());
+ EXPECT_EQ(arr, wv.data());
+ // ArrayView<char> v;
+ // v = std::move(z); // Compile error, because can't drop const.
+}
+
+TEST(ArrayViewTest, TestStdArray) {
+ EXPECT_EQ(4u, Call<const int>(std::array<int, 4>{1, 2, 3, 4}));
+ CallFixed<const int, 3>(std::array<int, 3>{2, 3, 4});
+ constexpr size_t size = 5;
+ std::array<float, size> arr{};
+ // Fixed size view.
+ rtc::ArrayView<float, size> arr_view_fixed(arr);
+ EXPECT_EQ(arr.data(), arr_view_fixed.data());
+ static_assert(size == arr_view_fixed.size(), "");
+ // Variable size view.
+ rtc::ArrayView<float> arr_view(arr);
+ EXPECT_EQ(arr.data(), arr_view.data());
+ EXPECT_EQ(size, arr_view.size());
+}
+
+TEST(ArrayViewTest, TestConstStdArray) {
+ constexpr size_t size = 5;
+
+ constexpr std::array<float, size> constexpr_arr{};
+ rtc::ArrayView<const float, size> constexpr_arr_view(constexpr_arr);
+ EXPECT_EQ(constexpr_arr.data(), constexpr_arr_view.data());
+ static_assert(constexpr_arr.size() == constexpr_arr_view.size(), "");
+
+ const std::array<float, size> const_arr{};
+ rtc::ArrayView<const float, size> const_arr_view(const_arr);
+ EXPECT_EQ(const_arr.data(), const_arr_view.data());
+ static_assert(const_arr.size() == const_arr_view.size(), "");
+
+ std::array<float, size> non_const_arr{};
+ rtc::ArrayView<const float, size> non_const_arr_view(non_const_arr);
+ EXPECT_EQ(non_const_arr.data(), non_const_arr_view.data());
+ static_assert(non_const_arr.size() == non_const_arr_view.size(), "");
+}
+
+TEST(ArrayViewTest, TestStdVector) {
+ EXPECT_EQ(3u, Call<const int>(std::vector<int>{4, 5, 6}));
+ std::vector<int> v;
+ v.push_back(3);
+ v.push_back(11);
+ EXPECT_EQ(2u, Call<const int>(v));
+ EXPECT_EQ(2u, Call<int>(v));
+ // Call<unsigned int>(v); // Compile error, because incompatible types.
+ ArrayView<int> x = v;
+ EXPECT_EQ(2u, x.size());
+ EXPECT_EQ(v.data(), x.data());
+ ArrayView<const int> y;
+ y = v;
+ EXPECT_EQ(2u, y.size());
+ EXPECT_EQ(v.data(), y.data());
+ // ArrayView<double> d = v; // Compile error, because incompatible types.
+ const std::vector<int> cv;
+ EXPECT_EQ(0u, Call<const int>(cv));
+ // Call<int>(cv); // Compile error, because can't drop const.
+ ArrayView<const int> z = cv;
+ EXPECT_EQ(0u, z.size());
+ EXPECT_EQ(nullptr, z.data());
+ // ArrayView<int> w = cv; // Compile error, because can't drop const.
+}
+
+TEST(ArrayViewTest, TestRtcBuffer) {
+ rtc::Buffer b = "so buffer";
+ EXPECT_EQ(10u, Call<const uint8_t>(b));
+ EXPECT_EQ(10u, Call<uint8_t>(b));
+ // Call<int8_t>(b); // Compile error, because incompatible types.
+ ArrayView<uint8_t> x = b;
+ EXPECT_EQ(10u, x.size());
+ EXPECT_EQ(b.data(), x.data());
+ ArrayView<const uint8_t> y;
+ y = b;
+ EXPECT_EQ(10u, y.size());
+ EXPECT_EQ(b.data(), y.data());
+ // ArrayView<char> d = b; // Compile error, because incompatible types.
+ const rtc::Buffer cb = "very const";
+ EXPECT_EQ(11u, Call<const uint8_t>(cb));
+ // Call<uint8_t>(cb); // Compile error, because can't drop const.
+ ArrayView<const uint8_t> z = cb;
+ EXPECT_EQ(11u, z.size());
+ EXPECT_EQ(cb.data(), z.data());
+ // ArrayView<uint8_t> w = cb; // Compile error, because can't drop const.
+}
+
+TEST(ArrayViewTest, TestSwapVariable) {
+ const char arr[] = "Arrr!";
+ const char aye[] = "Aye, Cap'n!";
+ ArrayView<const char> x(arr);
+ EXPECT_EQ(6u, x.size());
+ EXPECT_EQ(arr, x.data());
+ ArrayView<const char> y(aye);
+ EXPECT_EQ(12u, y.size());
+ EXPECT_EQ(aye, y.data());
+ using std::swap;
+ swap(x, y);
+ EXPECT_EQ(12u, x.size());
+ EXPECT_EQ(aye, x.data());
+ EXPECT_EQ(6u, y.size());
+ EXPECT_EQ(arr, y.data());
+ // ArrayView<char> z;
+ // swap(x, z); // Compile error, because can't drop const.
+}
+
+TEST(FixArrayViewTest, TestSwapFixed) {
+ const char arr[] = "Arr!";
+ char aye[] = "Aye!";
+ ArrayView<const char, 5> x(arr);
+ EXPECT_EQ(arr, x.data());
+ ArrayView<const char, 5> y(aye);
+ EXPECT_EQ(aye, y.data());
+ using std::swap;
+ swap(x, y);
+ EXPECT_EQ(aye, x.data());
+ EXPECT_EQ(arr, y.data());
+ // ArrayView<char, 5> z(aye);
+ // swap(x, z); // Compile error, because can't drop const.
+ // ArrayView<const char, 4> w(aye, 4);
+ // swap(x, w); // Compile error, because different sizes.
+}
+
+TEST(ArrayViewDeathTest, TestIndexing) {
+ char arr[] = "abcdefg";
+ ArrayView<char> x(arr);
+ const ArrayView<char> y(arr);
+ ArrayView<const char, 8> z(arr);
+ EXPECT_EQ(8u, x.size());
+ EXPECT_EQ(8u, y.size());
+ EXPECT_EQ(8u, z.size());
+ EXPECT_EQ('b', x[1]);
+ EXPECT_EQ('c', y[2]);
+ EXPECT_EQ('d', z[3]);
+ x[3] = 'X';
+ y[2] = 'Y';
+ // z[1] = 'Z'; // Compile error, because z's element type is const char.
+ EXPECT_EQ('b', x[1]);
+ EXPECT_EQ('Y', y[2]);
+ EXPECT_EQ('X', z[3]);
+#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
+ EXPECT_DEATH(z[8], ""); // DCHECK error (index out of bounds).
+#endif
+}
+
+TEST(ArrayViewTest, TestIterationEmpty) {
+ // Variable-size.
+ ArrayView<std::vector<std::vector<std::vector<std::string>>>> av;
+ EXPECT_EQ(av.begin(), av.end());
+ EXPECT_EQ(av.cbegin(), av.cend());
+ for (auto& e : av) {
+ EXPECT_TRUE(false);
+ EXPECT_EQ(42u, e.size()); // Dummy use of e to prevent unused var warning.
+ }
+
+ // Fixed-size.
+ ArrayView<std::vector<std::vector<std::vector<std::string>>>, 0> af;
+ EXPECT_EQ(af.begin(), af.end());
+ EXPECT_EQ(af.cbegin(), af.cend());
+ for (auto& e : af) {
+ EXPECT_TRUE(false);
+ EXPECT_EQ(42u, e.size()); // Dummy use of e to prevent unused var warning.
+ }
+}
+
+TEST(ArrayViewTest, TestReverseIterationEmpty) {
+ // Variable-size.
+ ArrayView<std::vector<std::vector<std::vector<std::string>>>> av;
+ EXPECT_EQ(av.rbegin(), av.rend());
+ EXPECT_EQ(av.crbegin(), av.crend());
+ EXPECT_TRUE(av.empty());
+
+ // Fixed-size.
+ ArrayView<std::vector<std::vector<std::vector<std::string>>>, 0> af;
+ EXPECT_EQ(af.begin(), af.end());
+ EXPECT_EQ(af.cbegin(), af.cend());
+ EXPECT_TRUE(af.empty());
+}
+
+TEST(ArrayViewTest, TestIterationVariable) {
+ char arr[] = "Arrr!";
+ ArrayView<char> av(arr);
+ EXPECT_EQ('A', *av.begin());
+ EXPECT_EQ('A', *av.cbegin());
+ EXPECT_EQ('\0', *(av.end() - 1));
+ EXPECT_EQ('\0', *(av.cend() - 1));
+ char i = 0;
+ for (auto& e : av) {
+ EXPECT_EQ(arr + i, &e);
+ e = 's' + i;
+ ++i;
+ }
+ i = 0;
+ for (auto& e : ArrayView<const char>(av)) {
+ EXPECT_EQ(arr + i, &e);
+ // e = 'q' + i; // Compile error, because e is a const char&.
+ ++i;
+ }
+}
+
+TEST(ArrayViewTest, TestReverseIterationVariable) {
+ char arr[] = "Arrr!";
+ ArrayView<char> av(arr);
+ EXPECT_EQ('\0', *av.rbegin());
+ EXPECT_EQ('\0', *av.crbegin());
+ EXPECT_EQ('A', *(av.rend() - 1));
+ EXPECT_EQ('A', *(av.crend() - 1));
+
+ const char* cit = av.cend() - 1;
+ for (auto crit = av.crbegin(); crit != av.crend(); ++crit, --cit) {
+ EXPECT_EQ(*cit, *crit);
+ }
+
+ char* it = av.end() - 1;
+ for (auto rit = av.rbegin(); rit != av.rend(); ++rit, --it) {
+ EXPECT_EQ(*it, *rit);
+ }
+}
+
+TEST(ArrayViewTest, TestIterationFixed) {
+ char arr[] = "Arrr!";
+ ArrayView<char, 6> av(arr);
+ EXPECT_EQ('A', *av.begin());
+ EXPECT_EQ('A', *av.cbegin());
+ EXPECT_EQ('\0', *(av.end() - 1));
+ EXPECT_EQ('\0', *(av.cend() - 1));
+ char i = 0;
+ for (auto& e : av) {
+ EXPECT_EQ(arr + i, &e);
+ e = 's' + i;
+ ++i;
+ }
+ i = 0;
+ for (auto& e : ArrayView<const char, 6>(av)) {
+ EXPECT_EQ(arr + i, &e);
+ // e = 'q' + i; // Compile error, because e is a const char&.
+ ++i;
+ }
+}
+
+TEST(ArrayViewTest, TestReverseIterationFixed) {
+ char arr[] = "Arrr!";
+ ArrayView<char, 6> av(arr);
+ EXPECT_EQ('\0', *av.rbegin());
+ EXPECT_EQ('\0', *av.crbegin());
+ EXPECT_EQ('A', *(av.rend() - 1));
+ EXPECT_EQ('A', *(av.crend() - 1));
+
+ const char* cit = av.cend() - 1;
+ for (auto crit = av.crbegin(); crit != av.crend(); ++crit, --cit) {
+ EXPECT_EQ(*cit, *crit);
+ }
+
+ char* it = av.end() - 1;
+ for (auto rit = av.rbegin(); rit != av.rend(); ++rit, --it) {
+ EXPECT_EQ(*it, *rit);
+ }
+}
+
+TEST(ArrayViewTest, TestEmpty) {
+ EXPECT_TRUE(ArrayView<int>().empty());
+ const int a[] = {1, 2, 3};
+ EXPECT_FALSE(ArrayView<const int>(a).empty());
+
+ static_assert(ArrayView<int, 0>::empty(), "");
+ static_assert(!ArrayView<int, 3>::empty(), "");
+}
+
+TEST(ArrayViewTest, TestCompare) {
+ int a[] = {1, 2, 3};
+ int b[] = {1, 2, 3};
+
+ EXPECT_EQ(ArrayView<int>(a), ArrayView<int>(a));
+ EXPECT_EQ((ArrayView<int, 3>(a)), (ArrayView<int, 3>(a)));
+ EXPECT_EQ(ArrayView<int>(a), (ArrayView<int, 3>(a)));
+ EXPECT_EQ(ArrayView<int>(), ArrayView<int>());
+ EXPECT_EQ(ArrayView<int>(), ArrayView<int>(a, 0));
+ EXPECT_EQ(ArrayView<int>(a, 0), ArrayView<int>(b, 0));
+ EXPECT_EQ((ArrayView<int, 0>(a, 0)), ArrayView<int>());
+
+ EXPECT_NE(ArrayView<int>(a), ArrayView<int>(b));
+ EXPECT_NE((ArrayView<int, 3>(a)), (ArrayView<int, 3>(b)));
+ EXPECT_NE((ArrayView<int, 3>(a)), ArrayView<int>(b));
+ EXPECT_NE(ArrayView<int>(a), ArrayView<int>());
+ EXPECT_NE(ArrayView<int>(a), ArrayView<int>(a, 2));
+ EXPECT_NE((ArrayView<int, 3>(a)), (ArrayView<int, 2>(a, 2)));
+}
+
+TEST(ArrayViewTest, TestSubViewVariable) {
+ int a[] = {1, 2, 3};
+ ArrayView<int> av(a);
+
+ EXPECT_EQ(av.subview(0), av);
+
+ EXPECT_THAT(av.subview(1), ElementsAre(2, 3));
+ EXPECT_THAT(av.subview(2), ElementsAre(3));
+ EXPECT_THAT(av.subview(3), IsEmpty());
+ EXPECT_THAT(av.subview(4), IsEmpty());
+
+ EXPECT_THAT(av.subview(1, 0), IsEmpty());
+ EXPECT_THAT(av.subview(1, 1), ElementsAre(2));
+ EXPECT_THAT(av.subview(1, 2), ElementsAre(2, 3));
+ EXPECT_THAT(av.subview(1, 3), ElementsAre(2, 3));
+}
+
+TEST(ArrayViewTest, TestSubViewFixed) {
+ int a[] = {1, 2, 3};
+ ArrayView<int, 3> av(a);
+
+ EXPECT_EQ(av.subview(0), av);
+
+ EXPECT_THAT(av.subview(1), ElementsAre(2, 3));
+ EXPECT_THAT(av.subview(2), ElementsAre(3));
+ EXPECT_THAT(av.subview(3), IsEmpty());
+ EXPECT_THAT(av.subview(4), IsEmpty());
+
+ EXPECT_THAT(av.subview(1, 0), IsEmpty());
+ EXPECT_THAT(av.subview(1, 1), ElementsAre(2));
+ EXPECT_THAT(av.subview(1, 2), ElementsAre(2, 3));
+ EXPECT_THAT(av.subview(1, 3), ElementsAre(2, 3));
+}
+
+TEST(ArrayViewTest, TestReinterpretCastFixedSize) {
+ uint8_t bytes[] = {1, 2, 3};
+ ArrayView<uint8_t, 3> uint8_av(bytes);
+ ArrayView<int8_t, 3> int8_av = reinterpret_array_view<int8_t>(uint8_av);
+ EXPECT_EQ(int8_av.size(), uint8_av.size());
+ EXPECT_EQ(int8_av[0], 1);
+ EXPECT_EQ(int8_av[1], 2);
+ EXPECT_EQ(int8_av[2], 3);
+}
+
+TEST(ArrayViewTest, TestReinterpretCastVariableSize) {
+ std::vector<int8_t> v = {1, 2, 3};
+ ArrayView<int8_t> int8_av(v);
+ ArrayView<uint8_t> uint8_av = reinterpret_array_view<uint8_t>(int8_av);
+ EXPECT_EQ(int8_av.size(), uint8_av.size());
+ EXPECT_EQ(uint8_av[0], 1);
+ EXPECT_EQ(uint8_av[1], 2);
+ EXPECT_EQ(uint8_av[2], 3);
+}
+} // namespace rtc
diff --git a/third_party/libwebrtc/api/async_dns_resolver.h b/third_party/libwebrtc/api/async_dns_resolver.h
new file mode 100644
index 0000000000..82d80de2c3
--- /dev/null
+++ b/third_party/libwebrtc/api/async_dns_resolver.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2021 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_ASYNC_DNS_RESOLVER_H_
+#define API_ASYNC_DNS_RESOLVER_H_
+
+#include <functional>
+#include <memory>
+
+#include "rtc_base/checks.h"
+#include "rtc_base/socket_address.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// This interface defines the methods to resolve a hostname asynchronously.
+// The AsyncDnsResolverInterface class encapsulates a single name query.
+//
+// Usage:
+// std::unique_ptr<AsyncDnsResolverInterface> resolver =
+// factory->Create(address-to-be-resolved, [r = resolver.get()]() {
+// if (r->result.GetResolvedAddress(AF_INET, &addr) {
+// // success
+// } else {
+// // failure
+// error = r->result().GetError();
+// }
+// // Release resolver.
+// resolver_list.erase(std::remove_if(resolver_list.begin(),
+// resolver_list.end(),
+// [](refptr) { refptr.get() == r; });
+// });
+// resolver_list.push_back(std::move(resolver));
+
+class AsyncDnsResolverResult {
+ public:
+ virtual ~AsyncDnsResolverResult() = default;
+ // Returns true iff the address from `Start` was successfully resolved.
+ // If the address was successfully resolved, sets `addr` to a copy of the
+ // address from `Start` with the IP address set to the top most resolved
+ // address of `family` (`addr` will have both hostname and the resolved ip).
+ virtual bool GetResolvedAddress(int family,
+ rtc::SocketAddress* addr) const = 0;
+ // Returns error from resolver.
+ virtual int GetError() const = 0;
+};
+
+// The API for a single name query.
+// The constructor, destructor and all functions must be called from
+// the same sequence, and the callback will also be called on that sequence.
+// The class guarantees that the callback will not be called if the
+// resolver's destructor has been called.
+class RTC_EXPORT AsyncDnsResolverInterface {
+ public:
+ virtual ~AsyncDnsResolverInterface() = default;
+
+ // Start address resolution of the hostname in `addr`.
+ virtual void Start(const rtc::SocketAddress& addr,
+ std::function<void()> callback) = 0;
+ // Start address resolution of the hostname in `addr` matching `family`.
+ virtual void Start(const rtc::SocketAddress& addr,
+ int family,
+ std::function<void()> callback) = 0;
+ virtual const AsyncDnsResolverResult& result() const = 0;
+};
+
+// An abstract factory for creating AsyncDnsResolverInterfaces. This allows
+// client applications to provide WebRTC with their own mechanism for
+// performing DNS resolution.
+class AsyncDnsResolverFactoryInterface {
+ public:
+ virtual ~AsyncDnsResolverFactoryInterface() = default;
+
+ // Creates an AsyncDnsResolver and starts resolving the name. The callback
+ // will be called when resolution is finished.
+ // The callback will be called on the sequence that the caller runs on.
+ virtual std::unique_ptr<webrtc::AsyncDnsResolverInterface> CreateAndResolve(
+ const rtc::SocketAddress& addr,
+ std::function<void()> callback) = 0;
+ // Creates an AsyncDnsResolver and starts resolving the name to an address
+ // matching the specified family. The callback will be called when resolution
+ // is finished. The callback will be called on the sequence that the caller
+ // runs on.
+ virtual std::unique_ptr<webrtc::AsyncDnsResolverInterface> CreateAndResolve(
+ const rtc::SocketAddress& addr,
+ int family,
+ std::function<void()> callback) = 0;
+ // Creates an AsyncDnsResolver and does not start it.
+ // For backwards compatibility, will be deprecated and removed.
+ // One has to do a separate Start() call on the
+ // resolver to start name resolution.
+ virtual std::unique_ptr<webrtc::AsyncDnsResolverInterface> Create() = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_ASYNC_DNS_RESOLVER_H_
diff --git a/third_party/libwebrtc/api/async_resolver_factory.h b/third_party/libwebrtc/api/async_resolver_factory.h
new file mode 100644
index 0000000000..93d3f7934b
--- /dev/null
+++ b/third_party/libwebrtc/api/async_resolver_factory.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_ASYNC_RESOLVER_FACTORY_H_
+#define API_ASYNC_RESOLVER_FACTORY_H_
+
+#include "rtc_base/async_resolver_interface.h"
+
+namespace webrtc {
+
+// An abstract factory for creating AsyncResolverInterfaces. This allows
+// client applications to provide WebRTC with their own mechanism for
+// performing DNS resolution.
+class AsyncResolverFactory {
+ public:
+ AsyncResolverFactory() = default;
+ virtual ~AsyncResolverFactory() = default;
+
+ // The caller should call Destroy on the returned object to delete it.
+ virtual rtc::AsyncResolverInterface* Create() = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_ASYNC_RESOLVER_FACTORY_H_
diff --git a/third_party/libwebrtc/api/audio/BUILD.gn b/third_party/libwebrtc/api/audio/BUILD.gn
new file mode 100644
index 0000000000..4832751b5f
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/BUILD.gn
@@ -0,0 +1,111 @@
+# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../webrtc.gni")
+
+rtc_library("audio_frame_api") {
+ visibility = [ "*" ]
+ sources = [
+ "audio_frame.cc",
+ "audio_frame.h",
+ "channel_layout.cc",
+ "channel_layout.h",
+ ]
+
+ deps = [
+ "..:rtp_packet_info",
+ "../../rtc_base:checks",
+ "../../rtc_base:logging",
+ "../../rtc_base:macromagic",
+ "../../rtc_base:timeutils",
+ ]
+}
+
+rtc_source_set("audio_frame_processor") {
+ visibility = [ "*" ]
+ sources = [ "audio_frame_processor.h" ]
+}
+
+rtc_source_set("audio_mixer_api") {
+ visibility = [ "*" ]
+ sources = [ "audio_mixer.h" ]
+
+ deps = [
+ ":audio_frame_api",
+ "..:make_ref_counted",
+ "../../rtc_base:refcount",
+ ]
+}
+
+rtc_library("aec3_config") {
+ visibility = [ "*" ]
+ sources = [
+ "echo_canceller3_config.cc",
+ "echo_canceller3_config.h",
+ ]
+ deps = [
+ "../../rtc_base:checks",
+ "../../rtc_base:safe_minmax",
+ "../../rtc_base/system:rtc_export",
+ ]
+}
+
+rtc_library("aec3_config_json") {
+ visibility = [ "*" ]
+ allow_poison = [ "rtc_json" ]
+ sources = [
+ "echo_canceller3_config_json.cc",
+ "echo_canceller3_config_json.h",
+ ]
+ deps = [
+ ":aec3_config",
+ "../../rtc_base:checks",
+ "../../rtc_base:logging",
+ "../../rtc_base:rtc_json",
+ "../../rtc_base:stringutils",
+ "../../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
+}
+
+rtc_library("aec3_factory") {
+ visibility = [ "*" ]
+ configs += [ "../../modules/audio_processing:apm_debug_dump" ]
+ sources = [
+ "echo_canceller3_factory.cc",
+ "echo_canceller3_factory.h",
+ ]
+
+ deps = [
+ ":aec3_config",
+ ":echo_control",
+ "../../modules/audio_processing/aec3",
+ "../../rtc_base/system:rtc_export",
+ ]
+}
+
+rtc_source_set("echo_control") {
+ visibility = [ "*" ]
+ sources = [ "echo_control.h" ]
+ deps = [ "../../rtc_base:checks" ]
+}
+
+rtc_source_set("echo_detector_creator") {
+ visibility = [ "*" ]
+ allow_poison = [ "default_echo_detector" ]
+ sources = [
+ "echo_detector_creator.cc",
+ "echo_detector_creator.h",
+ ]
+ deps = [
+ "..:make_ref_counted",
+ "../../api:scoped_refptr",
+ "../../modules/audio_processing:api",
+ "../../modules/audio_processing:residual_echo_detector",
+ ]
+}
diff --git a/third_party/libwebrtc/api/audio/OWNERS b/third_party/libwebrtc/api/audio/OWNERS
new file mode 100644
index 0000000000..bb499b450f
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/OWNERS
@@ -0,0 +1,2 @@
+gustaf@webrtc.org
+peah@webrtc.org
diff --git a/third_party/libwebrtc/api/audio/aec3_config_gn/moz.build b/third_party/libwebrtc/api/audio/aec3_config_gn/moz.build
new file mode 100644
index 0000000000..c2d256488d
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/aec3_config_gn/moz.build
@@ -0,0 +1,221 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio/echo_canceller3_config.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("aec3_config_gn")
diff --git a/third_party/libwebrtc/api/audio/aec3_factory_gn/moz.build b/third_party/libwebrtc/api/audio/aec3_factory_gn/moz.build
new file mode 100644
index 0000000000..ecd28a7006
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/aec3_factory_gn/moz.build
@@ -0,0 +1,233 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_APM_DEBUG_DUMP"] = "0"
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio/echo_canceller3_factory.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "rt"
+ ]
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "crypt32",
+ "iphlpapi",
+ "secur32",
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("aec3_factory_gn")
diff --git a/third_party/libwebrtc/api/audio/audio_frame.cc b/third_party/libwebrtc/api/audio/audio_frame.cc
new file mode 100644
index 0000000000..3e12006386
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/audio_frame.cc
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio/audio_frame.h"
+
+#include <string.h>
+
+#include "rtc_base/checks.h"
+#include "rtc_base/time_utils.h"
+
+namespace webrtc {
+
+AudioFrame::AudioFrame() {
+ // Visual Studio doesn't like this in the class definition.
+ static_assert(sizeof(data_) == kMaxDataSizeBytes, "kMaxDataSizeBytes");
+}
+
+void AudioFrame::Reset() {
+ ResetWithoutMuting();
+ muted_ = true;
+}
+
+void AudioFrame::ResetWithoutMuting() {
+ // TODO(wu): Zero is a valid value for `timestamp_`. We should initialize
+ // to an invalid value, or add a new member to indicate invalidity.
+ timestamp_ = 0;
+ elapsed_time_ms_ = -1;
+ ntp_time_ms_ = -1;
+ samples_per_channel_ = 0;
+ sample_rate_hz_ = 0;
+ num_channels_ = 0;
+ channel_layout_ = CHANNEL_LAYOUT_NONE;
+ speech_type_ = kUndefined;
+ vad_activity_ = kVadUnknown;
+ profile_timestamp_ms_ = 0;
+ packet_infos_ = RtpPacketInfos();
+ absolute_capture_timestamp_ms_ = absl::nullopt;
+}
+
+void AudioFrame::UpdateFrame(uint32_t timestamp,
+ const int16_t* data,
+ size_t samples_per_channel,
+ int sample_rate_hz,
+ SpeechType speech_type,
+ VADActivity vad_activity,
+ size_t num_channels) {
+ timestamp_ = timestamp;
+ samples_per_channel_ = samples_per_channel;
+ sample_rate_hz_ = sample_rate_hz;
+ speech_type_ = speech_type;
+ vad_activity_ = vad_activity;
+ num_channels_ = num_channels;
+ channel_layout_ = GuessChannelLayout(num_channels);
+ if (channel_layout_ != CHANNEL_LAYOUT_UNSUPPORTED) {
+ RTC_DCHECK_EQ(num_channels, ChannelLayoutToChannelCount(channel_layout_));
+ }
+
+ const size_t length = samples_per_channel * num_channels;
+ RTC_CHECK_LE(length, kMaxDataSizeSamples);
+ if (data != nullptr) {
+ memcpy(data_, data, sizeof(int16_t) * length);
+ muted_ = false;
+ } else {
+ muted_ = true;
+ }
+}
+
+void AudioFrame::CopyFrom(const AudioFrame& src) {
+ if (this == &src)
+ return;
+
+ timestamp_ = src.timestamp_;
+ elapsed_time_ms_ = src.elapsed_time_ms_;
+ ntp_time_ms_ = src.ntp_time_ms_;
+ packet_infos_ = src.packet_infos_;
+ muted_ = src.muted();
+ samples_per_channel_ = src.samples_per_channel_;
+ sample_rate_hz_ = src.sample_rate_hz_;
+ speech_type_ = src.speech_type_;
+ vad_activity_ = src.vad_activity_;
+ num_channels_ = src.num_channels_;
+ channel_layout_ = src.channel_layout_;
+ absolute_capture_timestamp_ms_ = src.absolute_capture_timestamp_ms();
+
+ const size_t length = samples_per_channel_ * num_channels_;
+ RTC_CHECK_LE(length, kMaxDataSizeSamples);
+ if (!src.muted()) {
+ memcpy(data_, src.data(), sizeof(int16_t) * length);
+ muted_ = false;
+ }
+}
+
+void AudioFrame::UpdateProfileTimeStamp() {
+ profile_timestamp_ms_ = rtc::TimeMillis();
+}
+
+int64_t AudioFrame::ElapsedProfileTimeMs() const {
+ if (profile_timestamp_ms_ == 0) {
+ // Profiling has not been activated.
+ return -1;
+ }
+ return rtc::TimeSince(profile_timestamp_ms_);
+}
+
+const int16_t* AudioFrame::data() const {
+ return muted_ ? empty_data() : data_;
+}
+
+// TODO(henrik.lundin) Can we skip zeroing the buffer?
+// See https://bugs.chromium.org/p/webrtc/issues/detail?id=5647.
+int16_t* AudioFrame::mutable_data() {
+ if (muted_) {
+ memset(data_, 0, kMaxDataSizeBytes);
+ muted_ = false;
+ }
+ return data_;
+}
+
+void AudioFrame::Mute() {
+ muted_ = true;
+}
+
+bool AudioFrame::muted() const {
+ return muted_;
+}
+
+// static
+const int16_t* AudioFrame::empty_data() {
+ static int16_t* null_data = new int16_t[kMaxDataSizeSamples]();
+ return &null_data[0];
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio/audio_frame.h b/third_party/libwebrtc/api/audio/audio_frame.h
new file mode 100644
index 0000000000..d5dcb5f788
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/audio_frame.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_AUDIO_FRAME_H_
+#define API_AUDIO_AUDIO_FRAME_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "api/audio/channel_layout.h"
+#include "api/rtp_packet_infos.h"
+
+namespace webrtc {
+
+/* This class holds up to 120 ms of super-wideband (32 kHz) stereo audio. It
+ * allows for adding and subtracting frames while keeping track of the resulting
+ * states.
+ *
+ * Notes
+ * - This is a de-facto api, not designed for external use. The AudioFrame class
+ * is in need of overhaul or even replacement, and anyone depending on it
+ * should be prepared for that.
+ * - The total number of samples is samples_per_channel_ * num_channels_.
+ * - Stereo data is interleaved starting with the left channel.
+ */
+class AudioFrame {
+ public:
+ // Using constexpr here causes linker errors unless the variable also has an
+ // out-of-class definition, which is impractical in this header-only class.
+ // (This makes no sense because it compiles as an enum value, which we most
+ // certainly cannot take the address of, just fine.) C++17 introduces inline
+ // variables which should allow us to switch to constexpr and keep this a
+ // header-only class.
+ enum : size_t {
+ // Stereo, 32 kHz, 120 ms (2 * 32 * 120)
+ // Stereo, 192 kHz, 20 ms (2 * 192 * 20)
+ kMaxDataSizeSamples = 7680,
+ kMaxDataSizeBytes = kMaxDataSizeSamples * sizeof(int16_t),
+ };
+
+ enum VADActivity { kVadActive = 0, kVadPassive = 1, kVadUnknown = 2 };
+ enum SpeechType {
+ kNormalSpeech = 0,
+ kPLC = 1,
+ kCNG = 2,
+ kPLCCNG = 3,
+ kCodecPLC = 5,
+ kUndefined = 4
+ };
+
+ AudioFrame();
+
+ AudioFrame(const AudioFrame&) = delete;
+ AudioFrame& operator=(const AudioFrame&) = delete;
+
+ // Resets all members to their default state.
+ void Reset();
+ // Same as Reset(), but leaves mute state unchanged. Muting a frame requires
+ // the buffer to be zeroed on the next call to mutable_data(). Callers
+ // intending to write to the buffer immediately after Reset() can instead use
+ // ResetWithoutMuting() to skip this wasteful zeroing.
+ void ResetWithoutMuting();
+
+ void UpdateFrame(uint32_t timestamp,
+ const int16_t* data,
+ size_t samples_per_channel,
+ int sample_rate_hz,
+ SpeechType speech_type,
+ VADActivity vad_activity,
+ size_t num_channels = 1);
+
+ void CopyFrom(const AudioFrame& src);
+
+ // Sets a wall-time clock timestamp in milliseconds to be used for profiling
+ // of time between two points in the audio chain.
+ // Example:
+ // t0: UpdateProfileTimeStamp()
+ // t1: ElapsedProfileTimeMs() => t1 - t0 [msec]
+ void UpdateProfileTimeStamp();
+ // Returns the time difference between now and when UpdateProfileTimeStamp()
+ // was last called. Returns -1 if UpdateProfileTimeStamp() has not yet been
+ // called.
+ int64_t ElapsedProfileTimeMs() const;
+
+ // data() returns a zeroed static buffer if the frame is muted.
+ // mutable_frame() always returns a non-static buffer; the first call to
+ // mutable_frame() zeros the non-static buffer and marks the frame unmuted.
+ const int16_t* data() const;
+ int16_t* mutable_data();
+
+ // Prefer to mute frames using AudioFrameOperations::Mute.
+ void Mute();
+ // Frame is muted by default.
+ bool muted() const;
+
+ size_t max_16bit_samples() const { return kMaxDataSizeSamples; }
+ size_t samples_per_channel() const { return samples_per_channel_; }
+ size_t num_channels() const { return num_channels_; }
+ ChannelLayout channel_layout() const { return channel_layout_; }
+ int sample_rate_hz() const { return sample_rate_hz_; }
+
+ void set_absolute_capture_timestamp_ms(
+ int64_t absolute_capture_time_stamp_ms) {
+ absolute_capture_timestamp_ms_ = absolute_capture_time_stamp_ms;
+ }
+
+ absl::optional<int64_t> absolute_capture_timestamp_ms() const {
+ return absolute_capture_timestamp_ms_;
+ }
+
+ // RTP timestamp of the first sample in the AudioFrame.
+ uint32_t timestamp_ = 0;
+ // Time since the first frame in milliseconds.
+ // -1 represents an uninitialized value.
+ int64_t elapsed_time_ms_ = -1;
+ // NTP time of the estimated capture time in local timebase in milliseconds.
+ // -1 represents an uninitialized value.
+ int64_t ntp_time_ms_ = -1;
+ size_t samples_per_channel_ = 0;
+ int sample_rate_hz_ = 0;
+ size_t num_channels_ = 0;
+ ChannelLayout channel_layout_ = CHANNEL_LAYOUT_NONE;
+ SpeechType speech_type_ = kUndefined;
+ VADActivity vad_activity_ = kVadUnknown;
+ // Monotonically increasing timestamp intended for profiling of audio frames.
+ // Typically used for measuring elapsed time between two different points in
+ // the audio path. No lock is used to save resources and we are thread safe
+ // by design.
+ // TODO(nisse@webrtc.org): consider using absl::optional.
+ int64_t profile_timestamp_ms_ = 0;
+
+ // Information about packets used to assemble this audio frame. This is needed
+ // by `SourceTracker` when the frame is delivered to the RTCRtpReceiver's
+ // MediaStreamTrack, in order to implement getContributingSources(). See:
+ // https://w3c.github.io/webrtc-pc/#dom-rtcrtpreceiver-getcontributingsources
+ //
+ // TODO(bugs.webrtc.org/10757):
+ // Note that this information might not be fully accurate since we currently
+ // don't have a proper way to track it across the audio sync buffer. The
+ // sync buffer is the small sample-holding buffer located after the audio
+ // decoder and before where samples are assembled into output frames.
+ //
+ // `RtpPacketInfos` may also be empty if the audio samples did not come from
+ // RTP packets. E.g. if the audio were locally generated by packet loss
+ // concealment, comfort noise generation, etc.
+ RtpPacketInfos packet_infos_;
+
+ private:
+ // A permanently zeroed out buffer to represent muted frames. This is a
+ // header-only class, so the only way to avoid creating a separate empty
+ // buffer per translation unit is to wrap a static in an inline function.
+ static const int16_t* empty_data();
+
+ int16_t data_[kMaxDataSizeSamples];
+ bool muted_ = true;
+
+ // Absolute capture timestamp when this audio frame was originally captured.
+ // This is only valid for audio frames captured on this machine. The absolute
+ // capture timestamp of a received frame is found in `packet_infos_`.
+ // This timestamp MUST be based on the same clock as rtc::TimeMillis().
+ absl::optional<int64_t> absolute_capture_timestamp_ms_;
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_AUDIO_FRAME_H_
diff --git a/third_party/libwebrtc/api/audio/audio_frame_api_gn/moz.build b/third_party/libwebrtc/api/audio/audio_frame_api_gn/moz.build
new file mode 100644
index 0000000000..6fac266c73
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/audio_frame_api_gn/moz.build
@@ -0,0 +1,226 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio/audio_frame.cc",
+ "/third_party/libwebrtc/api/audio/channel_layout.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_frame_api_gn")
diff --git a/third_party/libwebrtc/api/audio/audio_frame_processor.h b/third_party/libwebrtc/api/audio/audio_frame_processor.h
new file mode 100644
index 0000000000..cb65c4817e
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/audio_frame_processor.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_AUDIO_FRAME_PROCESSOR_H_
+#define API_AUDIO_AUDIO_FRAME_PROCESSOR_H_
+
+#include <functional>
+#include <memory>
+
+namespace webrtc {
+
+class AudioFrame;
+
+// If passed into PeerConnectionFactory, will be used for additional
+// processing of captured audio frames, performed before encoding.
+// Implementations must be thread-safe.
+class AudioFrameProcessor {
+ public:
+ using OnAudioFrameCallback = std::function<void(std::unique_ptr<AudioFrame>)>;
+ virtual ~AudioFrameProcessor() = default;
+
+ // Processes the frame received from WebRTC, is called by WebRTC off the
+ // realtime audio capturing path. AudioFrameProcessor must reply with
+ // processed frames by calling `sink_callback` if it was provided in SetSink()
+ // call. `sink_callback` can be called in the context of Process().
+ virtual void Process(std::unique_ptr<AudioFrame> frame) = 0;
+
+ // Atomically replaces the current sink with the new one. Before the
+ // first call to this function, or if the provided `sink_callback` is nullptr,
+ // processed frames are simply discarded.
+ virtual void SetSink(OnAudioFrameCallback sink_callback) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_AUDIO_FRAME_PROCESSOR_H_
diff --git a/third_party/libwebrtc/api/audio/audio_frame_processor_gn/moz.build b/third_party/libwebrtc/api/audio/audio_frame_processor_gn/moz.build
new file mode 100644
index 0000000000..1732aa7d0c
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/audio_frame_processor_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_frame_processor_gn")
diff --git a/third_party/libwebrtc/api/audio/audio_mixer.h b/third_party/libwebrtc/api/audio/audio_mixer.h
new file mode 100644
index 0000000000..3483df22bc
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/audio_mixer.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_AUDIO_MIXER_H_
+#define API_AUDIO_AUDIO_MIXER_H_
+
+#include <memory>
+
+#include "api/audio/audio_frame.h"
+#include "rtc_base/ref_count.h"
+
+namespace webrtc {
+
+// WORK IN PROGRESS
+// This class is under development and is not yet intended for for use outside
+// of WebRtc/Libjingle.
+class AudioMixer : public rtc::RefCountInterface {
+ public:
+ // A callback class that all mixer participants must inherit from/implement.
+ class Source {
+ public:
+ enum class AudioFrameInfo {
+ kNormal, // The samples in audio_frame are valid and should be used.
+ kMuted, // The samples in audio_frame should not be used, but
+ // should be implicitly interpreted as zero. Other
+ // fields in audio_frame may be read and should
+ // contain meaningful values.
+ kError, // The audio_frame will not be used.
+ };
+
+ // Overwrites `audio_frame`. The data_ field is overwritten with
+ // 10 ms of new audio (either 1 or 2 interleaved channels) at
+ // `sample_rate_hz`. All fields in `audio_frame` must be updated.
+ virtual AudioFrameInfo GetAudioFrameWithInfo(int sample_rate_hz,
+ AudioFrame* audio_frame) = 0;
+
+ // A way for a mixer implementation to distinguish participants.
+ virtual int Ssrc() const = 0;
+
+ // A way for this source to say that GetAudioFrameWithInfo called
+ // with this sample rate or higher will not cause quality loss.
+ virtual int PreferredSampleRate() const = 0;
+
+ virtual ~Source() {}
+ };
+
+ // Returns true if adding was successful. A source is never added
+ // twice. Addition and removal can happen on different threads.
+ virtual bool AddSource(Source* audio_source) = 0;
+
+ // Removal is never attempted if a source has not been successfully
+ // added to the mixer.
+ virtual void RemoveSource(Source* audio_source) = 0;
+
+ // Performs mixing by asking registered audio sources for audio. The
+ // mixed result is placed in the provided AudioFrame. This method
+ // will only be called from a single thread. The channels argument
+ // specifies the number of channels of the mix result. The mixer
+ // should mix at a rate that doesn't cause quality loss of the
+ // sources' audio. The mixing rate is one of the rates listed in
+ // AudioProcessing::NativeRate. All fields in
+ // `audio_frame_for_mixing` must be updated.
+ virtual void Mix(size_t number_of_channels,
+ AudioFrame* audio_frame_for_mixing) = 0;
+
+ protected:
+ // Since the mixer is reference counted, the destructor may be
+ // called from any thread.
+ ~AudioMixer() override {}
+};
+} // namespace webrtc
+
+#endif // API_AUDIO_AUDIO_MIXER_H_
diff --git a/third_party/libwebrtc/api/audio/audio_mixer_api_gn/moz.build b/third_party/libwebrtc/api/audio/audio_mixer_api_gn/moz.build
new file mode 100644
index 0000000000..4eac2aa4b4
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/audio_mixer_api_gn/moz.build
@@ -0,0 +1,209 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_mixer_api_gn")
diff --git a/third_party/libwebrtc/api/audio/channel_layout.cc b/third_party/libwebrtc/api/audio/channel_layout.cc
new file mode 100644
index 0000000000..e4ae356fab
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/channel_layout.cc
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio/channel_layout.h"
+
+#include <stddef.h>
+
+#include "rtc_base/arraysize.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/logging.h"
+
+namespace webrtc {
+
+static const int kLayoutToChannels[] = {
+ 0, // CHANNEL_LAYOUT_NONE
+ 0, // CHANNEL_LAYOUT_UNSUPPORTED
+ 1, // CHANNEL_LAYOUT_MONO
+ 2, // CHANNEL_LAYOUT_STEREO
+ 3, // CHANNEL_LAYOUT_2_1
+ 3, // CHANNEL_LAYOUT_SURROUND
+ 4, // CHANNEL_LAYOUT_4_0
+ 4, // CHANNEL_LAYOUT_2_2
+ 4, // CHANNEL_LAYOUT_QUAD
+ 5, // CHANNEL_LAYOUT_5_0
+ 6, // CHANNEL_LAYOUT_5_1
+ 5, // CHANNEL_LAYOUT_5_0_BACK
+ 6, // CHANNEL_LAYOUT_5_1_BACK
+ 7, // CHANNEL_LAYOUT_7_0
+ 8, // CHANNEL_LAYOUT_7_1
+ 8, // CHANNEL_LAYOUT_7_1_WIDE
+ 2, // CHANNEL_LAYOUT_STEREO_DOWNMIX
+ 3, // CHANNEL_LAYOUT_2POINT1
+ 4, // CHANNEL_LAYOUT_3_1
+ 5, // CHANNEL_LAYOUT_4_1
+ 6, // CHANNEL_LAYOUT_6_0
+ 6, // CHANNEL_LAYOUT_6_0_FRONT
+ 6, // CHANNEL_LAYOUT_HEXAGONAL
+ 7, // CHANNEL_LAYOUT_6_1
+ 7, // CHANNEL_LAYOUT_6_1_BACK
+ 7, // CHANNEL_LAYOUT_6_1_FRONT
+ 7, // CHANNEL_LAYOUT_7_0_FRONT
+ 8, // CHANNEL_LAYOUT_7_1_WIDE_BACK
+ 8, // CHANNEL_LAYOUT_OCTAGONAL
+ 0, // CHANNEL_LAYOUT_DISCRETE
+ 3, // CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC
+ 5, // CHANNEL_LAYOUT_4_1_QUAD_SIDE
+ 0, // CHANNEL_LAYOUT_BITSTREAM
+};
+
+// The channel orderings for each layout as specified by FFmpeg. Each value
+// represents the index of each channel in each layout. Values of -1 mean the
+// channel at that index is not used for that layout. For example, the left side
+// surround sound channel in FFmpeg's 5.1 layout is in the 5th position (because
+// the order is L, R, C, LFE, LS, RS), so
+// kChannelOrderings[CHANNEL_LAYOUT_5_1][SIDE_LEFT] = 4;
+static const int kChannelOrderings[CHANNEL_LAYOUT_MAX + 1][CHANNELS_MAX + 1] = {
+ // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
+
+ // CHANNEL_LAYOUT_NONE
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+
+ // CHANNEL_LAYOUT_UNSUPPORTED
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+
+ // CHANNEL_LAYOUT_MONO
+ {-1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1},
+
+ // CHANNEL_LAYOUT_STEREO
+ {0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+
+ // CHANNEL_LAYOUT_2_1
+ {0, 1, -1, -1, -1, -1, -1, -1, 2, -1, -1},
+
+ // CHANNEL_LAYOUT_SURROUND
+ {0, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1},
+
+ // CHANNEL_LAYOUT_4_0
+ {0, 1, 2, -1, -1, -1, -1, -1, 3, -1, -1},
+
+ // CHANNEL_LAYOUT_2_2
+ {0, 1, -1, -1, -1, -1, -1, -1, -1, 2, 3},
+
+ // CHANNEL_LAYOUT_QUAD
+ {0, 1, -1, -1, 2, 3, -1, -1, -1, -1, -1},
+
+ // CHANNEL_LAYOUT_5_0
+ {0, 1, 2, -1, -1, -1, -1, -1, -1, 3, 4},
+
+ // CHANNEL_LAYOUT_5_1
+ {0, 1, 2, 3, -1, -1, -1, -1, -1, 4, 5},
+
+ // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
+
+ // CHANNEL_LAYOUT_5_0_BACK
+ {0, 1, 2, -1, 3, 4, -1, -1, -1, -1, -1},
+
+ // CHANNEL_LAYOUT_5_1_BACK
+ {0, 1, 2, 3, 4, 5, -1, -1, -1, -1, -1},
+
+ // CHANNEL_LAYOUT_7_0
+ {0, 1, 2, -1, 5, 6, -1, -1, -1, 3, 4},
+
+ // CHANNEL_LAYOUT_7_1
+ {0, 1, 2, 3, 6, 7, -1, -1, -1, 4, 5},
+
+ // CHANNEL_LAYOUT_7_1_WIDE
+ {0, 1, 2, 3, -1, -1, 6, 7, -1, 4, 5},
+
+ // CHANNEL_LAYOUT_STEREO_DOWNMIX
+ {0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+
+ // CHANNEL_LAYOUT_2POINT1
+ {0, 1, -1, 2, -1, -1, -1, -1, -1, -1, -1},
+
+ // CHANNEL_LAYOUT_3_1
+ {0, 1, 2, 3, -1, -1, -1, -1, -1, -1, -1},
+
+ // CHANNEL_LAYOUT_4_1
+ {0, 1, 2, 4, -1, -1, -1, -1, 3, -1, -1},
+
+ // CHANNEL_LAYOUT_6_0
+ {0, 1, 2, -1, -1, -1, -1, -1, 5, 3, 4},
+
+ // CHANNEL_LAYOUT_6_0_FRONT
+ {0, 1, -1, -1, -1, -1, 4, 5, -1, 2, 3},
+
+ // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
+
+ // CHANNEL_LAYOUT_HEXAGONAL
+ {0, 1, 2, -1, 3, 4, -1, -1, 5, -1, -1},
+
+ // CHANNEL_LAYOUT_6_1
+ {0, 1, 2, 3, -1, -1, -1, -1, 6, 4, 5},
+
+ // CHANNEL_LAYOUT_6_1_BACK
+ {0, 1, 2, 3, 4, 5, -1, -1, 6, -1, -1},
+
+ // CHANNEL_LAYOUT_6_1_FRONT
+ {0, 1, -1, 6, -1, -1, 4, 5, -1, 2, 3},
+
+ // CHANNEL_LAYOUT_7_0_FRONT
+ {0, 1, 2, -1, -1, -1, 5, 6, -1, 3, 4},
+
+ // CHANNEL_LAYOUT_7_1_WIDE_BACK
+ {0, 1, 2, 3, 4, 5, 6, 7, -1, -1, -1},
+
+ // CHANNEL_LAYOUT_OCTAGONAL
+ {0, 1, 2, -1, 5, 6, -1, -1, 7, 3, 4},
+
+ // CHANNEL_LAYOUT_DISCRETE
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+
+ // CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC
+ {0, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1},
+
+ // CHANNEL_LAYOUT_4_1_QUAD_SIDE
+ {0, 1, -1, 4, -1, -1, -1, -1, -1, 2, 3},
+
+ // CHANNEL_LAYOUT_BITSTREAM
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+
+ // FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
+};
+
+int ChannelLayoutToChannelCount(ChannelLayout layout) {
+ RTC_DCHECK_LT(static_cast<size_t>(layout), arraysize(kLayoutToChannels));
+ RTC_DCHECK_LE(kLayoutToChannels[layout], kMaxConcurrentChannels);
+ return kLayoutToChannels[layout];
+}
+
+// Converts a channel count into a channel layout.
+ChannelLayout GuessChannelLayout(int channels) {
+ switch (channels) {
+ case 1:
+ return CHANNEL_LAYOUT_MONO;
+ case 2:
+ return CHANNEL_LAYOUT_STEREO;
+ case 3:
+ return CHANNEL_LAYOUT_SURROUND;
+ case 4:
+ return CHANNEL_LAYOUT_QUAD;
+ case 5:
+ return CHANNEL_LAYOUT_5_0;
+ case 6:
+ return CHANNEL_LAYOUT_5_1;
+ case 7:
+ return CHANNEL_LAYOUT_6_1;
+ case 8:
+ return CHANNEL_LAYOUT_7_1;
+ default:
+ RTC_DLOG(LS_WARNING) << "Unsupported channel count: " << channels;
+ }
+ return CHANNEL_LAYOUT_UNSUPPORTED;
+}
+
+int ChannelOrder(ChannelLayout layout, Channels channel) {
+ RTC_DCHECK_LT(static_cast<size_t>(layout), arraysize(kChannelOrderings));
+ RTC_DCHECK_LT(static_cast<size_t>(channel), arraysize(kChannelOrderings[0]));
+ return kChannelOrderings[layout][channel];
+}
+
+const char* ChannelLayoutToString(ChannelLayout layout) {
+ switch (layout) {
+ case CHANNEL_LAYOUT_NONE:
+ return "NONE";
+ case CHANNEL_LAYOUT_UNSUPPORTED:
+ return "UNSUPPORTED";
+ case CHANNEL_LAYOUT_MONO:
+ return "MONO";
+ case CHANNEL_LAYOUT_STEREO:
+ return "STEREO";
+ case CHANNEL_LAYOUT_2_1:
+ return "2.1";
+ case CHANNEL_LAYOUT_SURROUND:
+ return "SURROUND";
+ case CHANNEL_LAYOUT_4_0:
+ return "4.0";
+ case CHANNEL_LAYOUT_2_2:
+ return "QUAD_SIDE";
+ case CHANNEL_LAYOUT_QUAD:
+ return "QUAD";
+ case CHANNEL_LAYOUT_5_0:
+ return "5.0";
+ case CHANNEL_LAYOUT_5_1:
+ return "5.1";
+ case CHANNEL_LAYOUT_5_0_BACK:
+ return "5.0_BACK";
+ case CHANNEL_LAYOUT_5_1_BACK:
+ return "5.1_BACK";
+ case CHANNEL_LAYOUT_7_0:
+ return "7.0";
+ case CHANNEL_LAYOUT_7_1:
+ return "7.1";
+ case CHANNEL_LAYOUT_7_1_WIDE:
+ return "7.1_WIDE";
+ case CHANNEL_LAYOUT_STEREO_DOWNMIX:
+ return "STEREO_DOWNMIX";
+ case CHANNEL_LAYOUT_2POINT1:
+ return "2POINT1";
+ case CHANNEL_LAYOUT_3_1:
+ return "3.1";
+ case CHANNEL_LAYOUT_4_1:
+ return "4.1";
+ case CHANNEL_LAYOUT_6_0:
+ return "6.0";
+ case CHANNEL_LAYOUT_6_0_FRONT:
+ return "6.0_FRONT";
+ case CHANNEL_LAYOUT_HEXAGONAL:
+ return "HEXAGONAL";
+ case CHANNEL_LAYOUT_6_1:
+ return "6.1";
+ case CHANNEL_LAYOUT_6_1_BACK:
+ return "6.1_BACK";
+ case CHANNEL_LAYOUT_6_1_FRONT:
+ return "6.1_FRONT";
+ case CHANNEL_LAYOUT_7_0_FRONT:
+ return "7.0_FRONT";
+ case CHANNEL_LAYOUT_7_1_WIDE_BACK:
+ return "7.1_WIDE_BACK";
+ case CHANNEL_LAYOUT_OCTAGONAL:
+ return "OCTAGONAL";
+ case CHANNEL_LAYOUT_DISCRETE:
+ return "DISCRETE";
+ case CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC:
+ return "STEREO_AND_KEYBOARD_MIC";
+ case CHANNEL_LAYOUT_4_1_QUAD_SIDE:
+ return "4.1_QUAD_SIDE";
+ case CHANNEL_LAYOUT_BITSTREAM:
+ return "BITSTREAM";
+ }
+ RTC_DCHECK_NOTREACHED() << "Invalid channel layout provided: " << layout;
+ return "";
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio/channel_layout.h b/third_party/libwebrtc/api/audio/channel_layout.h
new file mode 100644
index 0000000000..175aee71e5
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/channel_layout.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CHANNEL_LAYOUT_H_
+#define API_AUDIO_CHANNEL_LAYOUT_H_
+
+namespace webrtc {
+
+// This file is derived from Chromium's base/channel_layout.h.
+
+// Enumerates the various representations of the ordering of audio channels.
+// Logged to UMA, so never reuse a value, always add new/greater ones!
+enum ChannelLayout {
+ CHANNEL_LAYOUT_NONE = 0,
+ CHANNEL_LAYOUT_UNSUPPORTED = 1,
+
+ // Front C
+ CHANNEL_LAYOUT_MONO = 2,
+
+ // Front L, Front R
+ CHANNEL_LAYOUT_STEREO = 3,
+
+ // Front L, Front R, Back C
+ CHANNEL_LAYOUT_2_1 = 4,
+
+ // Front L, Front R, Front C
+ CHANNEL_LAYOUT_SURROUND = 5,
+
+ // Front L, Front R, Front C, Back C
+ CHANNEL_LAYOUT_4_0 = 6,
+
+ // Front L, Front R, Side L, Side R
+ CHANNEL_LAYOUT_2_2 = 7,
+
+ // Front L, Front R, Back L, Back R
+ CHANNEL_LAYOUT_QUAD = 8,
+
+ // Front L, Front R, Front C, Side L, Side R
+ CHANNEL_LAYOUT_5_0 = 9,
+
+ // Front L, Front R, Front C, LFE, Side L, Side R
+ CHANNEL_LAYOUT_5_1 = 10,
+
+ // Front L, Front R, Front C, Back L, Back R
+ CHANNEL_LAYOUT_5_0_BACK = 11,
+
+ // Front L, Front R, Front C, LFE, Back L, Back R
+ CHANNEL_LAYOUT_5_1_BACK = 12,
+
+ // Front L, Front R, Front C, Side L, Side R, Back L, Back R
+ CHANNEL_LAYOUT_7_0 = 13,
+
+ // Front L, Front R, Front C, LFE, Side L, Side R, Back L, Back R
+ CHANNEL_LAYOUT_7_1 = 14,
+
+ // Front L, Front R, Front C, LFE, Side L, Side R, Front LofC, Front RofC
+ CHANNEL_LAYOUT_7_1_WIDE = 15,
+
+ // Stereo L, Stereo R
+ CHANNEL_LAYOUT_STEREO_DOWNMIX = 16,
+
+ // Stereo L, Stereo R, LFE
+ CHANNEL_LAYOUT_2POINT1 = 17,
+
+ // Stereo L, Stereo R, Front C, LFE
+ CHANNEL_LAYOUT_3_1 = 18,
+
+ // Stereo L, Stereo R, Front C, Rear C, LFE
+ CHANNEL_LAYOUT_4_1 = 19,
+
+ // Stereo L, Stereo R, Front C, Side L, Side R, Back C
+ CHANNEL_LAYOUT_6_0 = 20,
+
+ // Stereo L, Stereo R, Side L, Side R, Front LofC, Front RofC
+ CHANNEL_LAYOUT_6_0_FRONT = 21,
+
+ // Stereo L, Stereo R, Front C, Rear L, Rear R, Rear C
+ CHANNEL_LAYOUT_HEXAGONAL = 22,
+
+ // Stereo L, Stereo R, Front C, LFE, Side L, Side R, Rear Center
+ CHANNEL_LAYOUT_6_1 = 23,
+
+ // Stereo L, Stereo R, Front C, LFE, Back L, Back R, Rear Center
+ CHANNEL_LAYOUT_6_1_BACK = 24,
+
+ // Stereo L, Stereo R, Side L, Side R, Front LofC, Front RofC, LFE
+ CHANNEL_LAYOUT_6_1_FRONT = 25,
+
+ // Front L, Front R, Front C, Side L, Side R, Front LofC, Front RofC
+ CHANNEL_LAYOUT_7_0_FRONT = 26,
+
+ // Front L, Front R, Front C, LFE, Back L, Back R, Front LofC, Front RofC
+ CHANNEL_LAYOUT_7_1_WIDE_BACK = 27,
+
+ // Front L, Front R, Front C, Side L, Side R, Rear L, Back R, Back C.
+ CHANNEL_LAYOUT_OCTAGONAL = 28,
+
+ // Channels are not explicitly mapped to speakers.
+ CHANNEL_LAYOUT_DISCRETE = 29,
+
+ // Front L, Front R, Front C. Front C contains the keyboard mic audio. This
+ // layout is only intended for input for WebRTC. The Front C channel
+ // is stripped away in the WebRTC audio input pipeline and never seen outside
+ // of that.
+ CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC = 30,
+
+ // Front L, Front R, Side L, Side R, LFE
+ CHANNEL_LAYOUT_4_1_QUAD_SIDE = 31,
+
+ // Actual channel layout is specified in the bitstream and the actual channel
+ // count is unknown at Chromium media pipeline level (useful for audio
+ // pass-through mode).
+ CHANNEL_LAYOUT_BITSTREAM = 32,
+
+ // Max value, must always equal the largest entry ever logged.
+ CHANNEL_LAYOUT_MAX = CHANNEL_LAYOUT_BITSTREAM
+};
+
+// Note: Do not reorder or reassign these values; other code depends on their
+// ordering to operate correctly. E.g., CoreAudio channel layout computations.
+enum Channels {
+ LEFT = 0,
+ RIGHT,
+ CENTER,
+ LFE,
+ BACK_LEFT,
+ BACK_RIGHT,
+ LEFT_OF_CENTER,
+ RIGHT_OF_CENTER,
+ BACK_CENTER,
+ SIDE_LEFT,
+ SIDE_RIGHT,
+ CHANNELS_MAX =
+ SIDE_RIGHT, // Must always equal the largest value ever logged.
+};
+
+// The maximum number of concurrently active channels for all possible layouts.
+// ChannelLayoutToChannelCount() will never return a value higher than this.
+constexpr int kMaxConcurrentChannels = 8;
+
+// Returns the expected channel position in an interleaved stream. Values of -1
+// mean the channel at that index is not used for that layout. Values range
+// from 0 to ChannelLayoutToChannelCount(layout) - 1.
+int ChannelOrder(ChannelLayout layout, Channels channel);
+
+// Returns the number of channels in a given ChannelLayout.
+int ChannelLayoutToChannelCount(ChannelLayout layout);
+
+// Given the number of channels, return the best layout,
+// or return CHANNEL_LAYOUT_UNSUPPORTED if there is no good match.
+ChannelLayout GuessChannelLayout(int channels);
+
+// Returns a string representation of the channel layout.
+const char* ChannelLayoutToString(ChannelLayout layout);
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CHANNEL_LAYOUT_H_
diff --git a/third_party/libwebrtc/api/audio/echo_canceller3_config.cc b/third_party/libwebrtc/api/audio/echo_canceller3_config.cc
new file mode 100644
index 0000000000..0224c712b4
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/echo_canceller3_config.cc
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/audio/echo_canceller3_config.h"
+
+#include <algorithm>
+#include <cmath>
+
+#include "rtc_base/checks.h"
+#include "rtc_base/numerics/safe_minmax.h"
+
+namespace webrtc {
+namespace {
+bool Limit(float* value, float min, float max) {
+ float clamped = rtc::SafeClamp(*value, min, max);
+ clamped = std::isfinite(clamped) ? clamped : min;
+ bool res = *value == clamped;
+ *value = clamped;
+ return res;
+}
+
+bool Limit(size_t* value, size_t min, size_t max) {
+ size_t clamped = rtc::SafeClamp(*value, min, max);
+ bool res = *value == clamped;
+ *value = clamped;
+ return res;
+}
+
+bool Limit(int* value, int min, int max) {
+ int clamped = rtc::SafeClamp(*value, min, max);
+ bool res = *value == clamped;
+ *value = clamped;
+ return res;
+}
+
+bool FloorLimit(size_t* value, size_t min) {
+ size_t clamped = *value >= min ? *value : min;
+ bool res = *value == clamped;
+ *value = clamped;
+ return res;
+}
+
+} // namespace
+
+EchoCanceller3Config::EchoCanceller3Config() = default;
+EchoCanceller3Config::EchoCanceller3Config(const EchoCanceller3Config& e) =
+ default;
+EchoCanceller3Config& EchoCanceller3Config::operator=(
+ const EchoCanceller3Config& e) = default;
+EchoCanceller3Config::Delay::Delay() = default;
+EchoCanceller3Config::Delay::Delay(const EchoCanceller3Config::Delay& e) =
+ default;
+EchoCanceller3Config::Delay& EchoCanceller3Config::Delay::operator=(
+ const Delay& e) = default;
+
+EchoCanceller3Config::EchoModel::EchoModel() = default;
+EchoCanceller3Config::EchoModel::EchoModel(
+ const EchoCanceller3Config::EchoModel& e) = default;
+EchoCanceller3Config::EchoModel& EchoCanceller3Config::EchoModel::operator=(
+ const EchoModel& e) = default;
+
+EchoCanceller3Config::Suppressor::Suppressor() = default;
+EchoCanceller3Config::Suppressor::Suppressor(
+ const EchoCanceller3Config::Suppressor& e) = default;
+EchoCanceller3Config::Suppressor& EchoCanceller3Config::Suppressor::operator=(
+ const Suppressor& e) = default;
+
+EchoCanceller3Config::Suppressor::MaskingThresholds::MaskingThresholds(
+ float enr_transparent,
+ float enr_suppress,
+ float emr_transparent)
+ : enr_transparent(enr_transparent),
+ enr_suppress(enr_suppress),
+ emr_transparent(emr_transparent) {}
+EchoCanceller3Config::Suppressor::MaskingThresholds::MaskingThresholds(
+ const EchoCanceller3Config::Suppressor::MaskingThresholds& e) = default;
+EchoCanceller3Config::Suppressor::MaskingThresholds&
+EchoCanceller3Config::Suppressor::MaskingThresholds::operator=(
+ const MaskingThresholds& e) = default;
+
+EchoCanceller3Config::Suppressor::Tuning::Tuning(MaskingThresholds mask_lf,
+ MaskingThresholds mask_hf,
+ float max_inc_factor,
+ float max_dec_factor_lf)
+ : mask_lf(mask_lf),
+ mask_hf(mask_hf),
+ max_inc_factor(max_inc_factor),
+ max_dec_factor_lf(max_dec_factor_lf) {}
+EchoCanceller3Config::Suppressor::Tuning::Tuning(
+ const EchoCanceller3Config::Suppressor::Tuning& e) = default;
+EchoCanceller3Config::Suppressor::Tuning&
+EchoCanceller3Config::Suppressor::Tuning::operator=(const Tuning& e) = default;
+
+bool EchoCanceller3Config::Validate(EchoCanceller3Config* config) {
+ RTC_DCHECK(config);
+ EchoCanceller3Config* c = config;
+ bool res = true;
+
+ if (c->delay.down_sampling_factor != 4 &&
+ c->delay.down_sampling_factor != 8) {
+ c->delay.down_sampling_factor = 4;
+ res = false;
+ }
+
+ res = res & Limit(&c->delay.default_delay, 0, 5000);
+ res = res & Limit(&c->delay.num_filters, 0, 5000);
+ res = res & Limit(&c->delay.delay_headroom_samples, 0, 5000);
+ res = res & Limit(&c->delay.hysteresis_limit_blocks, 0, 5000);
+ res = res & Limit(&c->delay.fixed_capture_delay_samples, 0, 5000);
+ res = res & Limit(&c->delay.delay_estimate_smoothing, 0.f, 1.f);
+ res = res & Limit(&c->delay.delay_candidate_detection_threshold, 0.f, 1.f);
+ res = res & Limit(&c->delay.delay_selection_thresholds.initial, 1, 250);
+ res = res & Limit(&c->delay.delay_selection_thresholds.converged, 1, 250);
+
+ res = res & FloorLimit(&c->filter.refined.length_blocks, 1);
+ res = res & Limit(&c->filter.refined.leakage_converged, 0.f, 1000.f);
+ res = res & Limit(&c->filter.refined.leakage_diverged, 0.f, 1000.f);
+ res = res & Limit(&c->filter.refined.error_floor, 0.f, 1000.f);
+ res = res & Limit(&c->filter.refined.error_ceil, 0.f, 100000000.f);
+ res = res & Limit(&c->filter.refined.noise_gate, 0.f, 100000000.f);
+
+ res = res & FloorLimit(&c->filter.refined_initial.length_blocks, 1);
+ res = res & Limit(&c->filter.refined_initial.leakage_converged, 0.f, 1000.f);
+ res = res & Limit(&c->filter.refined_initial.leakage_diverged, 0.f, 1000.f);
+ res = res & Limit(&c->filter.refined_initial.error_floor, 0.f, 1000.f);
+ res = res & Limit(&c->filter.refined_initial.error_ceil, 0.f, 100000000.f);
+ res = res & Limit(&c->filter.refined_initial.noise_gate, 0.f, 100000000.f);
+
+ if (c->filter.refined.length_blocks <
+ c->filter.refined_initial.length_blocks) {
+ c->filter.refined_initial.length_blocks = c->filter.refined.length_blocks;
+ res = false;
+ }
+
+ res = res & FloorLimit(&c->filter.coarse.length_blocks, 1);
+ res = res & Limit(&c->filter.coarse.rate, 0.f, 1.f);
+ res = res & Limit(&c->filter.coarse.noise_gate, 0.f, 100000000.f);
+
+ res = res & FloorLimit(&c->filter.coarse_initial.length_blocks, 1);
+ res = res & Limit(&c->filter.coarse_initial.rate, 0.f, 1.f);
+ res = res & Limit(&c->filter.coarse_initial.noise_gate, 0.f, 100000000.f);
+
+ if (c->filter.coarse.length_blocks < c->filter.coarse_initial.length_blocks) {
+ c->filter.coarse_initial.length_blocks = c->filter.coarse.length_blocks;
+ res = false;
+ }
+
+ res = res & Limit(&c->filter.config_change_duration_blocks, 0, 100000);
+ res = res & Limit(&c->filter.initial_state_seconds, 0.f, 100.f);
+ res = res & Limit(&c->filter.coarse_reset_hangover_blocks, 0, 250000);
+
+ res = res & Limit(&c->erle.min, 1.f, 100000.f);
+ res = res & Limit(&c->erle.max_l, 1.f, 100000.f);
+ res = res & Limit(&c->erle.max_h, 1.f, 100000.f);
+ if (c->erle.min > c->erle.max_l || c->erle.min > c->erle.max_h) {
+ c->erle.min = std::min(c->erle.max_l, c->erle.max_h);
+ res = false;
+ }
+ res = res & Limit(&c->erle.num_sections, 1, c->filter.refined.length_blocks);
+
+ res = res & Limit(&c->ep_strength.default_gain, 0.f, 1000000.f);
+ res = res & Limit(&c->ep_strength.default_len, -1.f, 1.f);
+ res = res & Limit(&c->ep_strength.nearend_len, -1.0f, 1.0f);
+
+ res =
+ res & Limit(&c->echo_audibility.low_render_limit, 0.f, 32768.f * 32768.f);
+ res = res &
+ Limit(&c->echo_audibility.normal_render_limit, 0.f, 32768.f * 32768.f);
+ res = res & Limit(&c->echo_audibility.floor_power, 0.f, 32768.f * 32768.f);
+ res = res & Limit(&c->echo_audibility.audibility_threshold_lf, 0.f,
+ 32768.f * 32768.f);
+ res = res & Limit(&c->echo_audibility.audibility_threshold_mf, 0.f,
+ 32768.f * 32768.f);
+ res = res & Limit(&c->echo_audibility.audibility_threshold_hf, 0.f,
+ 32768.f * 32768.f);
+
+ res = res &
+ Limit(&c->render_levels.active_render_limit, 0.f, 32768.f * 32768.f);
+ res = res & Limit(&c->render_levels.poor_excitation_render_limit, 0.f,
+ 32768.f * 32768.f);
+ res = res & Limit(&c->render_levels.poor_excitation_render_limit_ds8, 0.f,
+ 32768.f * 32768.f);
+
+ res = res & Limit(&c->echo_model.noise_floor_hold, 0, 1000);
+ res = res & Limit(&c->echo_model.min_noise_floor_power, 0, 2000000.f);
+ res = res & Limit(&c->echo_model.stationary_gate_slope, 0, 1000000.f);
+ res = res & Limit(&c->echo_model.noise_gate_power, 0, 1000000.f);
+ res = res & Limit(&c->echo_model.noise_gate_slope, 0, 1000000.f);
+ res = res & Limit(&c->echo_model.render_pre_window_size, 0, 100);
+ res = res & Limit(&c->echo_model.render_post_window_size, 0, 100);
+
+ res = res & Limit(&c->comfort_noise.noise_floor_dbfs, -200.f, 0.f);
+
+ res = res & Limit(&c->suppressor.nearend_average_blocks, 1, 5000);
+
+ res = res &
+ Limit(&c->suppressor.normal_tuning.mask_lf.enr_transparent, 0.f, 100.f);
+ res = res &
+ Limit(&c->suppressor.normal_tuning.mask_lf.enr_suppress, 0.f, 100.f);
+ res = res &
+ Limit(&c->suppressor.normal_tuning.mask_lf.emr_transparent, 0.f, 100.f);
+ res = res &
+ Limit(&c->suppressor.normal_tuning.mask_hf.enr_transparent, 0.f, 100.f);
+ res = res &
+ Limit(&c->suppressor.normal_tuning.mask_hf.enr_suppress, 0.f, 100.f);
+ res = res &
+ Limit(&c->suppressor.normal_tuning.mask_hf.emr_transparent, 0.f, 100.f);
+ res = res & Limit(&c->suppressor.normal_tuning.max_inc_factor, 0.f, 100.f);
+ res = res & Limit(&c->suppressor.normal_tuning.max_dec_factor_lf, 0.f, 100.f);
+
+ res = res & Limit(&c->suppressor.nearend_tuning.mask_lf.enr_transparent, 0.f,
+ 100.f);
+ res = res &
+ Limit(&c->suppressor.nearend_tuning.mask_lf.enr_suppress, 0.f, 100.f);
+ res = res & Limit(&c->suppressor.nearend_tuning.mask_lf.emr_transparent, 0.f,
+ 100.f);
+ res = res & Limit(&c->suppressor.nearend_tuning.mask_hf.enr_transparent, 0.f,
+ 100.f);
+ res = res &
+ Limit(&c->suppressor.nearend_tuning.mask_hf.enr_suppress, 0.f, 100.f);
+ res = res & Limit(&c->suppressor.nearend_tuning.mask_hf.emr_transparent, 0.f,
+ 100.f);
+ res = res & Limit(&c->suppressor.nearend_tuning.max_inc_factor, 0.f, 100.f);
+ res =
+ res & Limit(&c->suppressor.nearend_tuning.max_dec_factor_lf, 0.f, 100.f);
+
+ res = res & Limit(&c->suppressor.last_permanent_lf_smoothing_band, 0, 64);
+ res = res & Limit(&c->suppressor.last_lf_smoothing_band, 0, 64);
+ res = res & Limit(&c->suppressor.last_lf_band, 0, 63);
+ res = res &
+ Limit(&c->suppressor.first_hf_band, c->suppressor.last_lf_band + 1, 64);
+
+ res = res & Limit(&c->suppressor.dominant_nearend_detection.enr_threshold,
+ 0.f, 1000000.f);
+ res = res & Limit(&c->suppressor.dominant_nearend_detection.snr_threshold,
+ 0.f, 1000000.f);
+ res = res & Limit(&c->suppressor.dominant_nearend_detection.hold_duration, 0,
+ 10000);
+ res = res & Limit(&c->suppressor.dominant_nearend_detection.trigger_threshold,
+ 0, 10000);
+
+ res = res &
+ Limit(&c->suppressor.subband_nearend_detection.nearend_average_blocks,
+ 1, 1024);
+ res =
+ res & Limit(&c->suppressor.subband_nearend_detection.subband1.low, 0, 65);
+ res = res & Limit(&c->suppressor.subband_nearend_detection.subband1.high,
+ c->suppressor.subband_nearend_detection.subband1.low, 65);
+ res =
+ res & Limit(&c->suppressor.subband_nearend_detection.subband2.low, 0, 65);
+ res = res & Limit(&c->suppressor.subband_nearend_detection.subband2.high,
+ c->suppressor.subband_nearend_detection.subband2.low, 65);
+ res = res & Limit(&c->suppressor.subband_nearend_detection.nearend_threshold,
+ 0.f, 1.e24f);
+ res = res & Limit(&c->suppressor.subband_nearend_detection.snr_threshold, 0.f,
+ 1.e24f);
+
+ res = res & Limit(&c->suppressor.high_bands_suppression.enr_threshold, 0.f,
+ 1000000.f);
+ res = res & Limit(&c->suppressor.high_bands_suppression.max_gain_during_echo,
+ 0.f, 1.f);
+ res = res & Limit(&c->suppressor.high_bands_suppression
+ .anti_howling_activation_threshold,
+ 0.f, 32768.f * 32768.f);
+ res = res & Limit(&c->suppressor.high_bands_suppression.anti_howling_gain,
+ 0.f, 1.f);
+
+ res = res & Limit(&c->suppressor.floor_first_increase, 0.f, 1000000.f);
+
+ return res;
+}
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio/echo_canceller3_config.h b/third_party/libwebrtc/api/audio/echo_canceller3_config.h
new file mode 100644
index 0000000000..4b1c7fbc47
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/echo_canceller3_config.h
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_ECHO_CANCELLER3_CONFIG_H_
+#define API_AUDIO_ECHO_CANCELLER3_CONFIG_H_
+
+#include <stddef.h> // size_t
+
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Configuration struct for EchoCanceller3
+struct RTC_EXPORT EchoCanceller3Config {
+ // Checks and updates the config parameters to lie within (mostly) reasonable
+ // ranges. Returns true if and only of the config did not need to be changed.
+ static bool Validate(EchoCanceller3Config* config);
+
+ EchoCanceller3Config();
+ EchoCanceller3Config(const EchoCanceller3Config& e);
+ EchoCanceller3Config& operator=(const EchoCanceller3Config& other);
+
+ struct Buffering {
+ size_t excess_render_detection_interval_blocks = 250;
+ size_t max_allowed_excess_render_blocks = 8;
+ } buffering;
+
+ struct Delay {
+ Delay();
+ Delay(const Delay& e);
+ Delay& operator=(const Delay& e);
+ size_t default_delay = 5;
+ size_t down_sampling_factor = 4;
+ size_t num_filters = 5;
+ size_t delay_headroom_samples = 32;
+ size_t hysteresis_limit_blocks = 1;
+ size_t fixed_capture_delay_samples = 0;
+ float delay_estimate_smoothing = 0.7f;
+ float delay_estimate_smoothing_delay_found = 0.7f;
+ float delay_candidate_detection_threshold = 0.2f;
+ struct DelaySelectionThresholds {
+ int initial;
+ int converged;
+ } delay_selection_thresholds = {5, 20};
+ bool use_external_delay_estimator = false;
+ bool log_warning_on_delay_changes = false;
+ struct AlignmentMixing {
+ bool downmix;
+ bool adaptive_selection;
+ float activity_power_threshold;
+ bool prefer_first_two_channels;
+ };
+ AlignmentMixing render_alignment_mixing = {false, true, 10000.f, true};
+ AlignmentMixing capture_alignment_mixing = {false, true, 10000.f, false};
+ bool detect_pre_echo = true;
+ } delay;
+
+ struct Filter {
+ struct RefinedConfiguration {
+ size_t length_blocks;
+ float leakage_converged;
+ float leakage_diverged;
+ float error_floor;
+ float error_ceil;
+ float noise_gate;
+ };
+
+ struct CoarseConfiguration {
+ size_t length_blocks;
+ float rate;
+ float noise_gate;
+ };
+
+ RefinedConfiguration refined = {13, 0.00005f, 0.05f,
+ 0.001f, 2.f, 20075344.f};
+ CoarseConfiguration coarse = {13, 0.7f, 20075344.f};
+
+ RefinedConfiguration refined_initial = {12, 0.005f, 0.5f,
+ 0.001f, 2.f, 20075344.f};
+ CoarseConfiguration coarse_initial = {12, 0.9f, 20075344.f};
+
+ size_t config_change_duration_blocks = 250;
+ float initial_state_seconds = 2.5f;
+ int coarse_reset_hangover_blocks = 25;
+ bool conservative_initial_phase = false;
+ bool enable_coarse_filter_output_usage = true;
+ bool use_linear_filter = true;
+ bool high_pass_filter_echo_reference = false;
+ bool export_linear_aec_output = false;
+ } filter;
+
+ struct Erle {
+ float min = 1.f;
+ float max_l = 4.f;
+ float max_h = 1.5f;
+ bool onset_detection = true;
+ size_t num_sections = 1;
+ bool clamp_quality_estimate_to_zero = true;
+ bool clamp_quality_estimate_to_one = true;
+ } erle;
+
+ struct EpStrength {
+ float default_gain = 1.f;
+ float default_len = 0.83f;
+ float nearend_len = 0.83f;
+ bool echo_can_saturate = true;
+ bool bounded_erl = false;
+ bool erle_onset_compensation_in_dominant_nearend = false;
+ bool use_conservative_tail_frequency_response = true;
+ } ep_strength;
+
+ struct EchoAudibility {
+ float low_render_limit = 4 * 64.f;
+ float normal_render_limit = 64.f;
+ float floor_power = 2 * 64.f;
+ float audibility_threshold_lf = 10;
+ float audibility_threshold_mf = 10;
+ float audibility_threshold_hf = 10;
+ bool use_stationarity_properties = false;
+ bool use_stationarity_properties_at_init = false;
+ } echo_audibility;
+
+ struct RenderLevels {
+ float active_render_limit = 100.f;
+ float poor_excitation_render_limit = 150.f;
+ float poor_excitation_render_limit_ds8 = 20.f;
+ float render_power_gain_db = 0.f;
+ } render_levels;
+
+ struct EchoRemovalControl {
+ bool has_clock_drift = false;
+ bool linear_and_stable_echo_path = false;
+ } echo_removal_control;
+
+ struct EchoModel {
+ EchoModel();
+ EchoModel(const EchoModel& e);
+ EchoModel& operator=(const EchoModel& e);
+ size_t noise_floor_hold = 50;
+ float min_noise_floor_power = 1638400.f;
+ float stationary_gate_slope = 10.f;
+ float noise_gate_power = 27509.42f;
+ float noise_gate_slope = 0.3f;
+ size_t render_pre_window_size = 1;
+ size_t render_post_window_size = 1;
+ bool model_reverb_in_nonlinear_mode = true;
+ } echo_model;
+
+ struct ComfortNoise {
+ float noise_floor_dbfs = -96.03406f;
+ } comfort_noise;
+
+ struct Suppressor {
+ Suppressor();
+ Suppressor(const Suppressor& e);
+ Suppressor& operator=(const Suppressor& e);
+
+ size_t nearend_average_blocks = 4;
+
+ struct MaskingThresholds {
+ MaskingThresholds(float enr_transparent,
+ float enr_suppress,
+ float emr_transparent);
+ MaskingThresholds(const MaskingThresholds& e);
+ MaskingThresholds& operator=(const MaskingThresholds& e);
+ float enr_transparent;
+ float enr_suppress;
+ float emr_transparent;
+ };
+
+ struct Tuning {
+ Tuning(MaskingThresholds mask_lf,
+ MaskingThresholds mask_hf,
+ float max_inc_factor,
+ float max_dec_factor_lf);
+ Tuning(const Tuning& e);
+ Tuning& operator=(const Tuning& e);
+ MaskingThresholds mask_lf;
+ MaskingThresholds mask_hf;
+ float max_inc_factor;
+ float max_dec_factor_lf;
+ };
+
+ Tuning normal_tuning = Tuning(MaskingThresholds(.3f, .4f, .3f),
+ MaskingThresholds(.07f, .1f, .3f),
+ 2.0f,
+ 0.25f);
+ Tuning nearend_tuning = Tuning(MaskingThresholds(1.09f, 1.1f, .3f),
+ MaskingThresholds(.1f, .3f, .3f),
+ 2.0f,
+ 0.25f);
+
+ bool lf_smoothing_during_initial_phase = true;
+ int last_permanent_lf_smoothing_band = 0;
+ int last_lf_smoothing_band = 5;
+ int last_lf_band = 5;
+ int first_hf_band = 8;
+
+ struct DominantNearendDetection {
+ float enr_threshold = .25f;
+ float enr_exit_threshold = 10.f;
+ float snr_threshold = 30.f;
+ int hold_duration = 50;
+ int trigger_threshold = 12;
+ bool use_during_initial_phase = true;
+ bool use_unbounded_echo_spectrum = true;
+ } dominant_nearend_detection;
+
+ struct SubbandNearendDetection {
+ size_t nearend_average_blocks = 1;
+ struct SubbandRegion {
+ size_t low;
+ size_t high;
+ };
+ SubbandRegion subband1 = {1, 1};
+ SubbandRegion subband2 = {1, 1};
+ float nearend_threshold = 1.f;
+ float snr_threshold = 1.f;
+ } subband_nearend_detection;
+
+ bool use_subband_nearend_detection = false;
+
+ struct HighBandsSuppression {
+ float enr_threshold = 1.f;
+ float max_gain_during_echo = 1.f;
+ float anti_howling_activation_threshold = 400.f;
+ float anti_howling_gain = 1.f;
+ } high_bands_suppression;
+
+ float floor_first_increase = 0.00001f;
+ bool conservative_hf_suppression = false;
+ } suppressor;
+
+ struct MultiChannel {
+ bool detect_stereo_content = true;
+ float stereo_detection_threshold = 0.0f;
+ int stereo_detection_timeout_threshold_seconds = 300;
+ float stereo_detection_hysteresis_seconds = 2.0f;
+ } multi_channel;
+};
+} // namespace webrtc
+
+#endif // API_AUDIO_ECHO_CANCELLER3_CONFIG_H_
diff --git a/third_party/libwebrtc/api/audio/echo_canceller3_config_json.cc b/third_party/libwebrtc/api/audio/echo_canceller3_config_json.cc
new file mode 100644
index 0000000000..96e45ffe6d
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/echo_canceller3_config_json.cc
@@ -0,0 +1,772 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/audio/echo_canceller3_config_json.h"
+
+#include <stddef.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "rtc_base/checks.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/strings/json.h"
+#include "rtc_base/strings/string_builder.h"
+
+namespace webrtc {
+namespace {
+void ReadParam(const Json::Value& root, std::string param_name, bool* param) {
+ RTC_DCHECK(param);
+ bool v;
+ if (rtc::GetBoolFromJsonObject(root, param_name, &v)) {
+ *param = v;
+ }
+}
+
+void ReadParam(const Json::Value& root, std::string param_name, size_t* param) {
+ RTC_DCHECK(param);
+ int v;
+ if (rtc::GetIntFromJsonObject(root, param_name, &v) && v >= 0) {
+ *param = v;
+ }
+}
+
+void ReadParam(const Json::Value& root, std::string param_name, int* param) {
+ RTC_DCHECK(param);
+ int v;
+ if (rtc::GetIntFromJsonObject(root, param_name, &v)) {
+ *param = v;
+ }
+}
+
+void ReadParam(const Json::Value& root, std::string param_name, float* param) {
+ RTC_DCHECK(param);
+ double v;
+ if (rtc::GetDoubleFromJsonObject(root, param_name, &v)) {
+ *param = static_cast<float>(v);
+ }
+}
+
+void ReadParam(const Json::Value& root,
+ std::string param_name,
+ EchoCanceller3Config::Filter::RefinedConfiguration* param) {
+ RTC_DCHECK(param);
+ Json::Value json_array;
+ if (rtc::GetValueFromJsonObject(root, param_name, &json_array)) {
+ std::vector<double> v;
+ rtc::JsonArrayToDoubleVector(json_array, &v);
+ if (v.size() != 6) {
+ RTC_LOG(LS_ERROR) << "Incorrect array size for " << param_name;
+ return;
+ }
+ param->length_blocks = static_cast<size_t>(v[0]);
+ param->leakage_converged = static_cast<float>(v[1]);
+ param->leakage_diverged = static_cast<float>(v[2]);
+ param->error_floor = static_cast<float>(v[3]);
+ param->error_ceil = static_cast<float>(v[4]);
+ param->noise_gate = static_cast<float>(v[5]);
+ }
+}
+
+void ReadParam(const Json::Value& root,
+ std::string param_name,
+ EchoCanceller3Config::Filter::CoarseConfiguration* param) {
+ RTC_DCHECK(param);
+ Json::Value json_array;
+ if (rtc::GetValueFromJsonObject(root, param_name, &json_array)) {
+ std::vector<double> v;
+ rtc::JsonArrayToDoubleVector(json_array, &v);
+ if (v.size() != 3) {
+ RTC_LOG(LS_ERROR) << "Incorrect array size for " << param_name;
+ return;
+ }
+ param->length_blocks = static_cast<size_t>(v[0]);
+ param->rate = static_cast<float>(v[1]);
+ param->noise_gate = static_cast<float>(v[2]);
+ }
+}
+
+void ReadParam(const Json::Value& root,
+ std::string param_name,
+ EchoCanceller3Config::Delay::AlignmentMixing* param) {
+ RTC_DCHECK(param);
+
+ Json::Value subsection;
+ if (rtc::GetValueFromJsonObject(root, param_name, &subsection)) {
+ ReadParam(subsection, "downmix", &param->downmix);
+ ReadParam(subsection, "adaptive_selection", &param->adaptive_selection);
+ ReadParam(subsection, "activity_power_threshold",
+ &param->activity_power_threshold);
+ ReadParam(subsection, "prefer_first_two_channels",
+ &param->prefer_first_two_channels);
+ }
+}
+
+void ReadParam(
+ const Json::Value& root,
+ std::string param_name,
+ EchoCanceller3Config::Suppressor::SubbandNearendDetection::SubbandRegion*
+ param) {
+ RTC_DCHECK(param);
+ Json::Value json_array;
+ if (rtc::GetValueFromJsonObject(root, param_name, &json_array)) {
+ std::vector<int> v;
+ rtc::JsonArrayToIntVector(json_array, &v);
+ if (v.size() != 2) {
+ RTC_LOG(LS_ERROR) << "Incorrect array size for " << param_name;
+ return;
+ }
+ param->low = static_cast<size_t>(v[0]);
+ param->high = static_cast<size_t>(v[1]);
+ }
+}
+
+void ReadParam(const Json::Value& root,
+ std::string param_name,
+ EchoCanceller3Config::Suppressor::MaskingThresholds* param) {
+ RTC_DCHECK(param);
+ Json::Value json_array;
+ if (rtc::GetValueFromJsonObject(root, param_name, &json_array)) {
+ std::vector<double> v;
+ rtc::JsonArrayToDoubleVector(json_array, &v);
+ if (v.size() != 3) {
+ RTC_LOG(LS_ERROR) << "Incorrect array size for " << param_name;
+ return;
+ }
+ param->enr_transparent = static_cast<float>(v[0]);
+ param->enr_suppress = static_cast<float>(v[1]);
+ param->emr_transparent = static_cast<float>(v[2]);
+ }
+}
+} // namespace
+
+void Aec3ConfigFromJsonString(absl::string_view json_string,
+ EchoCanceller3Config* config,
+ bool* parsing_successful) {
+ RTC_DCHECK(config);
+ RTC_DCHECK(parsing_successful);
+ EchoCanceller3Config& cfg = *config;
+ cfg = EchoCanceller3Config();
+ *parsing_successful = true;
+
+ Json::Value root;
+ Json::CharReaderBuilder builder;
+ std::string error_message;
+ std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
+ bool success =
+ reader->parse(json_string.data(), json_string.data() + json_string.size(),
+ &root, &error_message);
+ if (!success) {
+ RTC_LOG(LS_ERROR) << "Incorrect JSON format: " << error_message;
+ *parsing_successful = false;
+ return;
+ }
+
+ Json::Value aec3_root;
+ success = rtc::GetValueFromJsonObject(root, "aec3", &aec3_root);
+ if (!success) {
+ RTC_LOG(LS_ERROR) << "Missing AEC3 config field: " << json_string;
+ *parsing_successful = false;
+ return;
+ }
+
+ Json::Value section;
+ if (rtc::GetValueFromJsonObject(aec3_root, "buffering", &section)) {
+ ReadParam(section, "excess_render_detection_interval_blocks",
+ &cfg.buffering.excess_render_detection_interval_blocks);
+ ReadParam(section, "max_allowed_excess_render_blocks",
+ &cfg.buffering.max_allowed_excess_render_blocks);
+ }
+
+ if (rtc::GetValueFromJsonObject(aec3_root, "delay", &section)) {
+ ReadParam(section, "default_delay", &cfg.delay.default_delay);
+ ReadParam(section, "down_sampling_factor", &cfg.delay.down_sampling_factor);
+ ReadParam(section, "num_filters", &cfg.delay.num_filters);
+ ReadParam(section, "delay_headroom_samples",
+ &cfg.delay.delay_headroom_samples);
+ ReadParam(section, "hysteresis_limit_blocks",
+ &cfg.delay.hysteresis_limit_blocks);
+ ReadParam(section, "fixed_capture_delay_samples",
+ &cfg.delay.fixed_capture_delay_samples);
+ ReadParam(section, "delay_estimate_smoothing",
+ &cfg.delay.delay_estimate_smoothing);
+ ReadParam(section, "delay_estimate_smoothing_delay_found",
+ &cfg.delay.delay_estimate_smoothing_delay_found);
+ ReadParam(section, "delay_candidate_detection_threshold",
+ &cfg.delay.delay_candidate_detection_threshold);
+
+ Json::Value subsection;
+ if (rtc::GetValueFromJsonObject(section, "delay_selection_thresholds",
+ &subsection)) {
+ ReadParam(subsection, "initial",
+ &cfg.delay.delay_selection_thresholds.initial);
+ ReadParam(subsection, "converged",
+ &cfg.delay.delay_selection_thresholds.converged);
+ }
+
+ ReadParam(section, "use_external_delay_estimator",
+ &cfg.delay.use_external_delay_estimator);
+ ReadParam(section, "log_warning_on_delay_changes",
+ &cfg.delay.log_warning_on_delay_changes);
+
+ ReadParam(section, "render_alignment_mixing",
+ &cfg.delay.render_alignment_mixing);
+ ReadParam(section, "capture_alignment_mixing",
+ &cfg.delay.capture_alignment_mixing);
+ ReadParam(section, "detect_pre_echo", &cfg.delay.detect_pre_echo);
+ }
+
+ if (rtc::GetValueFromJsonObject(aec3_root, "filter", &section)) {
+ ReadParam(section, "refined", &cfg.filter.refined);
+ ReadParam(section, "coarse", &cfg.filter.coarse);
+ ReadParam(section, "refined_initial", &cfg.filter.refined_initial);
+ ReadParam(section, "coarse_initial", &cfg.filter.coarse_initial);
+ ReadParam(section, "config_change_duration_blocks",
+ &cfg.filter.config_change_duration_blocks);
+ ReadParam(section, "initial_state_seconds",
+ &cfg.filter.initial_state_seconds);
+ ReadParam(section, "coarse_reset_hangover_blocks",
+ &cfg.filter.coarse_reset_hangover_blocks);
+ ReadParam(section, "conservative_initial_phase",
+ &cfg.filter.conservative_initial_phase);
+ ReadParam(section, "enable_coarse_filter_output_usage",
+ &cfg.filter.enable_coarse_filter_output_usage);
+ ReadParam(section, "use_linear_filter", &cfg.filter.use_linear_filter);
+ ReadParam(section, "high_pass_filter_echo_reference",
+ &cfg.filter.high_pass_filter_echo_reference);
+ ReadParam(section, "export_linear_aec_output",
+ &cfg.filter.export_linear_aec_output);
+ }
+
+ if (rtc::GetValueFromJsonObject(aec3_root, "erle", &section)) {
+ ReadParam(section, "min", &cfg.erle.min);
+ ReadParam(section, "max_l", &cfg.erle.max_l);
+ ReadParam(section, "max_h", &cfg.erle.max_h);
+ ReadParam(section, "onset_detection", &cfg.erle.onset_detection);
+ ReadParam(section, "num_sections", &cfg.erle.num_sections);
+ ReadParam(section, "clamp_quality_estimate_to_zero",
+ &cfg.erle.clamp_quality_estimate_to_zero);
+ ReadParam(section, "clamp_quality_estimate_to_one",
+ &cfg.erle.clamp_quality_estimate_to_one);
+ }
+
+ if (rtc::GetValueFromJsonObject(aec3_root, "ep_strength", &section)) {
+ ReadParam(section, "default_gain", &cfg.ep_strength.default_gain);
+ ReadParam(section, "default_len", &cfg.ep_strength.default_len);
+ ReadParam(section, "nearend_len", &cfg.ep_strength.nearend_len);
+ ReadParam(section, "echo_can_saturate", &cfg.ep_strength.echo_can_saturate);
+ ReadParam(section, "bounded_erl", &cfg.ep_strength.bounded_erl);
+ ReadParam(section, "erle_onset_compensation_in_dominant_nearend",
+ &cfg.ep_strength.erle_onset_compensation_in_dominant_nearend);
+ ReadParam(section, "use_conservative_tail_frequency_response",
+ &cfg.ep_strength.use_conservative_tail_frequency_response);
+ }
+
+ if (rtc::GetValueFromJsonObject(aec3_root, "echo_audibility", &section)) {
+ ReadParam(section, "low_render_limit",
+ &cfg.echo_audibility.low_render_limit);
+ ReadParam(section, "normal_render_limit",
+ &cfg.echo_audibility.normal_render_limit);
+
+ ReadParam(section, "floor_power", &cfg.echo_audibility.floor_power);
+ ReadParam(section, "audibility_threshold_lf",
+ &cfg.echo_audibility.audibility_threshold_lf);
+ ReadParam(section, "audibility_threshold_mf",
+ &cfg.echo_audibility.audibility_threshold_mf);
+ ReadParam(section, "audibility_threshold_hf",
+ &cfg.echo_audibility.audibility_threshold_hf);
+ ReadParam(section, "use_stationarity_properties",
+ &cfg.echo_audibility.use_stationarity_properties);
+ ReadParam(section, "use_stationarity_properties_at_init",
+ &cfg.echo_audibility.use_stationarity_properties_at_init);
+ }
+
+ if (rtc::GetValueFromJsonObject(aec3_root, "render_levels", &section)) {
+ ReadParam(section, "active_render_limit",
+ &cfg.render_levels.active_render_limit);
+ ReadParam(section, "poor_excitation_render_limit",
+ &cfg.render_levels.poor_excitation_render_limit);
+ ReadParam(section, "poor_excitation_render_limit_ds8",
+ &cfg.render_levels.poor_excitation_render_limit_ds8);
+ ReadParam(section, "render_power_gain_db",
+ &cfg.render_levels.render_power_gain_db);
+ }
+
+ if (rtc::GetValueFromJsonObject(aec3_root, "echo_removal_control",
+ &section)) {
+ ReadParam(section, "has_clock_drift",
+ &cfg.echo_removal_control.has_clock_drift);
+ ReadParam(section, "linear_and_stable_echo_path",
+ &cfg.echo_removal_control.linear_and_stable_echo_path);
+ }
+
+ if (rtc::GetValueFromJsonObject(aec3_root, "echo_model", &section)) {
+ Json::Value subsection;
+ ReadParam(section, "noise_floor_hold", &cfg.echo_model.noise_floor_hold);
+ ReadParam(section, "min_noise_floor_power",
+ &cfg.echo_model.min_noise_floor_power);
+ ReadParam(section, "stationary_gate_slope",
+ &cfg.echo_model.stationary_gate_slope);
+ ReadParam(section, "noise_gate_power", &cfg.echo_model.noise_gate_power);
+ ReadParam(section, "noise_gate_slope", &cfg.echo_model.noise_gate_slope);
+ ReadParam(section, "render_pre_window_size",
+ &cfg.echo_model.render_pre_window_size);
+ ReadParam(section, "render_post_window_size",
+ &cfg.echo_model.render_post_window_size);
+ ReadParam(section, "model_reverb_in_nonlinear_mode",
+ &cfg.echo_model.model_reverb_in_nonlinear_mode);
+ }
+
+ if (rtc::GetValueFromJsonObject(aec3_root, "comfort_noise", &section)) {
+ ReadParam(section, "noise_floor_dbfs", &cfg.comfort_noise.noise_floor_dbfs);
+ }
+
+ Json::Value subsection;
+ if (rtc::GetValueFromJsonObject(aec3_root, "suppressor", &section)) {
+ ReadParam(section, "nearend_average_blocks",
+ &cfg.suppressor.nearend_average_blocks);
+
+ if (rtc::GetValueFromJsonObject(section, "normal_tuning", &subsection)) {
+ ReadParam(subsection, "mask_lf", &cfg.suppressor.normal_tuning.mask_lf);
+ ReadParam(subsection, "mask_hf", &cfg.suppressor.normal_tuning.mask_hf);
+ ReadParam(subsection, "max_inc_factor",
+ &cfg.suppressor.normal_tuning.max_inc_factor);
+ ReadParam(subsection, "max_dec_factor_lf",
+ &cfg.suppressor.normal_tuning.max_dec_factor_lf);
+ }
+
+ if (rtc::GetValueFromJsonObject(section, "nearend_tuning", &subsection)) {
+ ReadParam(subsection, "mask_lf", &cfg.suppressor.nearend_tuning.mask_lf);
+ ReadParam(subsection, "mask_hf", &cfg.suppressor.nearend_tuning.mask_hf);
+ ReadParam(subsection, "max_inc_factor",
+ &cfg.suppressor.nearend_tuning.max_inc_factor);
+ ReadParam(subsection, "max_dec_factor_lf",
+ &cfg.suppressor.nearend_tuning.max_dec_factor_lf);
+ }
+
+ ReadParam(section, "lf_smoothing_during_initial_phase",
+ &cfg.suppressor.lf_smoothing_during_initial_phase);
+ ReadParam(section, "last_permanent_lf_smoothing_band",
+ &cfg.suppressor.last_permanent_lf_smoothing_band);
+ ReadParam(section, "last_lf_smoothing_band",
+ &cfg.suppressor.last_lf_smoothing_band);
+ ReadParam(section, "last_lf_band", &cfg.suppressor.last_lf_band);
+ ReadParam(section, "first_hf_band", &cfg.suppressor.first_hf_band);
+
+ if (rtc::GetValueFromJsonObject(section, "dominant_nearend_detection",
+ &subsection)) {
+ ReadParam(subsection, "enr_threshold",
+ &cfg.suppressor.dominant_nearend_detection.enr_threshold);
+ ReadParam(subsection, "enr_exit_threshold",
+ &cfg.suppressor.dominant_nearend_detection.enr_exit_threshold);
+ ReadParam(subsection, "snr_threshold",
+ &cfg.suppressor.dominant_nearend_detection.snr_threshold);
+ ReadParam(subsection, "hold_duration",
+ &cfg.suppressor.dominant_nearend_detection.hold_duration);
+ ReadParam(subsection, "trigger_threshold",
+ &cfg.suppressor.dominant_nearend_detection.trigger_threshold);
+ ReadParam(
+ subsection, "use_during_initial_phase",
+ &cfg.suppressor.dominant_nearend_detection.use_during_initial_phase);
+ ReadParam(subsection, "use_unbounded_echo_spectrum",
+ &cfg.suppressor.dominant_nearend_detection
+ .use_unbounded_echo_spectrum);
+ }
+
+ if (rtc::GetValueFromJsonObject(section, "subband_nearend_detection",
+ &subsection)) {
+ ReadParam(
+ subsection, "nearend_average_blocks",
+ &cfg.suppressor.subband_nearend_detection.nearend_average_blocks);
+ ReadParam(subsection, "subband1",
+ &cfg.suppressor.subband_nearend_detection.subband1);
+ ReadParam(subsection, "subband2",
+ &cfg.suppressor.subband_nearend_detection.subband2);
+ ReadParam(subsection, "nearend_threshold",
+ &cfg.suppressor.subband_nearend_detection.nearend_threshold);
+ ReadParam(subsection, "snr_threshold",
+ &cfg.suppressor.subband_nearend_detection.snr_threshold);
+ }
+
+ ReadParam(section, "use_subband_nearend_detection",
+ &cfg.suppressor.use_subband_nearend_detection);
+
+ if (rtc::GetValueFromJsonObject(section, "high_bands_suppression",
+ &subsection)) {
+ ReadParam(subsection, "enr_threshold",
+ &cfg.suppressor.high_bands_suppression.enr_threshold);
+ ReadParam(subsection, "max_gain_during_echo",
+ &cfg.suppressor.high_bands_suppression.max_gain_during_echo);
+ ReadParam(subsection, "anti_howling_activation_threshold",
+ &cfg.suppressor.high_bands_suppression
+ .anti_howling_activation_threshold);
+ ReadParam(subsection, "anti_howling_gain",
+ &cfg.suppressor.high_bands_suppression.anti_howling_gain);
+ }
+
+ ReadParam(section, "floor_first_increase",
+ &cfg.suppressor.floor_first_increase);
+ ReadParam(section, "conservative_hf_suppression",
+ &cfg.suppressor.conservative_hf_suppression);
+ }
+
+ if (rtc::GetValueFromJsonObject(aec3_root, "multi_channel", &section)) {
+ ReadParam(section, "detect_stereo_content",
+ &cfg.multi_channel.detect_stereo_content);
+ ReadParam(section, "stereo_detection_threshold",
+ &cfg.multi_channel.stereo_detection_threshold);
+ ReadParam(section, "stereo_detection_timeout_threshold_seconds",
+ &cfg.multi_channel.stereo_detection_timeout_threshold_seconds);
+ ReadParam(section, "stereo_detection_hysteresis_seconds",
+ &cfg.multi_channel.stereo_detection_hysteresis_seconds);
+ }
+}
+
+EchoCanceller3Config Aec3ConfigFromJsonString(absl::string_view json_string) {
+ EchoCanceller3Config cfg;
+ bool not_used;
+ Aec3ConfigFromJsonString(json_string, &cfg, &not_used);
+ return cfg;
+}
+
+std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) {
+ rtc::StringBuilder ost;
+ ost << "{";
+ ost << "\"aec3\": {";
+ ost << "\"buffering\": {";
+ ost << "\"excess_render_detection_interval_blocks\": "
+ << config.buffering.excess_render_detection_interval_blocks << ",";
+ ost << "\"max_allowed_excess_render_blocks\": "
+ << config.buffering.max_allowed_excess_render_blocks;
+ ost << "},";
+
+ ost << "\"delay\": {";
+ ost << "\"default_delay\": " << config.delay.default_delay << ",";
+ ost << "\"down_sampling_factor\": " << config.delay.down_sampling_factor
+ << ",";
+ ost << "\"num_filters\": " << config.delay.num_filters << ",";
+ ost << "\"delay_headroom_samples\": " << config.delay.delay_headroom_samples
+ << ",";
+ ost << "\"hysteresis_limit_blocks\": " << config.delay.hysteresis_limit_blocks
+ << ",";
+ ost << "\"fixed_capture_delay_samples\": "
+ << config.delay.fixed_capture_delay_samples << ",";
+ ost << "\"delay_estimate_smoothing\": "
+ << config.delay.delay_estimate_smoothing << ",";
+ ost << "\"delay_estimate_smoothing_delay_found\": "
+ << config.delay.delay_estimate_smoothing_delay_found << ",";
+ ost << "\"delay_candidate_detection_threshold\": "
+ << config.delay.delay_candidate_detection_threshold << ",";
+
+ ost << "\"delay_selection_thresholds\": {";
+ ost << "\"initial\": " << config.delay.delay_selection_thresholds.initial
+ << ",";
+ ost << "\"converged\": " << config.delay.delay_selection_thresholds.converged;
+ ost << "},";
+
+ ost << "\"use_external_delay_estimator\": "
+ << (config.delay.use_external_delay_estimator ? "true" : "false") << ",";
+ ost << "\"log_warning_on_delay_changes\": "
+ << (config.delay.log_warning_on_delay_changes ? "true" : "false") << ",";
+
+ ost << "\"render_alignment_mixing\": {";
+ ost << "\"downmix\": "
+ << (config.delay.render_alignment_mixing.downmix ? "true" : "false")
+ << ",";
+ ost << "\"adaptive_selection\": "
+ << (config.delay.render_alignment_mixing.adaptive_selection ? "true"
+ : "false")
+ << ",";
+ ost << "\"activity_power_threshold\": "
+ << config.delay.render_alignment_mixing.activity_power_threshold << ",";
+ ost << "\"prefer_first_two_channels\": "
+ << (config.delay.render_alignment_mixing.prefer_first_two_channels
+ ? "true"
+ : "false");
+ ost << "},";
+
+ ost << "\"capture_alignment_mixing\": {";
+ ost << "\"downmix\": "
+ << (config.delay.capture_alignment_mixing.downmix ? "true" : "false")
+ << ",";
+ ost << "\"adaptive_selection\": "
+ << (config.delay.capture_alignment_mixing.adaptive_selection ? "true"
+ : "false")
+ << ",";
+ ost << "\"activity_power_threshold\": "
+ << config.delay.capture_alignment_mixing.activity_power_threshold << ",";
+ ost << "\"prefer_first_two_channels\": "
+ << (config.delay.capture_alignment_mixing.prefer_first_two_channels
+ ? "true"
+ : "false");
+ ost << "},";
+ ost << "\"detect_pre_echo\": "
+ << (config.delay.detect_pre_echo ? "true" : "false");
+ ost << "},";
+
+ ost << "\"filter\": {";
+
+ ost << "\"refined\": [";
+ ost << config.filter.refined.length_blocks << ",";
+ ost << config.filter.refined.leakage_converged << ",";
+ ost << config.filter.refined.leakage_diverged << ",";
+ ost << config.filter.refined.error_floor << ",";
+ ost << config.filter.refined.error_ceil << ",";
+ ost << config.filter.refined.noise_gate;
+ ost << "],";
+
+ ost << "\"coarse\": [";
+ ost << config.filter.coarse.length_blocks << ",";
+ ost << config.filter.coarse.rate << ",";
+ ost << config.filter.coarse.noise_gate;
+ ost << "],";
+
+ ost << "\"refined_initial\": [";
+ ost << config.filter.refined_initial.length_blocks << ",";
+ ost << config.filter.refined_initial.leakage_converged << ",";
+ ost << config.filter.refined_initial.leakage_diverged << ",";
+ ost << config.filter.refined_initial.error_floor << ",";
+ ost << config.filter.refined_initial.error_ceil << ",";
+ ost << config.filter.refined_initial.noise_gate;
+ ost << "],";
+
+ ost << "\"coarse_initial\": [";
+ ost << config.filter.coarse_initial.length_blocks << ",";
+ ost << config.filter.coarse_initial.rate << ",";
+ ost << config.filter.coarse_initial.noise_gate;
+ ost << "],";
+
+ ost << "\"config_change_duration_blocks\": "
+ << config.filter.config_change_duration_blocks << ",";
+ ost << "\"initial_state_seconds\": " << config.filter.initial_state_seconds
+ << ",";
+ ost << "\"coarse_reset_hangover_blocks\": "
+ << config.filter.coarse_reset_hangover_blocks << ",";
+ ost << "\"conservative_initial_phase\": "
+ << (config.filter.conservative_initial_phase ? "true" : "false") << ",";
+ ost << "\"enable_coarse_filter_output_usage\": "
+ << (config.filter.enable_coarse_filter_output_usage ? "true" : "false")
+ << ",";
+ ost << "\"use_linear_filter\": "
+ << (config.filter.use_linear_filter ? "true" : "false") << ",";
+ ost << "\"high_pass_filter_echo_reference\": "
+ << (config.filter.high_pass_filter_echo_reference ? "true" : "false")
+ << ",";
+ ost << "\"export_linear_aec_output\": "
+ << (config.filter.export_linear_aec_output ? "true" : "false");
+
+ ost << "},";
+
+ ost << "\"erle\": {";
+ ost << "\"min\": " << config.erle.min << ",";
+ ost << "\"max_l\": " << config.erle.max_l << ",";
+ ost << "\"max_h\": " << config.erle.max_h << ",";
+ ost << "\"onset_detection\": "
+ << (config.erle.onset_detection ? "true" : "false") << ",";
+ ost << "\"num_sections\": " << config.erle.num_sections << ",";
+ ost << "\"clamp_quality_estimate_to_zero\": "
+ << (config.erle.clamp_quality_estimate_to_zero ? "true" : "false") << ",";
+ ost << "\"clamp_quality_estimate_to_one\": "
+ << (config.erle.clamp_quality_estimate_to_one ? "true" : "false");
+ ost << "},";
+
+ ost << "\"ep_strength\": {";
+ ost << "\"default_gain\": " << config.ep_strength.default_gain << ",";
+ ost << "\"default_len\": " << config.ep_strength.default_len << ",";
+ ost << "\"nearend_len\": " << config.ep_strength.nearend_len << ",";
+ ost << "\"echo_can_saturate\": "
+ << (config.ep_strength.echo_can_saturate ? "true" : "false") << ",";
+ ost << "\"bounded_erl\": "
+ << (config.ep_strength.bounded_erl ? "true" : "false") << ",";
+ ost << "\"erle_onset_compensation_in_dominant_nearend\": "
+ << (config.ep_strength.erle_onset_compensation_in_dominant_nearend
+ ? "true"
+ : "false")
+ << ",";
+ ost << "\"use_conservative_tail_frequency_response\": "
+ << (config.ep_strength.use_conservative_tail_frequency_response
+ ? "true"
+ : "false");
+ ost << "},";
+
+ ost << "\"echo_audibility\": {";
+ ost << "\"low_render_limit\": " << config.echo_audibility.low_render_limit
+ << ",";
+ ost << "\"normal_render_limit\": "
+ << config.echo_audibility.normal_render_limit << ",";
+ ost << "\"floor_power\": " << config.echo_audibility.floor_power << ",";
+ ost << "\"audibility_threshold_lf\": "
+ << config.echo_audibility.audibility_threshold_lf << ",";
+ ost << "\"audibility_threshold_mf\": "
+ << config.echo_audibility.audibility_threshold_mf << ",";
+ ost << "\"audibility_threshold_hf\": "
+ << config.echo_audibility.audibility_threshold_hf << ",";
+ ost << "\"use_stationarity_properties\": "
+ << (config.echo_audibility.use_stationarity_properties ? "true" : "false")
+ << ",";
+ ost << "\"use_stationarity_properties_at_init\": "
+ << (config.echo_audibility.use_stationarity_properties_at_init ? "true"
+ : "false");
+ ost << "},";
+
+ ost << "\"render_levels\": {";
+ ost << "\"active_render_limit\": " << config.render_levels.active_render_limit
+ << ",";
+ ost << "\"poor_excitation_render_limit\": "
+ << config.render_levels.poor_excitation_render_limit << ",";
+ ost << "\"poor_excitation_render_limit_ds8\": "
+ << config.render_levels.poor_excitation_render_limit_ds8 << ",";
+ ost << "\"render_power_gain_db\": "
+ << config.render_levels.render_power_gain_db;
+ ost << "},";
+
+ ost << "\"echo_removal_control\": {";
+ ost << "\"has_clock_drift\": "
+ << (config.echo_removal_control.has_clock_drift ? "true" : "false")
+ << ",";
+ ost << "\"linear_and_stable_echo_path\": "
+ << (config.echo_removal_control.linear_and_stable_echo_path ? "true"
+ : "false");
+
+ ost << "},";
+
+ ost << "\"echo_model\": {";
+ ost << "\"noise_floor_hold\": " << config.echo_model.noise_floor_hold << ",";
+ ost << "\"min_noise_floor_power\": "
+ << config.echo_model.min_noise_floor_power << ",";
+ ost << "\"stationary_gate_slope\": "
+ << config.echo_model.stationary_gate_slope << ",";
+ ost << "\"noise_gate_power\": " << config.echo_model.noise_gate_power << ",";
+ ost << "\"noise_gate_slope\": " << config.echo_model.noise_gate_slope << ",";
+ ost << "\"render_pre_window_size\": "
+ << config.echo_model.render_pre_window_size << ",";
+ ost << "\"render_post_window_size\": "
+ << config.echo_model.render_post_window_size << ",";
+ ost << "\"model_reverb_in_nonlinear_mode\": "
+ << (config.echo_model.model_reverb_in_nonlinear_mode ? "true" : "false");
+ ost << "},";
+
+ ost << "\"comfort_noise\": {";
+ ost << "\"noise_floor_dbfs\": " << config.comfort_noise.noise_floor_dbfs;
+ ost << "},";
+
+ ost << "\"suppressor\": {";
+ ost << "\"nearend_average_blocks\": "
+ << config.suppressor.nearend_average_blocks << ",";
+ ost << "\"normal_tuning\": {";
+ ost << "\"mask_lf\": [";
+ ost << config.suppressor.normal_tuning.mask_lf.enr_transparent << ",";
+ ost << config.suppressor.normal_tuning.mask_lf.enr_suppress << ",";
+ ost << config.suppressor.normal_tuning.mask_lf.emr_transparent;
+ ost << "],";
+ ost << "\"mask_hf\": [";
+ ost << config.suppressor.normal_tuning.mask_hf.enr_transparent << ",";
+ ost << config.suppressor.normal_tuning.mask_hf.enr_suppress << ",";
+ ost << config.suppressor.normal_tuning.mask_hf.emr_transparent;
+ ost << "],";
+ ost << "\"max_inc_factor\": "
+ << config.suppressor.normal_tuning.max_inc_factor << ",";
+ ost << "\"max_dec_factor_lf\": "
+ << config.suppressor.normal_tuning.max_dec_factor_lf;
+ ost << "},";
+ ost << "\"nearend_tuning\": {";
+ ost << "\"mask_lf\": [";
+ ost << config.suppressor.nearend_tuning.mask_lf.enr_transparent << ",";
+ ost << config.suppressor.nearend_tuning.mask_lf.enr_suppress << ",";
+ ost << config.suppressor.nearend_tuning.mask_lf.emr_transparent;
+ ost << "],";
+ ost << "\"mask_hf\": [";
+ ost << config.suppressor.nearend_tuning.mask_hf.enr_transparent << ",";
+ ost << config.suppressor.nearend_tuning.mask_hf.enr_suppress << ",";
+ ost << config.suppressor.nearend_tuning.mask_hf.emr_transparent;
+ ost << "],";
+ ost << "\"max_inc_factor\": "
+ << config.suppressor.nearend_tuning.max_inc_factor << ",";
+ ost << "\"max_dec_factor_lf\": "
+ << config.suppressor.nearend_tuning.max_dec_factor_lf;
+ ost << "},";
+ ost << "\"lf_smoothing_during_initial_phase\": "
+ << (config.suppressor.lf_smoothing_during_initial_phase ? "true"
+ : "false")
+ << ",";
+ ost << "\"last_permanent_lf_smoothing_band\": "
+ << config.suppressor.last_permanent_lf_smoothing_band << ",";
+ ost << "\"last_lf_smoothing_band\": "
+ << config.suppressor.last_lf_smoothing_band << ",";
+ ost << "\"last_lf_band\": " << config.suppressor.last_lf_band << ",";
+ ost << "\"first_hf_band\": " << config.suppressor.first_hf_band << ",";
+ {
+ const auto& dnd = config.suppressor.dominant_nearend_detection;
+ ost << "\"dominant_nearend_detection\": {";
+ ost << "\"enr_threshold\": " << dnd.enr_threshold << ",";
+ ost << "\"enr_exit_threshold\": " << dnd.enr_exit_threshold << ",";
+ ost << "\"snr_threshold\": " << dnd.snr_threshold << ",";
+ ost << "\"hold_duration\": " << dnd.hold_duration << ",";
+ ost << "\"trigger_threshold\": " << dnd.trigger_threshold << ",";
+ ost << "\"use_during_initial_phase\": " << dnd.use_during_initial_phase
+ << ",";
+ ost << "\"use_unbounded_echo_spectrum\": "
+ << dnd.use_unbounded_echo_spectrum;
+ ost << "},";
+ }
+ ost << "\"subband_nearend_detection\": {";
+ ost << "\"nearend_average_blocks\": "
+ << config.suppressor.subband_nearend_detection.nearend_average_blocks
+ << ",";
+ ost << "\"subband1\": [";
+ ost << config.suppressor.subband_nearend_detection.subband1.low << ",";
+ ost << config.suppressor.subband_nearend_detection.subband1.high;
+ ost << "],";
+ ost << "\"subband2\": [";
+ ost << config.suppressor.subband_nearend_detection.subband2.low << ",";
+ ost << config.suppressor.subband_nearend_detection.subband2.high;
+ ost << "],";
+ ost << "\"nearend_threshold\": "
+ << config.suppressor.subband_nearend_detection.nearend_threshold << ",";
+ ost << "\"snr_threshold\": "
+ << config.suppressor.subband_nearend_detection.snr_threshold;
+ ost << "},";
+ ost << "\"use_subband_nearend_detection\": "
+ << config.suppressor.use_subband_nearend_detection << ",";
+ ost << "\"high_bands_suppression\": {";
+ ost << "\"enr_threshold\": "
+ << config.suppressor.high_bands_suppression.enr_threshold << ",";
+ ost << "\"max_gain_during_echo\": "
+ << config.suppressor.high_bands_suppression.max_gain_during_echo << ",";
+ ost << "\"anti_howling_activation_threshold\": "
+ << config.suppressor.high_bands_suppression
+ .anti_howling_activation_threshold
+ << ",";
+ ost << "\"anti_howling_gain\": "
+ << config.suppressor.high_bands_suppression.anti_howling_gain;
+ ost << "},";
+ ost << "\"floor_first_increase\": " << config.suppressor.floor_first_increase
+ << ",";
+ ost << "\"conservative_hf_suppression\": "
+ << config.suppressor.conservative_hf_suppression;
+ ost << "},";
+
+ ost << "\"multi_channel\": {";
+ ost << "\"detect_stereo_content\": "
+ << (config.multi_channel.detect_stereo_content ? "true" : "false") << ",";
+ ost << "\"stereo_detection_threshold\": "
+ << config.multi_channel.stereo_detection_threshold << ",";
+ ost << "\"stereo_detection_timeout_threshold_seconds\": "
+ << config.multi_channel.stereo_detection_timeout_threshold_seconds << ",";
+ ost << "\"stereo_detection_hysteresis_seconds\": "
+ << config.multi_channel.stereo_detection_hysteresis_seconds;
+ ost << "}";
+
+ ost << "}";
+ ost << "}";
+
+ return ost.Release();
+}
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio/echo_canceller3_config_json.h b/third_party/libwebrtc/api/audio/echo_canceller3_config_json.h
new file mode 100644
index 0000000000..ecee9541c7
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/echo_canceller3_config_json.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_ECHO_CANCELLER3_CONFIG_JSON_H_
+#define API_AUDIO_ECHO_CANCELLER3_CONFIG_JSON_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "api/audio/echo_canceller3_config.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+// Parses a JSON-encoded string into an Aec3 config. Fields corresponds to
+// substruct names, with the addition that there must be a top-level node
+// "aec3". Produces default config values for anything that cannot be parsed
+// from the string. If any error was found in the parsing, parsing_successful is
+// set to false.
+RTC_EXPORT void Aec3ConfigFromJsonString(absl::string_view json_string,
+ EchoCanceller3Config* config,
+ bool* parsing_successful);
+
+// To be deprecated.
+// Parses a JSON-encoded string into an Aec3 config. Fields corresponds to
+// substruct names, with the addition that there must be a top-level node
+// "aec3". Returns default config values for anything that cannot be parsed from
+// the string.
+RTC_EXPORT EchoCanceller3Config
+Aec3ConfigFromJsonString(absl::string_view json_string);
+
+// Encodes an Aec3 config in JSON format. Fields corresponds to substruct names,
+// with the addition that the top-level node is named "aec3".
+RTC_EXPORT std::string Aec3ConfigToJsonString(
+ const EchoCanceller3Config& config);
+
+} // namespace webrtc
+
+#endif // API_AUDIO_ECHO_CANCELLER3_CONFIG_JSON_H_
diff --git a/third_party/libwebrtc/api/audio/echo_canceller3_factory.cc b/third_party/libwebrtc/api/audio/echo_canceller3_factory.cc
new file mode 100644
index 0000000000..284b117bea
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/echo_canceller3_factory.cc
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/audio/echo_canceller3_factory.h"
+
+#include <memory>
+
+#include "modules/audio_processing/aec3/echo_canceller3.h"
+
+namespace webrtc {
+
+EchoCanceller3Factory::EchoCanceller3Factory() {}
+
+EchoCanceller3Factory::EchoCanceller3Factory(const EchoCanceller3Config& config)
+ : config_(config) {}
+
+std::unique_ptr<EchoControl> EchoCanceller3Factory::Create(
+ int sample_rate_hz,
+ int num_render_channels,
+ int num_capture_channels) {
+ return std::make_unique<EchoCanceller3>(
+ config_, /*multichannel_config=*/absl::nullopt, sample_rate_hz,
+ num_render_channels, num_capture_channels);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio/echo_canceller3_factory.h b/third_party/libwebrtc/api/audio/echo_canceller3_factory.h
new file mode 100644
index 0000000000..8b5380057b
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/echo_canceller3_factory.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_ECHO_CANCELLER3_FACTORY_H_
+#define API_AUDIO_ECHO_CANCELLER3_FACTORY_H_
+
+#include <memory>
+
+#include "api/audio/echo_canceller3_config.h"
+#include "api/audio/echo_control.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+class RTC_EXPORT EchoCanceller3Factory : public EchoControlFactory {
+ public:
+ // Factory producing EchoCanceller3 instances with the default configuration.
+ EchoCanceller3Factory();
+
+ // Factory producing EchoCanceller3 instances with the specified
+ // configuration.
+ explicit EchoCanceller3Factory(const EchoCanceller3Config& config);
+
+ // Creates an EchoCanceller3 with a specified channel count and sampling rate.
+ std::unique_ptr<EchoControl> Create(int sample_rate_hz,
+ int num_render_channels,
+ int num_capture_channels) override;
+
+ private:
+ const EchoCanceller3Config config_;
+};
+} // namespace webrtc
+
+#endif // API_AUDIO_ECHO_CANCELLER3_FACTORY_H_
diff --git a/third_party/libwebrtc/api/audio/echo_control.h b/third_party/libwebrtc/api/audio/echo_control.h
new file mode 100644
index 0000000000..74fbc27b12
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/echo_control.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_ECHO_CONTROL_H_
+#define API_AUDIO_ECHO_CONTROL_H_
+
+#include <memory>
+
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+class AudioBuffer;
+
+// Interface for an acoustic echo cancellation (AEC) submodule.
+class EchoControl {
+ public:
+ // Analysis (not changing) of the render signal.
+ virtual void AnalyzeRender(AudioBuffer* render) = 0;
+
+ // Analysis (not changing) of the capture signal.
+ virtual void AnalyzeCapture(AudioBuffer* capture) = 0;
+
+ // Processes the capture signal in order to remove the echo.
+ virtual void ProcessCapture(AudioBuffer* capture, bool level_change) = 0;
+
+ // As above, but also returns the linear filter output.
+ virtual void ProcessCapture(AudioBuffer* capture,
+ AudioBuffer* linear_output,
+ bool level_change) = 0;
+
+ struct Metrics {
+ double echo_return_loss;
+ double echo_return_loss_enhancement;
+ int delay_ms;
+ };
+
+ // Collect current metrics from the echo controller.
+ virtual Metrics GetMetrics() const = 0;
+
+ // Provides an optional external estimate of the audio buffer delay.
+ virtual void SetAudioBufferDelay(int delay_ms) = 0;
+
+ // Specifies whether the capture output will be used. The purpose of this is
+ // to allow the echo controller to deactivate some of the processing when the
+ // resulting output is anyway not used, for instance when the endpoint is
+ // muted.
+ // TODO(b/177830919): Make pure virtual.
+ virtual void SetCaptureOutputUsage(bool capture_output_used) {}
+
+ // Returns wheter the signal is altered.
+ virtual bool ActiveProcessing() const = 0;
+
+ virtual ~EchoControl() {}
+};
+
+// Interface for a factory that creates EchoControllers.
+class EchoControlFactory {
+ public:
+ virtual std::unique_ptr<EchoControl> Create(int sample_rate_hz,
+ int num_render_channels,
+ int num_capture_channels) = 0;
+
+ virtual ~EchoControlFactory() = default;
+};
+} // namespace webrtc
+
+#endif // API_AUDIO_ECHO_CONTROL_H_
diff --git a/third_party/libwebrtc/api/audio/echo_control_gn/moz.build b/third_party/libwebrtc/api/audio/echo_control_gn/moz.build
new file mode 100644
index 0000000000..2e128f8038
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/echo_control_gn/moz.build
@@ -0,0 +1,205 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("echo_control_gn")
diff --git a/third_party/libwebrtc/api/audio/echo_detector_creator.cc b/third_party/libwebrtc/api/audio/echo_detector_creator.cc
new file mode 100644
index 0000000000..15b7c51dca
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/echo_detector_creator.cc
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/audio/echo_detector_creator.h"
+
+#include "api/make_ref_counted.h"
+#include "modules/audio_processing/residual_echo_detector.h"
+
+namespace webrtc {
+
+rtc::scoped_refptr<EchoDetector> CreateEchoDetector() {
+ return rtc::make_ref_counted<ResidualEchoDetector>();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio/echo_detector_creator.h b/third_party/libwebrtc/api/audio/echo_detector_creator.h
new file mode 100644
index 0000000000..5ba171de97
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/echo_detector_creator.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_ECHO_DETECTOR_CREATOR_H_
+#define API_AUDIO_ECHO_DETECTOR_CREATOR_H_
+
+#include "api/scoped_refptr.h"
+#include "modules/audio_processing/include/audio_processing.h"
+
+namespace webrtc {
+
+// Returns an instance of the WebRTC implementation of a residual echo detector.
+// It can be provided to the webrtc::AudioProcessingBuilder to obtain the
+// usual residual echo metrics.
+rtc::scoped_refptr<EchoDetector> CreateEchoDetector();
+
+} // namespace webrtc
+
+#endif // API_AUDIO_ECHO_DETECTOR_CREATOR_H_
diff --git a/third_party/libwebrtc/api/audio/test/BUILD.gn b/third_party/libwebrtc/api/audio/test/BUILD.gn
new file mode 100644
index 0000000000..dfe8c32f80
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/test/BUILD.gn
@@ -0,0 +1,30 @@
+# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+if (is_android) {
+ import("//build/config/android/config.gni")
+ import("//build/config/android/rules.gni")
+}
+
+if (rtc_include_tests) {
+ rtc_library("audio_api_unittests") {
+ testonly = true
+ sources = [
+ "audio_frame_unittest.cc",
+ "echo_canceller3_config_json_unittest.cc",
+ "echo_canceller3_config_unittest.cc",
+ ]
+ deps = [
+ "..:aec3_config",
+ "..:aec3_config_json",
+ "..:audio_frame_api",
+ "../../../test:test_support",
+ ]
+ }
+}
diff --git a/third_party/libwebrtc/api/audio/test/audio_frame_unittest.cc b/third_party/libwebrtc/api/audio/test/audio_frame_unittest.cc
new file mode 100644
index 0000000000..dbf45ceabc
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/test/audio_frame_unittest.cc
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2018 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio/audio_frame.h"
+
+#include <stdint.h>
+#include <string.h> // memcmp
+
+#include "test/gtest.h"
+
+namespace webrtc {
+
+namespace {
+
+bool AllSamplesAre(int16_t sample, const AudioFrame& frame) {
+ const int16_t* frame_data = frame.data();
+ for (size_t i = 0; i < frame.max_16bit_samples(); i++) {
+ if (frame_data[i] != sample) {
+ return false;
+ }
+ }
+ return true;
+}
+
+constexpr uint32_t kTimestamp = 27;
+constexpr int kSampleRateHz = 16000;
+constexpr size_t kNumChannelsMono = 1;
+constexpr size_t kNumChannelsStereo = 2;
+constexpr size_t kNumChannels5_1 = 6;
+constexpr size_t kSamplesPerChannel = kSampleRateHz / 100;
+
+} // namespace
+
+TEST(AudioFrameTest, FrameStartsMuted) {
+ AudioFrame frame;
+ EXPECT_TRUE(frame.muted());
+ EXPECT_TRUE(AllSamplesAre(0, frame));
+}
+
+TEST(AudioFrameTest, UnmutedFrameIsInitiallyZeroed) {
+ AudioFrame frame;
+ frame.mutable_data();
+ EXPECT_FALSE(frame.muted());
+ EXPECT_TRUE(AllSamplesAre(0, frame));
+}
+
+TEST(AudioFrameTest, MutedFrameBufferIsZeroed) {
+ AudioFrame frame;
+ int16_t* frame_data = frame.mutable_data();
+ for (size_t i = 0; i < frame.max_16bit_samples(); i++) {
+ frame_data[i] = 17;
+ }
+ ASSERT_TRUE(AllSamplesAre(17, frame));
+ frame.Mute();
+ EXPECT_TRUE(frame.muted());
+ EXPECT_TRUE(AllSamplesAre(0, frame));
+}
+
+TEST(AudioFrameTest, UpdateFrameMono) {
+ AudioFrame frame;
+ int16_t samples[kNumChannelsMono * kSamplesPerChannel] = {17};
+ frame.UpdateFrame(kTimestamp, samples, kSamplesPerChannel, kSampleRateHz,
+ AudioFrame::kPLC, AudioFrame::kVadActive, kNumChannelsMono);
+
+ EXPECT_EQ(kTimestamp, frame.timestamp_);
+ EXPECT_EQ(kSamplesPerChannel, frame.samples_per_channel());
+ EXPECT_EQ(kSampleRateHz, frame.sample_rate_hz());
+ EXPECT_EQ(AudioFrame::kPLC, frame.speech_type_);
+ EXPECT_EQ(AudioFrame::kVadActive, frame.vad_activity_);
+ EXPECT_EQ(kNumChannelsMono, frame.num_channels());
+ EXPECT_EQ(CHANNEL_LAYOUT_MONO, frame.channel_layout());
+
+ EXPECT_FALSE(frame.muted());
+ EXPECT_EQ(0, memcmp(samples, frame.data(), sizeof(samples)));
+
+ frame.UpdateFrame(kTimestamp, nullptr /* data*/, kSamplesPerChannel,
+ kSampleRateHz, AudioFrame::kPLC, AudioFrame::kVadActive,
+ kNumChannelsMono);
+ EXPECT_TRUE(frame.muted());
+ EXPECT_TRUE(AllSamplesAre(0, frame));
+}
+
+TEST(AudioFrameTest, UpdateFrameMultiChannel) {
+ AudioFrame frame;
+ frame.UpdateFrame(kTimestamp, nullptr /* data */, kSamplesPerChannel,
+ kSampleRateHz, AudioFrame::kPLC, AudioFrame::kVadActive,
+ kNumChannelsStereo);
+ EXPECT_EQ(kSamplesPerChannel, frame.samples_per_channel());
+ EXPECT_EQ(kNumChannelsStereo, frame.num_channels());
+ EXPECT_EQ(CHANNEL_LAYOUT_STEREO, frame.channel_layout());
+
+ frame.UpdateFrame(kTimestamp, nullptr /* data */, kSamplesPerChannel,
+ kSampleRateHz, AudioFrame::kPLC, AudioFrame::kVadActive,
+ kNumChannels5_1);
+ EXPECT_EQ(kSamplesPerChannel, frame.samples_per_channel());
+ EXPECT_EQ(kNumChannels5_1, frame.num_channels());
+ EXPECT_EQ(CHANNEL_LAYOUT_5_1, frame.channel_layout());
+}
+
+TEST(AudioFrameTest, CopyFrom) {
+ AudioFrame frame1;
+ AudioFrame frame2;
+
+ int16_t samples[kNumChannelsMono * kSamplesPerChannel] = {17};
+ frame2.UpdateFrame(kTimestamp, samples, kSamplesPerChannel, kSampleRateHz,
+ AudioFrame::kPLC, AudioFrame::kVadActive,
+ kNumChannelsMono);
+ frame1.CopyFrom(frame2);
+
+ EXPECT_EQ(frame2.timestamp_, frame1.timestamp_);
+ EXPECT_EQ(frame2.samples_per_channel_, frame1.samples_per_channel_);
+ EXPECT_EQ(frame2.sample_rate_hz_, frame1.sample_rate_hz_);
+ EXPECT_EQ(frame2.speech_type_, frame1.speech_type_);
+ EXPECT_EQ(frame2.vad_activity_, frame1.vad_activity_);
+ EXPECT_EQ(frame2.num_channels_, frame1.num_channels_);
+
+ EXPECT_EQ(frame2.muted(), frame1.muted());
+ EXPECT_EQ(0, memcmp(frame2.data(), frame1.data(), sizeof(samples)));
+
+ frame2.UpdateFrame(kTimestamp, nullptr /* data */, kSamplesPerChannel,
+ kSampleRateHz, AudioFrame::kPLC, AudioFrame::kVadActive,
+ kNumChannelsMono);
+ frame1.CopyFrom(frame2);
+
+ EXPECT_EQ(frame2.muted(), frame1.muted());
+ EXPECT_EQ(0, memcmp(frame2.data(), frame1.data(), sizeof(samples)));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio/test/echo_canceller3_config_json_unittest.cc b/third_party/libwebrtc/api/audio/test/echo_canceller3_config_json_unittest.cc
new file mode 100644
index 0000000000..4146dda9fe
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/test/echo_canceller3_config_json_unittest.cc
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2018 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio/echo_canceller3_config_json.h"
+
+#include "api/audio/echo_canceller3_config.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+TEST(EchoCanceller3JsonHelpers, ToStringAndParseJson) {
+ EchoCanceller3Config cfg;
+ cfg.delay.down_sampling_factor = 1u;
+ cfg.delay.log_warning_on_delay_changes = true;
+ cfg.filter.refined.error_floor = 2.f;
+ cfg.filter.coarse_initial.length_blocks = 3u;
+ cfg.filter.high_pass_filter_echo_reference =
+ !cfg.filter.high_pass_filter_echo_reference;
+ cfg.comfort_noise.noise_floor_dbfs = 100.f;
+ cfg.echo_model.model_reverb_in_nonlinear_mode = false;
+ cfg.suppressor.normal_tuning.mask_hf.enr_suppress = .5f;
+ cfg.suppressor.subband_nearend_detection.nearend_average_blocks = 3;
+ cfg.suppressor.subband_nearend_detection.subband1 = {1, 3};
+ cfg.suppressor.subband_nearend_detection.subband1 = {4, 5};
+ cfg.suppressor.subband_nearend_detection.nearend_threshold = 2.f;
+ cfg.suppressor.subband_nearend_detection.snr_threshold = 100.f;
+ cfg.multi_channel.detect_stereo_content =
+ !cfg.multi_channel.detect_stereo_content;
+ cfg.multi_channel.stereo_detection_threshold += 1.0f;
+ cfg.multi_channel.stereo_detection_timeout_threshold_seconds += 1;
+ cfg.multi_channel.stereo_detection_hysteresis_seconds += 1;
+ std::string json_string = Aec3ConfigToJsonString(cfg);
+ EchoCanceller3Config cfg_transformed = Aec3ConfigFromJsonString(json_string);
+
+ // Expect unchanged values to remain default.
+ EXPECT_EQ(cfg.ep_strength.default_len,
+ cfg_transformed.ep_strength.default_len);
+ EXPECT_EQ(cfg.ep_strength.nearend_len,
+ cfg_transformed.ep_strength.nearend_len);
+ EXPECT_EQ(cfg.suppressor.normal_tuning.mask_lf.enr_suppress,
+ cfg_transformed.suppressor.normal_tuning.mask_lf.enr_suppress);
+
+ // Expect changed values to carry through the transformation.
+ EXPECT_EQ(cfg.delay.down_sampling_factor,
+ cfg_transformed.delay.down_sampling_factor);
+ EXPECT_EQ(cfg.delay.log_warning_on_delay_changes,
+ cfg_transformed.delay.log_warning_on_delay_changes);
+ EXPECT_EQ(cfg.filter.coarse_initial.length_blocks,
+ cfg_transformed.filter.coarse_initial.length_blocks);
+ EXPECT_EQ(cfg.filter.refined.error_floor,
+ cfg_transformed.filter.refined.error_floor);
+ EXPECT_EQ(cfg.filter.high_pass_filter_echo_reference,
+ cfg_transformed.filter.high_pass_filter_echo_reference);
+ EXPECT_EQ(cfg.comfort_noise.noise_floor_dbfs,
+ cfg_transformed.comfort_noise.noise_floor_dbfs);
+ EXPECT_EQ(cfg.echo_model.model_reverb_in_nonlinear_mode,
+ cfg_transformed.echo_model.model_reverb_in_nonlinear_mode);
+ EXPECT_EQ(cfg.suppressor.normal_tuning.mask_hf.enr_suppress,
+ cfg_transformed.suppressor.normal_tuning.mask_hf.enr_suppress);
+ EXPECT_EQ(cfg.suppressor.subband_nearend_detection.nearend_average_blocks,
+ cfg_transformed.suppressor.subband_nearend_detection
+ .nearend_average_blocks);
+ EXPECT_EQ(cfg.suppressor.subband_nearend_detection.subband1.low,
+ cfg_transformed.suppressor.subband_nearend_detection.subband1.low);
+ EXPECT_EQ(cfg.suppressor.subband_nearend_detection.subband1.high,
+ cfg_transformed.suppressor.subband_nearend_detection.subband1.high);
+ EXPECT_EQ(cfg.suppressor.subband_nearend_detection.subband2.low,
+ cfg_transformed.suppressor.subband_nearend_detection.subband2.low);
+ EXPECT_EQ(cfg.suppressor.subband_nearend_detection.subband2.high,
+ cfg_transformed.suppressor.subband_nearend_detection.subband2.high);
+ EXPECT_EQ(
+ cfg.suppressor.subband_nearend_detection.nearend_threshold,
+ cfg_transformed.suppressor.subband_nearend_detection.nearend_threshold);
+ EXPECT_EQ(cfg.suppressor.subband_nearend_detection.snr_threshold,
+ cfg_transformed.suppressor.subband_nearend_detection.snr_threshold);
+ EXPECT_EQ(cfg.multi_channel.detect_stereo_content,
+ cfg_transformed.multi_channel.detect_stereo_content);
+ EXPECT_EQ(cfg.multi_channel.stereo_detection_threshold,
+ cfg_transformed.multi_channel.stereo_detection_threshold);
+ EXPECT_EQ(
+ cfg.multi_channel.stereo_detection_timeout_threshold_seconds,
+ cfg_transformed.multi_channel.stereo_detection_timeout_threshold_seconds);
+ EXPECT_EQ(cfg.multi_channel.stereo_detection_hysteresis_seconds,
+ cfg_transformed.multi_channel.stereo_detection_hysteresis_seconds);
+}
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio/test/echo_canceller3_config_unittest.cc b/third_party/libwebrtc/api/audio/test/echo_canceller3_config_unittest.cc
new file mode 100644
index 0000000000..91312a0f40
--- /dev/null
+++ b/third_party/libwebrtc/api/audio/test/echo_canceller3_config_unittest.cc
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2018 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio/echo_canceller3_config.h"
+
+#include "api/audio/echo_canceller3_config_json.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+TEST(EchoCanceller3Config, ValidConfigIsNotModified) {
+ EchoCanceller3Config config;
+ EXPECT_TRUE(EchoCanceller3Config::Validate(&config));
+ EchoCanceller3Config default_config;
+ EXPECT_EQ(Aec3ConfigToJsonString(config),
+ Aec3ConfigToJsonString(default_config));
+}
+
+TEST(EchoCanceller3Config, InvalidConfigIsCorrected) {
+ // Change a parameter and validate.
+ EchoCanceller3Config config;
+ config.echo_model.min_noise_floor_power = -1600000.f;
+ EXPECT_FALSE(EchoCanceller3Config::Validate(&config));
+ EXPECT_GE(config.echo_model.min_noise_floor_power, 0.f);
+ // Verify remaining parameters are unchanged.
+ EchoCanceller3Config default_config;
+ config.echo_model.min_noise_floor_power =
+ default_config.echo_model.min_noise_floor_power;
+ EXPECT_EQ(Aec3ConfigToJsonString(config),
+ Aec3ConfigToJsonString(default_config));
+}
+
+TEST(EchoCanceller3Config, ValidatedConfigsAreValid) {
+ EchoCanceller3Config config;
+ config.delay.down_sampling_factor = 983;
+ EXPECT_FALSE(EchoCanceller3Config::Validate(&config));
+ EXPECT_TRUE(EchoCanceller3Config::Validate(&config));
+}
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/BUILD.gn b/third_party/libwebrtc/api/audio_codecs/BUILD.gn
new file mode 100644
index 0000000000..82ed31a5da
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/BUILD.gn
@@ -0,0 +1,144 @@
+# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../webrtc.gni")
+if (is_android) {
+ import("//build/config/android/config.gni")
+ import("//build/config/android/rules.gni")
+}
+
+rtc_library("audio_codecs_api") {
+ visibility = [ "*" ]
+ sources = [
+ "audio_codec_pair_id.cc",
+ "audio_codec_pair_id.h",
+ "audio_decoder.cc",
+ "audio_decoder.h",
+ "audio_decoder_factory.h",
+ "audio_decoder_factory_template.h",
+ "audio_encoder.cc",
+ "audio_encoder.h",
+ "audio_encoder_factory.h",
+ "audio_encoder_factory_template.h",
+ "audio_format.cc",
+ "audio_format.h",
+ ]
+ deps = [
+ "..:array_view",
+ "..:bitrate_allocation",
+ "..:make_ref_counted",
+ "..:scoped_refptr",
+ "../../api:field_trials_view",
+ "../../rtc_base:buffer",
+ "../../rtc_base:checks",
+ "../../rtc_base:event_tracer",
+ "../../rtc_base:refcount",
+ "../../rtc_base:sanitizer",
+ "../../rtc_base/system:rtc_export",
+ "../units:time_delta",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
+rtc_library("builtin_audio_decoder_factory") {
+ visibility = [ "*" ]
+ allow_poison = [ "audio_codecs" ]
+ sources = [
+ "builtin_audio_decoder_factory.cc",
+ "builtin_audio_decoder_factory.h",
+ ]
+ deps = [
+ ":audio_codecs_api",
+ "..:scoped_refptr",
+ "L16:audio_decoder_L16",
+ "g711:audio_decoder_g711",
+ "g722:audio_decoder_g722",
+ ]
+ defines = []
+ if (rtc_include_ilbc) {
+ deps += [ "ilbc:audio_decoder_ilbc" ]
+ defines += [ "WEBRTC_USE_BUILTIN_ILBC=1" ]
+ } else {
+ defines += [ "WEBRTC_USE_BUILTIN_ILBC=0" ]
+ }
+ if (rtc_include_opus) {
+ deps += [
+ "opus:audio_decoder_multiopus",
+ "opus:audio_decoder_opus",
+ ]
+ defines += [ "WEBRTC_USE_BUILTIN_OPUS=1" ]
+ } else {
+ defines += [ "WEBRTC_USE_BUILTIN_OPUS=0" ]
+ }
+}
+
+rtc_library("builtin_audio_encoder_factory") {
+ visibility = [ "*" ]
+ allow_poison = [ "audio_codecs" ]
+ sources = [
+ "builtin_audio_encoder_factory.cc",
+ "builtin_audio_encoder_factory.h",
+ ]
+ deps = [
+ ":audio_codecs_api",
+ "..:scoped_refptr",
+ "L16:audio_encoder_L16",
+ "g711:audio_encoder_g711",
+ "g722:audio_encoder_g722",
+ ]
+ defines = []
+ if (rtc_include_ilbc) {
+ deps += [ "ilbc:audio_encoder_ilbc" ]
+ defines += [ "WEBRTC_USE_BUILTIN_ILBC=1" ]
+ } else {
+ defines += [ "WEBRTC_USE_BUILTIN_ILBC=0" ]
+ }
+ if (rtc_include_opus) {
+ deps += [
+ "opus:audio_encoder_multiopus",
+ "opus:audio_encoder_opus",
+ ]
+ defines += [ "WEBRTC_USE_BUILTIN_OPUS=1" ]
+ } else {
+ defines += [ "WEBRTC_USE_BUILTIN_OPUS=0" ]
+ }
+}
+
+rtc_library("opus_audio_decoder_factory") {
+ visibility = [ "*" ]
+ allow_poison = [ "audio_codecs" ]
+ sources = [
+ "opus_audio_decoder_factory.cc",
+ "opus_audio_decoder_factory.h",
+ ]
+ deps = [
+ ":audio_codecs_api",
+ "..:scoped_refptr",
+ "opus:audio_decoder_multiopus",
+ "opus:audio_decoder_opus",
+ ]
+}
+
+rtc_library("opus_audio_encoder_factory") {
+ visibility = [ "*" ]
+ allow_poison = [ "audio_codecs" ]
+ sources = [
+ "opus_audio_encoder_factory.cc",
+ "opus_audio_encoder_factory.h",
+ ]
+ deps = [
+ ":audio_codecs_api",
+ "..:scoped_refptr",
+ "opus:audio_encoder_multiopus",
+ "opus:audio_encoder_opus",
+ ]
+}
diff --git a/third_party/libwebrtc/api/audio_codecs/L16/BUILD.gn b/third_party/libwebrtc/api/audio_codecs/L16/BUILD.gn
new file mode 100644
index 0000000000..41e9eb42d8
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/L16/BUILD.gn
@@ -0,0 +1,55 @@
+# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+if (is_android) {
+ import("//build/config/android/config.gni")
+ import("//build/config/android/rules.gni")
+}
+
+rtc_library("audio_encoder_L16") {
+ visibility = [ "*" ]
+ poisonous = [ "audio_codecs" ]
+ sources = [
+ "audio_encoder_L16.cc",
+ "audio_encoder_L16.h",
+ ]
+ deps = [
+ "..:audio_codecs_api",
+ "../../../api:field_trials_view",
+ "../../../modules/audio_coding:pcm16b",
+ "../../../rtc_base:safe_conversions",
+ "../../../rtc_base:safe_minmax",
+ "../../../rtc_base:stringutils",
+ "../../../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
+rtc_library("audio_decoder_L16") {
+ visibility = [ "*" ]
+ poisonous = [ "audio_codecs" ]
+ sources = [
+ "audio_decoder_L16.cc",
+ "audio_decoder_L16.h",
+ ]
+ deps = [
+ "..:audio_codecs_api",
+ "../../../api:field_trials_view",
+ "../../../modules/audio_coding:pcm16b",
+ "../../../rtc_base:safe_conversions",
+ "../../../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
diff --git a/third_party/libwebrtc/api/audio_codecs/L16/audio_decoder_L16.cc b/third_party/libwebrtc/api/audio_codecs/L16/audio_decoder_L16.cc
new file mode 100644
index 0000000000..a03abe26f7
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/L16/audio_decoder_L16.cc
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/L16/audio_decoder_L16.h"
+
+#include <memory>
+
+#include "absl/strings/match.h"
+#include "modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h"
+#include "modules/audio_coding/codecs/pcm16b/pcm16b_common.h"
+#include "rtc_base/numerics/safe_conversions.h"
+
+namespace webrtc {
+
+absl::optional<AudioDecoderL16::Config> AudioDecoderL16::SdpToConfig(
+ const SdpAudioFormat& format) {
+ Config config;
+ config.sample_rate_hz = format.clockrate_hz;
+ config.num_channels = rtc::checked_cast<int>(format.num_channels);
+ if (absl::EqualsIgnoreCase(format.name, "L16") && config.IsOk()) {
+ return config;
+ }
+ return absl::nullopt;
+}
+
+void AudioDecoderL16::AppendSupportedDecoders(
+ std::vector<AudioCodecSpec>* specs) {
+ Pcm16BAppendSupportedCodecSpecs(specs);
+}
+
+std::unique_ptr<AudioDecoder> AudioDecoderL16::MakeAudioDecoder(
+ const Config& config,
+ absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+ const FieldTrialsView* field_trials) {
+ if (!config.IsOk()) {
+ return nullptr;
+ }
+ return std::make_unique<AudioDecoderPcm16B>(config.sample_rate_hz,
+ config.num_channels);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/L16/audio_decoder_L16.h b/third_party/libwebrtc/api/audio_codecs/L16/audio_decoder_L16.h
new file mode 100644
index 0000000000..5a01b7dc01
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/L16/audio_decoder_L16.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_L16_AUDIO_DECODER_L16_H_
+#define API_AUDIO_CODECS_L16_AUDIO_DECODER_L16_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/audio_codecs/audio_codec_pair_id.h"
+#include "api/audio_codecs/audio_decoder.h"
+#include "api/audio_codecs/audio_format.h"
+#include "api/field_trials_view.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// L16 decoder API for use as a template parameter to
+// CreateAudioDecoderFactory<...>().
+struct RTC_EXPORT AudioDecoderL16 {
+ struct Config {
+ bool IsOk() const {
+ return (sample_rate_hz == 8000 || sample_rate_hz == 16000 ||
+ sample_rate_hz == 32000 || sample_rate_hz == 48000) &&
+ (num_channels >= 1 &&
+ num_channels <= AudioDecoder::kMaxNumberOfChannels);
+ }
+ int sample_rate_hz = 8000;
+ int num_channels = 1;
+ };
+ static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
+ static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
+ static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
+ const Config& config,
+ absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+ const FieldTrialsView* field_trials = nullptr);
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_L16_AUDIO_DECODER_L16_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/L16/audio_decoder_L16_gn/moz.build b/third_party/libwebrtc/api/audio_codecs/L16/audio_decoder_L16_gn/moz.build
new file mode 100644
index 0000000000..87335c298d
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/L16/audio_decoder_L16_gn/moz.build
@@ -0,0 +1,225 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio_codecs/L16/audio_decoder_L16.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_decoder_L16_gn")
diff --git a/third_party/libwebrtc/api/audio_codecs/L16/audio_encoder_L16.cc b/third_party/libwebrtc/api/audio_codecs/L16/audio_encoder_L16.cc
new file mode 100644
index 0000000000..20259b9ad8
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/L16/audio_encoder_L16.cc
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/L16/audio_encoder_L16.h"
+
+#include <memory>
+
+#include "absl/strings/match.h"
+#include "modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.h"
+#include "modules/audio_coding/codecs/pcm16b/pcm16b_common.h"
+#include "rtc_base/numerics/safe_conversions.h"
+#include "rtc_base/numerics/safe_minmax.h"
+#include "rtc_base/string_to_number.h"
+
+namespace webrtc {
+
+absl::optional<AudioEncoderL16::Config> AudioEncoderL16::SdpToConfig(
+ const SdpAudioFormat& format) {
+ if (!rtc::IsValueInRangeForNumericType<int>(format.num_channels)) {
+ RTC_DCHECK_NOTREACHED();
+ return absl::nullopt;
+ }
+ Config config;
+ config.sample_rate_hz = format.clockrate_hz;
+ config.num_channels = rtc::dchecked_cast<int>(format.num_channels);
+ auto ptime_iter = format.parameters.find("ptime");
+ if (ptime_iter != format.parameters.end()) {
+ const auto ptime = rtc::StringToNumber<int>(ptime_iter->second);
+ if (ptime && *ptime > 0) {
+ config.frame_size_ms = rtc::SafeClamp(10 * (*ptime / 10), 10, 60);
+ }
+ }
+ if (absl::EqualsIgnoreCase(format.name, "L16") && config.IsOk()) {
+ return config;
+ }
+ return absl::nullopt;
+}
+
+void AudioEncoderL16::AppendSupportedEncoders(
+ std::vector<AudioCodecSpec>* specs) {
+ Pcm16BAppendSupportedCodecSpecs(specs);
+}
+
+AudioCodecInfo AudioEncoderL16::QueryAudioEncoder(
+ const AudioEncoderL16::Config& config) {
+ RTC_DCHECK(config.IsOk());
+ return {config.sample_rate_hz,
+ rtc::dchecked_cast<size_t>(config.num_channels),
+ config.sample_rate_hz * config.num_channels * 16};
+}
+
+std::unique_ptr<AudioEncoder> AudioEncoderL16::MakeAudioEncoder(
+ const AudioEncoderL16::Config& config,
+ int payload_type,
+ absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+ const FieldTrialsView* field_trials) {
+ AudioEncoderPcm16B::Config c;
+ c.sample_rate_hz = config.sample_rate_hz;
+ c.num_channels = config.num_channels;
+ c.frame_size_ms = config.frame_size_ms;
+ c.payload_type = payload_type;
+ if (!config.IsOk()) {
+ RTC_DCHECK_NOTREACHED();
+ return nullptr;
+ }
+ return std::make_unique<AudioEncoderPcm16B>(c);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/L16/audio_encoder_L16.h b/third_party/libwebrtc/api/audio_codecs/L16/audio_encoder_L16.h
new file mode 100644
index 0000000000..47509849de
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/L16/audio_encoder_L16.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_L16_AUDIO_ENCODER_L16_H_
+#define API_AUDIO_CODECS_L16_AUDIO_ENCODER_L16_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/audio_codecs/audio_codec_pair_id.h"
+#include "api/audio_codecs/audio_encoder.h"
+#include "api/audio_codecs/audio_format.h"
+#include "api/field_trials_view.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// L16 encoder API for use as a template parameter to
+// CreateAudioEncoderFactory<...>().
+struct RTC_EXPORT AudioEncoderL16 {
+ struct Config {
+ bool IsOk() const {
+ return (sample_rate_hz == 8000 || sample_rate_hz == 16000 ||
+ sample_rate_hz == 32000 || sample_rate_hz == 48000) &&
+ num_channels >= 1 &&
+ num_channels <= AudioEncoder::kMaxNumberOfChannels &&
+ frame_size_ms > 0 && frame_size_ms <= 120 &&
+ frame_size_ms % 10 == 0;
+ }
+ int sample_rate_hz = 8000;
+ int num_channels = 1;
+ int frame_size_ms = 10;
+ };
+ static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
+ static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
+ static AudioCodecInfo QueryAudioEncoder(const Config& config);
+ static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
+ const Config& config,
+ int payload_type,
+ absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+ const FieldTrialsView* field_trials = nullptr);
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_L16_AUDIO_ENCODER_L16_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/L16/audio_encoder_L16_gn/moz.build b/third_party/libwebrtc/api/audio_codecs/L16/audio_encoder_L16_gn/moz.build
new file mode 100644
index 0000000000..49e0d546f1
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/L16/audio_encoder_L16_gn/moz.build
@@ -0,0 +1,225 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio_codecs/L16/audio_encoder_L16.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_encoder_L16_gn")
diff --git a/third_party/libwebrtc/api/audio_codecs/OWNERS b/third_party/libwebrtc/api/audio_codecs/OWNERS
new file mode 100644
index 0000000000..77b414abc3
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/OWNERS
@@ -0,0 +1,3 @@
+alessiob@webrtc.org
+henrik.lundin@webrtc.org
+jakobi@webrtc.org
diff --git a/third_party/libwebrtc/api/audio_codecs/audio_codec_pair_id.cc b/third_party/libwebrtc/api/audio_codecs/audio_codec_pair_id.cc
new file mode 100644
index 0000000000..6cb51ed6b7
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/audio_codec_pair_id.cc
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/audio_codec_pair_id.h"
+
+#include <atomic>
+#include <cstdint>
+
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+namespace {
+
+// Returns a new value that it has never returned before. You may call it at
+// most 2^63 times in the lifetime of the program. Note: The returned values
+// may be easily predictable.
+uint64_t GetNextId() {
+ static std::atomic<uint64_t> next_id(0);
+
+ // Atomically increment `next_id`, and return the previous value. Relaxed
+ // memory order is sufficient, since all we care about is that different
+ // callers return different values.
+ const uint64_t new_id = next_id.fetch_add(1, std::memory_order_relaxed);
+
+ // This check isn't atomic with the increment, so if we start 2^63 + 1
+ // invocations of GetNextId() in parallel, the last one to do the atomic
+ // increment could return the ID 0 before any of the others had time to
+ // trigger this DCHECK. We blithely assume that this won't happen.
+ RTC_DCHECK_LT(new_id, uint64_t{1} << 63) << "Used up all ID values";
+
+ return new_id;
+}
+
+// Make an integer ID more unpredictable. This is a 1:1 mapping, so you can
+// feed it any value, but the idea is that you can feed it a sequence such as
+// 0, 1, 2, ... and get a new sequence that isn't as trivially predictable, so
+// that users won't rely on it being consecutive or increasing or anything like
+// that.
+constexpr uint64_t ObfuscateId(uint64_t id) {
+ // Any nonzero coefficient that's relatively prime to 2^64 (that is, any odd
+ // number) and any constant will give a 1:1 mapping. These high-entropy
+ // values will prevent the sequence from being trivially predictable.
+ //
+ // Both the multiplication and the addition going to overflow almost always,
+ // but that's fine---we *want* arithmetic mod 2^64.
+ return uint64_t{0x85fdb20e1294309a} + uint64_t{0xc516ef5c37462469} * id;
+}
+
+// The first ten values. Verified against the Python function
+//
+// def f(n):
+// return (0x85fdb20e1294309a + 0xc516ef5c37462469 * n) % 2**64
+//
+// Callers should obviously not depend on these exact values...
+//
+// (On Visual C++, we have to disable warning C4307 (integral constant
+// overflow), even though unsigned integers have perfectly well-defined
+// overflow behavior.)
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4307)
+#endif
+static_assert(ObfuscateId(0) == uint64_t{0x85fdb20e1294309a}, "");
+static_assert(ObfuscateId(1) == uint64_t{0x4b14a16a49da5503}, "");
+static_assert(ObfuscateId(2) == uint64_t{0x102b90c68120796c}, "");
+static_assert(ObfuscateId(3) == uint64_t{0xd5428022b8669dd5}, "");
+static_assert(ObfuscateId(4) == uint64_t{0x9a596f7eefacc23e}, "");
+static_assert(ObfuscateId(5) == uint64_t{0x5f705edb26f2e6a7}, "");
+static_assert(ObfuscateId(6) == uint64_t{0x24874e375e390b10}, "");
+static_assert(ObfuscateId(7) == uint64_t{0xe99e3d93957f2f79}, "");
+static_assert(ObfuscateId(8) == uint64_t{0xaeb52cefccc553e2}, "");
+static_assert(ObfuscateId(9) == uint64_t{0x73cc1c4c040b784b}, "");
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+} // namespace
+
+AudioCodecPairId AudioCodecPairId::Create() {
+ return AudioCodecPairId(ObfuscateId(GetNextId()));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/audio_codec_pair_id.h b/third_party/libwebrtc/api/audio_codecs/audio_codec_pair_id.h
new file mode 100644
index 0000000000..b10f14ea66
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/audio_codec_pair_id.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_AUDIO_CODEC_PAIR_ID_H_
+#define API_AUDIO_CODECS_AUDIO_CODEC_PAIR_ID_H_
+
+#include <stdint.h>
+
+#include <utility>
+
+namespace webrtc {
+
+class AudioCodecPairId final {
+ public:
+ // Copyable, but not default constructible.
+ AudioCodecPairId() = delete;
+ AudioCodecPairId(const AudioCodecPairId&) = default;
+ AudioCodecPairId(AudioCodecPairId&&) = default;
+ AudioCodecPairId& operator=(const AudioCodecPairId&) = default;
+ AudioCodecPairId& operator=(AudioCodecPairId&&) = default;
+
+ friend void swap(AudioCodecPairId& a, AudioCodecPairId& b) {
+ using std::swap;
+ swap(a.id_, b.id_);
+ }
+
+ // Creates a new ID, unequal to any previously created ID.
+ static AudioCodecPairId Create();
+
+ // IDs can be tested for equality.
+ friend bool operator==(AudioCodecPairId a, AudioCodecPairId b) {
+ return a.id_ == b.id_;
+ }
+ friend bool operator!=(AudioCodecPairId a, AudioCodecPairId b) {
+ return a.id_ != b.id_;
+ }
+
+ // Comparisons. The ordering of ID values is completely arbitrary, but
+ // stable, so it's useful e.g. if you want to use IDs as keys in an ordered
+ // map.
+ friend bool operator<(AudioCodecPairId a, AudioCodecPairId b) {
+ return a.id_ < b.id_;
+ }
+ friend bool operator<=(AudioCodecPairId a, AudioCodecPairId b) {
+ return a.id_ <= b.id_;
+ }
+ friend bool operator>=(AudioCodecPairId a, AudioCodecPairId b) {
+ return a.id_ >= b.id_;
+ }
+ friend bool operator>(AudioCodecPairId a, AudioCodecPairId b) {
+ return a.id_ > b.id_;
+ }
+
+ // Returns a numeric representation of the ID. The numeric values are
+ // completely arbitrary, but stable, collision-free, and reasonably evenly
+ // distributed, so they are e.g. useful as hash values in unordered maps.
+ uint64_t NumericRepresentation() const { return id_; }
+
+ private:
+ explicit AudioCodecPairId(uint64_t id) : id_(id) {}
+
+ uint64_t id_;
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_AUDIO_CODEC_PAIR_ID_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/audio_codecs_api_gn/moz.build b/third_party/libwebrtc/api/audio_codecs/audio_codecs_api_gn/moz.build
new file mode 100644
index 0000000000..846946073e
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/audio_codecs_api_gn/moz.build
@@ -0,0 +1,228 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio_codecs/audio_codec_pair_id.cc",
+ "/third_party/libwebrtc/api/audio_codecs/audio_decoder.cc",
+ "/third_party/libwebrtc/api/audio_codecs/audio_encoder.cc",
+ "/third_party/libwebrtc/api/audio_codecs/audio_format.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_codecs_api_gn")
diff --git a/third_party/libwebrtc/api/audio_codecs/audio_decoder.cc b/third_party/libwebrtc/api/audio_codecs/audio_decoder.cc
new file mode 100644
index 0000000000..28f5b8aae8
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/audio_decoder.cc
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/audio_decoder.h"
+
+
+#include <memory>
+#include <utility>
+
+#include "api/array_view.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/sanitizer.h"
+#include "rtc_base/trace_event.h"
+
+namespace webrtc {
+
+namespace {
+
+class OldStyleEncodedFrame final : public AudioDecoder::EncodedAudioFrame {
+ public:
+ OldStyleEncodedFrame(AudioDecoder* decoder, rtc::Buffer&& payload)
+ : decoder_(decoder), payload_(std::move(payload)) {}
+
+ size_t Duration() const override {
+ const int ret = decoder_->PacketDuration(payload_.data(), payload_.size());
+ return ret < 0 ? 0 : static_cast<size_t>(ret);
+ }
+
+ absl::optional<DecodeResult> Decode(
+ rtc::ArrayView<int16_t> decoded) const override {
+ auto speech_type = AudioDecoder::kSpeech;
+ const int ret = decoder_->Decode(
+ payload_.data(), payload_.size(), decoder_->SampleRateHz(),
+ decoded.size() * sizeof(int16_t), decoded.data(), &speech_type);
+ return ret < 0 ? absl::nullopt
+ : absl::optional<DecodeResult>(
+ {static_cast<size_t>(ret), speech_type});
+ }
+
+ private:
+ AudioDecoder* const decoder_;
+ const rtc::Buffer payload_;
+};
+
+} // namespace
+
+bool AudioDecoder::EncodedAudioFrame::IsDtxPacket() const {
+ return false;
+}
+
+AudioDecoder::ParseResult::ParseResult() = default;
+AudioDecoder::ParseResult::ParseResult(ParseResult&& b) = default;
+AudioDecoder::ParseResult::ParseResult(uint32_t timestamp,
+ int priority,
+ std::unique_ptr<EncodedAudioFrame> frame)
+ : timestamp(timestamp), priority(priority), frame(std::move(frame)) {
+ RTC_DCHECK_GE(priority, 0);
+}
+
+AudioDecoder::ParseResult::~ParseResult() = default;
+
+AudioDecoder::ParseResult& AudioDecoder::ParseResult::operator=(
+ ParseResult&& b) = default;
+
+std::vector<AudioDecoder::ParseResult> AudioDecoder::ParsePayload(
+ rtc::Buffer&& payload,
+ uint32_t timestamp) {
+ std::vector<ParseResult> results;
+ std::unique_ptr<EncodedAudioFrame> frame(
+ new OldStyleEncodedFrame(this, std::move(payload)));
+ results.emplace_back(timestamp, 0, std::move(frame));
+ return results;
+}
+
+int AudioDecoder::Decode(const uint8_t* encoded,
+ size_t encoded_len,
+ int sample_rate_hz,
+ size_t max_decoded_bytes,
+ int16_t* decoded,
+ SpeechType* speech_type) {
+ TRACE_EVENT0("webrtc", "AudioDecoder::Decode");
+ rtc::MsanCheckInitialized(rtc::MakeArrayView(encoded, encoded_len));
+ int duration = PacketDuration(encoded, encoded_len);
+ if (duration >= 0 &&
+ duration * Channels() * sizeof(int16_t) > max_decoded_bytes) {
+ return -1;
+ }
+ return DecodeInternal(encoded, encoded_len, sample_rate_hz, decoded,
+ speech_type);
+}
+
+int AudioDecoder::DecodeRedundant(const uint8_t* encoded,
+ size_t encoded_len,
+ int sample_rate_hz,
+ size_t max_decoded_bytes,
+ int16_t* decoded,
+ SpeechType* speech_type) {
+ TRACE_EVENT0("webrtc", "AudioDecoder::DecodeRedundant");
+ rtc::MsanCheckInitialized(rtc::MakeArrayView(encoded, encoded_len));
+ int duration = PacketDurationRedundant(encoded, encoded_len);
+ if (duration >= 0 &&
+ duration * Channels() * sizeof(int16_t) > max_decoded_bytes) {
+ return -1;
+ }
+ return DecodeRedundantInternal(encoded, encoded_len, sample_rate_hz, decoded,
+ speech_type);
+}
+
+int AudioDecoder::DecodeRedundantInternal(const uint8_t* encoded,
+ size_t encoded_len,
+ int sample_rate_hz,
+ int16_t* decoded,
+ SpeechType* speech_type) {
+ return DecodeInternal(encoded, encoded_len, sample_rate_hz, decoded,
+ speech_type);
+}
+
+bool AudioDecoder::HasDecodePlc() const {
+ return false;
+}
+
+size_t AudioDecoder::DecodePlc(size_t num_frames, int16_t* decoded) {
+ return 0;
+}
+
+// TODO(bugs.webrtc.org/9676): Remove default implementation.
+void AudioDecoder::GeneratePlc(size_t /*requested_samples_per_channel*/,
+ rtc::BufferT<int16_t>* /*concealment_audio*/) {}
+
+int AudioDecoder::ErrorCode() {
+ return 0;
+}
+
+int AudioDecoder::PacketDuration(const uint8_t* encoded,
+ size_t encoded_len) const {
+ return kNotImplemented;
+}
+
+int AudioDecoder::PacketDurationRedundant(const uint8_t* encoded,
+ size_t encoded_len) const {
+ return kNotImplemented;
+}
+
+bool AudioDecoder::PacketHasFec(const uint8_t* encoded,
+ size_t encoded_len) const {
+ return false;
+}
+
+AudioDecoder::SpeechType AudioDecoder::ConvertSpeechType(int16_t type) {
+ switch (type) {
+ case 0: // TODO(hlundin): Both iSAC and Opus return 0 for speech.
+ case 1:
+ return kSpeech;
+ case 2:
+ return kComfortNoise;
+ default:
+ RTC_DCHECK_NOTREACHED();
+ return kSpeech;
+ }
+}
+
+constexpr int AudioDecoder::kMaxNumberOfChannels;
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/audio_decoder.h b/third_party/libwebrtc/api/audio_codecs/audio_decoder.h
new file mode 100644
index 0000000000..41138741bb
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/audio_decoder.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_AUDIO_DECODER_H_
+#define API_AUDIO_CODECS_AUDIO_DECODER_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "rtc_base/buffer.h"
+
+namespace webrtc {
+
+class AudioDecoder {
+ public:
+ enum SpeechType {
+ kSpeech = 1,
+ kComfortNoise = 2,
+ };
+
+ // Used by PacketDuration below. Save the value -1 for errors.
+ enum { kNotImplemented = -2 };
+
+ AudioDecoder() = default;
+ virtual ~AudioDecoder() = default;
+
+ AudioDecoder(const AudioDecoder&) = delete;
+ AudioDecoder& operator=(const AudioDecoder&) = delete;
+
+ class EncodedAudioFrame {
+ public:
+ struct DecodeResult {
+ size_t num_decoded_samples;
+ SpeechType speech_type;
+ };
+
+ virtual ~EncodedAudioFrame() = default;
+
+ // Returns the duration in samples-per-channel of this audio frame.
+ // If no duration can be ascertained, returns zero.
+ virtual size_t Duration() const = 0;
+
+ // Returns true if this packet contains DTX.
+ virtual bool IsDtxPacket() const;
+
+ // Decodes this frame of audio and writes the result in `decoded`.
+ // `decoded` must be large enough to store as many samples as indicated by a
+ // call to Duration() . On success, returns an absl::optional containing the
+ // total number of samples across all channels, as well as whether the
+ // decoder produced comfort noise or speech. On failure, returns an empty
+ // absl::optional. Decode may be called at most once per frame object.
+ virtual absl::optional<DecodeResult> Decode(
+ rtc::ArrayView<int16_t> decoded) const = 0;
+ };
+
+ struct ParseResult {
+ ParseResult();
+ ParseResult(uint32_t timestamp,
+ int priority,
+ std::unique_ptr<EncodedAudioFrame> frame);
+ ParseResult(ParseResult&& b);
+ ~ParseResult();
+
+ ParseResult& operator=(ParseResult&& b);
+
+ // The timestamp of the frame is in samples per channel.
+ uint32_t timestamp;
+ // The relative priority of the frame compared to other frames of the same
+ // payload and the same timeframe. A higher value means a lower priority.
+ // The highest priority is zero - negative values are not allowed.
+ int priority;
+ std::unique_ptr<EncodedAudioFrame> frame;
+ };
+
+ // Let the decoder parse this payload and prepare zero or more decodable
+ // frames. Each frame must be between 10 ms and 120 ms long. The caller must
+ // ensure that the AudioDecoder object outlives any frame objects returned by
+ // this call. The decoder is free to swap or move the data from the `payload`
+ // buffer. `timestamp` is the input timestamp, in samples, corresponding to
+ // the start of the payload.
+ virtual std::vector<ParseResult> ParsePayload(rtc::Buffer&& payload,
+ uint32_t timestamp);
+
+ // TODO(bugs.webrtc.org/10098): The Decode and DecodeRedundant methods are
+ // obsolete; callers should call ParsePayload instead. For now, subclasses
+ // must still implement DecodeInternal.
+
+ // Decodes `encode_len` bytes from `encoded` and writes the result in
+ // `decoded`. The maximum bytes allowed to be written into `decoded` is
+ // `max_decoded_bytes`. Returns the total number of samples across all
+ // channels. If the decoder produced comfort noise, `speech_type`
+ // is set to kComfortNoise, otherwise it is kSpeech. The desired output
+ // sample rate is provided in `sample_rate_hz`, which must be valid for the
+ // codec at hand.
+ int Decode(const uint8_t* encoded,
+ size_t encoded_len,
+ int sample_rate_hz,
+ size_t max_decoded_bytes,
+ int16_t* decoded,
+ SpeechType* speech_type);
+
+ // Same as Decode(), but interfaces to the decoders redundant decode function.
+ // The default implementation simply calls the regular Decode() method.
+ int DecodeRedundant(const uint8_t* encoded,
+ size_t encoded_len,
+ int sample_rate_hz,
+ size_t max_decoded_bytes,
+ int16_t* decoded,
+ SpeechType* speech_type);
+
+ // Indicates if the decoder implements the DecodePlc method.
+ virtual bool HasDecodePlc() const;
+
+ // Calls the packet-loss concealment of the decoder to update the state after
+ // one or several lost packets. The caller has to make sure that the
+ // memory allocated in `decoded` should accommodate `num_frames` frames.
+ virtual size_t DecodePlc(size_t num_frames, int16_t* decoded);
+
+ // Asks the decoder to generate packet-loss concealment and append it to the
+ // end of `concealment_audio`. The concealment audio should be in
+ // channel-interleaved format, with as many channels as the last decoded
+ // packet produced. The implementation must produce at least
+ // requested_samples_per_channel, or nothing at all. This is a signal to the
+ // caller to conceal the loss with other means. If the implementation provides
+ // concealment samples, it is also responsible for "stitching" it together
+ // with the decoded audio on either side of the concealment.
+ // Note: The default implementation of GeneratePlc will be deleted soon. All
+ // implementations must provide their own, which can be a simple as a no-op.
+ // TODO(bugs.webrtc.org/9676): Remove default implementation.
+ virtual void GeneratePlc(size_t requested_samples_per_channel,
+ rtc::BufferT<int16_t>* concealment_audio);
+
+ // Resets the decoder state (empty buffers etc.).
+ virtual void Reset() = 0;
+
+ // Returns the last error code from the decoder.
+ virtual int ErrorCode();
+
+ // Returns the duration in samples-per-channel of the payload in `encoded`
+ // which is `encoded_len` bytes long. Returns kNotImplemented if no duration
+ // estimate is available, or -1 in case of an error.
+ virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
+
+ // Returns the duration in samples-per-channel of the redandant payload in
+ // `encoded` which is `encoded_len` bytes long. Returns kNotImplemented if no
+ // duration estimate is available, or -1 in case of an error.
+ virtual int PacketDurationRedundant(const uint8_t* encoded,
+ size_t encoded_len) const;
+
+ // Detects whether a packet has forward error correction. The packet is
+ // comprised of the samples in `encoded` which is `encoded_len` bytes long.
+ // Returns true if the packet has FEC and false otherwise.
+ virtual bool PacketHasFec(const uint8_t* encoded, size_t encoded_len) const;
+
+ // Returns the actual sample rate of the decoder's output. This value may not
+ // change during the lifetime of the decoder.
+ virtual int SampleRateHz() const = 0;
+
+ // The number of channels in the decoder's output. This value may not change
+ // during the lifetime of the decoder.
+ virtual size_t Channels() const = 0;
+
+ // The maximum number of audio channels supported by WebRTC decoders.
+ static constexpr int kMaxNumberOfChannels = 24;
+
+ protected:
+ static SpeechType ConvertSpeechType(int16_t type);
+
+ virtual int DecodeInternal(const uint8_t* encoded,
+ size_t encoded_len,
+ int sample_rate_hz,
+ int16_t* decoded,
+ SpeechType* speech_type) = 0;
+
+ virtual int DecodeRedundantInternal(const uint8_t* encoded,
+ size_t encoded_len,
+ int sample_rate_hz,
+ int16_t* decoded,
+ SpeechType* speech_type);
+};
+
+} // namespace webrtc
+#endif // API_AUDIO_CODECS_AUDIO_DECODER_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/audio_decoder_factory.h b/third_party/libwebrtc/api/audio_codecs/audio_decoder_factory.h
new file mode 100644
index 0000000000..2811f6704b
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/audio_decoder_factory.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_AUDIO_DECODER_FACTORY_H_
+#define API_AUDIO_CODECS_AUDIO_DECODER_FACTORY_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/audio_codecs/audio_codec_pair_id.h"
+#include "api/audio_codecs/audio_decoder.h"
+#include "api/audio_codecs/audio_format.h"
+#include "rtc_base/ref_count.h"
+
+namespace webrtc {
+
+// A factory that creates AudioDecoders.
+class AudioDecoderFactory : public rtc::RefCountInterface {
+ public:
+ virtual std::vector<AudioCodecSpec> GetSupportedDecoders() = 0;
+
+ virtual bool IsSupportedDecoder(const SdpAudioFormat& format) = 0;
+
+ // Create a new decoder instance. The `codec_pair_id` argument is used to link
+ // encoders and decoders that talk to the same remote entity: if a
+ // AudioEncoderFactory::MakeAudioEncoder() and a
+ // AudioDecoderFactory::MakeAudioDecoder() call receive non-null IDs that
+ // compare equal, the factory implementations may assume that the encoder and
+ // decoder form a pair. (The intended use case for this is to set up
+ // communication between the AudioEncoder and AudioDecoder instances, which is
+ // needed for some codecs with built-in bandwidth adaptation.)
+ //
+ // Returns null if the format isn't supported.
+ //
+ // Note: Implementations need to be robust against combinations other than
+ // one encoder, one decoder getting the same ID; such decoders must still
+ // work.
+ virtual std::unique_ptr<AudioDecoder> MakeAudioDecoder(
+ const SdpAudioFormat& format,
+ absl::optional<AudioCodecPairId> codec_pair_id) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_AUDIO_DECODER_FACTORY_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/audio_decoder_factory_template.h b/third_party/libwebrtc/api/audio_codecs/audio_decoder_factory_template.h
new file mode 100644
index 0000000000..7ea0c91372
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/audio_decoder_factory_template.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_AUDIO_DECODER_FACTORY_TEMPLATE_H_
+#define API_AUDIO_CODECS_AUDIO_DECODER_FACTORY_TEMPLATE_H_
+
+#include <memory>
+#include <vector>
+
+#include "api/audio_codecs/audio_decoder_factory.h"
+#include "api/field_trials_view.h"
+#include "api/make_ref_counted.h"
+#include "api/scoped_refptr.h"
+
+namespace webrtc {
+
+namespace audio_decoder_factory_template_impl {
+
+template <typename... Ts>
+struct Helper;
+
+// Base case: 0 template parameters.
+template <>
+struct Helper<> {
+ static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs) {}
+ static bool IsSupportedDecoder(const SdpAudioFormat& format) { return false; }
+ static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
+ const SdpAudioFormat& format,
+ absl::optional<AudioCodecPairId> codec_pair_id,
+ const FieldTrialsView* field_trials) {
+ return nullptr;
+ }
+};
+
+// Inductive case: Called with n + 1 template parameters; calls subroutines
+// with n template parameters.
+template <typename T, typename... Ts>
+struct Helper<T, Ts...> {
+ static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs) {
+ T::AppendSupportedDecoders(specs);
+ Helper<Ts...>::AppendSupportedDecoders(specs);
+ }
+ static bool IsSupportedDecoder(const SdpAudioFormat& format) {
+ auto opt_config = T::SdpToConfig(format);
+ static_assert(std::is_same<decltype(opt_config),
+ absl::optional<typename T::Config>>::value,
+ "T::SdpToConfig() must return a value of type "
+ "absl::optional<T::Config>");
+ return opt_config ? true : Helper<Ts...>::IsSupportedDecoder(format);
+ }
+ static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
+ const SdpAudioFormat& format,
+ absl::optional<AudioCodecPairId> codec_pair_id,
+ const FieldTrialsView* field_trials) {
+ auto opt_config = T::SdpToConfig(format);
+ return opt_config ? T::MakeAudioDecoder(*opt_config, codec_pair_id)
+ : Helper<Ts...>::MakeAudioDecoder(format, codec_pair_id,
+ field_trials);
+ }
+};
+
+template <typename... Ts>
+class AudioDecoderFactoryT : public AudioDecoderFactory {
+ public:
+ explicit AudioDecoderFactoryT(const FieldTrialsView* field_trials) {
+ field_trials_ = field_trials;
+ }
+
+ std::vector<AudioCodecSpec> GetSupportedDecoders() override {
+ std::vector<AudioCodecSpec> specs;
+ Helper<Ts...>::AppendSupportedDecoders(&specs);
+ return specs;
+ }
+
+ bool IsSupportedDecoder(const SdpAudioFormat& format) override {
+ return Helper<Ts...>::IsSupportedDecoder(format);
+ }
+
+ std::unique_ptr<AudioDecoder> MakeAudioDecoder(
+ const SdpAudioFormat& format,
+ absl::optional<AudioCodecPairId> codec_pair_id) override {
+ return Helper<Ts...>::MakeAudioDecoder(format, codec_pair_id,
+ field_trials_);
+ }
+
+ const FieldTrialsView* field_trials_;
+};
+
+} // namespace audio_decoder_factory_template_impl
+
+// Make an AudioDecoderFactory that can create instances of the given decoders.
+//
+// Each decoder type is given as a template argument to the function; it should
+// be a struct with the following static member functions:
+//
+// // Converts `audio_format` to a ConfigType instance. Returns an empty
+// // optional if `audio_format` doesn't correctly specify a decoder of our
+// // type.
+// absl::optional<ConfigType> SdpToConfig(const SdpAudioFormat& audio_format);
+//
+// // Appends zero or more AudioCodecSpecs to the list that will be returned
+// // by AudioDecoderFactory::GetSupportedDecoders().
+// void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
+//
+// // Creates an AudioDecoder for the specified format. Used to implement
+// // AudioDecoderFactory::MakeAudioDecoder().
+// std::unique_ptr<AudioDecoder> MakeAudioDecoder(
+// const ConfigType& config,
+// absl::optional<AudioCodecPairId> codec_pair_id);
+//
+// ConfigType should be a type that encapsulates all the settings needed to
+// create an AudioDecoder. T::Config (where T is the decoder struct) should
+// either be the config type, or an alias for it.
+//
+// Whenever it tries to do something, the new factory will try each of the
+// decoder types in the order they were specified in the template argument
+// list, stopping at the first one that claims to be able to do the job.
+//
+// TODO(kwiberg): Point at CreateBuiltinAudioDecoderFactory() for an example of
+// how it is used.
+template <typename... Ts>
+rtc::scoped_refptr<AudioDecoderFactory> CreateAudioDecoderFactory(
+ const FieldTrialsView* field_trials = nullptr) {
+ // There's no technical reason we couldn't allow zero template parameters,
+ // but such a factory couldn't create any decoders, and callers can do this
+ // by mistake by simply forgetting the <> altogether. So we forbid it in
+ // order to prevent caller foot-shooting.
+ static_assert(sizeof...(Ts) >= 1,
+ "Caller must give at least one template parameter");
+
+ return rtc::make_ref_counted<
+ audio_decoder_factory_template_impl::AudioDecoderFactoryT<Ts...>>(
+ field_trials);
+}
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_AUDIO_DECODER_FACTORY_TEMPLATE_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/audio_encoder.cc b/third_party/libwebrtc/api/audio_codecs/audio_encoder.cc
new file mode 100644
index 0000000000..31bb8739f7
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/audio_encoder.cc
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/audio_encoder.h"
+
+#include "rtc_base/checks.h"
+#include "rtc_base/trace_event.h"
+
+namespace webrtc {
+
+ANAStats::ANAStats() = default;
+ANAStats::~ANAStats() = default;
+ANAStats::ANAStats(const ANAStats&) = default;
+
+AudioEncoder::EncodedInfo::EncodedInfo() = default;
+AudioEncoder::EncodedInfo::EncodedInfo(const EncodedInfo&) = default;
+AudioEncoder::EncodedInfo::EncodedInfo(EncodedInfo&&) = default;
+AudioEncoder::EncodedInfo::~EncodedInfo() = default;
+AudioEncoder::EncodedInfo& AudioEncoder::EncodedInfo::operator=(
+ const EncodedInfo&) = default;
+AudioEncoder::EncodedInfo& AudioEncoder::EncodedInfo::operator=(EncodedInfo&&) =
+ default;
+
+int AudioEncoder::RtpTimestampRateHz() const {
+ return SampleRateHz();
+}
+
+AudioEncoder::EncodedInfo AudioEncoder::Encode(
+ uint32_t rtp_timestamp,
+ rtc::ArrayView<const int16_t> audio,
+ rtc::Buffer* encoded) {
+ TRACE_EVENT0("webrtc", "AudioEncoder::Encode");
+ RTC_CHECK_EQ(audio.size(),
+ static_cast<size_t>(NumChannels() * SampleRateHz() / 100));
+
+ const size_t old_size = encoded->size();
+ EncodedInfo info = EncodeImpl(rtp_timestamp, audio, encoded);
+ RTC_CHECK_EQ(encoded->size() - old_size, info.encoded_bytes);
+ return info;
+}
+
+bool AudioEncoder::SetFec(bool enable) {
+ return !enable;
+}
+
+bool AudioEncoder::SetDtx(bool enable) {
+ return !enable;
+}
+
+bool AudioEncoder::GetDtx() const {
+ return false;
+}
+
+bool AudioEncoder::SetApplication(Application application) {
+ return false;
+}
+
+void AudioEncoder::SetMaxPlaybackRate(int frequency_hz) {}
+
+void AudioEncoder::SetTargetBitrate(int target_bps) {}
+
+rtc::ArrayView<std::unique_ptr<AudioEncoder>>
+AudioEncoder::ReclaimContainedEncoders() {
+ return nullptr;
+}
+
+bool AudioEncoder::EnableAudioNetworkAdaptor(const std::string& config_string,
+ RtcEventLog* event_log) {
+ return false;
+}
+
+void AudioEncoder::DisableAudioNetworkAdaptor() {}
+
+void AudioEncoder::OnReceivedUplinkPacketLossFraction(
+ float uplink_packet_loss_fraction) {}
+
+void AudioEncoder::OnReceivedUplinkRecoverablePacketLossFraction(
+ float uplink_recoverable_packet_loss_fraction) {
+ RTC_DCHECK_NOTREACHED();
+}
+
+void AudioEncoder::OnReceivedTargetAudioBitrate(int target_audio_bitrate_bps) {
+ OnReceivedUplinkBandwidth(target_audio_bitrate_bps, absl::nullopt);
+}
+
+void AudioEncoder::OnReceivedUplinkBandwidth(
+ int target_audio_bitrate_bps,
+ absl::optional<int64_t> bwe_period_ms) {}
+
+void AudioEncoder::OnReceivedUplinkAllocation(BitrateAllocationUpdate update) {
+ OnReceivedUplinkBandwidth(update.target_bitrate.bps(),
+ update.bwe_period.ms());
+}
+
+void AudioEncoder::OnReceivedRtt(int rtt_ms) {}
+
+void AudioEncoder::OnReceivedOverhead(size_t overhead_bytes_per_packet) {}
+
+void AudioEncoder::SetReceiverFrameLengthRange(int min_frame_length_ms,
+ int max_frame_length_ms) {}
+
+ANAStats AudioEncoder::GetANAStats() const {
+ return ANAStats();
+}
+
+constexpr int AudioEncoder::kMaxNumberOfChannels;
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/audio_encoder.h b/third_party/libwebrtc/api/audio_codecs/audio_encoder.h
new file mode 100644
index 0000000000..7f5a34214f
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/audio_encoder.h
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_AUDIO_ENCODER_H_
+#define API_AUDIO_CODECS_AUDIO_ENCODER_H_
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/base/attributes.h"
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/call/bitrate_allocation.h"
+#include "api/units/time_delta.h"
+#include "rtc_base/buffer.h"
+
+namespace webrtc {
+
+class RtcEventLog;
+
+// Statistics related to Audio Network Adaptation.
+struct ANAStats {
+ ANAStats();
+ ANAStats(const ANAStats&);
+ ~ANAStats();
+ // Number of actions taken by the ANA bitrate controller since the start of
+ // the call. If this value is not set, it indicates that the bitrate
+ // controller is disabled.
+ absl::optional<uint32_t> bitrate_action_counter;
+ // Number of actions taken by the ANA channel controller since the start of
+ // the call. If this value is not set, it indicates that the channel
+ // controller is disabled.
+ absl::optional<uint32_t> channel_action_counter;
+ // Number of actions taken by the ANA DTX controller since the start of the
+ // call. If this value is not set, it indicates that the DTX controller is
+ // disabled.
+ absl::optional<uint32_t> dtx_action_counter;
+ // Number of actions taken by the ANA FEC controller since the start of the
+ // call. If this value is not set, it indicates that the FEC controller is
+ // disabled.
+ absl::optional<uint32_t> fec_action_counter;
+ // Number of times the ANA frame length controller decided to increase the
+ // frame length since the start of the call. If this value is not set, it
+ // indicates that the frame length controller is disabled.
+ absl::optional<uint32_t> frame_length_increase_counter;
+ // Number of times the ANA frame length controller decided to decrease the
+ // frame length since the start of the call. If this value is not set, it
+ // indicates that the frame length controller is disabled.
+ absl::optional<uint32_t> frame_length_decrease_counter;
+ // The uplink packet loss fractions as set by the ANA FEC controller. If this
+ // value is not set, it indicates that the ANA FEC controller is not active.
+ absl::optional<float> uplink_packet_loss_fraction;
+};
+
+// This is the interface class for encoders in AudioCoding module. Each codec
+// type must have an implementation of this class.
+class AudioEncoder {
+ public:
+ // Used for UMA logging of codec usage. The same codecs, with the
+ // same values, must be listed in
+ // src/tools/metrics/histograms/histograms.xml in chromium to log
+ // correct values.
+ enum class CodecType {
+ kOther = 0, // Codec not specified, and/or not listed in this enum
+ kOpus = 1,
+ kIsac = 2,
+ kPcmA = 3,
+ kPcmU = 4,
+ kG722 = 5,
+ kIlbc = 6,
+
+ // Number of histogram bins in the UMA logging of codec types. The
+ // total number of different codecs that are logged cannot exceed this
+ // number.
+ kMaxLoggedAudioCodecTypes
+ };
+
+ struct EncodedInfoLeaf {
+ size_t encoded_bytes = 0;
+ uint32_t encoded_timestamp = 0;
+ int payload_type = 0;
+ bool send_even_if_empty = false;
+ bool speech = true;
+ CodecType encoder_type = CodecType::kOther;
+ };
+
+ // This is the main struct for auxiliary encoding information. Each encoded
+ // packet should be accompanied by one EncodedInfo struct, containing the
+ // total number of `encoded_bytes`, the `encoded_timestamp` and the
+ // `payload_type`. If the packet contains redundant encodings, the `redundant`
+ // vector will be populated with EncodedInfoLeaf structs. Each struct in the
+ // vector represents one encoding; the order of structs in the vector is the
+ // same as the order in which the actual payloads are written to the byte
+ // stream. When EncoderInfoLeaf structs are present in the vector, the main
+ // struct's `encoded_bytes` will be the sum of all the `encoded_bytes` in the
+ // vector.
+ struct EncodedInfo : public EncodedInfoLeaf {
+ EncodedInfo();
+ EncodedInfo(const EncodedInfo&);
+ EncodedInfo(EncodedInfo&&);
+ ~EncodedInfo();
+ EncodedInfo& operator=(const EncodedInfo&);
+ EncodedInfo& operator=(EncodedInfo&&);
+
+ std::vector<EncodedInfoLeaf> redundant;
+ };
+
+ virtual ~AudioEncoder() = default;
+
+ // Returns the input sample rate in Hz and the number of input channels.
+ // These are constants set at instantiation time.
+ virtual int SampleRateHz() const = 0;
+ virtual size_t NumChannels() const = 0;
+
+ // Returns the rate at which the RTP timestamps are updated. The default
+ // implementation returns SampleRateHz().
+ virtual int RtpTimestampRateHz() const;
+
+ // Returns the number of 10 ms frames the encoder will put in the next
+ // packet. This value may only change when Encode() outputs a packet; i.e.,
+ // the encoder may vary the number of 10 ms frames from packet to packet, but
+ // it must decide the length of the next packet no later than when outputting
+ // the preceding packet.
+ virtual size_t Num10MsFramesInNextPacket() const = 0;
+
+ // Returns the maximum value that can be returned by
+ // Num10MsFramesInNextPacket().
+ virtual size_t Max10MsFramesInAPacket() const = 0;
+
+ // Returns the current target bitrate in bits/s. The value -1 means that the
+ // codec adapts the target automatically, and a current target cannot be
+ // provided.
+ virtual int GetTargetBitrate() const = 0;
+
+ // Accepts one 10 ms block of input audio (i.e., SampleRateHz() / 100 *
+ // NumChannels() samples). Multi-channel audio must be sample-interleaved.
+ // The encoder appends zero or more bytes of output to `encoded` and returns
+ // additional encoding information. Encode() checks some preconditions, calls
+ // EncodeImpl() which does the actual work, and then checks some
+ // postconditions.
+ EncodedInfo Encode(uint32_t rtp_timestamp,
+ rtc::ArrayView<const int16_t> audio,
+ rtc::Buffer* encoded);
+
+ // Resets the encoder to its starting state, discarding any input that has
+ // been fed to the encoder but not yet emitted in a packet.
+ virtual void Reset() = 0;
+
+ // Enables or disables codec-internal FEC (forward error correction). Returns
+ // true if the codec was able to comply. The default implementation returns
+ // true when asked to disable FEC and false when asked to enable it (meaning
+ // that FEC isn't supported).
+ virtual bool SetFec(bool enable);
+
+ // Enables or disables codec-internal VAD/DTX. Returns true if the codec was
+ // able to comply. The default implementation returns true when asked to
+ // disable DTX and false when asked to enable it (meaning that DTX isn't
+ // supported).
+ virtual bool SetDtx(bool enable);
+
+ // Returns the status of codec-internal DTX. The default implementation always
+ // returns false.
+ virtual bool GetDtx() const;
+
+ // Sets the application mode. Returns true if the codec was able to comply.
+ // The default implementation just returns false.
+ enum class Application { kSpeech, kAudio };
+ virtual bool SetApplication(Application application);
+
+ // Tells the encoder about the highest sample rate the decoder is expected to
+ // use when decoding the bitstream. The encoder would typically use this
+ // information to adjust the quality of the encoding. The default
+ // implementation does nothing.
+ virtual void SetMaxPlaybackRate(int frequency_hz);
+
+ // Tells the encoder what average bitrate we'd like it to produce. The
+ // encoder is free to adjust or disregard the given bitrate (the default
+ // implementation does the latter).
+ ABSL_DEPRECATED("Use OnReceivedTargetAudioBitrate instead")
+ virtual void SetTargetBitrate(int target_bps);
+
+ // Causes this encoder to let go of any other encoders it contains, and
+ // returns a pointer to an array where they are stored (which is required to
+ // live as long as this encoder). Unless the returned array is empty, you may
+ // not call any methods on this encoder afterwards, except for the
+ // destructor. The default implementation just returns an empty array.
+ // NOTE: This method is subject to change. Do not call or override it.
+ virtual rtc::ArrayView<std::unique_ptr<AudioEncoder>>
+ ReclaimContainedEncoders();
+
+ // Enables audio network adaptor. Returns true if successful.
+ virtual bool EnableAudioNetworkAdaptor(const std::string& config_string,
+ RtcEventLog* event_log);
+
+ // Disables audio network adaptor.
+ virtual void DisableAudioNetworkAdaptor();
+
+ // Provides uplink packet loss fraction to this encoder to allow it to adapt.
+ // `uplink_packet_loss_fraction` is in the range [0.0, 1.0].
+ virtual void OnReceivedUplinkPacketLossFraction(
+ float uplink_packet_loss_fraction);
+
+ ABSL_DEPRECATED("")
+ virtual void OnReceivedUplinkRecoverablePacketLossFraction(
+ float uplink_recoverable_packet_loss_fraction);
+
+ // Provides target audio bitrate to this encoder to allow it to adapt.
+ virtual void OnReceivedTargetAudioBitrate(int target_bps);
+
+ // Provides target audio bitrate and corresponding probing interval of
+ // the bandwidth estimator to this encoder to allow it to adapt.
+ virtual void OnReceivedUplinkBandwidth(int target_audio_bitrate_bps,
+ absl::optional<int64_t> bwe_period_ms);
+
+ // Provides target audio bitrate and corresponding probing interval of
+ // the bandwidth estimator to this encoder to allow it to adapt.
+ virtual void OnReceivedUplinkAllocation(BitrateAllocationUpdate update);
+
+ // Provides RTT to this encoder to allow it to adapt.
+ virtual void OnReceivedRtt(int rtt_ms);
+
+ // Provides overhead to this encoder to adapt. The overhead is the number of
+ // bytes that will be added to each packet the encoder generates.
+ virtual void OnReceivedOverhead(size_t overhead_bytes_per_packet);
+
+ // To allow encoder to adapt its frame length, it must be provided the frame
+ // length range that receivers can accept.
+ virtual void SetReceiverFrameLengthRange(int min_frame_length_ms,
+ int max_frame_length_ms);
+
+ // Get statistics related to audio network adaptation.
+ virtual ANAStats GetANAStats() const;
+
+ // The range of frame lengths that are supported or nullopt if there's no sch
+ // information. This is used to calculated the full bitrate range, including
+ // overhead.
+ virtual absl::optional<std::pair<TimeDelta, TimeDelta>> GetFrameLengthRange()
+ const = 0;
+
+ // The maximum number of audio channels supported by WebRTC encoders.
+ static constexpr int kMaxNumberOfChannels = 24;
+
+ protected:
+ // Subclasses implement this to perform the actual encoding. Called by
+ // Encode().
+ virtual EncodedInfo EncodeImpl(uint32_t rtp_timestamp,
+ rtc::ArrayView<const int16_t> audio,
+ rtc::Buffer* encoded) = 0;
+};
+} // namespace webrtc
+#endif // API_AUDIO_CODECS_AUDIO_ENCODER_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/audio_encoder_factory.h b/third_party/libwebrtc/api/audio_codecs/audio_encoder_factory.h
new file mode 100644
index 0000000000..6128b1b6f3
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/audio_encoder_factory.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_AUDIO_ENCODER_FACTORY_H_
+#define API_AUDIO_CODECS_AUDIO_ENCODER_FACTORY_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/audio_codecs/audio_codec_pair_id.h"
+#include "api/audio_codecs/audio_encoder.h"
+#include "api/audio_codecs/audio_format.h"
+#include "rtc_base/ref_count.h"
+
+namespace webrtc {
+
+// A factory that creates AudioEncoders.
+class AudioEncoderFactory : public rtc::RefCountInterface {
+ public:
+ // Returns a prioritized list of audio codecs, to use for signaling etc.
+ virtual std::vector<AudioCodecSpec> GetSupportedEncoders() = 0;
+
+ // Returns information about how this format would be encoded, provided it's
+ // supported. More format and format variations may be supported than those
+ // returned by GetSupportedEncoders().
+ virtual absl::optional<AudioCodecInfo> QueryAudioEncoder(
+ const SdpAudioFormat& format) = 0;
+
+ // Creates an AudioEncoder for the specified format. The encoder will tags its
+ // payloads with the specified payload type. The `codec_pair_id` argument is
+ // used to link encoders and decoders that talk to the same remote entity: if
+ // a AudioEncoderFactory::MakeAudioEncoder() and a
+ // AudioDecoderFactory::MakeAudioDecoder() call receive non-null IDs that
+ // compare equal, the factory implementations may assume that the encoder and
+ // decoder form a pair. (The intended use case for this is to set up
+ // communication between the AudioEncoder and AudioDecoder instances, which is
+ // needed for some codecs with built-in bandwidth adaptation.)
+ //
+ // Returns null if the format isn't supported.
+ //
+ // Note: Implementations need to be robust against combinations other than
+ // one encoder, one decoder getting the same ID; such encoders must still
+ // work.
+ //
+ // TODO(ossu): Try to avoid audio encoders having to know their payload type.
+ virtual std::unique_ptr<AudioEncoder> MakeAudioEncoder(
+ int payload_type,
+ const SdpAudioFormat& format,
+ absl::optional<AudioCodecPairId> codec_pair_id) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_AUDIO_ENCODER_FACTORY_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/audio_encoder_factory_template.h b/third_party/libwebrtc/api/audio_codecs/audio_encoder_factory_template.h
new file mode 100644
index 0000000000..8a70ba2268
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/audio_encoder_factory_template.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_AUDIO_ENCODER_FACTORY_TEMPLATE_H_
+#define API_AUDIO_CODECS_AUDIO_ENCODER_FACTORY_TEMPLATE_H_
+
+#include <memory>
+#include <vector>
+
+#include "api/audio_codecs/audio_encoder_factory.h"
+#include "api/field_trials_view.h"
+#include "api/make_ref_counted.h"
+#include "api/scoped_refptr.h"
+
+namespace webrtc {
+
+namespace audio_encoder_factory_template_impl {
+
+template <typename... Ts>
+struct Helper;
+
+// Base case: 0 template parameters.
+template <>
+struct Helper<> {
+ static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs) {}
+ static absl::optional<AudioCodecInfo> QueryAudioEncoder(
+ const SdpAudioFormat& format) {
+ return absl::nullopt;
+ }
+ static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
+ int payload_type,
+ const SdpAudioFormat& format,
+ absl::optional<AudioCodecPairId> codec_pair_id,
+ const FieldTrialsView* field_trials) {
+ return nullptr;
+ }
+};
+
+// Inductive case: Called with n + 1 template parameters; calls subroutines
+// with n template parameters.
+template <typename T, typename... Ts>
+struct Helper<T, Ts...> {
+ static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs) {
+ T::AppendSupportedEncoders(specs);
+ Helper<Ts...>::AppendSupportedEncoders(specs);
+ }
+ static absl::optional<AudioCodecInfo> QueryAudioEncoder(
+ const SdpAudioFormat& format) {
+ auto opt_config = T::SdpToConfig(format);
+ static_assert(std::is_same<decltype(opt_config),
+ absl::optional<typename T::Config>>::value,
+ "T::SdpToConfig() must return a value of type "
+ "absl::optional<T::Config>");
+ return opt_config ? absl::optional<AudioCodecInfo>(
+ T::QueryAudioEncoder(*opt_config))
+ : Helper<Ts...>::QueryAudioEncoder(format);
+ }
+ static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
+ int payload_type,
+ const SdpAudioFormat& format,
+ absl::optional<AudioCodecPairId> codec_pair_id,
+ const FieldTrialsView* field_trials) {
+ auto opt_config = T::SdpToConfig(format);
+ if (opt_config) {
+ return T::MakeAudioEncoder(*opt_config, payload_type, codec_pair_id);
+ } else {
+ return Helper<Ts...>::MakeAudioEncoder(payload_type, format,
+ codec_pair_id, field_trials);
+ }
+ }
+};
+
+template <typename... Ts>
+class AudioEncoderFactoryT : public AudioEncoderFactory {
+ public:
+ explicit AudioEncoderFactoryT(const FieldTrialsView* field_trials) {
+ field_trials_ = field_trials;
+ }
+
+ std::vector<AudioCodecSpec> GetSupportedEncoders() override {
+ std::vector<AudioCodecSpec> specs;
+ Helper<Ts...>::AppendSupportedEncoders(&specs);
+ return specs;
+ }
+
+ absl::optional<AudioCodecInfo> QueryAudioEncoder(
+ const SdpAudioFormat& format) override {
+ return Helper<Ts...>::QueryAudioEncoder(format);
+ }
+
+ std::unique_ptr<AudioEncoder> MakeAudioEncoder(
+ int payload_type,
+ const SdpAudioFormat& format,
+ absl::optional<AudioCodecPairId> codec_pair_id) override {
+ return Helper<Ts...>::MakeAudioEncoder(payload_type, format, codec_pair_id,
+ field_trials_);
+ }
+
+ const FieldTrialsView* field_trials_;
+};
+
+} // namespace audio_encoder_factory_template_impl
+
+// Make an AudioEncoderFactory that can create instances of the given encoders.
+//
+// Each encoder type is given as a template argument to the function; it should
+// be a struct with the following static member functions:
+//
+// // Converts `audio_format` to a ConfigType instance. Returns an empty
+// // optional if `audio_format` doesn't correctly specify an encoder of our
+// // type.
+// absl::optional<ConfigType> SdpToConfig(const SdpAudioFormat& audio_format);
+//
+// // Appends zero or more AudioCodecSpecs to the list that will be returned
+// // by AudioEncoderFactory::GetSupportedEncoders().
+// void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
+//
+// // Returns information about how this format would be encoded. Used to
+// // implement AudioEncoderFactory::QueryAudioEncoder().
+// AudioCodecInfo QueryAudioEncoder(const ConfigType& config);
+//
+// // Creates an AudioEncoder for the specified format. Used to implement
+// // AudioEncoderFactory::MakeAudioEncoder().
+// std::unique_ptr<AudioDecoder> MakeAudioEncoder(
+// const ConfigType& config,
+// int payload_type,
+// absl::optional<AudioCodecPairId> codec_pair_id);
+//
+// ConfigType should be a type that encapsulates all the settings needed to
+// create an AudioEncoder. T::Config (where T is the encoder struct) should
+// either be the config type, or an alias for it.
+//
+// Whenever it tries to do something, the new factory will try each of the
+// encoders in the order they were specified in the template argument list,
+// stopping at the first one that claims to be able to do the job.
+//
+// TODO(kwiberg): Point at CreateBuiltinAudioEncoderFactory() for an example of
+// how it is used.
+template <typename... Ts>
+rtc::scoped_refptr<AudioEncoderFactory> CreateAudioEncoderFactory(
+ const FieldTrialsView* field_trials = nullptr) {
+ // There's no technical reason we couldn't allow zero template parameters,
+ // but such a factory couldn't create any encoders, and callers can do this
+ // by mistake by simply forgetting the <> altogether. So we forbid it in
+ // order to prevent caller foot-shooting.
+ static_assert(sizeof...(Ts) >= 1,
+ "Caller must give at least one template parameter");
+
+ return rtc::make_ref_counted<
+ audio_encoder_factory_template_impl::AudioEncoderFactoryT<Ts...>>(
+ field_trials);
+}
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_AUDIO_ENCODER_FACTORY_TEMPLATE_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/audio_format.cc b/third_party/libwebrtc/api/audio_codecs/audio_format.cc
new file mode 100644
index 0000000000..2a529a49ee
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/audio_format.cc
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/audio_format.h"
+
+#include <utility>
+
+#include "absl/strings/match.h"
+
+namespace webrtc {
+
+SdpAudioFormat::SdpAudioFormat(const SdpAudioFormat&) = default;
+SdpAudioFormat::SdpAudioFormat(SdpAudioFormat&&) = default;
+
+SdpAudioFormat::SdpAudioFormat(absl::string_view name,
+ int clockrate_hz,
+ size_t num_channels)
+ : name(name), clockrate_hz(clockrate_hz), num_channels(num_channels) {}
+
+SdpAudioFormat::SdpAudioFormat(absl::string_view name,
+ int clockrate_hz,
+ size_t num_channels,
+ const Parameters& param)
+ : name(name),
+ clockrate_hz(clockrate_hz),
+ num_channels(num_channels),
+ parameters(param) {}
+
+SdpAudioFormat::SdpAudioFormat(absl::string_view name,
+ int clockrate_hz,
+ size_t num_channels,
+ Parameters&& param)
+ : name(name),
+ clockrate_hz(clockrate_hz),
+ num_channels(num_channels),
+ parameters(std::move(param)) {}
+
+bool SdpAudioFormat::Matches(const SdpAudioFormat& o) const {
+ return absl::EqualsIgnoreCase(name, o.name) &&
+ clockrate_hz == o.clockrate_hz && num_channels == o.num_channels;
+}
+
+SdpAudioFormat::~SdpAudioFormat() = default;
+SdpAudioFormat& SdpAudioFormat::operator=(const SdpAudioFormat&) = default;
+SdpAudioFormat& SdpAudioFormat::operator=(SdpAudioFormat&&) = default;
+
+bool operator==(const SdpAudioFormat& a, const SdpAudioFormat& b) {
+ return absl::EqualsIgnoreCase(a.name, b.name) &&
+ a.clockrate_hz == b.clockrate_hz && a.num_channels == b.num_channels &&
+ a.parameters == b.parameters;
+}
+
+AudioCodecInfo::AudioCodecInfo(int sample_rate_hz,
+ size_t num_channels,
+ int bitrate_bps)
+ : AudioCodecInfo(sample_rate_hz,
+ num_channels,
+ bitrate_bps,
+ bitrate_bps,
+ bitrate_bps) {}
+
+AudioCodecInfo::AudioCodecInfo(int sample_rate_hz,
+ size_t num_channels,
+ int default_bitrate_bps,
+ int min_bitrate_bps,
+ int max_bitrate_bps)
+ : sample_rate_hz(sample_rate_hz),
+ num_channels(num_channels),
+ default_bitrate_bps(default_bitrate_bps),
+ min_bitrate_bps(min_bitrate_bps),
+ max_bitrate_bps(max_bitrate_bps) {
+ RTC_DCHECK_GT(sample_rate_hz, 0);
+ RTC_DCHECK_GT(num_channels, 0);
+ RTC_DCHECK_GE(min_bitrate_bps, 0);
+ RTC_DCHECK_LE(min_bitrate_bps, default_bitrate_bps);
+ RTC_DCHECK_GE(max_bitrate_bps, default_bitrate_bps);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/audio_format.h b/third_party/libwebrtc/api/audio_codecs/audio_format.h
new file mode 100644
index 0000000000..0cf67799b8
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/audio_format.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_AUDIO_FORMAT_H_
+#define API_AUDIO_CODECS_AUDIO_FORMAT_H_
+
+#include <stddef.h>
+
+#include <map>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// SDP specification for a single audio codec.
+struct RTC_EXPORT SdpAudioFormat {
+ using Parameters = std::map<std::string, std::string>;
+
+ SdpAudioFormat(const SdpAudioFormat&);
+ SdpAudioFormat(SdpAudioFormat&&);
+ SdpAudioFormat(absl::string_view name, int clockrate_hz, size_t num_channels);
+ SdpAudioFormat(absl::string_view name,
+ int clockrate_hz,
+ size_t num_channels,
+ const Parameters& param);
+ SdpAudioFormat(absl::string_view name,
+ int clockrate_hz,
+ size_t num_channels,
+ Parameters&& param);
+ ~SdpAudioFormat();
+
+ // Returns true if this format is compatible with `o`. In SDP terminology:
+ // would it represent the same codec between an offer and an answer? As
+ // opposed to operator==, this method disregards codec parameters.
+ bool Matches(const SdpAudioFormat& o) const;
+
+ SdpAudioFormat& operator=(const SdpAudioFormat&);
+ SdpAudioFormat& operator=(SdpAudioFormat&&);
+
+ friend bool operator==(const SdpAudioFormat& a, const SdpAudioFormat& b);
+ friend bool operator!=(const SdpAudioFormat& a, const SdpAudioFormat& b) {
+ return !(a == b);
+ }
+
+ std::string name;
+ int clockrate_hz;
+ size_t num_channels;
+ Parameters parameters;
+};
+
+// Information about how an audio format is treated by the codec implementation.
+// Contains basic information, such as sample rate and number of channels, which
+// isn't uniformly presented by SDP. Also contains flags indicating support for
+// integrating with other parts of WebRTC, like external VAD and comfort noise
+// level calculation.
+//
+// To avoid API breakage, and make the code clearer, AudioCodecInfo should not
+// be directly initializable with any flags indicating optional support. If it
+// were, these initializers would break any time a new flag was added. It's also
+// more difficult to understand:
+// AudioCodecInfo info{16000, 1, 32000, true, false, false, true, true};
+// than
+// AudioCodecInfo info(16000, 1, 32000);
+// info.allow_comfort_noise = true;
+// info.future_flag_b = true;
+// info.future_flag_c = true;
+struct AudioCodecInfo {
+ AudioCodecInfo(int sample_rate_hz, size_t num_channels, int bitrate_bps);
+ AudioCodecInfo(int sample_rate_hz,
+ size_t num_channels,
+ int default_bitrate_bps,
+ int min_bitrate_bps,
+ int max_bitrate_bps);
+ AudioCodecInfo(const AudioCodecInfo& b) = default;
+ ~AudioCodecInfo() = default;
+
+ bool operator==(const AudioCodecInfo& b) const {
+ return sample_rate_hz == b.sample_rate_hz &&
+ num_channels == b.num_channels &&
+ default_bitrate_bps == b.default_bitrate_bps &&
+ min_bitrate_bps == b.min_bitrate_bps &&
+ max_bitrate_bps == b.max_bitrate_bps &&
+ allow_comfort_noise == b.allow_comfort_noise &&
+ supports_network_adaption == b.supports_network_adaption;
+ }
+
+ bool operator!=(const AudioCodecInfo& b) const { return !(*this == b); }
+
+ bool HasFixedBitrate() const {
+ RTC_DCHECK_GE(min_bitrate_bps, 0);
+ RTC_DCHECK_LE(min_bitrate_bps, default_bitrate_bps);
+ RTC_DCHECK_GE(max_bitrate_bps, default_bitrate_bps);
+ return min_bitrate_bps == max_bitrate_bps;
+ }
+
+ int sample_rate_hz;
+ size_t num_channels;
+ int default_bitrate_bps;
+ int min_bitrate_bps;
+ int max_bitrate_bps;
+
+ bool allow_comfort_noise = true; // This codec can be used with an external
+ // comfort noise generator.
+ bool supports_network_adaption = false; // This codec can adapt to varying
+ // network conditions.
+};
+
+// AudioCodecSpec ties an audio format to specific information about the codec
+// and its implementation.
+struct AudioCodecSpec {
+ bool operator==(const AudioCodecSpec& b) const {
+ return format == b.format && info == b.info;
+ }
+
+ bool operator!=(const AudioCodecSpec& b) const { return !(*this == b); }
+
+ SdpAudioFormat format;
+ AudioCodecInfo info;
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_AUDIO_FORMAT_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/builtin_audio_decoder_factory.cc b/third_party/libwebrtc/api/audio_codecs/builtin_audio_decoder_factory.cc
new file mode 100644
index 0000000000..881113d985
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/builtin_audio_decoder_factory.cc
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/builtin_audio_decoder_factory.h"
+
+#include <memory>
+#include <vector>
+
+#include "api/audio_codecs/L16/audio_decoder_L16.h"
+#include "api/audio_codecs/audio_decoder_factory_template.h"
+#include "api/audio_codecs/g711/audio_decoder_g711.h"
+#include "api/audio_codecs/g722/audio_decoder_g722.h"
+#if WEBRTC_USE_BUILTIN_ILBC
+#include "api/audio_codecs/ilbc/audio_decoder_ilbc.h" // nogncheck
+#endif
+#if WEBRTC_USE_BUILTIN_OPUS
+#include "api/audio_codecs/opus/audio_decoder_multi_channel_opus.h"
+#include "api/audio_codecs/opus/audio_decoder_opus.h" // nogncheck
+#endif
+
+namespace webrtc {
+
+namespace {
+
+// Modify an audio decoder to not advertise support for anything.
+template <typename T>
+struct NotAdvertised {
+ using Config = typename T::Config;
+ static absl::optional<Config> SdpToConfig(
+ const SdpAudioFormat& audio_format) {
+ return T::SdpToConfig(audio_format);
+ }
+ static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs) {
+ // Don't advertise support for anything.
+ }
+ static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
+ const Config& config,
+ absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt) {
+ return T::MakeAudioDecoder(config, codec_pair_id);
+ }
+};
+
+} // namespace
+
+rtc::scoped_refptr<AudioDecoderFactory> CreateBuiltinAudioDecoderFactory() {
+ return CreateAudioDecoderFactory<
+
+#if WEBRTC_USE_BUILTIN_OPUS
+ AudioDecoderOpus, NotAdvertised<AudioDecoderMultiChannelOpus>,
+#endif
+
+ AudioDecoderG722,
+
+#if WEBRTC_USE_BUILTIN_ILBC
+ AudioDecoderIlbc,
+#endif
+
+ AudioDecoderG711, NotAdvertised<AudioDecoderL16>>();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/builtin_audio_decoder_factory.h b/third_party/libwebrtc/api/audio_codecs/builtin_audio_decoder_factory.h
new file mode 100644
index 0000000000..72e1e3d96e
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/builtin_audio_decoder_factory.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_BUILTIN_AUDIO_DECODER_FACTORY_H_
+#define API_AUDIO_CODECS_BUILTIN_AUDIO_DECODER_FACTORY_H_
+
+#include "api/audio_codecs/audio_decoder_factory.h"
+#include "api/scoped_refptr.h"
+
+namespace webrtc {
+
+// Creates a new factory that can create the built-in types of audio decoders.
+// Note: This will link with all the code implementing those codecs, so if you
+// only need a subset of the codecs, consider using
+// CreateAudioDecoderFactory<...codecs listed here...>() or
+// CreateOpusAudioDecoderFactory() instead.
+rtc::scoped_refptr<AudioDecoderFactory> CreateBuiltinAudioDecoderFactory();
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_BUILTIN_AUDIO_DECODER_FACTORY_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/builtin_audio_decoder_factory_gn/moz.build b/third_party/libwebrtc/api/audio_codecs/builtin_audio_decoder_factory_gn/moz.build
new file mode 100644
index 0000000000..366307ea13
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/builtin_audio_decoder_factory_gn/moz.build
@@ -0,0 +1,234 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+DEFINES["WEBRTC_USE_BUILTIN_ILBC"] = "1"
+DEFINES["WEBRTC_USE_BUILTIN_OPUS"] = "1"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio_codecs/builtin_audio_decoder_factory.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "rt"
+ ]
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "crypt32",
+ "iphlpapi",
+ "secur32",
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("builtin_audio_decoder_factory_gn")
diff --git a/third_party/libwebrtc/api/audio_codecs/builtin_audio_encoder_factory.cc b/third_party/libwebrtc/api/audio_codecs/builtin_audio_encoder_factory.cc
new file mode 100644
index 0000000000..4546a2eaee
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/builtin_audio_encoder_factory.cc
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/builtin_audio_encoder_factory.h"
+
+#include <memory>
+#include <vector>
+
+#include "api/audio_codecs/L16/audio_encoder_L16.h"
+#include "api/audio_codecs/audio_encoder_factory_template.h"
+#include "api/audio_codecs/g711/audio_encoder_g711.h"
+#include "api/audio_codecs/g722/audio_encoder_g722.h"
+#if WEBRTC_USE_BUILTIN_ILBC
+#include "api/audio_codecs/ilbc/audio_encoder_ilbc.h" // nogncheck
+#endif
+#if WEBRTC_USE_BUILTIN_OPUS
+#include "api/audio_codecs/opus/audio_encoder_multi_channel_opus.h"
+#include "api/audio_codecs/opus/audio_encoder_opus.h" // nogncheck
+#endif
+
+namespace webrtc {
+
+namespace {
+
+// Modify an audio encoder to not advertise support for anything.
+template <typename T>
+struct NotAdvertised {
+ using Config = typename T::Config;
+ static absl::optional<Config> SdpToConfig(
+ const SdpAudioFormat& audio_format) {
+ return T::SdpToConfig(audio_format);
+ }
+ static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs) {
+ // Don't advertise support for anything.
+ }
+ static AudioCodecInfo QueryAudioEncoder(const Config& config) {
+ return T::QueryAudioEncoder(config);
+ }
+ static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
+ const Config& config,
+ int payload_type,
+ absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+ const FieldTrialsView* field_trials = nullptr) {
+ return T::MakeAudioEncoder(config, payload_type, codec_pair_id,
+ field_trials);
+ }
+};
+
+} // namespace
+
+rtc::scoped_refptr<AudioEncoderFactory> CreateBuiltinAudioEncoderFactory() {
+ return CreateAudioEncoderFactory<
+
+#if WEBRTC_USE_BUILTIN_OPUS
+ AudioEncoderOpus, NotAdvertised<AudioEncoderMultiChannelOpus>,
+#endif
+
+ AudioEncoderG722,
+
+#if WEBRTC_USE_BUILTIN_ILBC
+ AudioEncoderIlbc,
+#endif
+
+ AudioEncoderG711, NotAdvertised<AudioEncoderL16>>();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/builtin_audio_encoder_factory.h b/third_party/libwebrtc/api/audio_codecs/builtin_audio_encoder_factory.h
new file mode 100644
index 0000000000..f833de10f1
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/builtin_audio_encoder_factory.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_BUILTIN_AUDIO_ENCODER_FACTORY_H_
+#define API_AUDIO_CODECS_BUILTIN_AUDIO_ENCODER_FACTORY_H_
+
+#include "api/audio_codecs/audio_encoder_factory.h"
+#include "api/scoped_refptr.h"
+
+namespace webrtc {
+
+// Creates a new factory that can create the built-in types of audio encoders.
+// Note: This will link with all the code implementing those codecs, so if you
+// only need a subset of the codecs, consider using
+// CreateAudioEncoderFactory<...codecs listed here...>() or
+// CreateOpusAudioEncoderFactory() instead.
+rtc::scoped_refptr<AudioEncoderFactory> CreateBuiltinAudioEncoderFactory();
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_BUILTIN_AUDIO_ENCODER_FACTORY_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/builtin_audio_encoder_factory_gn/moz.build b/third_party/libwebrtc/api/audio_codecs/builtin_audio_encoder_factory_gn/moz.build
new file mode 100644
index 0000000000..db0e3fbe00
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/builtin_audio_encoder_factory_gn/moz.build
@@ -0,0 +1,234 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+DEFINES["WEBRTC_USE_BUILTIN_ILBC"] = "1"
+DEFINES["WEBRTC_USE_BUILTIN_OPUS"] = "1"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio_codecs/builtin_audio_encoder_factory.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "rt"
+ ]
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "crypt32",
+ "iphlpapi",
+ "secur32",
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("builtin_audio_encoder_factory_gn")
diff --git a/third_party/libwebrtc/api/audio_codecs/g711/BUILD.gn b/third_party/libwebrtc/api/audio_codecs/g711/BUILD.gn
new file mode 100644
index 0000000000..b2ff324f12
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/g711/BUILD.gn
@@ -0,0 +1,55 @@
+# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+if (is_android) {
+ import("//build/config/android/config.gni")
+ import("//build/config/android/rules.gni")
+}
+
+rtc_library("audio_encoder_g711") {
+ visibility = [ "*" ]
+ poisonous = [ "audio_codecs" ]
+ sources = [
+ "audio_encoder_g711.cc",
+ "audio_encoder_g711.h",
+ ]
+ deps = [
+ "..:audio_codecs_api",
+ "../../../api:field_trials_view",
+ "../../../modules/audio_coding:g711",
+ "../../../rtc_base:safe_conversions",
+ "../../../rtc_base:safe_minmax",
+ "../../../rtc_base:stringutils",
+ "../../../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
+rtc_library("audio_decoder_g711") {
+ visibility = [ "*" ]
+ poisonous = [ "audio_codecs" ]
+ sources = [
+ "audio_decoder_g711.cc",
+ "audio_decoder_g711.h",
+ ]
+ deps = [
+ "..:audio_codecs_api",
+ "../../../api:field_trials_view",
+ "../../../modules/audio_coding:g711",
+ "../../../rtc_base:safe_conversions",
+ "../../../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
diff --git a/third_party/libwebrtc/api/audio_codecs/g711/audio_decoder_g711.cc b/third_party/libwebrtc/api/audio_codecs/g711/audio_decoder_g711.cc
new file mode 100644
index 0000000000..838f7e9624
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/g711/audio_decoder_g711.cc
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/g711/audio_decoder_g711.h"
+
+#include <memory>
+#include <vector>
+
+#include "absl/strings/match.h"
+#include "modules/audio_coding/codecs/g711/audio_decoder_pcm.h"
+#include "rtc_base/numerics/safe_conversions.h"
+
+namespace webrtc {
+
+absl::optional<AudioDecoderG711::Config> AudioDecoderG711::SdpToConfig(
+ const SdpAudioFormat& format) {
+ const bool is_pcmu = absl::EqualsIgnoreCase(format.name, "PCMU");
+ const bool is_pcma = absl::EqualsIgnoreCase(format.name, "PCMA");
+ if (format.clockrate_hz == 8000 && format.num_channels >= 1 &&
+ (is_pcmu || is_pcma)) {
+ Config config;
+ config.type = is_pcmu ? Config::Type::kPcmU : Config::Type::kPcmA;
+ config.num_channels = rtc::dchecked_cast<int>(format.num_channels);
+ if (!config.IsOk()) {
+ RTC_DCHECK_NOTREACHED();
+ return absl::nullopt;
+ }
+ return config;
+ } else {
+ return absl::nullopt;
+ }
+}
+
+void AudioDecoderG711::AppendSupportedDecoders(
+ std::vector<AudioCodecSpec>* specs) {
+ for (const char* type : {"PCMU", "PCMA"}) {
+ specs->push_back({{type, 8000, 1}, {8000, 1, 64000}});
+ }
+}
+
+std::unique_ptr<AudioDecoder> AudioDecoderG711::MakeAudioDecoder(
+ const Config& config,
+ absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+ const FieldTrialsView* field_trials) {
+ if (!config.IsOk()) {
+ RTC_DCHECK_NOTREACHED();
+ return nullptr;
+ }
+ switch (config.type) {
+ case Config::Type::kPcmU:
+ return std::make_unique<AudioDecoderPcmU>(config.num_channels);
+ case Config::Type::kPcmA:
+ return std::make_unique<AudioDecoderPcmA>(config.num_channels);
+ default:
+ RTC_DCHECK_NOTREACHED();
+ return nullptr;
+ }
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/g711/audio_decoder_g711.h b/third_party/libwebrtc/api/audio_codecs/g711/audio_decoder_g711.h
new file mode 100644
index 0000000000..0f7a98d345
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/g711/audio_decoder_g711.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_G711_AUDIO_DECODER_G711_H_
+#define API_AUDIO_CODECS_G711_AUDIO_DECODER_G711_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/audio_codecs/audio_codec_pair_id.h"
+#include "api/audio_codecs/audio_decoder.h"
+#include "api/audio_codecs/audio_format.h"
+#include "api/field_trials_view.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// G711 decoder API for use as a template parameter to
+// CreateAudioDecoderFactory<...>().
+struct RTC_EXPORT AudioDecoderG711 {
+ struct Config {
+ enum class Type { kPcmU, kPcmA };
+ bool IsOk() const {
+ return (type == Type::kPcmU || type == Type::kPcmA) &&
+ num_channels >= 1 &&
+ num_channels <= AudioDecoder::kMaxNumberOfChannels;
+ }
+ Type type;
+ int num_channels;
+ };
+ static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
+ static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
+ static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
+ const Config& config,
+ absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+ const FieldTrialsView* field_trials = nullptr);
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_G711_AUDIO_DECODER_G711_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/g711/audio_decoder_g711_gn/moz.build b/third_party/libwebrtc/api/audio_codecs/g711/audio_decoder_g711_gn/moz.build
new file mode 100644
index 0000000000..4782d01dd1
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/g711/audio_decoder_g711_gn/moz.build
@@ -0,0 +1,225 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio_codecs/g711/audio_decoder_g711.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_decoder_g711_gn")
diff --git a/third_party/libwebrtc/api/audio_codecs/g711/audio_encoder_g711.cc b/third_party/libwebrtc/api/audio_codecs/g711/audio_encoder_g711.cc
new file mode 100644
index 0000000000..1dca3b80d3
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/g711/audio_encoder_g711.cc
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/g711/audio_encoder_g711.h"
+
+#include <memory>
+#include <vector>
+
+#include "absl/strings/match.h"
+#include "modules/audio_coding/codecs/g711/audio_encoder_pcm.h"
+#include "rtc_base/numerics/safe_conversions.h"
+#include "rtc_base/numerics/safe_minmax.h"
+#include "rtc_base/string_to_number.h"
+
+namespace webrtc {
+
+absl::optional<AudioEncoderG711::Config> AudioEncoderG711::SdpToConfig(
+ const SdpAudioFormat& format) {
+ const bool is_pcmu = absl::EqualsIgnoreCase(format.name, "PCMU");
+ const bool is_pcma = absl::EqualsIgnoreCase(format.name, "PCMA");
+ if (format.clockrate_hz == 8000 && format.num_channels >= 1 &&
+ (is_pcmu || is_pcma)) {
+ Config config;
+ config.type = is_pcmu ? Config::Type::kPcmU : Config::Type::kPcmA;
+ config.num_channels = rtc::dchecked_cast<int>(format.num_channels);
+ config.frame_size_ms = 20;
+ auto ptime_iter = format.parameters.find("ptime");
+ if (ptime_iter != format.parameters.end()) {
+ const auto ptime = rtc::StringToNumber<int>(ptime_iter->second);
+ if (ptime && *ptime > 0) {
+ config.frame_size_ms = rtc::SafeClamp(10 * (*ptime / 10), 10, 60);
+ }
+ }
+ if (!config.IsOk()) {
+ RTC_DCHECK_NOTREACHED();
+ return absl::nullopt;
+ }
+ return config;
+ } else {
+ return absl::nullopt;
+ }
+}
+
+void AudioEncoderG711::AppendSupportedEncoders(
+ std::vector<AudioCodecSpec>* specs) {
+ for (const char* type : {"PCMU", "PCMA"}) {
+ specs->push_back({{type, 8000, 1}, {8000, 1, 64000}});
+ }
+}
+
+AudioCodecInfo AudioEncoderG711::QueryAudioEncoder(const Config& config) {
+ RTC_DCHECK(config.IsOk());
+ return {8000, rtc::dchecked_cast<size_t>(config.num_channels),
+ 64000 * config.num_channels};
+}
+
+std::unique_ptr<AudioEncoder> AudioEncoderG711::MakeAudioEncoder(
+ const Config& config,
+ int payload_type,
+ absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+ const FieldTrialsView* field_trials) {
+ if (!config.IsOk()) {
+ RTC_DCHECK_NOTREACHED();
+ return nullptr;
+ }
+ switch (config.type) {
+ case Config::Type::kPcmU: {
+ AudioEncoderPcmU::Config impl_config;
+ impl_config.num_channels = config.num_channels;
+ impl_config.frame_size_ms = config.frame_size_ms;
+ impl_config.payload_type = payload_type;
+ return std::make_unique<AudioEncoderPcmU>(impl_config);
+ }
+ case Config::Type::kPcmA: {
+ AudioEncoderPcmA::Config impl_config;
+ impl_config.num_channels = config.num_channels;
+ impl_config.frame_size_ms = config.frame_size_ms;
+ impl_config.payload_type = payload_type;
+ return std::make_unique<AudioEncoderPcmA>(impl_config);
+ }
+ default: {
+ RTC_DCHECK_NOTREACHED();
+ return nullptr;
+ }
+ }
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/g711/audio_encoder_g711.h b/third_party/libwebrtc/api/audio_codecs/g711/audio_encoder_g711.h
new file mode 100644
index 0000000000..4b3eb845e0
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/g711/audio_encoder_g711.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_G711_AUDIO_ENCODER_G711_H_
+#define API_AUDIO_CODECS_G711_AUDIO_ENCODER_G711_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/audio_codecs/audio_codec_pair_id.h"
+#include "api/audio_codecs/audio_encoder.h"
+#include "api/audio_codecs/audio_format.h"
+#include "api/field_trials_view.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// G711 encoder API for use as a template parameter to
+// CreateAudioEncoderFactory<...>().
+struct RTC_EXPORT AudioEncoderG711 {
+ struct Config {
+ enum class Type { kPcmU, kPcmA };
+ bool IsOk() const {
+ return (type == Type::kPcmU || type == Type::kPcmA) &&
+ frame_size_ms > 0 && frame_size_ms % 10 == 0 &&
+ num_channels >= 1 &&
+ num_channels <= AudioEncoder::kMaxNumberOfChannels;
+ }
+ Type type = Type::kPcmU;
+ int num_channels = 1;
+ int frame_size_ms = 20;
+ };
+ static absl::optional<AudioEncoderG711::Config> SdpToConfig(
+ const SdpAudioFormat& audio_format);
+ static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
+ static AudioCodecInfo QueryAudioEncoder(const Config& config);
+ static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
+ const Config& config,
+ int payload_type,
+ absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+ const FieldTrialsView* field_trials = nullptr);
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_G711_AUDIO_ENCODER_G711_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/g711/audio_encoder_g711_gn/moz.build b/third_party/libwebrtc/api/audio_codecs/g711/audio_encoder_g711_gn/moz.build
new file mode 100644
index 0000000000..c972978c13
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/g711/audio_encoder_g711_gn/moz.build
@@ -0,0 +1,225 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio_codecs/g711/audio_encoder_g711.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_encoder_g711_gn")
diff --git a/third_party/libwebrtc/api/audio_codecs/g722/BUILD.gn b/third_party/libwebrtc/api/audio_codecs/g722/BUILD.gn
new file mode 100644
index 0000000000..af13ac3de3
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/g722/BUILD.gn
@@ -0,0 +1,62 @@
+# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+if (is_android) {
+ import("//build/config/android/config.gni")
+ import("//build/config/android/rules.gni")
+}
+
+rtc_source_set("audio_encoder_g722_config") {
+ visibility = [ "*" ]
+ sources = [ "audio_encoder_g722_config.h" ]
+ deps = [ "..:audio_codecs_api" ]
+}
+
+rtc_library("audio_encoder_g722") {
+ visibility = [ "*" ]
+ poisonous = [ "audio_codecs" ]
+ sources = [
+ "audio_encoder_g722.cc",
+ "audio_encoder_g722.h",
+ ]
+ deps = [
+ ":audio_encoder_g722_config",
+ "..:audio_codecs_api",
+ "../../../api:field_trials_view",
+ "../../../modules/audio_coding:g722",
+ "../../../rtc_base:safe_conversions",
+ "../../../rtc_base:safe_minmax",
+ "../../../rtc_base:stringutils",
+ "../../../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
+rtc_library("audio_decoder_g722") {
+ visibility = [ "*" ]
+ poisonous = [ "audio_codecs" ]
+ sources = [
+ "audio_decoder_g722.cc",
+ "audio_decoder_g722.h",
+ ]
+ deps = [
+ "..:audio_codecs_api",
+ "../../../api:field_trials_view",
+ "../../../modules/audio_coding:g722",
+ "../../../rtc_base:safe_conversions",
+ "../../../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
diff --git a/third_party/libwebrtc/api/audio_codecs/g722/audio_decoder_g722.cc b/third_party/libwebrtc/api/audio_codecs/g722/audio_decoder_g722.cc
new file mode 100644
index 0000000000..ed7163471a
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/g722/audio_decoder_g722.cc
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/g722/audio_decoder_g722.h"
+
+#include <memory>
+#include <vector>
+
+#include "absl/strings/match.h"
+#include "modules/audio_coding/codecs/g722/audio_decoder_g722.h"
+#include "rtc_base/numerics/safe_conversions.h"
+
+namespace webrtc {
+
+absl::optional<AudioDecoderG722::Config> AudioDecoderG722::SdpToConfig(
+ const SdpAudioFormat& format) {
+ if (absl::EqualsIgnoreCase(format.name, "G722") &&
+ format.clockrate_hz == 8000 &&
+ (format.num_channels == 1 || format.num_channels == 2)) {
+ return Config{rtc::dchecked_cast<int>(format.num_channels)};
+ }
+ return absl::nullopt;
+}
+
+void AudioDecoderG722::AppendSupportedDecoders(
+ std::vector<AudioCodecSpec>* specs) {
+ specs->push_back({{"G722", 8000, 1}, {16000, 1, 64000}});
+}
+
+std::unique_ptr<AudioDecoder> AudioDecoderG722::MakeAudioDecoder(
+ Config config,
+ absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+ const FieldTrialsView* field_trials) {
+ if (!config.IsOk()) {
+ RTC_DCHECK_NOTREACHED();
+ return nullptr;
+ }
+ switch (config.num_channels) {
+ case 1:
+ return std::make_unique<AudioDecoderG722Impl>();
+ case 2:
+ return std::make_unique<AudioDecoderG722StereoImpl>();
+ default:
+ RTC_DCHECK_NOTREACHED();
+ return nullptr;
+ }
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/g722/audio_decoder_g722.h b/third_party/libwebrtc/api/audio_codecs/g722/audio_decoder_g722.h
new file mode 100644
index 0000000000..6f7b253039
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/g722/audio_decoder_g722.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_G722_AUDIO_DECODER_G722_H_
+#define API_AUDIO_CODECS_G722_AUDIO_DECODER_G722_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/audio_codecs/audio_codec_pair_id.h"
+#include "api/audio_codecs/audio_decoder.h"
+#include "api/audio_codecs/audio_format.h"
+#include "api/field_trials_view.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// G722 decoder API for use as a template parameter to
+// CreateAudioDecoderFactory<...>().
+struct RTC_EXPORT AudioDecoderG722 {
+ struct Config {
+ bool IsOk() const { return num_channels == 1 || num_channels == 2; }
+ int num_channels;
+ };
+ static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
+ static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
+ static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
+ Config config,
+ absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+ const FieldTrialsView* field_trials = nullptr);
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_G722_AUDIO_DECODER_G722_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/g722/audio_decoder_g722_gn/moz.build b/third_party/libwebrtc/api/audio_codecs/g722/audio_decoder_g722_gn/moz.build
new file mode 100644
index 0000000000..77003c77a9
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/g722/audio_decoder_g722_gn/moz.build
@@ -0,0 +1,225 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio_codecs/g722/audio_decoder_g722.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_decoder_g722_gn")
diff --git a/third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722.cc b/third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722.cc
new file mode 100644
index 0000000000..56a6c4da6a
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722.cc
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/g722/audio_encoder_g722.h"
+
+#include <memory>
+#include <vector>
+
+#include "absl/strings/match.h"
+#include "modules/audio_coding/codecs/g722/audio_encoder_g722.h"
+#include "rtc_base/numerics/safe_conversions.h"
+#include "rtc_base/numerics/safe_minmax.h"
+#include "rtc_base/string_to_number.h"
+
+namespace webrtc {
+
+absl::optional<AudioEncoderG722Config> AudioEncoderG722::SdpToConfig(
+ const SdpAudioFormat& format) {
+ if (!absl::EqualsIgnoreCase(format.name, "g722") ||
+ format.clockrate_hz != 8000) {
+ return absl::nullopt;
+ }
+
+ AudioEncoderG722Config config;
+ config.num_channels = rtc::checked_cast<int>(format.num_channels);
+ auto ptime_iter = format.parameters.find("ptime");
+ if (ptime_iter != format.parameters.end()) {
+ auto ptime = rtc::StringToNumber<int>(ptime_iter->second);
+ if (ptime && *ptime > 0) {
+ const int whole_packets = *ptime / 10;
+ config.frame_size_ms = rtc::SafeClamp<int>(whole_packets * 10, 10, 60);
+ }
+ }
+ if (!config.IsOk()) {
+ RTC_DCHECK_NOTREACHED();
+ return absl::nullopt;
+ }
+ return config;
+}
+
+void AudioEncoderG722::AppendSupportedEncoders(
+ std::vector<AudioCodecSpec>* specs) {
+ const SdpAudioFormat fmt = {"G722", 8000, 1};
+ const AudioCodecInfo info = QueryAudioEncoder(*SdpToConfig(fmt));
+ specs->push_back({fmt, info});
+}
+
+AudioCodecInfo AudioEncoderG722::QueryAudioEncoder(
+ const AudioEncoderG722Config& config) {
+ RTC_DCHECK(config.IsOk());
+ return {16000, rtc::dchecked_cast<size_t>(config.num_channels),
+ 64000 * config.num_channels};
+}
+
+std::unique_ptr<AudioEncoder> AudioEncoderG722::MakeAudioEncoder(
+ const AudioEncoderG722Config& config,
+ int payload_type,
+ absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+ const FieldTrialsView* field_trials) {
+ if (!config.IsOk()) {
+ RTC_DCHECK_NOTREACHED();
+ return nullptr;
+ }
+ return std::make_unique<AudioEncoderG722Impl>(config, payload_type);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722.h b/third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722.h
new file mode 100644
index 0000000000..78ceddd1e9
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_G722_AUDIO_ENCODER_G722_H_
+#define API_AUDIO_CODECS_G722_AUDIO_ENCODER_G722_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/audio_codecs/audio_codec_pair_id.h"
+#include "api/audio_codecs/audio_encoder.h"
+#include "api/audio_codecs/audio_format.h"
+#include "api/audio_codecs/g722/audio_encoder_g722_config.h"
+#include "api/field_trials_view.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// G722 encoder API for use as a template parameter to
+// CreateAudioEncoderFactory<...>().
+struct RTC_EXPORT AudioEncoderG722 {
+ using Config = AudioEncoderG722Config;
+ static absl::optional<AudioEncoderG722Config> SdpToConfig(
+ const SdpAudioFormat& audio_format);
+ static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
+ static AudioCodecInfo QueryAudioEncoder(const AudioEncoderG722Config& config);
+ static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
+ const AudioEncoderG722Config& config,
+ int payload_type,
+ absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+ const FieldTrialsView* field_trials = nullptr);
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_G722_AUDIO_ENCODER_G722_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722_config.h b/third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722_config.h
new file mode 100644
index 0000000000..f3f3a9f016
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722_config.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_G722_AUDIO_ENCODER_G722_CONFIG_H_
+#define API_AUDIO_CODECS_G722_AUDIO_ENCODER_G722_CONFIG_H_
+
+#include "api/audio_codecs/audio_encoder.h"
+
+namespace webrtc {
+
+struct AudioEncoderG722Config {
+ bool IsOk() const {
+ return frame_size_ms > 0 && frame_size_ms % 10 == 0 && num_channels >= 1 &&
+ num_channels <= AudioEncoder::kMaxNumberOfChannels;
+ }
+ int frame_size_ms = 20;
+ int num_channels = 1;
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_G722_AUDIO_ENCODER_G722_CONFIG_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722_config_gn/moz.build b/third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722_config_gn/moz.build
new file mode 100644
index 0000000000..41e1e248c5
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722_config_gn/moz.build
@@ -0,0 +1,209 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_encoder_g722_config_gn")
diff --git a/third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722_gn/moz.build b/third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722_gn/moz.build
new file mode 100644
index 0000000000..c3beba6cdb
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722_gn/moz.build
@@ -0,0 +1,225 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio_codecs/g722/audio_encoder_g722.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_encoder_g722_gn")
diff --git a/third_party/libwebrtc/api/audio_codecs/ilbc/BUILD.gn b/third_party/libwebrtc/api/audio_codecs/ilbc/BUILD.gn
new file mode 100644
index 0000000000..22cf48220f
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/ilbc/BUILD.gn
@@ -0,0 +1,58 @@
+# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+if (is_android) {
+ import("//build/config/android/config.gni")
+ import("//build/config/android/rules.gni")
+}
+
+rtc_source_set("audio_encoder_ilbc_config") {
+ visibility = [ "*" ]
+ sources = [ "audio_encoder_ilbc_config.h" ]
+}
+
+rtc_library("audio_encoder_ilbc") {
+ visibility = [ "*" ]
+ poisonous = [ "audio_codecs" ]
+ sources = [
+ "audio_encoder_ilbc.cc",
+ "audio_encoder_ilbc.h",
+ ]
+ deps = [
+ ":audio_encoder_ilbc_config",
+ "..:audio_codecs_api",
+ "../../../api:field_trials_view",
+ "../../../modules/audio_coding:ilbc",
+ "../../../rtc_base:safe_conversions",
+ "../../../rtc_base:safe_minmax",
+ "../../../rtc_base:stringutils",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
+rtc_library("audio_decoder_ilbc") {
+ visibility = [ "*" ]
+ poisonous = [ "audio_codecs" ]
+ sources = [
+ "audio_decoder_ilbc.cc",
+ "audio_decoder_ilbc.h",
+ ]
+ deps = [
+ "..:audio_codecs_api",
+ "../../../api:field_trials_view",
+ "../../../modules/audio_coding:ilbc",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
diff --git a/third_party/libwebrtc/api/audio_codecs/ilbc/audio_decoder_ilbc.cc b/third_party/libwebrtc/api/audio_codecs/ilbc/audio_decoder_ilbc.cc
new file mode 100644
index 0000000000..c58316903a
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/ilbc/audio_decoder_ilbc.cc
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/ilbc/audio_decoder_ilbc.h"
+
+#include <memory>
+#include <vector>
+
+#include "absl/strings/match.h"
+#include "modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h"
+
+namespace webrtc {
+
+absl::optional<AudioDecoderIlbc::Config> AudioDecoderIlbc::SdpToConfig(
+ const SdpAudioFormat& format) {
+ if (absl::EqualsIgnoreCase(format.name, "ILBC") &&
+ format.clockrate_hz == 8000 && format.num_channels == 1) {
+ return Config();
+ }
+ return absl::nullopt;
+}
+
+void AudioDecoderIlbc::AppendSupportedDecoders(
+ std::vector<AudioCodecSpec>* specs) {
+ specs->push_back({{"ILBC", 8000, 1}, {8000, 1, 13300}});
+}
+
+std::unique_ptr<AudioDecoder> AudioDecoderIlbc::MakeAudioDecoder(
+ Config config,
+ absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+ const FieldTrialsView* field_trials) {
+ return std::make_unique<AudioDecoderIlbcImpl>();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/ilbc/audio_decoder_ilbc.h b/third_party/libwebrtc/api/audio_codecs/ilbc/audio_decoder_ilbc.h
new file mode 100644
index 0000000000..60566c88df
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/ilbc/audio_decoder_ilbc.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_ILBC_AUDIO_DECODER_ILBC_H_
+#define API_AUDIO_CODECS_ILBC_AUDIO_DECODER_ILBC_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/audio_codecs/audio_codec_pair_id.h"
+#include "api/audio_codecs/audio_decoder.h"
+#include "api/audio_codecs/audio_format.h"
+#include "api/field_trials_view.h"
+
+namespace webrtc {
+
+// ILBC decoder API for use as a template parameter to
+// CreateAudioDecoderFactory<...>().
+struct AudioDecoderIlbc {
+ struct Config {}; // Empty---no config values needed!
+ static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
+ static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
+ static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
+ Config config,
+ absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+ const FieldTrialsView* field_trials = nullptr);
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_ILBC_AUDIO_DECODER_ILBC_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/ilbc/audio_decoder_ilbc_gn/moz.build b/third_party/libwebrtc/api/audio_codecs/ilbc/audio_decoder_ilbc_gn/moz.build
new file mode 100644
index 0000000000..53e9d1a4a7
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/ilbc/audio_decoder_ilbc_gn/moz.build
@@ -0,0 +1,232 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio_codecs/ilbc/audio_decoder_ilbc.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "rt"
+ ]
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "crypt32",
+ "iphlpapi",
+ "secur32",
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_decoder_ilbc_gn")
diff --git a/third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc.cc b/third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc.cc
new file mode 100644
index 0000000000..b497948491
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc.cc
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/ilbc/audio_encoder_ilbc.h"
+
+#include <memory>
+#include <vector>
+
+#include "absl/strings/match.h"
+#include "modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h"
+#include "rtc_base/numerics/safe_conversions.h"
+#include "rtc_base/numerics/safe_minmax.h"
+#include "rtc_base/string_to_number.h"
+
+namespace webrtc {
+namespace {
+int GetIlbcBitrate(int ptime) {
+ switch (ptime) {
+ case 20:
+ case 40:
+ // 38 bytes per frame of 20 ms => 15200 bits/s.
+ return 15200;
+ case 30:
+ case 60:
+ // 50 bytes per frame of 30 ms => (approx) 13333 bits/s.
+ return 13333;
+ default:
+ RTC_CHECK_NOTREACHED();
+ }
+}
+} // namespace
+
+absl::optional<AudioEncoderIlbcConfig> AudioEncoderIlbc::SdpToConfig(
+ const SdpAudioFormat& format) {
+ if (!absl::EqualsIgnoreCase(format.name.c_str(), "ILBC") ||
+ format.clockrate_hz != 8000 || format.num_channels != 1) {
+ return absl::nullopt;
+ }
+
+ AudioEncoderIlbcConfig config;
+ auto ptime_iter = format.parameters.find("ptime");
+ if (ptime_iter != format.parameters.end()) {
+ auto ptime = rtc::StringToNumber<int>(ptime_iter->second);
+ if (ptime && *ptime > 0) {
+ const int whole_packets = *ptime / 10;
+ config.frame_size_ms = rtc::SafeClamp<int>(whole_packets * 10, 20, 60);
+ }
+ }
+ if (!config.IsOk()) {
+ RTC_DCHECK_NOTREACHED();
+ return absl::nullopt;
+ }
+ return config;
+}
+
+void AudioEncoderIlbc::AppendSupportedEncoders(
+ std::vector<AudioCodecSpec>* specs) {
+ const SdpAudioFormat fmt = {"ILBC", 8000, 1};
+ const AudioCodecInfo info = QueryAudioEncoder(*SdpToConfig(fmt));
+ specs->push_back({fmt, info});
+}
+
+AudioCodecInfo AudioEncoderIlbc::QueryAudioEncoder(
+ const AudioEncoderIlbcConfig& config) {
+ RTC_DCHECK(config.IsOk());
+ return {8000, 1, GetIlbcBitrate(config.frame_size_ms)};
+}
+
+std::unique_ptr<AudioEncoder> AudioEncoderIlbc::MakeAudioEncoder(
+ const AudioEncoderIlbcConfig& config,
+ int payload_type,
+ absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+ const FieldTrialsView* field_trials) {
+ if (!config.IsOk()) {
+ RTC_DCHECK_NOTREACHED();
+ return nullptr;
+ }
+ return std::make_unique<AudioEncoderIlbcImpl>(config, payload_type);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc.h b/third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc.h
new file mode 100644
index 0000000000..a5306841ce
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_ILBC_AUDIO_ENCODER_ILBC_H_
+#define API_AUDIO_CODECS_ILBC_AUDIO_ENCODER_ILBC_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/audio_codecs/audio_codec_pair_id.h"
+#include "api/audio_codecs/audio_encoder.h"
+#include "api/audio_codecs/audio_format.h"
+#include "api/audio_codecs/ilbc/audio_encoder_ilbc_config.h"
+#include "api/field_trials_view.h"
+
+namespace webrtc {
+
+// ILBC encoder API for use as a template parameter to
+// CreateAudioEncoderFactory<...>().
+struct AudioEncoderIlbc {
+ using Config = AudioEncoderIlbcConfig;
+ static absl::optional<AudioEncoderIlbcConfig> SdpToConfig(
+ const SdpAudioFormat& audio_format);
+ static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
+ static AudioCodecInfo QueryAudioEncoder(const AudioEncoderIlbcConfig& config);
+ static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
+ const AudioEncoderIlbcConfig& config,
+ int payload_type,
+ absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+ const FieldTrialsView* field_trials = nullptr);
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_ILBC_AUDIO_ENCODER_ILBC_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc_config.h b/third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc_config.h
new file mode 100644
index 0000000000..4d82f9901c
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc_config.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_ILBC_AUDIO_ENCODER_ILBC_CONFIG_H_
+#define API_AUDIO_CODECS_ILBC_AUDIO_ENCODER_ILBC_CONFIG_H_
+
+namespace webrtc {
+
+struct AudioEncoderIlbcConfig {
+ bool IsOk() const {
+ return (frame_size_ms == 20 || frame_size_ms == 30 || frame_size_ms == 40 ||
+ frame_size_ms == 60);
+ }
+ int frame_size_ms = 30; // Valid values are 20, 30, 40, and 60 ms.
+ // Note that frame size 40 ms produces encodings with two 20 ms frames in
+ // them, and frame size 60 ms consists of two 30 ms frames.
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_ILBC_AUDIO_ENCODER_ILBC_CONFIG_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc_config_gn/moz.build b/third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc_config_gn/moz.build
new file mode 100644
index 0000000000..75737b8f19
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc_config_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_encoder_ilbc_config_gn")
diff --git a/third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc_gn/moz.build b/third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc_gn/moz.build
new file mode 100644
index 0000000000..bddfe42193
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc_gn/moz.build
@@ -0,0 +1,232 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio_codecs/ilbc/audio_encoder_ilbc.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "rt"
+ ]
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "crypt32",
+ "iphlpapi",
+ "secur32",
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_encoder_ilbc_gn")
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/BUILD.gn b/third_party/libwebrtc/api/audio_codecs/opus/BUILD.gn
new file mode 100644
index 0000000000..eb90a0b9ac
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/BUILD.gn
@@ -0,0 +1,110 @@
+# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+if (is_android) {
+ import("//build/config/android/config.gni")
+ import("//build/config/android/rules.gni")
+}
+
+rtc_library("audio_encoder_opus_config") {
+ visibility = [ "*" ]
+ sources = [
+ "audio_encoder_multi_channel_opus_config.cc",
+ "audio_encoder_multi_channel_opus_config.h",
+ "audio_encoder_opus_config.cc",
+ "audio_encoder_opus_config.h",
+ ]
+ deps = [ "../../../rtc_base/system:rtc_export" ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+ defines = []
+ if (rtc_opus_variable_complexity) {
+ defines += [ "WEBRTC_OPUS_VARIABLE_COMPLEXITY=1" ]
+ } else {
+ defines += [ "WEBRTC_OPUS_VARIABLE_COMPLEXITY=0" ]
+ }
+}
+
+rtc_source_set("audio_decoder_opus_config") {
+ visibility = [ "*" ]
+ sources = [ "audio_decoder_multi_channel_opus_config.h" ]
+ deps = [ "..:audio_codecs_api" ]
+}
+
+rtc_library("audio_encoder_opus") {
+ visibility = [ "*" ]
+ poisonous = [ "audio_codecs" ]
+ public = [ "audio_encoder_opus.h" ]
+ sources = [ "audio_encoder_opus.cc" ]
+ deps = [
+ ":audio_encoder_opus_config",
+ "..:audio_codecs_api",
+ "../../../api:field_trials_view",
+ "../../../modules/audio_coding:webrtc_opus",
+ "../../../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
+rtc_library("audio_decoder_opus") {
+ visibility = [ "*" ]
+ poisonous = [ "audio_codecs" ]
+ sources = [
+ "audio_decoder_opus.cc",
+ "audio_decoder_opus.h",
+ ]
+ deps = [
+ "..:audio_codecs_api",
+ "../../../api:field_trials_view",
+ "../../../modules/audio_coding:webrtc_opus",
+ "../../../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
+rtc_library("audio_encoder_multiopus") {
+ visibility = [ "*" ]
+ poisonous = [ "audio_codecs" ]
+ public = [ "audio_encoder_multi_channel_opus.h" ]
+ sources = [ "audio_encoder_multi_channel_opus.cc" ]
+ deps = [
+ "..:audio_codecs_api",
+ "../../../api:field_trials_view",
+ "../../../modules/audio_coding:webrtc_multiopus",
+ "../../../rtc_base/system:rtc_export",
+ "../opus:audio_encoder_opus_config",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_library("audio_decoder_multiopus") {
+ visibility = [ "*" ]
+ poisonous = [ "audio_codecs" ]
+ sources = [
+ "audio_decoder_multi_channel_opus.cc",
+ "audio_decoder_multi_channel_opus.h",
+ ]
+ deps = [
+ ":audio_decoder_opus_config",
+ "..:audio_codecs_api",
+ "../../../api:field_trials_view",
+ "../../../modules/audio_coding:webrtc_multiopus",
+ "../../../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/memory",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_multi_channel_opus.cc b/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_multi_channel_opus.cc
new file mode 100644
index 0000000000..0fb4e05511
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_multi_channel_opus.cc
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/opus/audio_decoder_multi_channel_opus.h"
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/match.h"
+#include "modules/audio_coding/codecs/opus/audio_decoder_multi_channel_opus_impl.h"
+
+namespace webrtc {
+
+absl::optional<AudioDecoderMultiChannelOpusConfig>
+AudioDecoderMultiChannelOpus::SdpToConfig(const SdpAudioFormat& format) {
+ return AudioDecoderMultiChannelOpusImpl::SdpToConfig(format);
+}
+
+void AudioDecoderMultiChannelOpus::AppendSupportedDecoders(
+ std::vector<AudioCodecSpec>* specs) {
+ // To get full utilization of the surround support of the Opus lib, we can
+ // mark which channel is the low frequency effects (LFE). But that is not done
+ // ATM.
+ {
+ AudioCodecInfo surround_5_1_opus_info{48000, 6,
+ /* default_bitrate_bps= */ 128000};
+ surround_5_1_opus_info.allow_comfort_noise = false;
+ surround_5_1_opus_info.supports_network_adaption = false;
+ SdpAudioFormat opus_format({"multiopus",
+ 48000,
+ 6,
+ {{"minptime", "10"},
+ {"useinbandfec", "1"},
+ {"channel_mapping", "0,4,1,2,3,5"},
+ {"num_streams", "4"},
+ {"coupled_streams", "2"}}});
+ specs->push_back({std::move(opus_format), surround_5_1_opus_info});
+ }
+ {
+ AudioCodecInfo surround_7_1_opus_info{48000, 8,
+ /* default_bitrate_bps= */ 200000};
+ surround_7_1_opus_info.allow_comfort_noise = false;
+ surround_7_1_opus_info.supports_network_adaption = false;
+ SdpAudioFormat opus_format({"multiopus",
+ 48000,
+ 8,
+ {{"minptime", "10"},
+ {"useinbandfec", "1"},
+ {"channel_mapping", "0,6,1,2,3,4,5,7"},
+ {"num_streams", "5"},
+ {"coupled_streams", "3"}}});
+ specs->push_back({std::move(opus_format), surround_7_1_opus_info});
+ }
+}
+
+std::unique_ptr<AudioDecoder> AudioDecoderMultiChannelOpus::MakeAudioDecoder(
+ AudioDecoderMultiChannelOpusConfig config,
+ absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+ const FieldTrialsView* field_trials) {
+ return AudioDecoderMultiChannelOpusImpl::MakeAudioDecoder(config);
+}
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_multi_channel_opus.h b/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_multi_channel_opus.h
new file mode 100644
index 0000000000..eafd6c6939
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_multi_channel_opus.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_OPUS_AUDIO_DECODER_MULTI_CHANNEL_OPUS_H_
+#define API_AUDIO_CODECS_OPUS_AUDIO_DECODER_MULTI_CHANNEL_OPUS_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/audio_codecs/audio_codec_pair_id.h"
+#include "api/audio_codecs/audio_decoder.h"
+#include "api/audio_codecs/audio_format.h"
+#include "api/audio_codecs/opus/audio_decoder_multi_channel_opus_config.h"
+#include "api/field_trials_view.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Opus decoder API for use as a template parameter to
+// CreateAudioDecoderFactory<...>().
+struct RTC_EXPORT AudioDecoderMultiChannelOpus {
+ using Config = AudioDecoderMultiChannelOpusConfig;
+ static absl::optional<AudioDecoderMultiChannelOpusConfig> SdpToConfig(
+ const SdpAudioFormat& audio_format);
+ static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
+ static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
+ AudioDecoderMultiChannelOpusConfig config,
+ absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+ const FieldTrialsView* field_trials = nullptr);
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_OPUS_AUDIO_DECODER_MULTI_CHANNEL_OPUS_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_multi_channel_opus_config.h b/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_multi_channel_opus_config.h
new file mode 100644
index 0000000000..f97c5c3193
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_multi_channel_opus_config.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_OPUS_AUDIO_DECODER_MULTI_CHANNEL_OPUS_CONFIG_H_
+#define API_AUDIO_CODECS_OPUS_AUDIO_DECODER_MULTI_CHANNEL_OPUS_CONFIG_H_
+
+#include <vector>
+
+#include "api/audio_codecs/audio_decoder.h"
+
+namespace webrtc {
+struct AudioDecoderMultiChannelOpusConfig {
+ // The number of channels that the decoder will output.
+ int num_channels;
+
+ // Number of mono or stereo encoded Opus streams.
+ int num_streams;
+
+ // Number of channel pairs coupled together, see RFC 7845 section
+ // 5.1.1. Has to be less than the number of streams.
+ int coupled_streams;
+
+ // Channel mapping table, defines the mapping from encoded streams to output
+ // channels. See RFC 7845 section 5.1.1.
+ std::vector<unsigned char> channel_mapping;
+
+ bool IsOk() const {
+ if (num_channels < 1 || num_channels > AudioDecoder::kMaxNumberOfChannels ||
+ num_streams < 0 || coupled_streams < 0) {
+ return false;
+ }
+ if (num_streams < coupled_streams) {
+ return false;
+ }
+ if (channel_mapping.size() != static_cast<size_t>(num_channels)) {
+ return false;
+ }
+
+ // Every mono stream codes one channel, every coupled stream codes two. This
+ // is the total coded channel count:
+ const int max_coded_channel = num_streams + coupled_streams;
+ for (const auto& x : channel_mapping) {
+ // Coded channels >= max_coded_channel don't exist. Except for 255, which
+ // tells Opus to put silence in output channel x.
+ if (x >= max_coded_channel && x != 255) {
+ return false;
+ }
+ }
+
+ if (num_channels > 255 || max_coded_channel >= 255) {
+ return false;
+ }
+ return true;
+ }
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_OPUS_AUDIO_DECODER_MULTI_CHANNEL_OPUS_CONFIG_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_multiopus_gn/moz.build b/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_multiopus_gn/moz.build
new file mode 100644
index 0000000000..2b2bc6d9a7
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_multiopus_gn/moz.build
@@ -0,0 +1,226 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/media/libopus/include/",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_multi_channel_opus.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_decoder_multiopus_gn")
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_opus.cc b/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_opus.cc
new file mode 100644
index 0000000000..efc9a73546
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_opus.cc
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/opus/audio_decoder_opus.h"
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/match.h"
+#include "modules/audio_coding/codecs/opus/audio_decoder_opus.h"
+
+namespace webrtc {
+
+bool AudioDecoderOpus::Config::IsOk() const {
+ if (sample_rate_hz != 16000 && sample_rate_hz != 48000) {
+ // Unsupported sample rate. (libopus supports a few other rates as
+ // well; we can add support for them when needed.)
+ return false;
+ }
+ if (num_channels != 1 && num_channels != 2) {
+ return false;
+ }
+ return true;
+}
+
+absl::optional<AudioDecoderOpus::Config> AudioDecoderOpus::SdpToConfig(
+ const SdpAudioFormat& format) {
+ const auto num_channels = [&]() -> absl::optional<int> {
+ auto stereo = format.parameters.find("stereo");
+ if (stereo != format.parameters.end()) {
+ if (stereo->second == "0") {
+ return 1;
+ } else if (stereo->second == "1") {
+ return 2;
+ } else {
+ return absl::nullopt; // Bad stereo parameter.
+ }
+ }
+ return 1; // Default to mono.
+ }();
+ if (absl::EqualsIgnoreCase(format.name, "opus") &&
+ format.clockrate_hz == 48000 && format.num_channels == 2 &&
+ num_channels) {
+ Config config;
+ config.num_channels = *num_channels;
+ if (!config.IsOk()) {
+ RTC_DCHECK_NOTREACHED();
+ return absl::nullopt;
+ }
+ return config;
+ } else {
+ return absl::nullopt;
+ }
+}
+
+void AudioDecoderOpus::AppendSupportedDecoders(
+ std::vector<AudioCodecSpec>* specs) {
+ AudioCodecInfo opus_info{48000, 1, 64000, 6000, 510000};
+ opus_info.allow_comfort_noise = false;
+ opus_info.supports_network_adaption = true;
+ SdpAudioFormat opus_format(
+ {"opus", 48000, 2, {{"minptime", "10"}, {"useinbandfec", "1"}}});
+ specs->push_back({std::move(opus_format), opus_info});
+}
+
+std::unique_ptr<AudioDecoder> AudioDecoderOpus::MakeAudioDecoder(
+ Config config,
+ absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+ const FieldTrialsView* field_trials) {
+ if (!config.IsOk()) {
+ RTC_DCHECK_NOTREACHED();
+ return nullptr;
+ }
+ return std::make_unique<AudioDecoderOpusImpl>(config.num_channels,
+ config.sample_rate_hz);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_opus.h b/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_opus.h
new file mode 100644
index 0000000000..138c0377df
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_opus.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_OPUS_AUDIO_DECODER_OPUS_H_
+#define API_AUDIO_CODECS_OPUS_AUDIO_DECODER_OPUS_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/audio_codecs/audio_codec_pair_id.h"
+#include "api/audio_codecs/audio_decoder.h"
+#include "api/audio_codecs/audio_format.h"
+#include "api/field_trials_view.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Opus decoder API for use as a template parameter to
+// CreateAudioDecoderFactory<...>().
+struct RTC_EXPORT AudioDecoderOpus {
+ struct Config {
+ bool IsOk() const; // Checks if the values are currently OK.
+ int sample_rate_hz = 48000;
+ int num_channels = 1;
+ };
+ static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
+ static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
+ static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
+ Config config,
+ absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+ const FieldTrialsView* field_trials = nullptr);
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_OPUS_AUDIO_DECODER_OPUS_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_opus_config_gn/moz.build b/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_opus_config_gn/moz.build
new file mode 100644
index 0000000000..e2c470d5ee
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_opus_config_gn/moz.build
@@ -0,0 +1,209 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_decoder_opus_config_gn")
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_opus_gn/moz.build b/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_opus_gn/moz.build
new file mode 100644
index 0000000000..58e6355a55
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_opus_gn/moz.build
@@ -0,0 +1,233 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/media/libopus/include/",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio_codecs/opus/audio_decoder_opus.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "rt"
+ ]
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "crypt32",
+ "iphlpapi",
+ "secur32",
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_decoder_opus_gn")
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multi_channel_opus.cc b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multi_channel_opus.cc
new file mode 100644
index 0000000000..14f480b1ec
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multi_channel_opus.cc
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/opus/audio_encoder_multi_channel_opus.h"
+
+#include <utility>
+
+#include "modules/audio_coding/codecs/opus/audio_encoder_multi_channel_opus_impl.h"
+
+namespace webrtc {
+
+absl::optional<AudioEncoderMultiChannelOpusConfig>
+AudioEncoderMultiChannelOpus::SdpToConfig(const SdpAudioFormat& format) {
+ return AudioEncoderMultiChannelOpusImpl::SdpToConfig(format);
+}
+
+void AudioEncoderMultiChannelOpus::AppendSupportedEncoders(
+ std::vector<AudioCodecSpec>* specs) {
+ // To get full utilization of the surround support of the Opus lib, we can
+ // mark which channel is the low frequency effects (LFE). But that is not done
+ // ATM.
+ {
+ AudioCodecInfo surround_5_1_opus_info{48000, 6,
+ /* default_bitrate_bps= */ 128000};
+ surround_5_1_opus_info.allow_comfort_noise = false;
+ surround_5_1_opus_info.supports_network_adaption = false;
+ SdpAudioFormat opus_format({"multiopus",
+ 48000,
+ 6,
+ {{"minptime", "10"},
+ {"useinbandfec", "1"},
+ {"channel_mapping", "0,4,1,2,3,5"},
+ {"num_streams", "4"},
+ {"coupled_streams", "2"}}});
+ specs->push_back({std::move(opus_format), surround_5_1_opus_info});
+ }
+ {
+ AudioCodecInfo surround_7_1_opus_info{48000, 8,
+ /* default_bitrate_bps= */ 200000};
+ surround_7_1_opus_info.allow_comfort_noise = false;
+ surround_7_1_opus_info.supports_network_adaption = false;
+ SdpAudioFormat opus_format({"multiopus",
+ 48000,
+ 8,
+ {{"minptime", "10"},
+ {"useinbandfec", "1"},
+ {"channel_mapping", "0,6,1,2,3,4,5,7"},
+ {"num_streams", "5"},
+ {"coupled_streams", "3"}}});
+ specs->push_back({std::move(opus_format), surround_7_1_opus_info});
+ }
+}
+
+AudioCodecInfo AudioEncoderMultiChannelOpus::QueryAudioEncoder(
+ const AudioEncoderMultiChannelOpusConfig& config) {
+ return AudioEncoderMultiChannelOpusImpl::QueryAudioEncoder(config);
+}
+
+std::unique_ptr<AudioEncoder> AudioEncoderMultiChannelOpus::MakeAudioEncoder(
+ const AudioEncoderMultiChannelOpusConfig& config,
+ int payload_type,
+ absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+ const FieldTrialsView* field_trials) {
+ return AudioEncoderMultiChannelOpusImpl::MakeAudioEncoder(config,
+ payload_type);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multi_channel_opus.h b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multi_channel_opus.h
new file mode 100644
index 0000000000..c1c4db3577
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multi_channel_opus.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_MULTI_CHANNEL_OPUS_H_
+#define API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_MULTI_CHANNEL_OPUS_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/audio_codecs/audio_codec_pair_id.h"
+#include "api/audio_codecs/audio_encoder.h"
+#include "api/audio_codecs/audio_format.h"
+#include "api/audio_codecs/opus/audio_encoder_multi_channel_opus_config.h"
+#include "api/field_trials_view.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Opus encoder API for use as a template parameter to
+// CreateAudioEncoderFactory<...>().
+struct RTC_EXPORT AudioEncoderMultiChannelOpus {
+ using Config = AudioEncoderMultiChannelOpusConfig;
+ static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
+ static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
+ static AudioCodecInfo QueryAudioEncoder(const Config& config);
+ static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
+ const Config& config,
+ int payload_type,
+ absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+ const FieldTrialsView* field_trials = nullptr);
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_MULTI_CHANNEL_OPUS_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multi_channel_opus_config.cc b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multi_channel_opus_config.cc
new file mode 100644
index 0000000000..0052c429b2
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multi_channel_opus_config.cc
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/opus/audio_encoder_multi_channel_opus_config.h"
+
+namespace webrtc {
+
+namespace {
+constexpr int kDefaultComplexity = 9;
+} // namespace
+
+AudioEncoderMultiChannelOpusConfig::AudioEncoderMultiChannelOpusConfig()
+ : frame_size_ms(kDefaultFrameSizeMs),
+ num_channels(1),
+ application(ApplicationMode::kVoip),
+ bitrate_bps(32000),
+ fec_enabled(false),
+ cbr_enabled(false),
+ dtx_enabled(false),
+ max_playback_rate_hz(48000),
+ complexity(kDefaultComplexity),
+ num_streams(-1),
+ coupled_streams(-1) {}
+AudioEncoderMultiChannelOpusConfig::AudioEncoderMultiChannelOpusConfig(
+ const AudioEncoderMultiChannelOpusConfig&) = default;
+AudioEncoderMultiChannelOpusConfig::~AudioEncoderMultiChannelOpusConfig() =
+ default;
+AudioEncoderMultiChannelOpusConfig& AudioEncoderMultiChannelOpusConfig::
+operator=(const AudioEncoderMultiChannelOpusConfig&) = default;
+
+bool AudioEncoderMultiChannelOpusConfig::IsOk() const {
+ if (frame_size_ms <= 0 || frame_size_ms % 10 != 0)
+ return false;
+ if (num_channels >= 255) {
+ return false;
+ }
+ if (bitrate_bps < kMinBitrateBps || bitrate_bps > kMaxBitrateBps)
+ return false;
+ if (complexity < 0 || complexity > 10)
+ return false;
+
+ // Check the lengths:
+ if (num_streams < 0 || coupled_streams < 0) {
+ return false;
+ }
+ if (num_streams < coupled_streams) {
+ return false;
+ }
+ if (channel_mapping.size() != static_cast<size_t>(num_channels)) {
+ return false;
+ }
+
+ // Every mono stream codes one channel, every coupled stream codes two. This
+ // is the total coded channel count:
+ const int max_coded_channel = num_streams + coupled_streams;
+ for (const auto& x : channel_mapping) {
+ // Coded channels >= max_coded_channel don't exist. Except for 255, which
+ // tells Opus to ignore input channel x.
+ if (x >= max_coded_channel && x != 255) {
+ return false;
+ }
+ }
+
+ // Inverse mapping.
+ constexpr int kNotSet = -1;
+ std::vector<int> coded_channels_to_input_channels(max_coded_channel, kNotSet);
+ for (size_t i = 0; i < num_channels; ++i) {
+ if (channel_mapping[i] == 255) {
+ continue;
+ }
+
+ // If it's not ignored, put it in the inverted mapping. But first check if
+ // we've told Opus to use another input channel for this coded channel:
+ const int coded_channel = channel_mapping[i];
+ if (coded_channels_to_input_channels[coded_channel] != kNotSet) {
+ // Coded channel `coded_channel` comes from both input channels
+ // `coded_channels_to_input_channels[coded_channel]` and `i`.
+ return false;
+ }
+
+ coded_channels_to_input_channels[coded_channel] = i;
+ }
+
+ // Check that we specified what input the encoder should use to produce
+ // every coded channel.
+ for (int i = 0; i < max_coded_channel; ++i) {
+ if (coded_channels_to_input_channels[i] == kNotSet) {
+ // Coded channel `i` has unspecified input channel.
+ return false;
+ }
+ }
+
+ if (num_channels > 255 || max_coded_channel >= 255) {
+ return false;
+ }
+ return true;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multi_channel_opus_config.h b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multi_channel_opus_config.h
new file mode 100644
index 0000000000..9b51246c15
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multi_channel_opus_config.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_MULTI_CHANNEL_OPUS_CONFIG_H_
+#define API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_MULTI_CHANNEL_OPUS_CONFIG_H_
+
+#include <stddef.h>
+
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/audio_codecs/opus/audio_encoder_opus_config.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+struct RTC_EXPORT AudioEncoderMultiChannelOpusConfig {
+ static constexpr int kDefaultFrameSizeMs = 20;
+
+ // Opus API allows a min bitrate of 500bps, but Opus documentation suggests
+ // bitrate should be in the range of 6000 to 510000, inclusive.
+ static constexpr int kMinBitrateBps = 6000;
+ static constexpr int kMaxBitrateBps = 510000;
+
+ AudioEncoderMultiChannelOpusConfig();
+ AudioEncoderMultiChannelOpusConfig(const AudioEncoderMultiChannelOpusConfig&);
+ ~AudioEncoderMultiChannelOpusConfig();
+ AudioEncoderMultiChannelOpusConfig& operator=(
+ const AudioEncoderMultiChannelOpusConfig&);
+
+ int frame_size_ms;
+ size_t num_channels;
+ enum class ApplicationMode { kVoip, kAudio };
+ ApplicationMode application;
+ int bitrate_bps;
+ bool fec_enabled;
+ bool cbr_enabled;
+ bool dtx_enabled;
+ int max_playback_rate_hz;
+ std::vector<int> supported_frame_lengths_ms;
+
+ int complexity;
+
+ // Number of mono/stereo Opus streams.
+ int num_streams;
+
+ // Number of channel pairs coupled together, see RFC 7845 section
+ // 5.1.1. Has to be less than the number of streams
+ int coupled_streams;
+
+ // Channel mapping table, defines the mapping from encoded streams to input
+ // channels. See RFC 7845 section 5.1.1.
+ std::vector<unsigned char> channel_mapping;
+
+ bool IsOk() const;
+};
+
+} // namespace webrtc
+#endif // API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_MULTI_CHANNEL_OPUS_CONFIG_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multiopus_gn/moz.build b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multiopus_gn/moz.build
new file mode 100644
index 0000000000..91afd0a4e4
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multiopus_gn/moz.build
@@ -0,0 +1,226 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/media/libopus/include/",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multi_channel_opus.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_encoder_multiopus_gn")
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus.cc b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus.cc
new file mode 100644
index 0000000000..5b6322da4c
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus.cc
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/opus/audio_encoder_opus.h"
+
+#include "modules/audio_coding/codecs/opus/audio_encoder_opus.h"
+
+namespace webrtc {
+
+absl::optional<AudioEncoderOpusConfig> AudioEncoderOpus::SdpToConfig(
+ const SdpAudioFormat& format) {
+ return AudioEncoderOpusImpl::SdpToConfig(format);
+}
+
+void AudioEncoderOpus::AppendSupportedEncoders(
+ std::vector<AudioCodecSpec>* specs) {
+ AudioEncoderOpusImpl::AppendSupportedEncoders(specs);
+}
+
+AudioCodecInfo AudioEncoderOpus::QueryAudioEncoder(
+ const AudioEncoderOpusConfig& config) {
+ return AudioEncoderOpusImpl::QueryAudioEncoder(config);
+}
+
+std::unique_ptr<AudioEncoder> AudioEncoderOpus::MakeAudioEncoder(
+ const AudioEncoderOpusConfig& config,
+ int payload_type,
+ absl::optional<AudioCodecPairId> /*codec_pair_id*/,
+ const FieldTrialsView* field_trials) {
+ if (!config.IsOk()) {
+ RTC_DCHECK_NOTREACHED();
+ return nullptr;
+ }
+ return AudioEncoderOpusImpl::MakeAudioEncoder(config, payload_type);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus.h b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus.h
new file mode 100644
index 0000000000..df93ae5303
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_OPUS_H_
+#define API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_OPUS_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/audio_codecs/audio_codec_pair_id.h"
+#include "api/audio_codecs/audio_encoder.h"
+#include "api/audio_codecs/audio_format.h"
+#include "api/audio_codecs/opus/audio_encoder_opus_config.h"
+#include "api/field_trials_view.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Opus encoder API for use as a template parameter to
+// CreateAudioEncoderFactory<...>().
+struct RTC_EXPORT AudioEncoderOpus {
+ using Config = AudioEncoderOpusConfig;
+ static absl::optional<AudioEncoderOpusConfig> SdpToConfig(
+ const SdpAudioFormat& audio_format);
+ static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
+ static AudioCodecInfo QueryAudioEncoder(const AudioEncoderOpusConfig& config);
+ static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
+ const AudioEncoderOpusConfig& config,
+ int payload_type,
+ absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+ const FieldTrialsView* field_trials = nullptr);
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_OPUS_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus_config.cc b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus_config.cc
new file mode 100644
index 0000000000..a9ab924b38
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus_config.cc
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/opus/audio_encoder_opus_config.h"
+
+namespace webrtc {
+
+namespace {
+
+#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
+constexpr int kDefaultComplexity = 5;
+#else
+constexpr int kDefaultComplexity = 9;
+#endif
+
+constexpr int kDefaultLowRateComplexity =
+ WEBRTC_OPUS_VARIABLE_COMPLEXITY ? 9 : kDefaultComplexity;
+
+} // namespace
+
+constexpr int AudioEncoderOpusConfig::kDefaultFrameSizeMs;
+constexpr int AudioEncoderOpusConfig::kMinBitrateBps;
+constexpr int AudioEncoderOpusConfig::kMaxBitrateBps;
+
+AudioEncoderOpusConfig::AudioEncoderOpusConfig()
+ : frame_size_ms(kDefaultFrameSizeMs),
+ sample_rate_hz(48000),
+ num_channels(1),
+ application(ApplicationMode::kVoip),
+ bitrate_bps(32000),
+ fec_enabled(false),
+ cbr_enabled(false),
+ max_playback_rate_hz(48000),
+ complexity(kDefaultComplexity),
+ low_rate_complexity(kDefaultLowRateComplexity),
+ complexity_threshold_bps(12500),
+ complexity_threshold_window_bps(1500),
+ dtx_enabled(false),
+ uplink_bandwidth_update_interval_ms(200),
+ payload_type(-1) {}
+AudioEncoderOpusConfig::AudioEncoderOpusConfig(const AudioEncoderOpusConfig&) =
+ default;
+AudioEncoderOpusConfig::~AudioEncoderOpusConfig() = default;
+AudioEncoderOpusConfig& AudioEncoderOpusConfig::operator=(
+ const AudioEncoderOpusConfig&) = default;
+
+bool AudioEncoderOpusConfig::IsOk() const {
+ if (frame_size_ms <= 0 || frame_size_ms % 10 != 0)
+ return false;
+ if (sample_rate_hz != 16000 && sample_rate_hz != 48000) {
+ // Unsupported input sample rate. (libopus supports a few other rates as
+ // well; we can add support for them when needed.)
+ return false;
+ }
+ if (num_channels >= 255) {
+ return false;
+ }
+ if (!bitrate_bps)
+ return false;
+ if (*bitrate_bps < kMinBitrateBps || *bitrate_bps > kMaxBitrateBps)
+ return false;
+ if (complexity < 0 || complexity > 10)
+ return false;
+ if (low_rate_complexity < 0 || low_rate_complexity > 10)
+ return false;
+ return true;
+}
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus_config.h b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus_config.h
new file mode 100644
index 0000000000..d5d7256c70
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus_config.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_OPUS_CONFIG_H_
+#define API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_OPUS_CONFIG_H_
+
+#include <stddef.h>
+
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+struct RTC_EXPORT AudioEncoderOpusConfig {
+ static constexpr int kDefaultFrameSizeMs = 20;
+
+ // Opus API allows a min bitrate of 500bps, but Opus documentation suggests
+ // bitrate should be in the range of 6000 to 510000, inclusive.
+ static constexpr int kMinBitrateBps = 6000;
+ static constexpr int kMaxBitrateBps = 510000;
+
+ AudioEncoderOpusConfig();
+ AudioEncoderOpusConfig(const AudioEncoderOpusConfig&);
+ ~AudioEncoderOpusConfig();
+ AudioEncoderOpusConfig& operator=(const AudioEncoderOpusConfig&);
+
+ bool IsOk() const; // Checks if the values are currently OK.
+
+ int frame_size_ms;
+ int sample_rate_hz;
+ size_t num_channels;
+ enum class ApplicationMode { kVoip, kAudio };
+ ApplicationMode application;
+
+ // NOTE: This member must always be set.
+ // TODO(kwiberg): Turn it into just an int.
+ absl::optional<int> bitrate_bps;
+
+ bool fec_enabled;
+ bool cbr_enabled;
+ int max_playback_rate_hz;
+
+ // `complexity` is used when the bitrate goes above
+ // `complexity_threshold_bps` + `complexity_threshold_window_bps`;
+ // `low_rate_complexity` is used when the bitrate falls below
+ // `complexity_threshold_bps` - `complexity_threshold_window_bps`. In the
+ // interval in the middle, we keep using the most recent of the two
+ // complexity settings.
+ int complexity;
+ int low_rate_complexity;
+ int complexity_threshold_bps;
+ int complexity_threshold_window_bps;
+
+ bool dtx_enabled;
+ std::vector<int> supported_frame_lengths_ms;
+ int uplink_bandwidth_update_interval_ms;
+
+ // NOTE: This member isn't necessary, and will soon go away. See
+ // https://bugs.chromium.org/p/webrtc/issues/detail?id=7847
+ int payload_type;
+};
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_OPUS_CONFIG_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus_config_gn/moz.build b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus_config_gn/moz.build
new file mode 100644
index 0000000000..06732b48f4
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus_config_gn/moz.build
@@ -0,0 +1,222 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_OPUS_VARIABLE_COMPLEXITY"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+SOURCES += [
+ "/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus_config.cc"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_multi_channel_opus_config.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_encoder_opus_config_gn")
diff --git a/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus_gn/moz.build b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus_gn/moz.build
new file mode 100644
index 0000000000..ab84d3f755
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus_gn/moz.build
@@ -0,0 +1,233 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/media/libopus/include/",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio_codecs/opus/audio_encoder_opus.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "rt"
+ ]
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "crypt32",
+ "iphlpapi",
+ "secur32",
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_encoder_opus_gn")
diff --git a/third_party/libwebrtc/api/audio_codecs/opus_audio_decoder_factory.cc b/third_party/libwebrtc/api/audio_codecs/opus_audio_decoder_factory.cc
new file mode 100644
index 0000000000..ed68f2584e
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus_audio_decoder_factory.cc
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/opus_audio_decoder_factory.h"
+
+#include <memory>
+#include <vector>
+
+#include "api/audio_codecs/audio_decoder_factory_template.h"
+#include "api/audio_codecs/opus/audio_decoder_multi_channel_opus.h"
+#include "api/audio_codecs/opus/audio_decoder_opus.h"
+
+namespace webrtc {
+
+namespace {
+
+// Modify an audio decoder to not advertise support for anything.
+template <typename T>
+struct NotAdvertised {
+ using Config = typename T::Config;
+ static absl::optional<Config> SdpToConfig(
+ const SdpAudioFormat& audio_format) {
+ return T::SdpToConfig(audio_format);
+ }
+ static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs) {
+ // Don't advertise support for anything.
+ }
+ static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
+ const Config& config,
+ absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt) {
+ return T::MakeAudioDecoder(config, codec_pair_id);
+ }
+};
+
+} // namespace
+
+rtc::scoped_refptr<AudioDecoderFactory> CreateOpusAudioDecoderFactory() {
+ return CreateAudioDecoderFactory<
+ AudioDecoderOpus, NotAdvertised<AudioDecoderMultiChannelOpus>>();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/opus_audio_decoder_factory.h b/third_party/libwebrtc/api/audio_codecs/opus_audio_decoder_factory.h
new file mode 100644
index 0000000000..b4f497f8ff
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus_audio_decoder_factory.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_OPUS_AUDIO_DECODER_FACTORY_H_
+#define API_AUDIO_CODECS_OPUS_AUDIO_DECODER_FACTORY_H_
+
+#include "api/audio_codecs/audio_decoder_factory.h"
+#include "api/scoped_refptr.h"
+
+namespace webrtc {
+
+// Creates a new factory that can create only Opus audio decoders. Works like
+// CreateAudioDecoderFactory<AudioDecoderOpus>(), but is easier to use and is
+// not inline because it isn't a template.
+rtc::scoped_refptr<AudioDecoderFactory> CreateOpusAudioDecoderFactory();
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_OPUS_AUDIO_DECODER_FACTORY_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/opus_audio_encoder_factory.cc b/third_party/libwebrtc/api/audio_codecs/opus_audio_encoder_factory.cc
new file mode 100644
index 0000000000..8c286f21e1
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus_audio_encoder_factory.cc
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/opus_audio_encoder_factory.h"
+
+#include <memory>
+#include <vector>
+
+#include "api/audio_codecs/audio_encoder_factory_template.h"
+#include "api/audio_codecs/opus/audio_encoder_multi_channel_opus.h"
+#include "api/audio_codecs/opus/audio_encoder_opus.h"
+
+namespace webrtc {
+namespace {
+
+// Modify an audio encoder to not advertise support for anything.
+template <typename T>
+struct NotAdvertised {
+ using Config = typename T::Config;
+ static absl::optional<Config> SdpToConfig(
+ const SdpAudioFormat& audio_format) {
+ return T::SdpToConfig(audio_format);
+ }
+ static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs) {
+ // Don't advertise support for anything.
+ }
+ static AudioCodecInfo QueryAudioEncoder(const Config& config) {
+ return T::QueryAudioEncoder(config);
+ }
+ static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
+ const Config& config,
+ int payload_type,
+ absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
+ const FieldTrialsView* field_trials = nullptr) {
+ return T::MakeAudioEncoder(config, payload_type, codec_pair_id,
+ field_trials);
+ }
+};
+
+} // namespace
+
+rtc::scoped_refptr<AudioEncoderFactory> CreateOpusAudioEncoderFactory() {
+ return CreateAudioEncoderFactory<
+ AudioEncoderOpus, NotAdvertised<AudioEncoderMultiChannelOpus>>();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/opus_audio_encoder_factory.h b/third_party/libwebrtc/api/audio_codecs/opus_audio_encoder_factory.h
new file mode 100644
index 0000000000..8c1683b6f5
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/opus_audio_encoder_factory.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_FACTORY_H_
+#define API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_FACTORY_H_
+
+#include "api/audio_codecs/audio_encoder_factory.h"
+#include "api/scoped_refptr.h"
+
+namespace webrtc {
+
+// Creates a new factory that can create only Opus audio encoders. Works like
+// CreateAudioEncoderFactory<AudioEncoderOpus>(), but is easier to use and is
+// not inline because it isn't a template.
+rtc::scoped_refptr<AudioEncoderFactory> CreateOpusAudioEncoderFactory();
+
+} // namespace webrtc
+
+#endif // API_AUDIO_CODECS_OPUS_AUDIO_ENCODER_FACTORY_H_
diff --git a/third_party/libwebrtc/api/audio_codecs/test/BUILD.gn b/third_party/libwebrtc/api/audio_codecs/test/BUILD.gn
new file mode 100644
index 0000000000..89f5fef1ea
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/test/BUILD.gn
@@ -0,0 +1,39 @@
+# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+if (is_android) {
+ import("//build/config/android/config.gni")
+ import("//build/config/android/rules.gni")
+}
+
+if (rtc_include_tests) {
+ rtc_library("audio_codecs_api_unittests") {
+ testonly = true
+ sources = [
+ "audio_decoder_factory_template_unittest.cc",
+ "audio_encoder_factory_template_unittest.cc",
+ ]
+ deps = [
+ "..:audio_codecs_api",
+ "../../../test:audio_codec_mocks",
+ "../../../test:scoped_key_value_config",
+ "../../../test:test_support",
+ "../L16:audio_decoder_L16",
+ "../L16:audio_encoder_L16",
+ "../g711:audio_decoder_g711",
+ "../g711:audio_encoder_g711",
+ "../g722:audio_decoder_g722",
+ "../g722:audio_encoder_g722",
+ "../ilbc:audio_decoder_ilbc",
+ "../ilbc:audio_encoder_ilbc",
+ "../opus:audio_decoder_opus",
+ "../opus:audio_encoder_opus",
+ ]
+ }
+}
diff --git a/third_party/libwebrtc/api/audio_codecs/test/audio_decoder_factory_template_unittest.cc b/third_party/libwebrtc/api/audio_codecs/test/audio_decoder_factory_template_unittest.cc
new file mode 100644
index 0000000000..0b18cf934a
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/test/audio_decoder_factory_template_unittest.cc
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/audio_decoder_factory_template.h"
+
+#include <memory>
+
+#include "api/audio_codecs/L16/audio_decoder_L16.h"
+#include "api/audio_codecs/g711/audio_decoder_g711.h"
+#include "api/audio_codecs/g722/audio_decoder_g722.h"
+#include "api/audio_codecs/ilbc/audio_decoder_ilbc.h"
+#include "api/audio_codecs/opus/audio_decoder_opus.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+#include "test/mock_audio_decoder.h"
+#include "test/scoped_key_value_config.h"
+
+namespace webrtc {
+
+namespace {
+
+struct BogusParams {
+ static SdpAudioFormat AudioFormat() { return {"bogus", 8000, 1}; }
+ static AudioCodecInfo CodecInfo() { return {8000, 1, 12345}; }
+};
+
+struct ShamParams {
+ static SdpAudioFormat AudioFormat() {
+ return {"sham", 16000, 2, {{"param", "value"}}};
+ }
+ static AudioCodecInfo CodecInfo() { return {16000, 2, 23456}; }
+};
+
+template <typename Params>
+struct AudioDecoderFakeApi {
+ struct Config {
+ SdpAudioFormat audio_format;
+ };
+
+ static absl::optional<Config> SdpToConfig(
+ const SdpAudioFormat& audio_format) {
+ if (Params::AudioFormat() == audio_format) {
+ Config config = {audio_format};
+ return config;
+ } else {
+ return absl::nullopt;
+ }
+ }
+
+ static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs) {
+ specs->push_back({Params::AudioFormat(), Params::CodecInfo()});
+ }
+
+ static AudioCodecInfo QueryAudioDecoder(const Config&) {
+ return Params::CodecInfo();
+ }
+
+ static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
+ const Config&,
+ absl::optional<AudioCodecPairId> /*codec_pair_id*/ = absl::nullopt) {
+ auto dec = std::make_unique<testing::StrictMock<MockAudioDecoder>>();
+ EXPECT_CALL(*dec, SampleRateHz())
+ .WillOnce(::testing::Return(Params::CodecInfo().sample_rate_hz));
+ EXPECT_CALL(*dec, Die());
+ return std::move(dec);
+ }
+};
+
+} // namespace
+
+TEST(AudioDecoderFactoryTemplateTest, NoDecoderTypes) {
+ test::ScopedKeyValueConfig field_trials;
+ rtc::scoped_refptr<AudioDecoderFactory> factory(
+ rtc::make_ref_counted<
+ audio_decoder_factory_template_impl::AudioDecoderFactoryT<>>(
+ &field_trials));
+ EXPECT_THAT(factory->GetSupportedDecoders(), ::testing::IsEmpty());
+ EXPECT_FALSE(factory->IsSupportedDecoder({"foo", 8000, 1}));
+ EXPECT_EQ(nullptr,
+ factory->MakeAudioDecoder({"bar", 16000, 1}, absl::nullopt));
+}
+
+TEST(AudioDecoderFactoryTemplateTest, OneDecoderType) {
+ auto factory = CreateAudioDecoderFactory<AudioDecoderFakeApi<BogusParams>>();
+ EXPECT_THAT(factory->GetSupportedDecoders(),
+ ::testing::ElementsAre(
+ AudioCodecSpec{{"bogus", 8000, 1}, {8000, 1, 12345}}));
+ EXPECT_FALSE(factory->IsSupportedDecoder({"foo", 8000, 1}));
+ EXPECT_TRUE(factory->IsSupportedDecoder({"bogus", 8000, 1}));
+ EXPECT_EQ(nullptr,
+ factory->MakeAudioDecoder({"bar", 16000, 1}, absl::nullopt));
+ auto dec = factory->MakeAudioDecoder({"bogus", 8000, 1}, absl::nullopt);
+ ASSERT_NE(nullptr, dec);
+ EXPECT_EQ(8000, dec->SampleRateHz());
+}
+
+TEST(AudioDecoderFactoryTemplateTest, TwoDecoderTypes) {
+ auto factory = CreateAudioDecoderFactory<AudioDecoderFakeApi<BogusParams>,
+ AudioDecoderFakeApi<ShamParams>>();
+ EXPECT_THAT(factory->GetSupportedDecoders(),
+ ::testing::ElementsAre(
+ AudioCodecSpec{{"bogus", 8000, 1}, {8000, 1, 12345}},
+ AudioCodecSpec{{"sham", 16000, 2, {{"param", "value"}}},
+ {16000, 2, 23456}}));
+ EXPECT_FALSE(factory->IsSupportedDecoder({"foo", 8000, 1}));
+ EXPECT_TRUE(factory->IsSupportedDecoder({"bogus", 8000, 1}));
+ EXPECT_TRUE(
+ factory->IsSupportedDecoder({"sham", 16000, 2, {{"param", "value"}}}));
+ EXPECT_EQ(nullptr,
+ factory->MakeAudioDecoder({"bar", 16000, 1}, absl::nullopt));
+ auto dec1 = factory->MakeAudioDecoder({"bogus", 8000, 1}, absl::nullopt);
+ ASSERT_NE(nullptr, dec1);
+ EXPECT_EQ(8000, dec1->SampleRateHz());
+ EXPECT_EQ(nullptr,
+ factory->MakeAudioDecoder({"sham", 16000, 2}, absl::nullopt));
+ auto dec2 = factory->MakeAudioDecoder(
+ {"sham", 16000, 2, {{"param", "value"}}}, absl::nullopt);
+ ASSERT_NE(nullptr, dec2);
+ EXPECT_EQ(16000, dec2->SampleRateHz());
+}
+
+TEST(AudioDecoderFactoryTemplateTest, G711) {
+ auto factory = CreateAudioDecoderFactory<AudioDecoderG711>();
+ EXPECT_THAT(factory->GetSupportedDecoders(),
+ ::testing::ElementsAre(
+ AudioCodecSpec{{"PCMU", 8000, 1}, {8000, 1, 64000}},
+ AudioCodecSpec{{"PCMA", 8000, 1}, {8000, 1, 64000}}));
+ EXPECT_FALSE(factory->IsSupportedDecoder({"G711", 8000, 1}));
+ EXPECT_TRUE(factory->IsSupportedDecoder({"PCMU", 8000, 1}));
+ EXPECT_TRUE(factory->IsSupportedDecoder({"pcma", 8000, 1}));
+ EXPECT_EQ(nullptr,
+ factory->MakeAudioDecoder({"pcmu", 16000, 1}, absl::nullopt));
+ auto dec1 = factory->MakeAudioDecoder({"pcmu", 8000, 1}, absl::nullopt);
+ ASSERT_NE(nullptr, dec1);
+ EXPECT_EQ(8000, dec1->SampleRateHz());
+ auto dec2 = factory->MakeAudioDecoder({"PCMA", 8000, 1}, absl::nullopt);
+ ASSERT_NE(nullptr, dec2);
+ EXPECT_EQ(8000, dec2->SampleRateHz());
+}
+
+TEST(AudioDecoderFactoryTemplateTest, G722) {
+ auto factory = CreateAudioDecoderFactory<AudioDecoderG722>();
+ EXPECT_THAT(factory->GetSupportedDecoders(),
+ ::testing::ElementsAre(
+ AudioCodecSpec{{"G722", 8000, 1}, {16000, 1, 64000}}));
+ EXPECT_FALSE(factory->IsSupportedDecoder({"foo", 8000, 1}));
+ EXPECT_TRUE(factory->IsSupportedDecoder({"G722", 8000, 1}));
+ EXPECT_EQ(nullptr,
+ factory->MakeAudioDecoder({"bar", 16000, 1}, absl::nullopt));
+ auto dec1 = factory->MakeAudioDecoder({"G722", 8000, 1}, absl::nullopt);
+ ASSERT_NE(nullptr, dec1);
+ EXPECT_EQ(16000, dec1->SampleRateHz());
+ EXPECT_EQ(1u, dec1->Channels());
+ auto dec2 = factory->MakeAudioDecoder({"G722", 8000, 2}, absl::nullopt);
+ ASSERT_NE(nullptr, dec2);
+ EXPECT_EQ(16000, dec2->SampleRateHz());
+ EXPECT_EQ(2u, dec2->Channels());
+ auto dec3 = factory->MakeAudioDecoder({"G722", 8000, 3}, absl::nullopt);
+ ASSERT_EQ(nullptr, dec3);
+}
+
+TEST(AudioDecoderFactoryTemplateTest, Ilbc) {
+ auto factory = CreateAudioDecoderFactory<AudioDecoderIlbc>();
+ EXPECT_THAT(factory->GetSupportedDecoders(),
+ ::testing::ElementsAre(
+ AudioCodecSpec{{"ILBC", 8000, 1}, {8000, 1, 13300}}));
+ EXPECT_FALSE(factory->IsSupportedDecoder({"foo", 8000, 1}));
+ EXPECT_TRUE(factory->IsSupportedDecoder({"ilbc", 8000, 1}));
+ EXPECT_EQ(nullptr,
+ factory->MakeAudioDecoder({"bar", 8000, 1}, absl::nullopt));
+ auto dec = factory->MakeAudioDecoder({"ilbc", 8000, 1}, absl::nullopt);
+ ASSERT_NE(nullptr, dec);
+ EXPECT_EQ(8000, dec->SampleRateHz());
+}
+
+TEST(AudioDecoderFactoryTemplateTest, L16) {
+ auto factory = CreateAudioDecoderFactory<AudioDecoderL16>();
+ EXPECT_THAT(
+ factory->GetSupportedDecoders(),
+ ::testing::ElementsAre(
+ AudioCodecSpec{{"L16", 8000, 1}, {8000, 1, 8000 * 16}},
+ AudioCodecSpec{{"L16", 16000, 1}, {16000, 1, 16000 * 16}},
+ AudioCodecSpec{{"L16", 32000, 1}, {32000, 1, 32000 * 16}},
+ AudioCodecSpec{{"L16", 8000, 2}, {8000, 2, 8000 * 16 * 2}},
+ AudioCodecSpec{{"L16", 16000, 2}, {16000, 2, 16000 * 16 * 2}},
+ AudioCodecSpec{{"L16", 32000, 2}, {32000, 2, 32000 * 16 * 2}}));
+ EXPECT_FALSE(factory->IsSupportedDecoder({"foo", 8000, 1}));
+ EXPECT_TRUE(factory->IsSupportedDecoder({"L16", 48000, 1}));
+ EXPECT_FALSE(factory->IsSupportedDecoder({"L16", 96000, 1}));
+ EXPECT_EQ(nullptr,
+ factory->MakeAudioDecoder({"L16", 8000, 0}, absl::nullopt));
+ auto dec = factory->MakeAudioDecoder({"L16", 48000, 2}, absl::nullopt);
+ ASSERT_NE(nullptr, dec);
+ EXPECT_EQ(48000, dec->SampleRateHz());
+}
+
+TEST(AudioDecoderFactoryTemplateTest, Opus) {
+ auto factory = CreateAudioDecoderFactory<AudioDecoderOpus>();
+ AudioCodecInfo opus_info{48000, 1, 64000, 6000, 510000};
+ opus_info.allow_comfort_noise = false;
+ opus_info.supports_network_adaption = true;
+ const SdpAudioFormat opus_format(
+ {"opus", 48000, 2, {{"minptime", "10"}, {"useinbandfec", "1"}}});
+ EXPECT_THAT(factory->GetSupportedDecoders(),
+ ::testing::ElementsAre(AudioCodecSpec{opus_format, opus_info}));
+ EXPECT_FALSE(factory->IsSupportedDecoder({"opus", 48000, 1}));
+ EXPECT_TRUE(factory->IsSupportedDecoder({"opus", 48000, 2}));
+ EXPECT_EQ(nullptr,
+ factory->MakeAudioDecoder({"bar", 16000, 1}, absl::nullopt));
+ auto dec = factory->MakeAudioDecoder({"opus", 48000, 2}, absl::nullopt);
+ ASSERT_NE(nullptr, dec);
+ EXPECT_EQ(48000, dec->SampleRateHz());
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_codecs/test/audio_encoder_factory_template_unittest.cc b/third_party/libwebrtc/api/audio_codecs/test/audio_encoder_factory_template_unittest.cc
new file mode 100644
index 0000000000..dbba387724
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_codecs/test/audio_encoder_factory_template_unittest.cc
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_codecs/audio_encoder_factory_template.h"
+
+#include <memory>
+
+#include "api/audio_codecs/L16/audio_encoder_L16.h"
+#include "api/audio_codecs/g711/audio_encoder_g711.h"
+#include "api/audio_codecs/g722/audio_encoder_g722.h"
+#include "api/audio_codecs/ilbc/audio_encoder_ilbc.h"
+#include "api/audio_codecs/opus/audio_encoder_opus.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+#include "test/mock_audio_encoder.h"
+#include "test/scoped_key_value_config.h"
+
+namespace webrtc {
+
+namespace {
+
+struct BogusParams {
+ static SdpAudioFormat AudioFormat() { return {"bogus", 8000, 1}; }
+ static AudioCodecInfo CodecInfo() { return {8000, 1, 12345}; }
+};
+
+struct ShamParams {
+ static SdpAudioFormat AudioFormat() {
+ return {"sham", 16000, 2, {{"param", "value"}}};
+ }
+ static AudioCodecInfo CodecInfo() { return {16000, 2, 23456}; }
+};
+
+template <typename Params>
+struct AudioEncoderFakeApi {
+ struct Config {
+ SdpAudioFormat audio_format;
+ };
+
+ static absl::optional<Config> SdpToConfig(
+ const SdpAudioFormat& audio_format) {
+ if (Params::AudioFormat() == audio_format) {
+ Config config = {audio_format};
+ return config;
+ } else {
+ return absl::nullopt;
+ }
+ }
+
+ static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs) {
+ specs->push_back({Params::AudioFormat(), Params::CodecInfo()});
+ }
+
+ static AudioCodecInfo QueryAudioEncoder(const Config&) {
+ return Params::CodecInfo();
+ }
+
+ static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
+ const Config&,
+ int payload_type,
+ absl::optional<AudioCodecPairId> /*codec_pair_id*/ = absl::nullopt) {
+ auto enc = std::make_unique<testing::StrictMock<MockAudioEncoder>>();
+ EXPECT_CALL(*enc, SampleRateHz())
+ .WillOnce(::testing::Return(Params::CodecInfo().sample_rate_hz));
+ return std::move(enc);
+ }
+};
+
+} // namespace
+
+TEST(AudioEncoderFactoryTemplateTest, NoEncoderTypes) {
+ test::ScopedKeyValueConfig field_trials;
+ rtc::scoped_refptr<AudioEncoderFactory> factory(
+ rtc::make_ref_counted<
+ audio_encoder_factory_template_impl::AudioEncoderFactoryT<>>(
+ &field_trials));
+ EXPECT_THAT(factory->GetSupportedEncoders(), ::testing::IsEmpty());
+ EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
+ EXPECT_EQ(nullptr,
+ factory->MakeAudioEncoder(17, {"bar", 16000, 1}, absl::nullopt));
+}
+
+TEST(AudioEncoderFactoryTemplateTest, OneEncoderType) {
+ auto factory = CreateAudioEncoderFactory<AudioEncoderFakeApi<BogusParams>>();
+ EXPECT_THAT(factory->GetSupportedEncoders(),
+ ::testing::ElementsAre(
+ AudioCodecSpec{{"bogus", 8000, 1}, {8000, 1, 12345}}));
+ EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
+ EXPECT_EQ(AudioCodecInfo(8000, 1, 12345),
+ factory->QueryAudioEncoder({"bogus", 8000, 1}));
+ EXPECT_EQ(nullptr,
+ factory->MakeAudioEncoder(17, {"bar", 16000, 1}, absl::nullopt));
+ auto enc = factory->MakeAudioEncoder(17, {"bogus", 8000, 1}, absl::nullopt);
+ ASSERT_NE(nullptr, enc);
+ EXPECT_EQ(8000, enc->SampleRateHz());
+}
+
+TEST(AudioEncoderFactoryTemplateTest, TwoEncoderTypes) {
+ auto factory = CreateAudioEncoderFactory<AudioEncoderFakeApi<BogusParams>,
+ AudioEncoderFakeApi<ShamParams>>();
+ EXPECT_THAT(factory->GetSupportedEncoders(),
+ ::testing::ElementsAre(
+ AudioCodecSpec{{"bogus", 8000, 1}, {8000, 1, 12345}},
+ AudioCodecSpec{{"sham", 16000, 2, {{"param", "value"}}},
+ {16000, 2, 23456}}));
+ EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
+ EXPECT_EQ(AudioCodecInfo(8000, 1, 12345),
+ factory->QueryAudioEncoder({"bogus", 8000, 1}));
+ EXPECT_EQ(
+ AudioCodecInfo(16000, 2, 23456),
+ factory->QueryAudioEncoder({"sham", 16000, 2, {{"param", "value"}}}));
+ EXPECT_EQ(nullptr,
+ factory->MakeAudioEncoder(17, {"bar", 16000, 1}, absl::nullopt));
+ auto enc1 = factory->MakeAudioEncoder(17, {"bogus", 8000, 1}, absl::nullopt);
+ ASSERT_NE(nullptr, enc1);
+ EXPECT_EQ(8000, enc1->SampleRateHz());
+ EXPECT_EQ(nullptr,
+ factory->MakeAudioEncoder(17, {"sham", 16000, 2}, absl::nullopt));
+ auto enc2 = factory->MakeAudioEncoder(
+ 17, {"sham", 16000, 2, {{"param", "value"}}}, absl::nullopt);
+ ASSERT_NE(nullptr, enc2);
+ EXPECT_EQ(16000, enc2->SampleRateHz());
+}
+
+TEST(AudioEncoderFactoryTemplateTest, G711) {
+ auto factory = CreateAudioEncoderFactory<AudioEncoderG711>();
+ EXPECT_THAT(factory->GetSupportedEncoders(),
+ ::testing::ElementsAre(
+ AudioCodecSpec{{"PCMU", 8000, 1}, {8000, 1, 64000}},
+ AudioCodecSpec{{"PCMA", 8000, 1}, {8000, 1, 64000}}));
+ EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"PCMA", 16000, 1}));
+ EXPECT_EQ(AudioCodecInfo(8000, 1, 64000),
+ factory->QueryAudioEncoder({"PCMA", 8000, 1}));
+ EXPECT_EQ(nullptr,
+ factory->MakeAudioEncoder(17, {"PCMU", 16000, 1}, absl::nullopt));
+ auto enc1 = factory->MakeAudioEncoder(17, {"PCMU", 8000, 1}, absl::nullopt);
+ ASSERT_NE(nullptr, enc1);
+ EXPECT_EQ(8000, enc1->SampleRateHz());
+ auto enc2 = factory->MakeAudioEncoder(17, {"PCMA", 8000, 1}, absl::nullopt);
+ ASSERT_NE(nullptr, enc2);
+ EXPECT_EQ(8000, enc2->SampleRateHz());
+}
+
+TEST(AudioEncoderFactoryTemplateTest, G722) {
+ auto factory = CreateAudioEncoderFactory<AudioEncoderG722>();
+ EXPECT_THAT(factory->GetSupportedEncoders(),
+ ::testing::ElementsAre(
+ AudioCodecSpec{{"G722", 8000, 1}, {16000, 1, 64000}}));
+ EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
+ EXPECT_EQ(AudioCodecInfo(16000, 1, 64000),
+ factory->QueryAudioEncoder({"G722", 8000, 1}));
+ EXPECT_EQ(nullptr,
+ factory->MakeAudioEncoder(17, {"bar", 16000, 1}, absl::nullopt));
+ auto enc = factory->MakeAudioEncoder(17, {"G722", 8000, 1}, absl::nullopt);
+ ASSERT_NE(nullptr, enc);
+ EXPECT_EQ(16000, enc->SampleRateHz());
+}
+
+TEST(AudioEncoderFactoryTemplateTest, Ilbc) {
+ auto factory = CreateAudioEncoderFactory<AudioEncoderIlbc>();
+ EXPECT_THAT(factory->GetSupportedEncoders(),
+ ::testing::ElementsAre(
+ AudioCodecSpec{{"ILBC", 8000, 1}, {8000, 1, 13333}}));
+ EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
+ EXPECT_EQ(AudioCodecInfo(8000, 1, 13333),
+ factory->QueryAudioEncoder({"ilbc", 8000, 1}));
+ EXPECT_EQ(nullptr,
+ factory->MakeAudioEncoder(17, {"bar", 8000, 1}, absl::nullopt));
+ auto enc = factory->MakeAudioEncoder(17, {"ilbc", 8000, 1}, absl::nullopt);
+ ASSERT_NE(nullptr, enc);
+ EXPECT_EQ(8000, enc->SampleRateHz());
+}
+
+TEST(AudioEncoderFactoryTemplateTest, L16) {
+ auto factory = CreateAudioEncoderFactory<AudioEncoderL16>();
+ EXPECT_THAT(
+ factory->GetSupportedEncoders(),
+ ::testing::ElementsAre(
+ AudioCodecSpec{{"L16", 8000, 1}, {8000, 1, 8000 * 16}},
+ AudioCodecSpec{{"L16", 16000, 1}, {16000, 1, 16000 * 16}},
+ AudioCodecSpec{{"L16", 32000, 1}, {32000, 1, 32000 * 16}},
+ AudioCodecSpec{{"L16", 8000, 2}, {8000, 2, 8000 * 16 * 2}},
+ AudioCodecSpec{{"L16", 16000, 2}, {16000, 2, 16000 * 16 * 2}},
+ AudioCodecSpec{{"L16", 32000, 2}, {32000, 2, 32000 * 16 * 2}}));
+ EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"L16", 8000, 0}));
+ EXPECT_EQ(AudioCodecInfo(48000, 1, 48000 * 16),
+ factory->QueryAudioEncoder({"L16", 48000, 1}));
+ EXPECT_EQ(nullptr,
+ factory->MakeAudioEncoder(17, {"L16", 8000, 0}, absl::nullopt));
+ auto enc = factory->MakeAudioEncoder(17, {"L16", 48000, 2}, absl::nullopt);
+ ASSERT_NE(nullptr, enc);
+ EXPECT_EQ(48000, enc->SampleRateHz());
+}
+
+TEST(AudioEncoderFactoryTemplateTest, Opus) {
+ auto factory = CreateAudioEncoderFactory<AudioEncoderOpus>();
+ AudioCodecInfo info = {48000, 1, 32000, 6000, 510000};
+ info.allow_comfort_noise = false;
+ info.supports_network_adaption = true;
+ EXPECT_THAT(
+ factory->GetSupportedEncoders(),
+ ::testing::ElementsAre(AudioCodecSpec{
+ {"opus", 48000, 2, {{"minptime", "10"}, {"useinbandfec", "1"}}},
+ info}));
+ EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
+ EXPECT_EQ(
+ info,
+ factory->QueryAudioEncoder(
+ {"opus", 48000, 2, {{"minptime", "10"}, {"useinbandfec", "1"}}}));
+ EXPECT_EQ(nullptr,
+ factory->MakeAudioEncoder(17, {"bar", 16000, 1}, absl::nullopt));
+ auto enc = factory->MakeAudioEncoder(17, {"opus", 48000, 2}, absl::nullopt);
+ ASSERT_NE(nullptr, enc);
+ EXPECT_EQ(48000, enc->SampleRateHz());
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/audio_options.cc b/third_party/libwebrtc/api/audio_options.cc
new file mode 100644
index 0000000000..658515062c
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_options.cc
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/audio_options.h"
+
+#include "api/array_view.h"
+#include "rtc_base/strings/string_builder.h"
+
+namespace cricket {
+namespace {
+
+template <class T>
+void ToStringIfSet(rtc::SimpleStringBuilder* result,
+ const char* key,
+ const absl::optional<T>& val) {
+ if (val) {
+ (*result) << key << ": " << *val << ", ";
+ }
+}
+
+template <typename T>
+void SetFrom(absl::optional<T>* s, const absl::optional<T>& o) {
+ if (o) {
+ *s = o;
+ }
+}
+
+} // namespace
+
+AudioOptions::AudioOptions() = default;
+AudioOptions::~AudioOptions() = default;
+
+void AudioOptions::SetAll(const AudioOptions& change) {
+ SetFrom(&echo_cancellation, change.echo_cancellation);
+#if defined(WEBRTC_IOS)
+ SetFrom(&ios_force_software_aec_HACK, change.ios_force_software_aec_HACK);
+#endif
+ SetFrom(&auto_gain_control, change.auto_gain_control);
+ SetFrom(&noise_suppression, change.noise_suppression);
+ SetFrom(&highpass_filter, change.highpass_filter);
+ SetFrom(&stereo_swapping, change.stereo_swapping);
+ SetFrom(&audio_jitter_buffer_max_packets,
+ change.audio_jitter_buffer_max_packets);
+ SetFrom(&audio_jitter_buffer_fast_accelerate,
+ change.audio_jitter_buffer_fast_accelerate);
+ SetFrom(&audio_jitter_buffer_min_delay_ms,
+ change.audio_jitter_buffer_min_delay_ms);
+ SetFrom(&combined_audio_video_bwe, change.combined_audio_video_bwe);
+ SetFrom(&audio_network_adaptor, change.audio_network_adaptor);
+ SetFrom(&audio_network_adaptor_config, change.audio_network_adaptor_config);
+ SetFrom(&init_recording_on_send, change.init_recording_on_send);
+}
+
+bool AudioOptions::operator==(const AudioOptions& o) const {
+ return echo_cancellation == o.echo_cancellation &&
+#if defined(WEBRTC_IOS)
+ ios_force_software_aec_HACK == o.ios_force_software_aec_HACK &&
+#endif
+ auto_gain_control == o.auto_gain_control &&
+ noise_suppression == o.noise_suppression &&
+ highpass_filter == o.highpass_filter &&
+ stereo_swapping == o.stereo_swapping &&
+ audio_jitter_buffer_max_packets == o.audio_jitter_buffer_max_packets &&
+ audio_jitter_buffer_fast_accelerate ==
+ o.audio_jitter_buffer_fast_accelerate &&
+ audio_jitter_buffer_min_delay_ms ==
+ o.audio_jitter_buffer_min_delay_ms &&
+ combined_audio_video_bwe == o.combined_audio_video_bwe &&
+ audio_network_adaptor == o.audio_network_adaptor &&
+ audio_network_adaptor_config == o.audio_network_adaptor_config &&
+ init_recording_on_send == o.init_recording_on_send;
+}
+
+std::string AudioOptions::ToString() const {
+ char buffer[1024];
+ rtc::SimpleStringBuilder result(buffer);
+ result << "AudioOptions {";
+ ToStringIfSet(&result, "aec", echo_cancellation);
+#if defined(WEBRTC_IOS)
+ ToStringIfSet(&result, "ios_force_software_aec_HACK",
+ ios_force_software_aec_HACK);
+#endif
+ ToStringIfSet(&result, "agc", auto_gain_control);
+ ToStringIfSet(&result, "ns", noise_suppression);
+ ToStringIfSet(&result, "hf", highpass_filter);
+ ToStringIfSet(&result, "swap", stereo_swapping);
+ ToStringIfSet(&result, "audio_jitter_buffer_max_packets",
+ audio_jitter_buffer_max_packets);
+ ToStringIfSet(&result, "audio_jitter_buffer_fast_accelerate",
+ audio_jitter_buffer_fast_accelerate);
+ ToStringIfSet(&result, "audio_jitter_buffer_min_delay_ms",
+ audio_jitter_buffer_min_delay_ms);
+ ToStringIfSet(&result, "combined_audio_video_bwe", combined_audio_video_bwe);
+ ToStringIfSet(&result, "audio_network_adaptor", audio_network_adaptor);
+ ToStringIfSet(&result, "init_recording_on_send", init_recording_on_send);
+ result << "}";
+ return result.str();
+}
+
+} // namespace cricket
diff --git a/third_party/libwebrtc/api/audio_options.h b/third_party/libwebrtc/api/audio_options.h
new file mode 100644
index 0000000000..39ba3886ea
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_options.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_AUDIO_OPTIONS_H_
+#define API_AUDIO_OPTIONS_H_
+
+#include <stdint.h>
+
+#include <string>
+
+#include "absl/types/optional.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace cricket {
+
+// Options that can be applied to a VoiceMediaChannel or a VoiceMediaEngine.
+// Used to be flags, but that makes it hard to selectively apply options.
+// We are moving all of the setting of options to structs like this,
+// but some things currently still use flags.
+struct RTC_EXPORT AudioOptions {
+ AudioOptions();
+ ~AudioOptions();
+ void SetAll(const AudioOptions& change);
+
+ bool operator==(const AudioOptions& o) const;
+ bool operator!=(const AudioOptions& o) const { return !(*this == o); }
+
+ std::string ToString() const;
+
+ // Audio processing that attempts to filter away the output signal from
+ // later inbound pickup.
+ absl::optional<bool> echo_cancellation;
+#if defined(WEBRTC_IOS)
+ // Forces software echo cancellation on iOS. This is a temporary workaround
+ // (until Apple fixes the bug) for a device with non-functioning AEC. May
+ // improve performance on that particular device, but will cause unpredictable
+ // behavior in all other cases. See http://bugs.webrtc.org/8682.
+ absl::optional<bool> ios_force_software_aec_HACK;
+#endif
+ // Audio processing to adjust the sensitivity of the local mic dynamically.
+ absl::optional<bool> auto_gain_control;
+ // Audio processing to filter out background noise.
+ absl::optional<bool> noise_suppression;
+ // Audio processing to remove background noise of lower frequencies.
+ absl::optional<bool> highpass_filter;
+ // Audio processing to swap the left and right channels.
+ absl::optional<bool> stereo_swapping;
+ // Audio receiver jitter buffer (NetEq) max capacity in number of packets.
+ absl::optional<int> audio_jitter_buffer_max_packets;
+ // Audio receiver jitter buffer (NetEq) fast accelerate mode.
+ absl::optional<bool> audio_jitter_buffer_fast_accelerate;
+ // Audio receiver jitter buffer (NetEq) minimum target delay in milliseconds.
+ absl::optional<int> audio_jitter_buffer_min_delay_ms;
+ // Enable combined audio+bandwidth BWE.
+ // TODO(pthatcher): This flag is set from the
+ // "googCombinedAudioVideoBwe", but not used anywhere. So delete it,
+ // and check if any other AudioOptions members are unused.
+ absl::optional<bool> combined_audio_video_bwe;
+ // Enable audio network adaptor.
+ // TODO(webrtc:11717): Remove this API in favor of adaptivePtime in
+ // RtpEncodingParameters.
+ absl::optional<bool> audio_network_adaptor;
+ // Config string for audio network adaptor.
+ absl::optional<std::string> audio_network_adaptor_config;
+ // Pre-initialize the ADM for recording when starting to send. Default to
+ // true.
+ // TODO(webrtc:13566): Remove this option. See issue for details.
+ absl::optional<bool> init_recording_on_send;
+};
+
+} // namespace cricket
+
+#endif // API_AUDIO_OPTIONS_H_
diff --git a/third_party/libwebrtc/api/audio_options_api_gn/moz.build b/third_party/libwebrtc/api/audio_options_api_gn/moz.build
new file mode 100644
index 0000000000..1b19c42e98
--- /dev/null
+++ b/third_party/libwebrtc/api/audio_options_api_gn/moz.build
@@ -0,0 +1,221 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/audio_options.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("audio_options_api_gn")
diff --git a/third_party/libwebrtc/api/bitrate_allocation_gn/moz.build b/third_party/libwebrtc/api/bitrate_allocation_gn/moz.build
new file mode 100644
index 0000000000..a694eff03b
--- /dev/null
+++ b/third_party/libwebrtc/api/bitrate_allocation_gn/moz.build
@@ -0,0 +1,205 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("bitrate_allocation_gn")
diff --git a/third_party/libwebrtc/api/call/audio_sink.h b/third_party/libwebrtc/api/call/audio_sink.h
new file mode 100644
index 0000000000..fec26593a6
--- /dev/null
+++ b/third_party/libwebrtc/api/call/audio_sink.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_CALL_AUDIO_SINK_H_
+#define API_CALL_AUDIO_SINK_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace webrtc {
+
+// Represents a simple push audio sink.
+class AudioSinkInterface {
+ public:
+ virtual ~AudioSinkInterface() {}
+
+ struct Data {
+ Data(const int16_t* data,
+ size_t samples_per_channel,
+ int sample_rate,
+ size_t channels,
+ uint32_t timestamp)
+ : data(data),
+ samples_per_channel(samples_per_channel),
+ sample_rate(sample_rate),
+ channels(channels),
+ timestamp(timestamp) {}
+
+ const int16_t* data; // The actual 16bit audio data.
+ size_t samples_per_channel; // Number of frames in the buffer.
+ int sample_rate; // Sample rate in Hz.
+ size_t channels; // Number of channels in the audio data.
+ uint32_t timestamp; // The RTP timestamp of the first sample.
+ };
+
+ virtual void OnData(const Data& audio) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_CALL_AUDIO_SINK_H_
diff --git a/third_party/libwebrtc/api/call/bitrate_allocation.h b/third_party/libwebrtc/api/call/bitrate_allocation.h
new file mode 100644
index 0000000000..4b4e5e7ae1
--- /dev/null
+++ b/third_party/libwebrtc/api/call/bitrate_allocation.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_CALL_BITRATE_ALLOCATION_H_
+#define API_CALL_BITRATE_ALLOCATION_H_
+
+#include "api/units/data_rate.h"
+#include "api/units/time_delta.h"
+
+namespace webrtc {
+
+// BitrateAllocationUpdate provides information to allocated streams about their
+// bitrate allocation. It originates from the BitrateAllocater class and is
+// propagated from there.
+struct BitrateAllocationUpdate {
+ // The allocated target bitrate. Media streams should produce this amount of
+ // data. (Note that this may include packet overhead depending on
+ // configuration.)
+ DataRate target_bitrate = DataRate::Zero();
+ // The allocated part of the estimated link capacity. This is more stable than
+ // the target as it is based on the underlying link capacity estimate. This
+ // should be used to change encoder configuration when the cost of change is
+ // high.
+ DataRate stable_target_bitrate = DataRate::Zero();
+ // Predicted packet loss ratio.
+ double packet_loss_ratio = 0;
+ // Predicted round trip time.
+ TimeDelta round_trip_time = TimeDelta::PlusInfinity();
+ // `bwe_period` is deprecated, use `stable_target_bitrate` allocation instead.
+ TimeDelta bwe_period = TimeDelta::PlusInfinity();
+ // Congestion window pushback bitrate reduction fraction. Used in
+ // VideoStreamEncoder to reduce the bitrate by the given fraction
+ // by dropping frames.
+ double cwnd_reduce_ratio = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_CALL_BITRATE_ALLOCATION_H_
diff --git a/third_party/libwebrtc/api/call/call_factory_interface.h b/third_party/libwebrtc/api/call/call_factory_interface.h
new file mode 100644
index 0000000000..6051409cc3
--- /dev/null
+++ b/third_party/libwebrtc/api/call/call_factory_interface.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_CALL_CALL_FACTORY_INTERFACE_H_
+#define API_CALL_CALL_FACTORY_INTERFACE_H_
+
+#include <memory>
+
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// These classes are not part of the API, and are treated as opaque pointers.
+class Call;
+struct CallConfig;
+
+// This interface exists to allow webrtc to be optionally built without media
+// support (i.e., if only being used for data channels). PeerConnectionFactory
+// is constructed with a CallFactoryInterface, which may or may not be null.
+class CallFactoryInterface {
+ public:
+ virtual ~CallFactoryInterface() {}
+
+ virtual Call* CreateCall(const CallConfig& config) = 0;
+};
+
+RTC_EXPORT std::unique_ptr<CallFactoryInterface> CreateCallFactory();
+
+} // namespace webrtc
+
+#endif // API_CALL_CALL_FACTORY_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/call/transport.cc b/third_party/libwebrtc/api/call/transport.cc
new file mode 100644
index 0000000000..bcadc762de
--- /dev/null
+++ b/third_party/libwebrtc/api/call/transport.cc
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/call/transport.h"
+
+#include <cstdint>
+
+namespace webrtc {
+
+PacketOptions::PacketOptions() = default;
+
+PacketOptions::PacketOptions(const PacketOptions&) = default;
+
+PacketOptions::~PacketOptions() = default;
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/call/transport.h b/third_party/libwebrtc/api/call/transport.h
new file mode 100644
index 0000000000..8bff28825d
--- /dev/null
+++ b/third_party/libwebrtc/api/call/transport.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_CALL_TRANSPORT_H_
+#define API_CALL_TRANSPORT_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "api/ref_counted_base.h"
+#include "api/scoped_refptr.h"
+
+namespace webrtc {
+
+// TODO(holmer): Look into unifying this with the PacketOptions in
+// asyncpacketsocket.h.
+struct PacketOptions {
+ PacketOptions();
+ PacketOptions(const PacketOptions&);
+ ~PacketOptions();
+
+ // A 16 bits positive id. Negative ids are invalid and should be interpreted
+ // as packet_id not being set.
+ int packet_id = -1;
+ // Additional data bound to the RTP packet for use in application code,
+ // outside of WebRTC.
+ rtc::scoped_refptr<rtc::RefCountedBase> additional_data;
+ // Whether this is a retransmission of an earlier packet.
+ bool is_retransmit = false;
+ bool included_in_feedback = false;
+ bool included_in_allocation = false;
+};
+
+class Transport {
+ public:
+ virtual bool SendRtp(const uint8_t* packet,
+ size_t length,
+ const PacketOptions& options) = 0;
+ virtual bool SendRtcp(const uint8_t* packet, size_t length) = 0;
+
+ protected:
+ virtual ~Transport() {}
+};
+
+} // namespace webrtc
+
+#endif // API_CALL_TRANSPORT_H_
diff --git a/third_party/libwebrtc/api/call_api_gn/moz.build b/third_party/libwebrtc/api/call_api_gn/moz.build
new file mode 100644
index 0000000000..e446d82280
--- /dev/null
+++ b/third_party/libwebrtc/api/call_api_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("call_api_gn")
diff --git a/third_party/libwebrtc/api/callfactory_api_gn/moz.build b/third_party/libwebrtc/api/callfactory_api_gn/moz.build
new file mode 100644
index 0000000000..b0f2bbbf35
--- /dev/null
+++ b/third_party/libwebrtc/api/callfactory_api_gn/moz.build
@@ -0,0 +1,216 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "rt"
+ ]
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "crypt32",
+ "iphlpapi",
+ "secur32",
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("callfactory_api_gn")
diff --git a/third_party/libwebrtc/api/candidate.cc b/third_party/libwebrtc/api/candidate.cc
new file mode 100644
index 0000000000..a14dda350c
--- /dev/null
+++ b/third_party/libwebrtc/api/candidate.cc
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2017 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/candidate.h"
+
+#include "rtc_base/helpers.h"
+#include "rtc_base/ip_address.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/strings/string_builder.h"
+
+namespace cricket {
+
+Candidate::Candidate()
+ : id_(rtc::CreateRandomString(8)),
+ component_(0),
+ priority_(0),
+ network_type_(rtc::ADAPTER_TYPE_UNKNOWN),
+ underlying_type_for_vpn_(rtc::ADAPTER_TYPE_UNKNOWN),
+ generation_(0),
+ network_id_(0),
+ network_cost_(0) {}
+
+Candidate::Candidate(int component,
+ absl::string_view protocol,
+ const rtc::SocketAddress& address,
+ uint32_t priority,
+ absl::string_view username,
+ absl::string_view password,
+ absl::string_view type,
+ uint32_t generation,
+ absl::string_view foundation,
+ uint16_t network_id,
+ uint16_t network_cost)
+ : id_(rtc::CreateRandomString(8)),
+ component_(component),
+ protocol_(protocol),
+ address_(address),
+ priority_(priority),
+ username_(username),
+ password_(password),
+ type_(type),
+ network_type_(rtc::ADAPTER_TYPE_UNKNOWN),
+ underlying_type_for_vpn_(rtc::ADAPTER_TYPE_UNKNOWN),
+ generation_(generation),
+ foundation_(foundation),
+ network_id_(network_id),
+ network_cost_(network_cost) {}
+
+Candidate::Candidate(const Candidate&) = default;
+
+Candidate::~Candidate() = default;
+
+bool Candidate::IsEquivalent(const Candidate& c) const {
+ // We ignore the network name, since that is just debug information, and
+ // the priority and the network cost, since they should be the same if the
+ // rest are.
+ return (component_ == c.component_) && (protocol_ == c.protocol_) &&
+ (address_ == c.address_) && (username_ == c.username_) &&
+ (password_ == c.password_) && (type_ == c.type_) &&
+ (generation_ == c.generation_) && (foundation_ == c.foundation_) &&
+ (related_address_ == c.related_address_) &&
+ (network_id_ == c.network_id_);
+}
+
+bool Candidate::MatchesForRemoval(const Candidate& c) const {
+ return component_ == c.component_ && protocol_ == c.protocol_ &&
+ address_ == c.address_;
+}
+
+std::string Candidate::ToStringInternal(bool sensitive) const {
+ rtc::StringBuilder ost;
+ std::string address =
+ sensitive ? address_.ToSensitiveString() : address_.ToString();
+ ost << "Cand[" << transport_name_ << ":" << foundation_ << ":" << component_
+ << ":" << protocol_ << ":" << priority_ << ":" << address << ":" << type_
+ << ":" << related_address_.ToString() << ":" << username_ << ":"
+ << password_ << ":" << network_id_ << ":" << network_cost_ << ":"
+ << generation_ << "]";
+ return ost.Release();
+}
+
+uint32_t Candidate::GetPriority(uint32_t type_preference,
+ int network_adapter_preference,
+ int relay_preference) const {
+ // RFC 5245 - 4.1.2.1.
+ // priority = (2^24)*(type preference) +
+ // (2^8)*(local preference) +
+ // (2^0)*(256 - component ID)
+
+ // `local_preference` length is 2 bytes, 0-65535 inclusive.
+ // In our implemenation we will partion local_preference into
+ // 0 1
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | NIC Pref | Addr Pref |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // NIC Type - Type of the network adapter e.g. 3G/Wifi/Wired.
+ // Addr Pref - Address preference value as per RFC 3484.
+ // local preference = (NIC Type << 8 | Addr_Pref) + relay preference.
+ // The relay preference is based on the number of TURN servers, the
+ // first TURN server gets the highest preference.
+
+ int addr_pref = IPAddressPrecedence(address_.ipaddr());
+ int local_preference =
+ ((network_adapter_preference << 8) | addr_pref) + relay_preference;
+
+ return (type_preference << 24) | (local_preference << 8) | (256 - component_);
+}
+
+bool Candidate::operator==(const Candidate& o) const {
+ return id_ == o.id_ && component_ == o.component_ &&
+ protocol_ == o.protocol_ && relay_protocol_ == o.relay_protocol_ &&
+ address_ == o.address_ && priority_ == o.priority_ &&
+ username_ == o.username_ && password_ == o.password_ &&
+ type_ == o.type_ && network_name_ == o.network_name_ &&
+ network_type_ == o.network_type_ && generation_ == o.generation_ &&
+ foundation_ == o.foundation_ &&
+ related_address_ == o.related_address_ && tcptype_ == o.tcptype_ &&
+ transport_name_ == o.transport_name_ && network_id_ == o.network_id_;
+}
+
+bool Candidate::operator!=(const Candidate& o) const {
+ return !(*this == o);
+}
+
+Candidate Candidate::ToSanitizedCopy(bool use_hostname_address,
+ bool filter_related_address) const {
+ Candidate copy(*this);
+ if (use_hostname_address) {
+ rtc::IPAddress ip;
+ if (address().hostname().empty()) {
+ // IP needs to be redacted, but no hostname available.
+ rtc::SocketAddress redacted_addr("redacted-ip.invalid", address().port());
+ copy.set_address(redacted_addr);
+ } else if (IPFromString(address().hostname(), &ip)) {
+ // The hostname is an IP literal, and needs to be redacted too.
+ rtc::SocketAddress redacted_addr("redacted-literal.invalid",
+ address().port());
+ copy.set_address(redacted_addr);
+ } else {
+ rtc::SocketAddress hostname_only_addr(address().hostname(),
+ address().port());
+ copy.set_address(hostname_only_addr);
+ }
+ }
+ if (filter_related_address) {
+ copy.set_related_address(
+ rtc::EmptySocketAddressWithFamily(copy.address().family()));
+ }
+ return copy;
+}
+
+void Candidate::Assign(std::string& s, absl::string_view view) {
+ // Assigning via a temporary object, like s = std::string(view), results in
+ // binary size bloat. To avoid that, extract pointer and size from the
+ // string view, and use std::string::assign method.
+ s.assign(view.data(), view.size());
+}
+
+} // namespace cricket
diff --git a/third_party/libwebrtc/api/candidate.h b/third_party/libwebrtc/api/candidate.h
new file mode 100644
index 0000000000..281f2f01a5
--- /dev/null
+++ b/third_party/libwebrtc/api/candidate.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2004 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_CANDIDATE_H_
+#define API_CANDIDATE_H_
+
+#include <limits.h>
+#include <stdint.h>
+
+#include <algorithm>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/network_constants.h"
+#include "rtc_base/socket_address.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace cricket {
+
+// TURN servers are limited to 32 in accordance with
+// https://w3c.github.io/webrtc-pc/#dom-rtcconfiguration-iceservers
+static constexpr size_t kMaxTurnServers = 32;
+
+// Candidate for ICE based connection discovery.
+// TODO(phoglund): remove things in here that are not needed in the public API.
+
+class RTC_EXPORT Candidate {
+ public:
+ Candidate();
+ // TODO(pthatcher): Match the ordering and param list as per RFC 5245
+ // candidate-attribute syntax. http://tools.ietf.org/html/rfc5245#section-15.1
+ Candidate(int component,
+ absl::string_view protocol,
+ const rtc::SocketAddress& address,
+ uint32_t priority,
+ absl::string_view username,
+ absl::string_view password,
+ absl::string_view type,
+ uint32_t generation,
+ absl::string_view foundation,
+ uint16_t network_id = 0,
+ uint16_t network_cost = 0);
+ Candidate(const Candidate&);
+ ~Candidate();
+
+ const std::string& id() const { return id_; }
+ void set_id(absl::string_view id) { Assign(id_, id); }
+
+ int component() const { return component_; }
+ void set_component(int component) { component_ = component; }
+
+ const std::string& protocol() const { return protocol_; }
+ void set_protocol(absl::string_view protocol) { Assign(protocol_, protocol); }
+
+ // The protocol used to talk to relay.
+ const std::string& relay_protocol() const { return relay_protocol_; }
+ void set_relay_protocol(absl::string_view protocol) {
+ Assign(relay_protocol_, protocol);
+ }
+
+ const rtc::SocketAddress& address() const { return address_; }
+ void set_address(const rtc::SocketAddress& address) { address_ = address; }
+
+ uint32_t priority() const { return priority_; }
+ void set_priority(const uint32_t priority) { priority_ = priority; }
+
+ // TODO(pthatcher): Remove once Chromium's jingle/glue/utils.cc
+ // doesn't use it.
+ // Maps old preference (which was 0.0-1.0) to match priority (which
+ // is 0-2^32-1) to to match RFC 5245, section 4.1.2.1. Also see
+ // https://docs.google.com/a/google.com/document/d/
+ // 1iNQDiwDKMh0NQOrCqbj3DKKRT0Dn5_5UJYhmZO-t7Uc/edit
+ float preference() const {
+ // The preference value is clamped to two decimal precision.
+ return static_cast<float>(((priority_ >> 24) * 100 / 127) / 100.0);
+ }
+
+ // TODO(pthatcher): Remove once Chromium's jingle/glue/utils.cc
+ // doesn't use it.
+ void set_preference(float preference) {
+ // Limiting priority to UINT_MAX when value exceeds uint32_t max.
+ // This can happen for e.g. when preference = 3.
+ uint64_t prio_val = static_cast<uint64_t>(preference * 127) << 24;
+ priority_ = static_cast<uint32_t>(
+ std::min(prio_val, static_cast<uint64_t>(UINT_MAX)));
+ }
+
+ // TODO(honghaiz): Change to usernameFragment or ufrag.
+ const std::string& username() const { return username_; }
+ void set_username(absl::string_view username) { Assign(username_, username); }
+
+ const std::string& password() const { return password_; }
+ void set_password(absl::string_view password) { Assign(password_, password); }
+
+ const std::string& type() const { return type_; }
+ void set_type(absl::string_view type) { Assign(type_, type); }
+
+ const std::string& network_name() const { return network_name_; }
+ void set_network_name(absl::string_view network_name) {
+ Assign(network_name_, network_name);
+ }
+
+ rtc::AdapterType network_type() const { return network_type_; }
+ void set_network_type(rtc::AdapterType network_type) {
+ network_type_ = network_type;
+ }
+
+ rtc::AdapterType underlying_type_for_vpn() const {
+ return underlying_type_for_vpn_;
+ }
+ void set_underlying_type_for_vpn(rtc::AdapterType network_type) {
+ underlying_type_for_vpn_ = network_type;
+ }
+
+ // Candidates in a new generation replace those in the old generation.
+ uint32_t generation() const { return generation_; }
+ void set_generation(uint32_t generation) { generation_ = generation; }
+
+ // `network_cost` measures the cost/penalty of using this candidate. A network
+ // cost of 0 indicates this candidate can be used freely. A value of
+ // rtc::kNetworkCostMax indicates it should be used only as the last resort.
+ void set_network_cost(uint16_t network_cost) {
+ RTC_DCHECK_LE(network_cost, rtc::kNetworkCostMax);
+ network_cost_ = network_cost;
+ }
+ uint16_t network_cost() const { return network_cost_; }
+
+ // An ID assigned to the network hosting the candidate.
+ uint16_t network_id() const { return network_id_; }
+ void set_network_id(uint16_t network_id) { network_id_ = network_id; }
+
+ const std::string& foundation() const { return foundation_; }
+ void set_foundation(absl::string_view foundation) {
+ Assign(foundation_, foundation);
+ }
+
+ const rtc::SocketAddress& related_address() const { return related_address_; }
+ void set_related_address(const rtc::SocketAddress& related_address) {
+ related_address_ = related_address;
+ }
+ const std::string& tcptype() const { return tcptype_; }
+ void set_tcptype(absl::string_view tcptype) { Assign(tcptype_, tcptype); }
+
+ // The name of the transport channel of this candidate.
+ // TODO(phoglund): remove.
+ const std::string& transport_name() const { return transport_name_; }
+ void set_transport_name(absl::string_view transport_name) {
+ Assign(transport_name_, transport_name);
+ }
+
+ // The URL of the ICE server which this candidate is gathered from.
+ const std::string& url() const { return url_; }
+ void set_url(absl::string_view url) { Assign(url_, url); }
+
+ // Determines whether this candidate is equivalent to the given one.
+ bool IsEquivalent(const Candidate& c) const;
+
+ // Determines whether this candidate can be considered equivalent to the
+ // given one when looking for a matching candidate to remove.
+ bool MatchesForRemoval(const Candidate& c) const;
+
+ std::string ToString() const { return ToStringInternal(false); }
+
+ std::string ToSensitiveString() const { return ToStringInternal(true); }
+
+ uint32_t GetPriority(uint32_t type_preference,
+ int network_adapter_preference,
+ int relay_preference) const;
+
+ bool operator==(const Candidate& o) const;
+ bool operator!=(const Candidate& o) const;
+
+ // Returns a sanitized copy configured by the given booleans. If
+ // `use_host_address` is true, the returned copy has its IP removed from
+ // `address()`, which leads `address()` to be a hostname address. If
+ // `filter_related_address`, the returned copy has its related address reset
+ // to the wildcard address (i.e. 0.0.0.0 for IPv4 and :: for IPv6). Note that
+ // setting both booleans to false returns an identical copy to the original
+ // candidate.
+ Candidate ToSanitizedCopy(bool use_hostname_address,
+ bool filter_related_address) const;
+
+ private:
+ // TODO(bugs.webrtc.org/13220): With C++17, we get a std::string assignment
+ // operator accepting any object implicitly convertible to std::string_view,
+ // and then we don't need this workaround.
+ static void Assign(std::string& s, absl::string_view view);
+ std::string ToStringInternal(bool sensitive) const;
+
+ std::string id_;
+ int component_;
+ std::string protocol_;
+ std::string relay_protocol_;
+ rtc::SocketAddress address_;
+ uint32_t priority_;
+ std::string username_;
+ std::string password_;
+ std::string type_;
+ std::string network_name_;
+ rtc::AdapterType network_type_;
+ rtc::AdapterType underlying_type_for_vpn_;
+ uint32_t generation_;
+ std::string foundation_;
+ rtc::SocketAddress related_address_;
+ std::string tcptype_;
+ std::string transport_name_;
+ uint16_t network_id_;
+ uint16_t network_cost_;
+ std::string url_;
+};
+
+} // namespace cricket
+
+#endif // API_CANDIDATE_H_
diff --git a/third_party/libwebrtc/api/create_peerconnection_factory.cc b/third_party/libwebrtc/api/create_peerconnection_factory.cc
new file mode 100644
index 0000000000..f9cc7ad3e2
--- /dev/null
+++ b/third_party/libwebrtc/api/create_peerconnection_factory.cc
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/create_peerconnection_factory.h"
+
+#include <memory>
+#include <utility>
+
+#include "api/call/call_factory_interface.h"
+#include "api/peer_connection_interface.h"
+#include "api/rtc_event_log/rtc_event_log_factory.h"
+#include "api/scoped_refptr.h"
+#include "api/task_queue/default_task_queue_factory.h"
+#include "api/transport/field_trial_based_config.h"
+#include "media/base/media_engine.h"
+#include "media/engine/webrtc_media_engine.h"
+#include "modules/audio_device/include/audio_device.h"
+#include "modules/audio_processing/include/audio_processing.h"
+#include "rtc_base/thread.h"
+
+namespace webrtc {
+
+rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
+ rtc::Thread* network_thread,
+ rtc::Thread* worker_thread,
+ rtc::Thread* signaling_thread,
+ rtc::scoped_refptr<AudioDeviceModule> default_adm,
+ rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory,
+ rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory,
+ std::unique_ptr<VideoEncoderFactory> video_encoder_factory,
+ std::unique_ptr<VideoDecoderFactory> video_decoder_factory,
+ rtc::scoped_refptr<AudioMixer> audio_mixer,
+ rtc::scoped_refptr<AudioProcessing> audio_processing,
+ AudioFrameProcessor* audio_frame_processor,
+ std::unique_ptr<FieldTrialsView> field_trials) {
+ if (!field_trials) {
+ field_trials = std::make_unique<webrtc::FieldTrialBasedConfig>();
+ }
+
+ PeerConnectionFactoryDependencies dependencies;
+ dependencies.network_thread = network_thread;
+ dependencies.worker_thread = worker_thread;
+ dependencies.signaling_thread = signaling_thread;
+ dependencies.task_queue_factory =
+ CreateDefaultTaskQueueFactory(field_trials.get());
+ dependencies.call_factory = CreateCallFactory();
+ dependencies.event_log_factory = std::make_unique<RtcEventLogFactory>(
+ dependencies.task_queue_factory.get());
+ dependencies.trials = std::move(field_trials);
+
+ if (network_thread) {
+ // TODO(bugs.webrtc.org/13145): Add an rtc::SocketFactory* argument.
+ dependencies.socket_factory = network_thread->socketserver();
+ }
+ cricket::MediaEngineDependencies media_dependencies;
+ media_dependencies.task_queue_factory = dependencies.task_queue_factory.get();
+ media_dependencies.adm = std::move(default_adm);
+ media_dependencies.audio_encoder_factory = std::move(audio_encoder_factory);
+ media_dependencies.audio_decoder_factory = std::move(audio_decoder_factory);
+ media_dependencies.audio_frame_processor = audio_frame_processor;
+ if (audio_processing) {
+ media_dependencies.audio_processing = std::move(audio_processing);
+ } else {
+ media_dependencies.audio_processing = AudioProcessingBuilder().Create();
+ }
+ media_dependencies.audio_mixer = std::move(audio_mixer);
+ media_dependencies.video_encoder_factory = std::move(video_encoder_factory);
+ media_dependencies.video_decoder_factory = std::move(video_decoder_factory);
+ media_dependencies.trials = dependencies.trials.get();
+ dependencies.media_engine =
+ cricket::CreateMediaEngine(std::move(media_dependencies));
+
+ return CreateModularPeerConnectionFactory(std::move(dependencies));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/create_peerconnection_factory.h b/third_party/libwebrtc/api/create_peerconnection_factory.h
new file mode 100644
index 0000000000..efebc5f3ea
--- /dev/null
+++ b/third_party/libwebrtc/api/create_peerconnection_factory.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_CREATE_PEERCONNECTION_FACTORY_H_
+#define API_CREATE_PEERCONNECTION_FACTORY_H_
+
+#include <memory>
+
+#include "api/audio/audio_mixer.h"
+#include "api/audio_codecs/audio_decoder_factory.h"
+#include "api/audio_codecs/audio_encoder_factory.h"
+#include "api/peer_connection_interface.h"
+#include "api/scoped_refptr.h"
+#include "api/video_codecs/video_decoder_factory.h"
+#include "api/video_codecs/video_encoder_factory.h"
+
+namespace rtc {
+// TODO(bugs.webrtc.org/9987): Move rtc::Thread to api/ or expose a better
+// type. At the moment, rtc::Thread is not part of api/ so it cannot be
+// included in order to avoid to leak internal types.
+class Thread;
+} // namespace rtc
+
+namespace webrtc {
+
+class AudioDeviceModule;
+class AudioFrameProcessor;
+class AudioProcessing;
+
+// Create a new instance of PeerConnectionFactoryInterface with optional video
+// codec factories. These video factories represents all video codecs, i.e. no
+// extra internal video codecs will be added.
+RTC_EXPORT rtc::scoped_refptr<PeerConnectionFactoryInterface>
+CreatePeerConnectionFactory(
+ rtc::Thread* network_thread,
+ rtc::Thread* worker_thread,
+ rtc::Thread* signaling_thread,
+ rtc::scoped_refptr<AudioDeviceModule> default_adm,
+ rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory,
+ rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory,
+ std::unique_ptr<VideoEncoderFactory> video_encoder_factory,
+ std::unique_ptr<VideoDecoderFactory> video_decoder_factory,
+ rtc::scoped_refptr<AudioMixer> audio_mixer,
+ rtc::scoped_refptr<AudioProcessing> audio_processing,
+ AudioFrameProcessor* audio_frame_processor = nullptr,
+ std::unique_ptr<FieldTrialsView> field_trials = nullptr);
+
+} // namespace webrtc
+
+#endif // API_CREATE_PEERCONNECTION_FACTORY_H_
diff --git a/third_party/libwebrtc/api/crypto/BUILD.gn b/third_party/libwebrtc/api/crypto/BUILD.gn
new file mode 100644
index 0000000000..8d041ea059
--- /dev/null
+++ b/third_party/libwebrtc/api/crypto/BUILD.gn
@@ -0,0 +1,49 @@
+# Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../webrtc.gni")
+
+group("crypto") {
+ deps = [
+ ":frame_decryptor_interface",
+ ":frame_encryptor_interface",
+ ":options",
+ ]
+}
+
+rtc_library("options") {
+ visibility = [ "*" ]
+ sources = [
+ "crypto_options.cc",
+ "crypto_options.h",
+ ]
+ deps = [
+ "../../rtc_base:ssl",
+ "../../rtc_base/system:rtc_export",
+ ]
+}
+
+rtc_source_set("frame_decryptor_interface") {
+ visibility = [ "*" ]
+ sources = [ "frame_decryptor_interface.h" ]
+ deps = [
+ "..:array_view",
+ "..:rtp_parameters",
+ "../../rtc_base:refcount",
+ ]
+}
+
+rtc_source_set("frame_encryptor_interface") {
+ visibility = [ "*" ]
+ sources = [ "frame_encryptor_interface.h" ]
+ deps = [
+ "..:array_view",
+ "..:rtp_parameters",
+ "../../rtc_base:refcount",
+ ]
+}
diff --git a/third_party/libwebrtc/api/crypto/crypto_options.cc b/third_party/libwebrtc/api/crypto/crypto_options.cc
new file mode 100644
index 0000000000..22c5dd464b
--- /dev/null
+++ b/third_party/libwebrtc/api/crypto/crypto_options.cc
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2018 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/crypto/crypto_options.h"
+
+#include "rtc_base/ssl_stream_adapter.h"
+
+namespace webrtc {
+
+CryptoOptions::CryptoOptions() {}
+
+CryptoOptions::CryptoOptions(const CryptoOptions& other) {
+ srtp = other.srtp;
+ sframe = other.sframe;
+}
+
+CryptoOptions::~CryptoOptions() {}
+
+// static
+CryptoOptions CryptoOptions::NoGcm() {
+ CryptoOptions options;
+ options.srtp.enable_gcm_crypto_suites = false;
+ return options;
+}
+
+std::vector<int> CryptoOptions::GetSupportedDtlsSrtpCryptoSuites() const {
+ std::vector<int> crypto_suites;
+ // Note: kSrtpAes128CmSha1_80 is what is required to be supported (by
+ // draft-ietf-rtcweb-security-arch), but kSrtpAes128CmSha1_32 is allowed as
+ // well, and saves a few bytes per packet if it ends up selected.
+ // As the cipher suite is potentially insecure, it will only be used if
+ // enabled by both peers.
+ if (srtp.enable_aes128_sha1_32_crypto_cipher) {
+ crypto_suites.push_back(rtc::kSrtpAes128CmSha1_32);
+ }
+ if (srtp.enable_aes128_sha1_80_crypto_cipher) {
+ crypto_suites.push_back(rtc::kSrtpAes128CmSha1_80);
+ }
+
+ // Note: GCM cipher suites are not the top choice since they increase the
+ // packet size. In order to negotiate them the other side must not support
+ // kSrtpAes128CmSha1_80.
+ if (srtp.enable_gcm_crypto_suites) {
+ crypto_suites.push_back(rtc::kSrtpAeadAes256Gcm);
+ crypto_suites.push_back(rtc::kSrtpAeadAes128Gcm);
+ }
+ RTC_CHECK(!crypto_suites.empty());
+ return crypto_suites;
+}
+
+bool CryptoOptions::operator==(const CryptoOptions& other) const {
+ struct data_being_tested_for_equality {
+ struct Srtp {
+ bool enable_gcm_crypto_suites;
+ bool enable_aes128_sha1_32_crypto_cipher;
+ bool enable_aes128_sha1_80_crypto_cipher;
+ bool enable_encrypted_rtp_header_extensions;
+ } srtp;
+ struct SFrame {
+ bool require_frame_encryption;
+ } sframe;
+ };
+ static_assert(sizeof(data_being_tested_for_equality) == sizeof(*this),
+ "Did you add something to CryptoOptions and forget to "
+ "update operator==?");
+
+ return srtp.enable_gcm_crypto_suites == other.srtp.enable_gcm_crypto_suites &&
+ srtp.enable_aes128_sha1_32_crypto_cipher ==
+ other.srtp.enable_aes128_sha1_32_crypto_cipher &&
+ srtp.enable_aes128_sha1_80_crypto_cipher ==
+ other.srtp.enable_aes128_sha1_80_crypto_cipher &&
+ srtp.enable_encrypted_rtp_header_extensions ==
+ other.srtp.enable_encrypted_rtp_header_extensions &&
+ sframe.require_frame_encryption ==
+ other.sframe.require_frame_encryption;
+}
+
+bool CryptoOptions::operator!=(const CryptoOptions& other) const {
+ return !(*this == other);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/crypto/crypto_options.h b/third_party/libwebrtc/api/crypto/crypto_options.h
new file mode 100644
index 0000000000..317995134a
--- /dev/null
+++ b/third_party/libwebrtc/api/crypto/crypto_options.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2018 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_CRYPTO_CRYPTO_OPTIONS_H_
+#define API_CRYPTO_CRYPTO_OPTIONS_H_
+
+#include <vector>
+
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// CryptoOptions defines advanced cryptographic settings for native WebRTC.
+// These settings must be passed into PeerConnectionFactoryInterface::Options
+// and are only applicable to native use cases of WebRTC.
+struct RTC_EXPORT CryptoOptions {
+ CryptoOptions();
+ CryptoOptions(const CryptoOptions& other);
+ ~CryptoOptions();
+
+ // Helper method to return an instance of the CryptoOptions with GCM crypto
+ // suites disabled. This method should be used instead of depending on current
+ // default values set by the constructor.
+ static CryptoOptions NoGcm();
+
+ // Returns a list of the supported DTLS-SRTP Crypto suites based on this set
+ // of crypto options.
+ std::vector<int> GetSupportedDtlsSrtpCryptoSuites() const;
+
+ bool operator==(const CryptoOptions& other) const;
+ bool operator!=(const CryptoOptions& other) const;
+
+ // SRTP Related Peer Connection options.
+ struct Srtp {
+ // Enable GCM crypto suites from RFC 7714 for SRTP. GCM will only be used
+ // if both sides enable it.
+ bool enable_gcm_crypto_suites = false;
+
+ // If set to true, the (potentially insecure) crypto cipher
+ // kSrtpAes128CmSha1_32 will be included in the list of supported ciphers
+ // during negotiation. It will only be used if both peers support it and no
+ // other ciphers get preferred.
+ bool enable_aes128_sha1_32_crypto_cipher = false;
+
+ // The most commonly used cipher. Can be disabled, mostly for testing
+ // purposes.
+ bool enable_aes128_sha1_80_crypto_cipher = true;
+
+ // If set to true, encrypted RTP header extensions as defined in RFC 6904
+ // will be negotiated. They will only be used if both peers support them.
+ bool enable_encrypted_rtp_header_extensions = false;
+ } srtp;
+
+ // Options to be used when the FrameEncryptor / FrameDecryptor APIs are used.
+ struct SFrame {
+ // If set all RtpSenders must have an FrameEncryptor attached to them before
+ // they are allowed to send packets. All RtpReceivers must have a
+ // FrameDecryptor attached to them before they are able to receive packets.
+ bool require_frame_encryption = false;
+ } sframe;
+};
+
+} // namespace webrtc
+
+#endif // API_CRYPTO_CRYPTO_OPTIONS_H_
diff --git a/third_party/libwebrtc/api/crypto/frame_decryptor_interface.h b/third_party/libwebrtc/api/crypto/frame_decryptor_interface.h
new file mode 100644
index 0000000000..2f6bdac4b4
--- /dev/null
+++ b/third_party/libwebrtc/api/crypto/frame_decryptor_interface.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_CRYPTO_FRAME_DECRYPTOR_INTERFACE_H_
+#define API_CRYPTO_FRAME_DECRYPTOR_INTERFACE_H_
+
+#include <vector>
+
+#include "api/array_view.h"
+#include "api/media_types.h"
+#include "rtc_base/ref_count.h"
+
+namespace webrtc {
+
+// FrameDecryptorInterface allows users to provide a custom decryption
+// implementation for all incoming audio and video frames. The user must also
+// provide a FrameEncryptorInterface to be able to encrypt the frames being
+// sent out of the device. Note this is an additional layer of encyrption in
+// addition to the standard SRTP mechanism and is not intended to be used
+// without it. You may assume that this interface will have the same lifetime
+// as the RTPReceiver it is attached to. It must only be attached to one
+// RTPReceiver. Additional data may be null.
+class FrameDecryptorInterface : public rtc::RefCountInterface {
+ public:
+ // The Status enum represents all possible states that can be
+ // returned when attempting to decrypt a frame. kRecoverable indicates that
+ // there was an error with the given frame and so it should not be passed to
+ // the decoder, however it hints that the receive stream is still decryptable
+ // which is important for determining when to send key frame requests
+ // kUnknown should never be returned by the implementor.
+ enum class Status { kOk, kRecoverable, kFailedToDecrypt, kUnknown };
+
+ struct Result {
+ Result(Status status, size_t bytes_written)
+ : status(status), bytes_written(bytes_written) {}
+
+ bool IsOk() const { return status == Status::kOk; }
+
+ const Status status;
+ const size_t bytes_written;
+ };
+
+ ~FrameDecryptorInterface() override {}
+
+ // Attempts to decrypt the encrypted frame. You may assume the frame size will
+ // be allocated to the size returned from GetMaxPlaintextSize. You may assume
+ // that the frames are in order if SRTP is enabled. The stream is not provided
+ // here and it is up to the implementor to transport this information to the
+ // receiver if they care about it. You must set bytes_written to how many
+ // bytes you wrote to in the frame buffer. kOk must be returned if successful,
+ // kRecoverable should be returned if the failure was due to something other
+ // than a decryption failure. kFailedToDecrypt should be returned in all other
+ // cases.
+ virtual Result Decrypt(cricket::MediaType media_type,
+ const std::vector<uint32_t>& csrcs,
+ rtc::ArrayView<const uint8_t> additional_data,
+ rtc::ArrayView<const uint8_t> encrypted_frame,
+ rtc::ArrayView<uint8_t> frame) = 0;
+
+ // Returns the total required length in bytes for the output of the
+ // decryption. This can be larger than the actual number of bytes you need but
+ // must never be smaller as it informs the size of the frame buffer.
+ virtual size_t GetMaxPlaintextByteSize(cricket::MediaType media_type,
+ size_t encrypted_frame_size) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_CRYPTO_FRAME_DECRYPTOR_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/crypto/frame_decryptor_interface_gn/moz.build b/third_party/libwebrtc/api/crypto/frame_decryptor_interface_gn/moz.build
new file mode 100644
index 0000000000..1ce4cdd00a
--- /dev/null
+++ b/third_party/libwebrtc/api/crypto/frame_decryptor_interface_gn/moz.build
@@ -0,0 +1,205 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("frame_decryptor_interface_gn")
diff --git a/third_party/libwebrtc/api/crypto/frame_encryptor_interface.h b/third_party/libwebrtc/api/crypto/frame_encryptor_interface.h
new file mode 100644
index 0000000000..1452b80189
--- /dev/null
+++ b/third_party/libwebrtc/api/crypto/frame_encryptor_interface.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_CRYPTO_FRAME_ENCRYPTOR_INTERFACE_H_
+#define API_CRYPTO_FRAME_ENCRYPTOR_INTERFACE_H_
+
+#include "api/array_view.h"
+#include "api/media_types.h"
+#include "rtc_base/ref_count.h"
+
+namespace webrtc {
+
+// FrameEncryptorInterface allows users to provide a custom encryption
+// implementation to encrypt all outgoing audio and video frames. The user must
+// also provide a FrameDecryptorInterface to be able to decrypt the frames on
+// the receiving device. Note this is an additional layer of encryption in
+// addition to the standard SRTP mechanism and is not intended to be used
+// without it. Implementations of this interface will have the same lifetime as
+// the RTPSenders it is attached to. Additional data may be null.
+class FrameEncryptorInterface : public rtc::RefCountInterface {
+ public:
+ ~FrameEncryptorInterface() override {}
+
+ // Attempts to encrypt the provided frame. You may assume the encrypted_frame
+ // will match the size returned by GetMaxCiphertextByteSize for a give frame.
+ // You may assume that the frames will arrive in order if SRTP is enabled.
+ // The ssrc will simply identify which stream the frame is travelling on. You
+ // must set bytes_written to the number of bytes you wrote in the
+ // encrypted_frame. 0 must be returned if successful all other numbers can be
+ // selected by the implementer to represent error codes.
+ virtual int Encrypt(cricket::MediaType media_type,
+ uint32_t ssrc,
+ rtc::ArrayView<const uint8_t> additional_data,
+ rtc::ArrayView<const uint8_t> frame,
+ rtc::ArrayView<uint8_t> encrypted_frame,
+ size_t* bytes_written) = 0;
+
+ // Returns the total required length in bytes for the output of the
+ // encryption. This can be larger than the actual number of bytes you need but
+ // must never be smaller as it informs the size of the encrypted_frame buffer.
+ virtual size_t GetMaxCiphertextByteSize(cricket::MediaType media_type,
+ size_t frame_size) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_CRYPTO_FRAME_ENCRYPTOR_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/crypto/frame_encryptor_interface_gn/moz.build b/third_party/libwebrtc/api/crypto/frame_encryptor_interface_gn/moz.build
new file mode 100644
index 0000000000..b8385d1daa
--- /dev/null
+++ b/third_party/libwebrtc/api/crypto/frame_encryptor_interface_gn/moz.build
@@ -0,0 +1,205 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("frame_encryptor_interface_gn")
diff --git a/third_party/libwebrtc/api/crypto/options_gn/moz.build b/third_party/libwebrtc/api/crypto/options_gn/moz.build
new file mode 100644
index 0000000000..aee1983c3e
--- /dev/null
+++ b/third_party/libwebrtc/api/crypto/options_gn/moz.build
@@ -0,0 +1,217 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/crypto/crypto_options.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("options_gn")
diff --git a/third_party/libwebrtc/api/crypto_params.h b/third_party/libwebrtc/api/crypto_params.h
new file mode 100644
index 0000000000..95bd892f9c
--- /dev/null
+++ b/third_party/libwebrtc/api/crypto_params.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_CRYPTO_PARAMS_H_
+#define API_CRYPTO_PARAMS_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+
+namespace cricket {
+
+// Parameters for SRTP negotiation, as described in RFC 4568.
+// TODO(benwright) - Rename to SrtpCryptoParams as these only apply to SRTP and
+// not generic crypto parameters for WebRTC.
+struct CryptoParams {
+ CryptoParams() : tag(0) {}
+ CryptoParams(int t,
+ absl::string_view cs,
+ absl::string_view kp,
+ absl::string_view sp)
+ : tag(t), cipher_suite(cs), key_params(kp), session_params(sp) {}
+
+ bool Matches(const CryptoParams& params) const {
+ return (tag == params.tag && cipher_suite == params.cipher_suite);
+ }
+
+ int tag;
+ std::string cipher_suite;
+ std::string key_params;
+ std::string session_params;
+};
+
+} // namespace cricket
+
+#endif // API_CRYPTO_PARAMS_H_
diff --git a/third_party/libwebrtc/api/data_channel_interface.cc b/third_party/libwebrtc/api/data_channel_interface.cc
new file mode 100644
index 0000000000..bddb9d1b0a
--- /dev/null
+++ b/third_party/libwebrtc/api/data_channel_interface.cc
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/data_channel_interface.h"
+
+namespace webrtc {
+
+bool DataChannelInterface::ordered() const {
+ return false;
+}
+
+uint16_t DataChannelInterface::maxRetransmitTime() const {
+ return 0;
+}
+
+uint16_t DataChannelInterface::maxRetransmits() const {
+ return 0;
+}
+
+absl::optional<int> DataChannelInterface::maxRetransmitsOpt() const {
+ return absl::nullopt;
+}
+
+absl::optional<int> DataChannelInterface::maxPacketLifeTime() const {
+ return absl::nullopt;
+}
+
+std::string DataChannelInterface::protocol() const {
+ return std::string();
+}
+
+bool DataChannelInterface::negotiated() const {
+ return false;
+}
+
+uint64_t DataChannelInterface::MaxSendQueueSize() {
+ return 16 * 1024 * 1024; // 16 MiB
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/data_channel_interface.h b/third_party/libwebrtc/api/data_channel_interface.h
new file mode 100644
index 0000000000..4f74918ff9
--- /dev/null
+++ b/third_party/libwebrtc/api/data_channel_interface.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This file contains interfaces for DataChannels
+// http://dev.w3.org/2011/webrtc/editor/webrtc.html#rtcdatachannel
+
+#ifndef API_DATA_CHANNEL_INTERFACE_H_
+#define API_DATA_CHANNEL_INTERFACE_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <string>
+
+#include "absl/types/optional.h"
+#include "api/priority.h"
+#include "api/rtc_error.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/copy_on_write_buffer.h"
+#include "rtc_base/ref_count.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// C++ version of: https://www.w3.org/TR/webrtc/#idl-def-rtcdatachannelinit
+// TODO(deadbeef): Use absl::optional for the "-1 if unset" things.
+struct DataChannelInit {
+ // Deprecated. Reliability is assumed, and channel will be unreliable if
+ // maxRetransmitTime or MaxRetransmits is set.
+ bool reliable = false;
+
+ // True if ordered delivery is required.
+ bool ordered = true;
+
+ // The max period of time in milliseconds in which retransmissions will be
+ // sent. After this time, no more retransmissions will be sent.
+ //
+ // Cannot be set along with `maxRetransmits`.
+ // This is called `maxPacketLifeTime` in the WebRTC JS API.
+ // Negative values are ignored, and positive values are clamped to [0-65535]
+ absl::optional<int> maxRetransmitTime;
+
+ // The max number of retransmissions.
+ //
+ // Cannot be set along with `maxRetransmitTime`.
+ // Negative values are ignored, and positive values are clamped to [0-65535]
+ absl::optional<int> maxRetransmits;
+
+ // This is set by the application and opaque to the WebRTC implementation.
+ std::string protocol;
+
+ // True if the channel has been externally negotiated and we do not send an
+ // in-band signalling in the form of an "open" message. If this is true, `id`
+ // below must be set; otherwise it should be unset and will be negotiated
+ // in-band.
+ bool negotiated = false;
+
+ // The stream id, or SID, for SCTP data channels. -1 if unset (see above).
+ int id = -1;
+
+ // https://w3c.github.io/webrtc-priority/#new-rtcdatachannelinit-member
+ absl::optional<Priority> priority;
+};
+
+// At the JavaScript level, data can be passed in as a string or a blob, so
+// this structure's `binary` flag tells whether the data should be interpreted
+// as binary or text.
+struct DataBuffer {
+ DataBuffer(const rtc::CopyOnWriteBuffer& data, bool binary)
+ : data(data), binary(binary) {}
+ // For convenience for unit tests.
+ explicit DataBuffer(const std::string& text)
+ : data(text.data(), text.length()), binary(false) {}
+ size_t size() const { return data.size(); }
+
+ rtc::CopyOnWriteBuffer data;
+ // Indicates if the received data contains UTF-8 or binary data.
+ // Note that the upper layers are left to verify the UTF-8 encoding.
+ // TODO(jiayl): prefer to use an enum instead of a bool.
+ bool binary;
+};
+
+// Used to implement RTCDataChannel events.
+//
+// The code responding to these callbacks should unwind the stack before
+// using any other webrtc APIs; re-entrancy is not supported.
+class DataChannelObserver {
+ public:
+ // The data channel state have changed.
+ virtual void OnStateChange() = 0;
+ // A data buffer was successfully received.
+ virtual void OnMessage(const DataBuffer& buffer) = 0;
+ // The data channel's buffered_amount has changed.
+ virtual void OnBufferedAmountChange(uint64_t sent_data_size) {}
+
+ protected:
+ virtual ~DataChannelObserver() = default;
+};
+
+class RTC_EXPORT DataChannelInterface : public rtc::RefCountInterface {
+ public:
+ // C++ version of: https://www.w3.org/TR/webrtc/#idl-def-rtcdatachannelstate
+ // Unlikely to change, but keep in sync with DataChannel.java:State and
+ // RTCDataChannel.h:RTCDataChannelState.
+ enum DataState {
+ kConnecting,
+ kOpen, // The DataChannel is ready to send data.
+ kClosing,
+ kClosed
+ };
+
+ static const char* DataStateString(DataState state) {
+ switch (state) {
+ case kConnecting:
+ return "connecting";
+ case kOpen:
+ return "open";
+ case kClosing:
+ return "closing";
+ case kClosed:
+ return "closed";
+ }
+ RTC_CHECK(false) << "Unknown DataChannel state: " << state;
+ return "";
+ }
+
+ // Used to receive events from the data channel. Only one observer can be
+ // registered at a time. UnregisterObserver should be called before the
+ // observer object is destroyed.
+ virtual void RegisterObserver(DataChannelObserver* observer) = 0;
+ virtual void UnregisterObserver() = 0;
+
+ // The label attribute represents a label that can be used to distinguish this
+ // DataChannel object from other DataChannel objects.
+ virtual std::string label() const = 0;
+
+ // The accessors below simply return the properties from the DataChannelInit
+ // the data channel was constructed with.
+ virtual bool reliable() const = 0;
+ // TODO(deadbeef): Remove these dummy implementations when all classes have
+ // implemented these APIs. They should all just return the values the
+ // DataChannel was created with.
+ virtual bool ordered() const;
+ // TODO(hta): Deprecate and remove the following two functions.
+ virtual uint16_t maxRetransmitTime() const;
+ virtual uint16_t maxRetransmits() const;
+ virtual absl::optional<int> maxRetransmitsOpt() const;
+ virtual absl::optional<int> maxPacketLifeTime() const;
+ virtual std::string protocol() const;
+ virtual bool negotiated() const;
+
+ // Returns the ID from the DataChannelInit, if it was negotiated out-of-band.
+ // If negotiated in-band, this ID will be populated once the DTLS role is
+ // determined, and until then this will return -1.
+ virtual int id() const = 0;
+ virtual Priority priority() const { return Priority::kLow; }
+ virtual DataState state() const = 0;
+ // When state is kClosed, and the DataChannel was not closed using
+ // the closing procedure, returns the error information about the closing.
+ // The default implementation returns "no error".
+ virtual RTCError error() const { return RTCError(); }
+ virtual uint32_t messages_sent() const = 0;
+ virtual uint64_t bytes_sent() const = 0;
+ virtual uint32_t messages_received() const = 0;
+ virtual uint64_t bytes_received() const = 0;
+
+ // Returns the number of bytes of application data (UTF-8 text and binary
+ // data) that have been queued using Send but have not yet been processed at
+ // the SCTP level. See comment above Send below.
+ // Values are less or equal to MaxSendQueueSize().
+ virtual uint64_t buffered_amount() const = 0;
+
+ // Begins the graceful data channel closing procedure. See:
+ // https://tools.ietf.org/html/draft-ietf-rtcweb-data-channel-13#section-6.7
+ virtual void Close() = 0;
+
+ // Sends `data` to the remote peer. If the data can't be sent at the SCTP
+ // level (due to congestion control), it's buffered at the data channel level,
+ // up to a maximum of MaxSendQueueSize().
+ // Returns false if the data channel is not in open state or if the send
+ // buffer is full.
+ // TODO(webrtc:13289): Return an RTCError with information about the failure.
+ virtual bool Send(const DataBuffer& buffer) = 0;
+
+ // Amount of bytes that can be queued for sending on the data channel.
+ // Those are bytes that have not yet been processed at the SCTP level.
+ static uint64_t MaxSendQueueSize();
+
+ protected:
+ ~DataChannelInterface() override = default;
+};
+
+} // namespace webrtc
+
+#endif // API_DATA_CHANNEL_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/dtls_transport_interface.cc b/third_party/libwebrtc/api/dtls_transport_interface.cc
new file mode 100644
index 0000000000..faebc0972f
--- /dev/null
+++ b/third_party/libwebrtc/api/dtls_transport_interface.cc
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/dtls_transport_interface.h"
+
+namespace webrtc {
+
+DtlsTransportInformation::DtlsTransportInformation()
+ : state_(DtlsTransportState::kNew) {}
+
+DtlsTransportInformation::DtlsTransportInformation(DtlsTransportState state)
+ : state_(state) {}
+
+DtlsTransportInformation::DtlsTransportInformation(
+ DtlsTransportState state,
+ absl::optional<DtlsTransportTlsRole> role,
+ absl::optional<int> tls_version,
+ absl::optional<int> ssl_cipher_suite,
+ absl::optional<int> srtp_cipher_suite,
+ std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates)
+ : state_(state),
+ role_(role),
+ tls_version_(tls_version),
+ ssl_cipher_suite_(ssl_cipher_suite),
+ srtp_cipher_suite_(srtp_cipher_suite),
+ remote_ssl_certificates_(std::move(remote_ssl_certificates)) {}
+
+// Deprecated version
+DtlsTransportInformation::DtlsTransportInformation(
+ DtlsTransportState state,
+ absl::optional<int> tls_version,
+ absl::optional<int> ssl_cipher_suite,
+ absl::optional<int> srtp_cipher_suite,
+ std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates)
+ : state_(state),
+ role_(absl::nullopt),
+ tls_version_(tls_version),
+ ssl_cipher_suite_(ssl_cipher_suite),
+ srtp_cipher_suite_(srtp_cipher_suite),
+ remote_ssl_certificates_(std::move(remote_ssl_certificates)) {}
+
+DtlsTransportInformation::DtlsTransportInformation(
+ const DtlsTransportInformation& c)
+ : state_(c.state()),
+ role_(c.role_),
+ tls_version_(c.tls_version_),
+ ssl_cipher_suite_(c.ssl_cipher_suite_),
+ srtp_cipher_suite_(c.srtp_cipher_suite_),
+ remote_ssl_certificates_(c.remote_ssl_certificates()
+ ? c.remote_ssl_certificates()->Clone()
+ : nullptr) {}
+
+DtlsTransportInformation& DtlsTransportInformation::operator=(
+ const DtlsTransportInformation& c) {
+ state_ = c.state();
+ role_ = c.role_;
+ tls_version_ = c.tls_version_;
+ ssl_cipher_suite_ = c.ssl_cipher_suite_;
+ srtp_cipher_suite_ = c.srtp_cipher_suite_;
+ remote_ssl_certificates_ = c.remote_ssl_certificates()
+ ? c.remote_ssl_certificates()->Clone()
+ : nullptr;
+ return *this;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/dtls_transport_interface.h b/third_party/libwebrtc/api/dtls_transport_interface.h
new file mode 100644
index 0000000000..7b0151249c
--- /dev/null
+++ b/third_party/libwebrtc/api/dtls_transport_interface.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_DTLS_TRANSPORT_INTERFACE_H_
+#define API_DTLS_TRANSPORT_INTERFACE_H_
+
+#include <memory>
+#include <utility>
+
+#include "absl/types/optional.h"
+#include "api/ice_transport_interface.h"
+#include "api/rtc_error.h"
+#include "api/scoped_refptr.h"
+#include "rtc_base/ref_count.h"
+#include "rtc_base/ssl_certificate.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// States of a DTLS transport, corresponding to the JS API specification.
+// http://w3c.github.io/webrtc-pc/#dom-rtcdtlstransportstate
+enum class DtlsTransportState {
+ kNew, // Has not started negotiating yet.
+ kConnecting, // In the process of negotiating a secure connection.
+ kConnected, // Completed negotiation and verified fingerprints.
+ kClosed, // Intentionally closed.
+ kFailed, // Failure due to an error or failing to verify a remote
+ // fingerprint.
+ kNumValues
+};
+
+enum class DtlsTransportTlsRole {
+ kServer, // Other end sends CLIENT_HELLO
+ kClient // This end sends CLIENT_HELLO
+};
+
+// This object gives snapshot information about the changeable state of a
+// DTLSTransport.
+class RTC_EXPORT DtlsTransportInformation {
+ public:
+ DtlsTransportInformation();
+ explicit DtlsTransportInformation(DtlsTransportState state);
+ DtlsTransportInformation(
+ DtlsTransportState state,
+ absl::optional<DtlsTransportTlsRole> role,
+ absl::optional<int> tls_version,
+ absl::optional<int> ssl_cipher_suite,
+ absl::optional<int> srtp_cipher_suite,
+ std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates);
+ ABSL_DEPRECATED("Use version with role parameter")
+ DtlsTransportInformation(
+ DtlsTransportState state,
+ absl::optional<int> tls_version,
+ absl::optional<int> ssl_cipher_suite,
+ absl::optional<int> srtp_cipher_suite,
+ std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates);
+
+ // Copy and assign
+ DtlsTransportInformation(const DtlsTransportInformation& c);
+ DtlsTransportInformation& operator=(const DtlsTransportInformation& c);
+ // Move
+ DtlsTransportInformation(DtlsTransportInformation&& other) = default;
+ DtlsTransportInformation& operator=(DtlsTransportInformation&& other) =
+ default;
+
+ DtlsTransportState state() const { return state_; }
+ absl::optional<DtlsTransportTlsRole> role() const { return role_; }
+ absl::optional<int> tls_version() const { return tls_version_; }
+ absl::optional<int> ssl_cipher_suite() const { return ssl_cipher_suite_; }
+ absl::optional<int> srtp_cipher_suite() const { return srtp_cipher_suite_; }
+ // The accessor returns a temporary pointer, it does not release ownership.
+ const rtc::SSLCertChain* remote_ssl_certificates() const {
+ return remote_ssl_certificates_.get();
+ }
+
+ private:
+ DtlsTransportState state_;
+ absl::optional<DtlsTransportTlsRole> role_;
+ absl::optional<int> tls_version_;
+ absl::optional<int> ssl_cipher_suite_;
+ absl::optional<int> srtp_cipher_suite_;
+ std::unique_ptr<rtc::SSLCertChain> remote_ssl_certificates_;
+};
+
+class DtlsTransportObserverInterface {
+ public:
+ // This callback carries information about the state of the transport.
+ // The argument is a pass-by-value snapshot of the state.
+ virtual void OnStateChange(DtlsTransportInformation info) = 0;
+ // This callback is called when an error occurs, causing the transport
+ // to go to the kFailed state.
+ virtual void OnError(RTCError error) = 0;
+
+ protected:
+ virtual ~DtlsTransportObserverInterface() = default;
+};
+
+// A DTLS transport, as represented to the outside world.
+// This object is created on the network thread, and can only be
+// accessed on that thread, except for functions explicitly marked otherwise.
+// References can be held by other threads, and destruction can therefore
+// be initiated by other threads.
+class DtlsTransportInterface : public rtc::RefCountInterface {
+ public:
+ // Returns a pointer to the ICE transport that is owned by the DTLS transport.
+ virtual rtc::scoped_refptr<IceTransportInterface> ice_transport() = 0;
+ // Returns information on the state of the DtlsTransport.
+ // This function can be called from other threads.
+ virtual DtlsTransportInformation Information() = 0;
+ // Observer management.
+ virtual void RegisterObserver(DtlsTransportObserverInterface* observer) = 0;
+ virtual void UnregisterObserver() = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_DTLS_TRANSPORT_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/dtmf_sender_interface.h b/third_party/libwebrtc/api/dtmf_sender_interface.h
new file mode 100644
index 0000000000..d63e66bbf7
--- /dev/null
+++ b/third_party/libwebrtc/api/dtmf_sender_interface.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_DTMF_SENDER_INTERFACE_H_
+#define API_DTMF_SENDER_INTERFACE_H_
+
+#include <string>
+
+#include "api/media_stream_interface.h"
+#include "rtc_base/ref_count.h"
+
+namespace webrtc {
+
+// DtmfSender callback interface, used to implement RTCDtmfSender events.
+// Applications should implement this interface to get notifications from the
+// DtmfSender.
+class DtmfSenderObserverInterface {
+ public:
+ // Triggered when DTMF `tone` is sent.
+ // If `tone` is empty that means the DtmfSender has sent out all the given
+ // tones.
+ // The callback includes the state of the tone buffer at the time when
+ // the tone finished playing.
+ virtual void OnToneChange(const std::string& tone,
+ const std::string& tone_buffer) {}
+ // DEPRECATED: Older API without tone buffer.
+ // TODO(bugs.webrtc.org/9725): Remove old API and default implementation
+ // when old callers are gone.
+ virtual void OnToneChange(const std::string& tone) {}
+
+ protected:
+ virtual ~DtmfSenderObserverInterface() = default;
+};
+
+// The interface of native implementation of the RTCDTMFSender defined by the
+// WebRTC W3C Editor's Draft.
+// See: https://www.w3.org/TR/webrtc/#peer-to-peer-dtmf
+class DtmfSenderInterface : public rtc::RefCountInterface {
+ public:
+ // Provides the spec compliant default 2 second delay for the ',' character.
+ static const int kDtmfDefaultCommaDelayMs = 2000;
+
+ // Used to receive events from the DTMF sender. Only one observer can be
+ // registered at a time. UnregisterObserver should be called before the
+ // observer object is destroyed.
+ virtual void RegisterObserver(DtmfSenderObserverInterface* observer) = 0;
+ virtual void UnregisterObserver() = 0;
+
+ // Returns true if this DtmfSender is capable of sending DTMF. Otherwise
+ // returns false. To be able to send DTMF, the associated RtpSender must be
+ // able to send packets, and a "telephone-event" codec must be negotiated.
+ virtual bool CanInsertDtmf() = 0;
+
+ // Queues a task that sends the DTMF `tones`. The `tones` parameter is treated
+ // as a series of characters. The characters 0 through 9, A through D, #, and
+ // * generate the associated DTMF tones. The characters a to d are equivalent
+ // to A to D. The character ',' indicates a delay of 2 seconds before
+ // processing the next character in the tones parameter.
+ //
+ // Unrecognized characters are ignored.
+ //
+ // The `duration` parameter indicates the duration in ms to use for each
+ // character passed in the `tones` parameter. The duration cannot be more
+ // than 6000 or less than 70.
+ //
+ // The `inter_tone_gap` parameter indicates the gap between tones in ms. The
+ // `inter_tone_gap` must be at least 50 ms but should be as short as
+ // possible.
+ //
+ // The `comma_delay` parameter indicates the delay after the ','
+ // character. InsertDtmf specifies `comma_delay` as an argument
+ // with a default value of 2 seconds as per the WebRTC spec. This parameter
+ // allows users to comply with legacy WebRTC clients. The `comma_delay`
+ // must be at least 50 ms.
+ //
+ // If InsertDtmf is called on the same object while an existing task for this
+ // object to generate DTMF is still running, the previous task is canceled.
+ // Returns true on success and false on failure.
+ virtual bool InsertDtmf(const std::string& tones,
+ int duration,
+ int inter_tone_gap) {
+ return InsertDtmf(tones, duration, inter_tone_gap,
+ kDtmfDefaultCommaDelayMs);
+ }
+ virtual bool InsertDtmf(const std::string& tones,
+ int duration,
+ int inter_tone_gap,
+ int comma_delay) {
+ // TODO(bugs.webrtc.org/165700): Remove once downstream implementations
+ // override this signature rather than the 3-parameter one.
+ return InsertDtmf(tones, duration, inter_tone_gap);
+ }
+
+ // Returns the tones remaining to be played out.
+ virtual std::string tones() const = 0;
+
+ // Returns the current tone duration value in ms.
+ // This value will be the value last set via the InsertDtmf() method, or the
+ // default value of 100 ms if InsertDtmf() was never called.
+ virtual int duration() const = 0;
+
+ // Returns the current value of the between-tone gap in ms.
+ // This value will be the value last set via the InsertDtmf() method, or the
+ // default value of 50 ms if InsertDtmf() was never called.
+ virtual int inter_tone_gap() const = 0;
+
+ // Returns the current value of the "," character delay in ms.
+ // This value will be the value last set via the InsertDtmf() method, or the
+ // default value of 2000 ms if InsertDtmf() was never called.
+ virtual int comma_delay() const { return kDtmfDefaultCommaDelayMs; }
+
+ protected:
+ ~DtmfSenderInterface() override = default;
+};
+
+} // namespace webrtc
+
+#endif // API_DTMF_SENDER_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/fec_controller.h b/third_party/libwebrtc/api/fec_controller.h
new file mode 100644
index 0000000000..f3d7a8aa26
--- /dev/null
+++ b/third_party/libwebrtc/api/fec_controller.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_FEC_CONTROLLER_H_
+#define API_FEC_CONTROLLER_H_
+
+#include <memory>
+#include <vector>
+
+#include "api/video/video_frame_type.h"
+#include "modules/include/module_fec_types.h"
+
+namespace webrtc {
+// TODO(yinwa): work in progress. API in class FecController should not be
+// used by other users until this comment is removed.
+
+// Callback class used for telling the user about how to configure the FEC,
+// and the rates sent the last second is returned to the VCM.
+class VCMProtectionCallback {
+ public:
+ virtual int ProtectionRequest(const FecProtectionParams* delta_params,
+ const FecProtectionParams* key_params,
+ uint32_t* sent_video_rate_bps,
+ uint32_t* sent_nack_rate_bps,
+ uint32_t* sent_fec_rate_bps) = 0;
+
+ protected:
+ virtual ~VCMProtectionCallback() {}
+};
+
+// FecController calculates how much of the allocated network
+// capacity that can be used by an encoder and how much that
+// is needed for redundant packets such as FEC and NACK. It uses an
+// implementation of `VCMProtectionCallback` to set new FEC parameters and get
+// the bitrate currently used for FEC and NACK.
+// Usage:
+// Setup by calling SetProtectionMethod and SetEncodingData.
+// For each encoded image, call UpdateWithEncodedData.
+// Each time the bandwidth estimate change, call UpdateFecRates. UpdateFecRates
+// will return the bitrate that can be used by an encoder.
+// A lock is used to protect internal states, so methods can be called on an
+// arbitrary thread.
+class FecController {
+ public:
+ virtual ~FecController() {}
+
+ virtual void SetProtectionCallback(
+ VCMProtectionCallback* protection_callback) = 0;
+ virtual void SetProtectionMethod(bool enable_fec, bool enable_nack) = 0;
+
+ // Informs loss protectoin logic of initial encoding state.
+ virtual void SetEncodingData(size_t width,
+ size_t height,
+ size_t num_temporal_layers,
+ size_t max_payload_size) = 0;
+
+ // Returns target rate for the encoder given the channel parameters.
+ // Inputs: estimated_bitrate_bps - the estimated network bitrate in bits/s.
+ // actual_framerate - encoder frame rate.
+ // fraction_lost - packet loss rate in % in the network.
+ // loss_mask_vector - packet loss mask since last time this method
+ // was called. round_trip_time_ms - round trip time in milliseconds.
+ virtual uint32_t UpdateFecRates(uint32_t estimated_bitrate_bps,
+ int actual_framerate,
+ uint8_t fraction_lost,
+ std::vector<bool> loss_mask_vector,
+ int64_t round_trip_time_ms) = 0;
+
+ // Informs of encoded output.
+ virtual void UpdateWithEncodedData(
+ size_t encoded_image_length,
+ VideoFrameType encoded_image_frametype) = 0;
+
+ // Returns whether this FEC Controller needs Loss Vector Mask as input.
+ virtual bool UseLossVectorMask() = 0;
+};
+
+class FecControllerFactoryInterface {
+ public:
+ virtual std::unique_ptr<FecController> CreateFecController() = 0;
+ virtual ~FecControllerFactoryInterface() = default;
+};
+
+} // namespace webrtc
+#endif // API_FEC_CONTROLLER_H_
diff --git a/third_party/libwebrtc/api/fec_controller_api_gn/moz.build b/third_party/libwebrtc/api/fec_controller_api_gn/moz.build
new file mode 100644
index 0000000000..014e7fe571
--- /dev/null
+++ b/third_party/libwebrtc/api/fec_controller_api_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("fec_controller_api_gn")
diff --git a/third_party/libwebrtc/api/fec_controller_override.h b/third_party/libwebrtc/api/fec_controller_override.h
new file mode 100644
index 0000000000..233812fb0a
--- /dev/null
+++ b/third_party/libwebrtc/api/fec_controller_override.h
@@ -0,0 +1,28 @@
+/* Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This is an EXPERIMENTAL interface.
+
+#ifndef API_FEC_CONTROLLER_OVERRIDE_H_
+#define API_FEC_CONTROLLER_OVERRIDE_H_
+
+namespace webrtc {
+
+// Interface for temporarily overriding FecController's bitrate allocation.
+class FecControllerOverride {
+ public:
+ virtual void SetFecAllowed(bool fec_allowed) = 0;
+
+ protected:
+ virtual ~FecControllerOverride() = default;
+};
+
+} // namespace webrtc
+
+#endif // API_FEC_CONTROLLER_OVERRIDE_H_
diff --git a/third_party/libwebrtc/api/field_trials.cc b/third_party/libwebrtc/api/field_trials.cc
new file mode 100644
index 0000000000..4bd11271dc
--- /dev/null
+++ b/third_party/libwebrtc/api/field_trials.cc
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/field_trials.h"
+
+#include <atomic>
+
+#include "rtc_base/checks.h"
+#include "system_wrappers/include/field_trial.h"
+
+namespace {
+
+// This part is copied from system_wrappers/field_trial.cc.
+webrtc::flat_map<std::string, std::string> InsertIntoMap(const std::string& s) {
+ std::string::size_type field_start = 0;
+ webrtc::flat_map<std::string, std::string> key_value_map;
+ while (field_start < s.size()) {
+ std::string::size_type separator_pos = s.find('/', field_start);
+ RTC_CHECK_NE(separator_pos, std::string::npos)
+ << "Missing separator '/' after field trial key.";
+ RTC_CHECK_GT(separator_pos, field_start)
+ << "Field trial key cannot be empty.";
+ std::string key = s.substr(field_start, separator_pos - field_start);
+ field_start = separator_pos + 1;
+
+ RTC_CHECK_LT(field_start, s.size())
+ << "Missing value after field trial key. String ended.";
+ separator_pos = s.find('/', field_start);
+ RTC_CHECK_NE(separator_pos, std::string::npos)
+ << "Missing terminating '/' in field trial string.";
+ RTC_CHECK_GT(separator_pos, field_start)
+ << "Field trial value cannot be empty.";
+ std::string value = s.substr(field_start, separator_pos - field_start);
+ field_start = separator_pos + 1;
+
+ // If a key is specified multiple times, only the value linked to the first
+ // key is stored. note: This will crash in debug build when calling
+ // InitFieldTrialsFromString().
+ key_value_map.emplace(key, value);
+ }
+ // This check is technically redundant due to earlier checks.
+ // We nevertheless keep the check to make it clear that the entire
+ // string has been processed, and without indexing past the end.
+ RTC_CHECK_EQ(field_start, s.size());
+
+ return key_value_map;
+}
+
+// Makes sure that only one instance is created, since the usage
+// of global string makes behaviour unpredicatable otherwise.
+// TODO(bugs.webrtc.org/10335): Remove once global string is gone.
+std::atomic<bool> instance_created_{false};
+
+} // namespace
+
+namespace webrtc {
+
+FieldTrials::FieldTrials(const std::string& s)
+ : uses_global_(true),
+ field_trial_string_(s),
+ previous_field_trial_string_(webrtc::field_trial::GetFieldTrialString()),
+ key_value_map_(InsertIntoMap(s)) {
+ // TODO(bugs.webrtc.org/10335): Remove the global string!
+ field_trial::InitFieldTrialsFromString(field_trial_string_.c_str());
+ RTC_CHECK(!instance_created_.exchange(true))
+ << "Only one instance may be instanciated at any given time!";
+}
+
+std::unique_ptr<FieldTrials> FieldTrials::CreateNoGlobal(const std::string& s) {
+ return std::unique_ptr<FieldTrials>(new FieldTrials(s, true));
+}
+
+FieldTrials::FieldTrials(const std::string& s, bool)
+ : uses_global_(false),
+ previous_field_trial_string_(nullptr),
+ key_value_map_(InsertIntoMap(s)) {}
+
+FieldTrials::~FieldTrials() {
+ // TODO(bugs.webrtc.org/10335): Remove the global string!
+ if (uses_global_) {
+ field_trial::InitFieldTrialsFromString(previous_field_trial_string_);
+ RTC_CHECK(instance_created_.exchange(false));
+ }
+}
+
+std::string FieldTrials::GetValue(absl::string_view key) const {
+ auto it = key_value_map_.find(std::string(key));
+ if (it != key_value_map_.end())
+ return it->second;
+
+ // Check the global string so that programs using
+ // a mix between FieldTrials and the global string continue to work
+ // TODO(bugs.webrtc.org/10335): Remove the global string!
+ if (uses_global_) {
+ return field_trial::FindFullName(std::string(key));
+ }
+ return "";
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/field_trials.h b/third_party/libwebrtc/api/field_trials.h
new file mode 100644
index 0000000000..bf7a7cc625
--- /dev/null
+++ b/third_party/libwebrtc/api/field_trials.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_FIELD_TRIALS_H_
+#define API_FIELD_TRIALS_H_
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "api/field_trials_registry.h"
+#include "rtc_base/containers/flat_map.h"
+
+namespace webrtc {
+
+// The FieldTrials class is used to inject field trials into webrtc.
+//
+// Field trials allow webrtc clients (such as Chromium) to turn on feature code
+// in binaries out in the field and gather information with that.
+//
+// They are designed to be easy to use with Chromium field trials and to speed
+// up developers by reducing the need to wire up APIs to control whether a
+// feature is on/off.
+//
+// The field trials are injected into objects that use them at creation time.
+//
+// NOTE: Creating multiple FieldTrials-object is currently prohibited
+// until we remove the global string (TODO(bugs.webrtc.org/10335))
+// (unless using CreateNoGlobal):
+class FieldTrials : public FieldTrialsRegistry {
+ public:
+ explicit FieldTrials(const std::string& s);
+ ~FieldTrials();
+
+ // Create a FieldTrials object that is not reading/writing from
+ // global variable (i.e can not be used for all parts of webrtc).
+ static std::unique_ptr<FieldTrials> CreateNoGlobal(const std::string& s);
+
+ private:
+ explicit FieldTrials(const std::string& s, bool);
+
+ std::string GetValue(absl::string_view key) const override;
+
+ const bool uses_global_;
+ const std::string field_trial_string_;
+ const char* const previous_field_trial_string_;
+ const flat_map<std::string, std::string> key_value_map_;
+};
+
+} // namespace webrtc
+
+#endif // API_FIELD_TRIALS_H_
diff --git a/third_party/libwebrtc/api/field_trials_registry.cc b/third_party/libwebrtc/api/field_trials_registry.cc
new file mode 100644
index 0000000000..f97e8a85a9
--- /dev/null
+++ b/third_party/libwebrtc/api/field_trials_registry.cc
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/field_trials_registry.h"
+
+#include <string>
+
+#include "absl/algorithm/container.h"
+#include "absl/strings/string_view.h"
+#include "experiments/registered_field_trials.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/containers/flat_set.h"
+
+namespace webrtc {
+
+std::string FieldTrialsRegistry::Lookup(absl::string_view key) const {
+#if WEBRTC_STRICT_FIELD_TRIALS
+ RTC_DCHECK(absl::c_linear_search(kRegisteredFieldTrials, key) ||
+ test_keys_.contains(key))
+ << key << " is not registered.";
+#endif
+ return GetValue(key);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/field_trials_registry.h b/third_party/libwebrtc/api/field_trials_registry.h
new file mode 100644
index 0000000000..dc7e8445b1
--- /dev/null
+++ b/third_party/libwebrtc/api/field_trials_registry.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_FIELD_TRIALS_REGISTRY_H_
+#define API_FIELD_TRIALS_REGISTRY_H_
+
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "api/field_trials_view.h"
+#include "rtc_base/containers/flat_set.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Abstract base class for a field trial registry that verifies that any looked
+// up key has been pre-registered in accordance with `g3doc/field-trials.md`.
+class RTC_EXPORT FieldTrialsRegistry : public FieldTrialsView {
+ public:
+ FieldTrialsRegistry() = default;
+
+ FieldTrialsRegistry(const FieldTrialsRegistry&) = default;
+ FieldTrialsRegistry& operator=(const FieldTrialsRegistry&) = default;
+
+ ~FieldTrialsRegistry() override = default;
+
+ // Verifies that `key` is a registered field trial and then returns the
+ // configured value for `key` or an empty string if the field trial isn't
+ // configured.
+ std::string Lookup(absl::string_view key) const override;
+
+ // Register additional `keys` for testing. This should only be used for
+ // imaginary keys that are never used outside test code.
+ void RegisterKeysForTesting(flat_set<std::string> keys) {
+ test_keys_ = std::move(keys);
+ }
+
+ private:
+ virtual std::string GetValue(absl::string_view key) const = 0;
+
+ // Imaginary keys only used for testing.
+ flat_set<std::string> test_keys_;
+};
+
+} // namespace webrtc
+
+#endif // API_FIELD_TRIALS_REGISTRY_H_
diff --git a/third_party/libwebrtc/api/field_trials_registry_gn/moz.build b/third_party/libwebrtc/api/field_trials_registry_gn/moz.build
new file mode 100644
index 0000000000..4210c8af82
--- /dev/null
+++ b/third_party/libwebrtc/api/field_trials_registry_gn/moz.build
@@ -0,0 +1,221 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/field_trials_registry.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("field_trials_registry_gn")
diff --git a/third_party/libwebrtc/api/field_trials_unittest.cc b/third_party/libwebrtc/api/field_trials_unittest.cc
new file mode 100644
index 0000000000..804b52a818
--- /dev/null
+++ b/third_party/libwebrtc/api/field_trials_unittest.cc
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2022 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/field_trials.h"
+
+#include <memory>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "api/transport/field_trial_based_config.h"
+#include "rtc_base/containers/flat_set.h"
+#include "system_wrappers/include/field_trial.h"
+#include "test/field_trial.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
+#include "test/testsupport/rtc_expect_death.h"
+#endif // GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
+
+namespace webrtc {
+namespace {
+
+using ::testing::NotNull;
+using ::webrtc::field_trial::FieldTrialsAllowedInScopeForTesting;
+using ::webrtc::test::ScopedFieldTrials;
+
+TEST(FieldTrialsTest, EmptyStringHasNoEffect) {
+ FieldTrialsAllowedInScopeForTesting k({"MyCoolTrial"});
+ FieldTrials f("");
+ f.RegisterKeysForTesting({"MyCoolTrial"});
+
+ EXPECT_FALSE(f.IsEnabled("MyCoolTrial"));
+ EXPECT_FALSE(f.IsDisabled("MyCoolTrial"));
+}
+
+TEST(FieldTrialsTest, EnabledDisabledMustBeFirstInValue) {
+ FieldTrials f(
+ "MyCoolTrial/EnabledFoo/"
+ "MyUncoolTrial/DisabledBar/"
+ "AnotherTrial/BazEnabled/");
+ f.RegisterKeysForTesting({"MyCoolTrial", "MyUncoolTrial", "AnotherTrial"});
+
+ EXPECT_TRUE(f.IsEnabled("MyCoolTrial"));
+ EXPECT_TRUE(f.IsDisabled("MyUncoolTrial"));
+ EXPECT_FALSE(f.IsEnabled("AnotherTrial"));
+}
+
+TEST(FieldTrialsTest, FieldTrialsDoesNotReadGlobalString) {
+ FieldTrialsAllowedInScopeForTesting k({"MyCoolTrial", "MyUncoolTrial"});
+ ScopedFieldTrials g("MyCoolTrial/Enabled/MyUncoolTrial/Disabled/");
+ FieldTrials f("");
+ f.RegisterKeysForTesting({"MyCoolTrial", "MyUncoolTrial"});
+
+ EXPECT_FALSE(f.IsEnabled("MyCoolTrial"));
+ EXPECT_FALSE(f.IsDisabled("MyUncoolTrial"));
+}
+
+TEST(FieldTrialsTest, FieldTrialsWritesGlobalString) {
+ FieldTrialsAllowedInScopeForTesting k({"MyCoolTrial", "MyUncoolTrial"});
+ FieldTrials f("MyCoolTrial/Enabled/MyUncoolTrial/Disabled/");
+ EXPECT_TRUE(webrtc::field_trial::IsEnabled("MyCoolTrial"));
+ EXPECT_TRUE(webrtc::field_trial::IsDisabled("MyUncoolTrial"));
+}
+
+TEST(FieldTrialsTest, FieldTrialsRestoresGlobalStringAfterDestruction) {
+ static constexpr char s[] = "SomeString/Enabled/";
+ ScopedFieldTrials g(s);
+ {
+ FieldTrials f("SomeOtherString/Enabled/");
+ EXPECT_STREQ(webrtc::field_trial::GetFieldTrialString(),
+ "SomeOtherString/Enabled/");
+ }
+ EXPECT_STREQ(webrtc::field_trial::GetFieldTrialString(), s);
+}
+
+#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
+TEST(FieldTrialsTest, FieldTrialsDoesNotSupportSimultaneousInstances) {
+ FieldTrials f("SomeString/Enabled/");
+ RTC_EXPECT_DEATH(FieldTrials("SomeOtherString/Enabled/").Lookup("Whatever"),
+ "Only one instance");
+}
+#endif // GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
+
+TEST(FieldTrialsTest, FieldTrialsSupportsSeparateInstances) {
+ { FieldTrials f("SomeString/Enabled/"); }
+ { FieldTrials f("SomeOtherString/Enabled/"); }
+}
+
+TEST(FieldTrialsTest, NonGlobalFieldTrialsInstanceDoesNotModifyGlobalString) {
+ FieldTrialsAllowedInScopeForTesting k({"SomeString"});
+ std::unique_ptr<FieldTrials> f =
+ FieldTrials::CreateNoGlobal("SomeString/Enabled/");
+ ASSERT_THAT(f, NotNull());
+ f->RegisterKeysForTesting({"SomeString"});
+
+ EXPECT_TRUE(f->IsEnabled("SomeString"));
+ EXPECT_FALSE(webrtc::field_trial::IsEnabled("SomeString"));
+}
+
+TEST(FieldTrialsTest, NonGlobalFieldTrialsSupportSimultaneousInstances) {
+ std::unique_ptr<FieldTrials> f1 =
+ FieldTrials::CreateNoGlobal("SomeString/Enabled/");
+ std::unique_ptr<FieldTrials> f2 =
+ FieldTrials::CreateNoGlobal("SomeOtherString/Enabled/");
+ ASSERT_THAT(f1, NotNull());
+ ASSERT_THAT(f2, NotNull());
+ f1->RegisterKeysForTesting({"SomeString", "SomeOtherString"});
+ f2->RegisterKeysForTesting({"SomeString", "SomeOtherString"});
+
+ EXPECT_TRUE(f1->IsEnabled("SomeString"));
+ EXPECT_FALSE(f1->IsEnabled("SomeOtherString"));
+
+ EXPECT_FALSE(f2->IsEnabled("SomeString"));
+ EXPECT_TRUE(f2->IsEnabled("SomeOtherString"));
+}
+
+TEST(FieldTrialsTest, GlobalAndNonGlobalFieldTrialsAreDisjoint) {
+ FieldTrialsAllowedInScopeForTesting k({"SomeString", "SomeOtherString"});
+ FieldTrials f1("SomeString/Enabled/");
+ std::unique_ptr<FieldTrials> f2 =
+ FieldTrials::CreateNoGlobal("SomeOtherString/Enabled/");
+ ASSERT_THAT(f2, NotNull());
+ f1.RegisterKeysForTesting({"SomeString", "SomeOtherString"});
+ f2->RegisterKeysForTesting({"SomeString", "SomeOtherString"});
+
+ EXPECT_TRUE(f1.IsEnabled("SomeString"));
+ EXPECT_FALSE(f1.IsEnabled("SomeOtherString"));
+
+ EXPECT_FALSE(f2->IsEnabled("SomeString"));
+ EXPECT_TRUE(f2->IsEnabled("SomeOtherString"));
+}
+
+TEST(FieldTrialsTest, FieldTrialBasedConfigReadsGlobalString) {
+ FieldTrialsAllowedInScopeForTesting k({"MyCoolTrial", "MyUncoolTrial"});
+ ScopedFieldTrials g("MyCoolTrial/Enabled/MyUncoolTrial/Disabled/");
+ FieldTrialBasedConfig f;
+ f.RegisterKeysForTesting({"MyCoolTrial", "MyUncoolTrial"});
+
+ EXPECT_TRUE(f.IsEnabled("MyCoolTrial"));
+ EXPECT_TRUE(f.IsDisabled("MyUncoolTrial"));
+}
+
+} // namespace
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/field_trials_view.h b/third_party/libwebrtc/api/field_trials_view.h
new file mode 100644
index 0000000000..45e6f7899b
--- /dev/null
+++ b/third_party/libwebrtc/api/field_trials_view.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_FIELD_TRIALS_VIEW_H_
+#define API_FIELD_TRIALS_VIEW_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// An interface that provides the means to access field trials.
+//
+// Note that there are no guarantess that the meaning of a particular key-value
+// mapping will be preserved over time and no announcements will be made if they
+// are changed. It's up to the library user to ensure that the behavior does not
+// break.
+class RTC_EXPORT FieldTrialsView {
+ public:
+ virtual ~FieldTrialsView() = default;
+
+ // Returns the configured value for `key` or an empty string if the field
+ // trial isn't configured.
+ virtual std::string Lookup(absl::string_view key) const = 0;
+
+ bool IsEnabled(absl::string_view key) const {
+ return Lookup(key).find("Enabled") == 0;
+ }
+
+ bool IsDisabled(absl::string_view key) const {
+ return Lookup(key).find("Disabled") == 0;
+ }
+};
+
+// TODO(bugs.webrtc.org/10335): Remove once all migrated to
+// api/field_trials_view.h
+typedef FieldTrialsView WebRtcKeyValueConfig;
+
+} // namespace webrtc
+
+#endif // API_FIELD_TRIALS_VIEW_H_
diff --git a/third_party/libwebrtc/api/field_trials_view_gn/moz.build b/third_party/libwebrtc/api/field_trials_view_gn/moz.build
new file mode 100644
index 0000000000..2c7f147d4a
--- /dev/null
+++ b/third_party/libwebrtc/api/field_trials_view_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("field_trials_view_gn")
diff --git a/third_party/libwebrtc/api/frame_transformer_factory.cc b/third_party/libwebrtc/api/frame_transformer_factory.cc
new file mode 100644
index 0000000000..af08372e37
--- /dev/null
+++ b/third_party/libwebrtc/api/frame_transformer_factory.cc
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/frame_transformer_factory.h"
+
+#include "modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h"
+
+namespace webrtc {
+
+std::unique_ptr<TransformableVideoFrameInterface> CreateVideoSenderFrame() {
+ RTC_CHECK_NOTREACHED();
+ return nullptr;
+}
+
+std::unique_ptr<TransformableVideoFrameInterface> CreateVideoReceiverFrame() {
+ RTC_CHECK_NOTREACHED();
+ return nullptr;
+}
+
+std::unique_ptr<TransformableVideoFrameInterface> CloneVideoFrame(
+ TransformableVideoFrameInterface* original) {
+ // At the moment, only making sender frames from receiver frames is supported.
+ return CloneSenderVideoFrame(original);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/frame_transformer_factory.h b/third_party/libwebrtc/api/frame_transformer_factory.h
new file mode 100644
index 0000000000..8ba9c292d5
--- /dev/null
+++ b/third_party/libwebrtc/api/frame_transformer_factory.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_FRAME_TRANSFORMER_FACTORY_H_
+#define API_FRAME_TRANSFORMER_FACTORY_H_
+
+#include <memory>
+#include <vector>
+
+#include "api/frame_transformer_interface.h"
+#include "api/scoped_refptr.h"
+#include "api/video/encoded_frame.h"
+#include "api/video/video_frame_metadata.h"
+
+// This file contains EXPERIMENTAL functions to create video frames from
+// either an old video frame or directly from parameters.
+// These functions will be used in Chrome functionality to manipulate
+// encoded frames from Javascript.
+namespace webrtc {
+
+// TODO(bugs.webrtc.org/14708): Add the required parameters to these APIs.
+std::unique_ptr<TransformableVideoFrameInterface> CreateVideoSenderFrame();
+// TODO(bugs.webrtc.org/14708): Consider whether Receiver frames ever make sense
+// to create.
+std::unique_ptr<TransformableVideoFrameInterface> CreateVideoReceiverFrame();
+// Creates a new frame with the same metadata as the original.
+// The original can be a sender or receiver frame.
+RTC_EXPORT std::unique_ptr<TransformableVideoFrameInterface> CloneVideoFrame(
+ TransformableVideoFrameInterface* original);
+} // namespace webrtc
+
+#endif // API_FRAME_TRANSFORMER_FACTORY_H_
diff --git a/third_party/libwebrtc/api/frame_transformer_interface.h b/third_party/libwebrtc/api/frame_transformer_interface.h
new file mode 100644
index 0000000000..fba09d5ff0
--- /dev/null
+++ b/third_party/libwebrtc/api/frame_transformer_interface.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_FRAME_TRANSFORMER_INTERFACE_H_
+#define API_FRAME_TRANSFORMER_INTERFACE_H_
+
+#include <memory>
+#include <vector>
+
+#include "api/scoped_refptr.h"
+#include "api/video/encoded_frame.h"
+#include "api/video/video_frame_metadata.h"
+#include "rtc_base/ref_count.h"
+
+namespace webrtc {
+
+// Owns the frame payload data.
+class TransformableFrameInterface {
+ public:
+ virtual ~TransformableFrameInterface() = default;
+
+ // Returns the frame payload data. The data is valid until the next non-const
+ // method call.
+ virtual rtc::ArrayView<const uint8_t> GetData() const = 0;
+
+ // Copies `data` into the owned frame payload data.
+ virtual void SetData(rtc::ArrayView<const uint8_t> data) = 0;
+
+ virtual uint8_t GetPayloadType() const = 0;
+ virtual uint32_t GetSsrc() const = 0;
+ virtual uint32_t GetTimestamp() const = 0;
+
+ enum class Direction {
+ kUnknown,
+ kReceiver,
+ kSender,
+ };
+ // TODO(crbug.com/1250638): Remove this distinction between receiver and
+ // sender frames to allow received frames to be directly re-transmitted on
+ // other PeerConnectionss.
+ virtual Direction GetDirection() const { return Direction::kUnknown; }
+};
+
+class TransformableVideoFrameInterface : public TransformableFrameInterface {
+ public:
+ virtual ~TransformableVideoFrameInterface() = default;
+ virtual bool IsKeyFrame() const = 0;
+
+ // Returns data needed in the frame transformation logic; for example,
+ // when the transformation applied to the frame is encryption/decryption, the
+ // additional data holds the serialized generic frame descriptor extension
+ // calculated in webrtc::RtpDescriptorAuthentication.
+ // TODO(bugs.webrtc.org/11380) remove from interface once
+ // webrtc::RtpDescriptorAuthentication is exposed in api/.
+ virtual std::vector<uint8_t> GetAdditionalData() const = 0;
+
+ virtual const VideoFrameMetadata& GetMetadata() const = 0;
+ // TODO(https://crbug.com/webrtc/14709): Make pure virtual when Chromium MOCK
+ // has implemented this.
+ virtual void SetMetadata(const VideoFrameMetadata&) {}
+};
+
+// Extends the TransformableFrameInterface to expose audio-specific information.
+class TransformableAudioFrameInterface : public TransformableFrameInterface {
+ public:
+ virtual ~TransformableAudioFrameInterface() = default;
+
+ // Exposes the frame header, enabling the interface clients to use the
+ // information in the header as needed, for example to compile the list of
+ // csrcs.
+ virtual const RTPHeader& GetHeader() const = 0;
+
+ virtual rtc::ArrayView<const uint32_t> GetContributingSources() const = 0;
+};
+
+// Objects implement this interface to be notified with the transformed frame.
+class TransformedFrameCallback : public rtc::RefCountInterface {
+ public:
+ virtual void OnTransformedFrame(
+ std::unique_ptr<TransformableFrameInterface> frame) = 0;
+
+ protected:
+ ~TransformedFrameCallback() override = default;
+};
+
+// Transforms encoded frames. The transformed frame is sent in a callback using
+// the TransformedFrameCallback interface (see above).
+class FrameTransformerInterface : public rtc::RefCountInterface {
+ public:
+ // Transforms `frame` using the implementing class' processing logic.
+ virtual void Transform(
+ std::unique_ptr<TransformableFrameInterface> transformable_frame) = 0;
+
+ virtual void RegisterTransformedFrameCallback(
+ rtc::scoped_refptr<TransformedFrameCallback>) {}
+ virtual void RegisterTransformedFrameSinkCallback(
+ rtc::scoped_refptr<TransformedFrameCallback>,
+ uint32_t ssrc) {}
+ virtual void UnregisterTransformedFrameCallback() {}
+ virtual void UnregisterTransformedFrameSinkCallback(uint32_t ssrc) {}
+
+ protected:
+ ~FrameTransformerInterface() override = default;
+};
+
+} // namespace webrtc
+
+#endif // API_FRAME_TRANSFORMER_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/frame_transformer_interface_gn/moz.build b/third_party/libwebrtc/api/frame_transformer_interface_gn/moz.build
new file mode 100644
index 0000000000..885c8437ae
--- /dev/null
+++ b/third_party/libwebrtc/api/frame_transformer_interface_gn/moz.build
@@ -0,0 +1,216 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "rt"
+ ]
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "crypt32",
+ "iphlpapi",
+ "secur32",
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("frame_transformer_interface_gn")
diff --git a/third_party/libwebrtc/api/function_view.h b/third_party/libwebrtc/api/function_view.h
new file mode 100644
index 0000000000..5ae1bd6cfe
--- /dev/null
+++ b/third_party/libwebrtc/api/function_view.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2016 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_FUNCTION_VIEW_H_
+#define API_FUNCTION_VIEW_H_
+
+#include <type_traits>
+#include <utility>
+
+#include "rtc_base/checks.h"
+
+// Just like std::function, FunctionView will wrap any callable and hide its
+// actual type, exposing only its signature. But unlike std::function,
+// FunctionView doesn't own its callable---it just points to it. Thus, it's a
+// good choice mainly as a function argument when the callable argument will
+// not be called again once the function has returned.
+//
+// Its constructors are implicit, so that callers won't have to convert lambdas
+// and other callables to FunctionView<Blah(Blah, Blah)> explicitly. This is
+// safe because FunctionView is only a reference to the real callable.
+//
+// Example use:
+//
+// void SomeFunction(rtc::FunctionView<int(int)> index_transform);
+// ...
+// SomeFunction([](int i) { return 2 * i + 1; });
+//
+// Note: FunctionView is tiny (essentially just two pointers) and trivially
+// copyable, so it's probably cheaper to pass it by value than by const
+// reference.
+
+namespace rtc {
+
+template <typename T>
+class FunctionView; // Undefined.
+
+template <typename RetT, typename... ArgT>
+class FunctionView<RetT(ArgT...)> final {
+ public:
+ // Constructor for lambdas and other callables; it accepts every type of
+ // argument except those noted in its enable_if call.
+ template <
+ typename F,
+ typename std::enable_if<
+ // Not for function pointers; we have another constructor for that
+ // below.
+ !std::is_function<typename std::remove_pointer<
+ typename std::remove_reference<F>::type>::type>::value &&
+
+ // Not for nullptr; we have another constructor for that below.
+ !std::is_same<std::nullptr_t,
+ typename std::remove_cv<F>::type>::value &&
+
+ // Not for FunctionView objects; we have another constructor for that
+ // (the implicitly declared copy constructor).
+ !std::is_same<FunctionView,
+ typename std::remove_cv<typename std::remove_reference<
+ F>::type>::type>::value>::type* = nullptr>
+ FunctionView(F&& f)
+ : call_(CallVoidPtr<typename std::remove_reference<F>::type>) {
+ f_.void_ptr = &f;
+ }
+
+ // Constructor that accepts function pointers. If the argument is null, the
+ // result is an empty FunctionView.
+ template <
+ typename F,
+ typename std::enable_if<std::is_function<typename std::remove_pointer<
+ typename std::remove_reference<F>::type>::type>::value>::type* =
+ nullptr>
+ FunctionView(F&& f)
+ : call_(f ? CallFunPtr<typename std::remove_pointer<F>::type> : nullptr) {
+ f_.fun_ptr = reinterpret_cast<void (*)()>(f);
+ }
+
+ // Constructor that accepts nullptr. It creates an empty FunctionView.
+ template <typename F,
+ typename std::enable_if<std::is_same<
+ std::nullptr_t,
+ typename std::remove_cv<F>::type>::value>::type* = nullptr>
+ FunctionView(F&& f) : call_(nullptr) {}
+
+ // Default constructor. Creates an empty FunctionView.
+ FunctionView() : call_(nullptr) {}
+
+ RetT operator()(ArgT... args) const {
+ RTC_DCHECK(call_);
+ return call_(f_, std::forward<ArgT>(args)...);
+ }
+
+ // Returns true if we have a function, false if we don't (i.e., we're null).
+ explicit operator bool() const { return !!call_; }
+
+ private:
+ union VoidUnion {
+ void* void_ptr;
+ void (*fun_ptr)();
+ };
+
+ template <typename F>
+ static RetT CallVoidPtr(VoidUnion vu, ArgT... args) {
+ return (*static_cast<F*>(vu.void_ptr))(std::forward<ArgT>(args)...);
+ }
+ template <typename F>
+ static RetT CallFunPtr(VoidUnion vu, ArgT... args) {
+ return (reinterpret_cast<typename std::add_pointer<F>::type>(vu.fun_ptr))(
+ std::forward<ArgT>(args)...);
+ }
+
+ // A pointer to the callable thing, with type information erased. It's a
+ // union because we have to use separate types depending on if the callable
+ // thing is a function pointer or something else.
+ VoidUnion f_;
+
+ // Pointer to a dispatch function that knows the type of the callable thing
+ // that's stored in f_, and how to call it. A FunctionView object is empty
+ // (null) iff call_ is null.
+ RetT (*call_)(VoidUnion, ArgT...);
+};
+
+} // namespace rtc
+
+#endif // API_FUNCTION_VIEW_H_
diff --git a/third_party/libwebrtc/api/function_view_gn/moz.build b/third_party/libwebrtc/api/function_view_gn/moz.build
new file mode 100644
index 0000000000..59ebc4ae7a
--- /dev/null
+++ b/third_party/libwebrtc/api/function_view_gn/moz.build
@@ -0,0 +1,205 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("function_view_gn")
diff --git a/third_party/libwebrtc/api/function_view_unittest.cc b/third_party/libwebrtc/api/function_view_unittest.cc
new file mode 100644
index 0000000000..156ea5c22d
--- /dev/null
+++ b/third_party/libwebrtc/api/function_view_unittest.cc
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2016 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/function_view.h"
+
+#include <memory>
+#include <utility>
+
+#include "test/gtest.h"
+
+namespace rtc {
+
+namespace {
+
+int CallWith33(rtc::FunctionView<int(int)> fv) {
+ return fv ? fv(33) : -1;
+}
+
+int Add33(int x) {
+ return x + 33;
+}
+
+} // namespace
+
+// Test the main use case of FunctionView: implicitly converting a callable
+// argument.
+TEST(FunctionViewTest, ImplicitConversion) {
+ EXPECT_EQ(38, CallWith33([](int x) { return x + 5; }));
+ EXPECT_EQ(66, CallWith33(Add33));
+ EXPECT_EQ(-1, CallWith33(nullptr));
+}
+
+TEST(FunctionViewTest, IntIntLambdaWithoutState) {
+ auto f = [](int x) { return x + 1; };
+ EXPECT_EQ(18, f(17));
+ rtc::FunctionView<int(int)> fv(f);
+ EXPECT_TRUE(fv);
+ EXPECT_EQ(18, fv(17));
+}
+
+TEST(FunctionViewTest, IntVoidLambdaWithState) {
+ int x = 13;
+ auto f = [x]() mutable { return ++x; };
+ rtc::FunctionView<int()> fv(f);
+ EXPECT_TRUE(fv);
+ EXPECT_EQ(14, f());
+ EXPECT_EQ(15, fv());
+ EXPECT_EQ(16, f());
+ EXPECT_EQ(17, fv());
+}
+
+TEST(FunctionViewTest, IntIntFunction) {
+ rtc::FunctionView<int(int)> fv(Add33);
+ EXPECT_TRUE(fv);
+ EXPECT_EQ(50, fv(17));
+}
+
+TEST(FunctionViewTest, IntIntFunctionPointer) {
+ rtc::FunctionView<int(int)> fv(&Add33);
+ EXPECT_TRUE(fv);
+ EXPECT_EQ(50, fv(17));
+}
+
+TEST(FunctionViewTest, Null) {
+ // These two call constructors that statically construct null FunctionViews.
+ EXPECT_FALSE(rtc::FunctionView<int()>());
+ EXPECT_FALSE(rtc::FunctionView<int()>(nullptr));
+
+ // This calls the constructor for function pointers.
+ EXPECT_FALSE(rtc::FunctionView<int()>(reinterpret_cast<int (*)()>(0)));
+}
+
+// Ensure that FunctionView handles move-only arguments and return values.
+TEST(FunctionViewTest, UniquePtrPassthrough) {
+ auto f = [](std::unique_ptr<int> x) { return x; };
+ rtc::FunctionView<std::unique_ptr<int>(std::unique_ptr<int>)> fv(f);
+ std::unique_ptr<int> x(new int);
+ int* x_addr = x.get();
+ auto y = fv(std::move(x));
+ EXPECT_EQ(x_addr, y.get());
+}
+
+TEST(FunctionViewTest, CopyConstructor) {
+ auto f17 = [] { return 17; };
+ rtc::FunctionView<int()> fv1(f17);
+ rtc::FunctionView<int()> fv2(fv1);
+ EXPECT_EQ(17, fv1());
+ EXPECT_EQ(17, fv2());
+}
+
+TEST(FunctionViewTest, MoveConstructorIsCopy) {
+ auto f17 = [] { return 17; };
+ rtc::FunctionView<int()> fv1(f17);
+ rtc::FunctionView<int()> fv2(std::move(fv1)); // NOLINT
+ EXPECT_EQ(17, fv1());
+ EXPECT_EQ(17, fv2());
+}
+
+TEST(FunctionViewTest, CopyAssignment) {
+ auto f17 = [] { return 17; };
+ rtc::FunctionView<int()> fv1(f17);
+ auto f23 = [] { return 23; };
+ rtc::FunctionView<int()> fv2(f23);
+ EXPECT_EQ(17, fv1());
+ EXPECT_EQ(23, fv2());
+ fv2 = fv1;
+ EXPECT_EQ(17, fv1());
+ EXPECT_EQ(17, fv2());
+}
+
+TEST(FunctionViewTest, MoveAssignmentIsCopy) {
+ auto f17 = [] { return 17; };
+ rtc::FunctionView<int()> fv1(f17);
+ auto f23 = [] { return 23; };
+ rtc::FunctionView<int()> fv2(f23);
+ EXPECT_EQ(17, fv1());
+ EXPECT_EQ(23, fv2());
+ fv2 = std::move(fv1); // NOLINT
+ EXPECT_EQ(17, fv1());
+ EXPECT_EQ(17, fv2());
+}
+
+TEST(FunctionViewTest, Swap) {
+ auto f17 = [] { return 17; };
+ rtc::FunctionView<int()> fv1(f17);
+ auto f23 = [] { return 23; };
+ rtc::FunctionView<int()> fv2(f23);
+ EXPECT_EQ(17, fv1());
+ EXPECT_EQ(23, fv2());
+ using std::swap;
+ swap(fv1, fv2);
+ EXPECT_EQ(23, fv1());
+ EXPECT_EQ(17, fv2());
+}
+
+// Ensure that when you copy-construct a FunctionView, the new object points to
+// the same function as the old one (as opposed to the new object pointing to
+// the old one).
+TEST(FunctionViewTest, CopyConstructorChaining) {
+ auto f17 = [] { return 17; };
+ rtc::FunctionView<int()> fv1(f17);
+ rtc::FunctionView<int()> fv2(fv1);
+ EXPECT_EQ(17, fv1());
+ EXPECT_EQ(17, fv2());
+ auto f23 = [] { return 23; };
+ fv1 = f23;
+ EXPECT_EQ(23, fv1());
+ EXPECT_EQ(17, fv2());
+}
+
+// Ensure that when you assign one FunctionView to another, we actually make a
+// copy (as opposed to making the second FunctionView point to the first one).
+TEST(FunctionViewTest, CopyAssignmentChaining) {
+ auto f17 = [] { return 17; };
+ rtc::FunctionView<int()> fv1(f17);
+ rtc::FunctionView<int()> fv2;
+ EXPECT_TRUE(fv1);
+ EXPECT_EQ(17, fv1());
+ EXPECT_FALSE(fv2);
+ fv2 = fv1;
+ EXPECT_EQ(17, fv1());
+ EXPECT_EQ(17, fv2());
+ auto f23 = [] { return 23; };
+ fv1 = f23;
+ EXPECT_EQ(23, fv1());
+ EXPECT_EQ(17, fv2());
+}
+
+} // namespace rtc
diff --git a/third_party/libwebrtc/api/g3doc/index.md b/third_party/libwebrtc/api/g3doc/index.md
new file mode 100644
index 0000000000..b576514d5e
--- /dev/null
+++ b/third_party/libwebrtc/api/g3doc/index.md
@@ -0,0 +1,51 @@
+<!-- go/cmark -->
+<!--* freshness: {owner: 'hta' reviewed: '2021-04-12'} *-->
+
+# The WebRTC API
+
+The public API of the WebRTC library consists of the api/ directory and
+its subdirectories. No other files should be depended on by webrtc users.
+
+Before starting to code against the API, it is important to understand
+some basic concepts, such as:
+
+* Memory management, including webrtc's reference counted objects
+* [Thread management](threading_design.md)
+
+## Using WebRTC through the PeerConnection class
+
+The
+[PeerConnectionInterface](https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/peer_connection_interface.h?q=webrtc::PeerConnectionInterface)
+class is the recommended way to use the WebRTC library.
+
+It is closely modeled after the Javascript API documented in the [WebRTC
+specification](https://w3c.github.io/webrtc-pc/).
+
+PeerConnections are created using the [PeerConnectionFactoryInterface](https://source.chromium.org/search?q=webrtc::PeerConnectionFactoryInterface).
+
+There are two levels of customization available:
+
+* Pass a PeerConnectionFactoryDependencies object to the function that creates
+ a PeerConnectionFactory. This object defines factories for a lot of internal
+ objects inside the PeerConnection, so that users can override them.
+ All PeerConnections using this interface will have the same options.
+* Pass a PeerConnectionInterface::RTCConfiguration object to the
+ CreatePeerConnectionOrError() function on the
+ PeerConnectionFactoryInterface. These customizations will apply only to a
+ single PeerConnection.
+
+Most functions on the PeerConnection interface are asynchronous, and take a
+callback that is executed when the function is finished. The callbacks are
+mostly called on the thread that is passed as the "signaling thread" field of
+the PeerConnectionFactoryDependencies, or the thread that called
+PeerConnectionFactory::CreatePeerConnectionOrError() if no thread is given.
+
+See each class' module documentation for details.
+
+## Using WebRTC components without the PeerConnection class
+
+This needs to be done carefully, and in consultation with the WebRTC team. There
+are non-obvious dependencies between many of the components.
+
+
+
diff --git a/third_party/libwebrtc/api/g3doc/threading_design.md b/third_party/libwebrtc/api/g3doc/threading_design.md
new file mode 100644
index 0000000000..8023b5eda0
--- /dev/null
+++ b/third_party/libwebrtc/api/g3doc/threading_design.md
@@ -0,0 +1,74 @@
+<!-- go/cmark -->
+<!--* freshness: {owner: 'hta' reviewed: '2021-04-12'} *-->
+
+# API Threading Design considerations
+
+The header files in this directory form the API to the WebRTC library
+that is intended for client applications' use.
+
+This API is designed to be used on top of a multithreaded runtime.
+
+The public API functions are designed to be called from a single thread*
+(the "client thread"), and can do internal dispatching to the thread
+where activity needs to happen. Those threads can be passed in by the
+client, typically as arguments to factory constructors, or they can be
+created by the library if factory constructors that don't take threads
+are used.
+
+Many of the functions are designed to be used in an asynchronous manner,
+where a function is called to initiate an activity, and a callback will
+be called when the activity is completed, or a handler function will
+be called on an observer object when interesting events happen.
+
+Note: Often, even functions that look like simple functions (such as
+information query functions) will need to jump between threads to perform
+their function - which means that things may happen on other threads
+between calls; writing "increment(x); increment(x)" is not a safe
+way to increment X by exactly two, since the increment function may have
+jumped to another thread that already had a queue of things to handle,
+causing large amounts of other activity to have intervened between
+the two calls.
+
+(*) The term "thread" is used here to denote any construct that guarantees
+sequential execution - other names for such constructs are task runners
+and sequenced task queues.
+
+## Client threads and callbacks
+
+At the moment, the API does not give any guarantee on which thread* the
+callbacks and events are called on. So it's best to write all callback
+and event handlers like this (pseudocode):
+```
+void ObserverClass::Handler(event) {
+ if (!called_on_client_thread()) {
+ dispatch_to_client_thread(bind(handler(event)));
+ return;
+ }
+ // Process event, we're now on the right thread
+}
+```
+In the future, the implementation may change to always call the callbacks
+and event handlers on the client thread.
+
+## Implementation considerations
+
+The C++ classes that are part of the public API are also used to derive
+classes that form part of the implementation.
+
+This should not directly concern users of the API, but may matter if one
+wants to look at how the WebRTC library is implemented, or for legacy code
+that directly accesses internal APIs.
+
+Many APIs are defined in terms of a "proxy object", which will do a blocking
+dispatch of the function to another thread, and an "implementation object"
+which will do the actual
+work, but can only be created, invoked and destroyed on its "home thread".
+
+Usually, the classes are named "xxxInterface" (in api/), "xxxProxy" and
+"xxx" (not in api/). WebRTC users should only need to depend on the files
+in api/. In many cases, the "xxxProxy" and "xxx" classes are subclasses
+of "xxxInterface", but this property is an implementation feature only,
+and should not be relied upon.
+
+The threading properties of these internal APIs are NOT documented in
+this note, and need to be understood by inspecting those classes.
diff --git a/third_party/libwebrtc/api/ice_transport_factory.cc b/third_party/libwebrtc/api/ice_transport_factory.cc
new file mode 100644
index 0000000000..e88ac183fa
--- /dev/null
+++ b/third_party/libwebrtc/api/ice_transport_factory.cc
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/ice_transport_factory.h"
+
+#include <memory>
+#include <utility>
+
+#include "api/make_ref_counted.h"
+#include "p2p/base/ice_transport_internal.h"
+#include "p2p/base/p2p_constants.h"
+#include "p2p/base/p2p_transport_channel.h"
+#include "p2p/base/port_allocator.h"
+#include "rtc_base/thread.h"
+
+namespace webrtc {
+
+namespace {
+
+// This implementation of IceTransportInterface is used in cases where
+// the only reference to the P2PTransport will be through this class.
+// It must be constructed, accessed and destroyed on the signaling thread.
+class IceTransportWithTransportChannel : public IceTransportInterface {
+ public:
+ IceTransportWithTransportChannel(
+ std::unique_ptr<cricket::IceTransportInternal> internal)
+ : internal_(std::move(internal)) {}
+
+ ~IceTransportWithTransportChannel() override {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
+ }
+
+ cricket::IceTransportInternal* internal() override {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
+ return internal_.get();
+ }
+
+ private:
+ const SequenceChecker thread_checker_{};
+ const std::unique_ptr<cricket::IceTransportInternal> internal_
+ RTC_GUARDED_BY(thread_checker_);
+};
+
+} // namespace
+
+rtc::scoped_refptr<IceTransportInterface> CreateIceTransport(
+ cricket::PortAllocator* port_allocator) {
+ IceTransportInit init;
+ init.set_port_allocator(port_allocator);
+ return CreateIceTransport(std::move(init));
+}
+
+rtc::scoped_refptr<IceTransportInterface> CreateIceTransport(
+ IceTransportInit init) {
+ return rtc::make_ref_counted<IceTransportWithTransportChannel>(
+ cricket::P2PTransportChannel::Create(
+ "", cricket::ICE_CANDIDATE_COMPONENT_RTP, std::move(init)));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/ice_transport_factory.h b/third_party/libwebrtc/api/ice_transport_factory.h
new file mode 100644
index 0000000000..2268ea5e12
--- /dev/null
+++ b/third_party/libwebrtc/api/ice_transport_factory.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_ICE_TRANSPORT_FACTORY_H_
+#define API_ICE_TRANSPORT_FACTORY_H_
+
+#include "api/ice_transport_interface.h"
+#include "api/scoped_refptr.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace cricket {
+class PortAllocator;
+} // namespace cricket
+
+namespace webrtc {
+
+// Static factory for an IceTransport object that can be created
+// without using a webrtc::PeerConnection.
+// The returned object must be accessed and destroyed on the thread that
+// created it.
+// The PortAllocator must outlive the created IceTransportInterface object.
+// TODO(steveanton): Remove in favor of the overload that takes
+// IceTransportInit.
+RTC_EXPORT rtc::scoped_refptr<IceTransportInterface> CreateIceTransport(
+ cricket::PortAllocator* port_allocator);
+
+// Static factory for an IceTransport object that can be created
+// without using a webrtc::PeerConnection.
+// The returned object must be accessed and destroyed on the thread that
+// created it.
+// `init.port_allocator()` is required and must outlive the created
+// IceTransportInterface object.
+// `init.async_resolver_factory()` and `init.event_log()` are optional, but if
+// provided must outlive the created IceTransportInterface object.
+RTC_EXPORT rtc::scoped_refptr<IceTransportInterface> CreateIceTransport(
+ IceTransportInit);
+
+} // namespace webrtc
+
+#endif // API_ICE_TRANSPORT_FACTORY_H_
diff --git a/third_party/libwebrtc/api/ice_transport_interface.h b/third_party/libwebrtc/api/ice_transport_interface.h
new file mode 100644
index 0000000000..2ec41aaa69
--- /dev/null
+++ b/third_party/libwebrtc/api/ice_transport_interface.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_ICE_TRANSPORT_INTERFACE_H_
+#define API_ICE_TRANSPORT_INTERFACE_H_
+
+#include <string>
+
+#include "api/async_dns_resolver.h"
+#include "api/async_resolver_factory.h"
+#include "api/rtc_error.h"
+#include "api/rtc_event_log/rtc_event_log.h"
+#include "api/scoped_refptr.h"
+#include "rtc_base/ref_count.h"
+
+namespace cricket {
+class IceTransportInternal;
+class PortAllocator;
+class IceControllerFactoryInterface;
+class ActiveIceControllerFactoryInterface;
+} // namespace cricket
+
+namespace webrtc {
+class FieldTrialsView;
+
+// An ICE transport, as represented to the outside world.
+// This object is refcounted, and is therefore alive until the
+// last holder has released it.
+class IceTransportInterface : public rtc::RefCountInterface {
+ public:
+ // Accessor for the internal representation of an ICE transport.
+ // The returned object can only be safely used on the signalling thread.
+ // TODO(crbug.com/907849): Add API calls for the functions that have to
+ // be exposed to clients, and stop allowing access to the
+ // cricket::IceTransportInternal API.
+ virtual cricket::IceTransportInternal* internal() = 0;
+};
+
+struct IceTransportInit final {
+ public:
+ IceTransportInit() = default;
+ IceTransportInit(const IceTransportInit&) = delete;
+ IceTransportInit(IceTransportInit&&) = default;
+ IceTransportInit& operator=(const IceTransportInit&) = delete;
+ IceTransportInit& operator=(IceTransportInit&&) = default;
+
+ cricket::PortAllocator* port_allocator() { return port_allocator_; }
+ void set_port_allocator(cricket::PortAllocator* port_allocator) {
+ port_allocator_ = port_allocator;
+ }
+
+ AsyncDnsResolverFactoryInterface* async_dns_resolver_factory() {
+ return async_dns_resolver_factory_;
+ }
+ void set_async_dns_resolver_factory(
+ AsyncDnsResolverFactoryInterface* async_dns_resolver_factory) {
+ RTC_DCHECK(!async_resolver_factory_);
+ async_dns_resolver_factory_ = async_dns_resolver_factory;
+ }
+ AsyncResolverFactory* async_resolver_factory() {
+ return async_resolver_factory_;
+ }
+ ABSL_DEPRECATED("bugs.webrtc.org/12598")
+ void set_async_resolver_factory(
+ AsyncResolverFactory* async_resolver_factory) {
+ RTC_DCHECK(!async_dns_resolver_factory_);
+ async_resolver_factory_ = async_resolver_factory;
+ }
+
+ RtcEventLog* event_log() { return event_log_; }
+ void set_event_log(RtcEventLog* event_log) { event_log_ = event_log; }
+
+ void set_ice_controller_factory(
+ cricket::IceControllerFactoryInterface* ice_controller_factory) {
+ ice_controller_factory_ = ice_controller_factory;
+ }
+ cricket::IceControllerFactoryInterface* ice_controller_factory() {
+ return ice_controller_factory_;
+ }
+
+ // An active ICE controller actively manages the connection used by an ICE
+ // transport, in contrast with a legacy ICE controller that only picks the
+ // best connection to use or ping, and lets the transport decide when and
+ // whether to switch.
+ //
+ // Which ICE controller is used is determined based on the field trial
+ // "WebRTC-UseActiveIceController" as follows:
+ //
+ // 1. If the field trial is not enabled
+ // a. The legacy ICE controller factory is used if one is supplied.
+ // b. If not, a default ICE controller (BasicIceController) is
+ // constructed and used.
+ //
+ // 2. If the field trial is enabled
+ // a. If an active ICE controller factory is supplied, it is used and
+ // the legacy ICE controller factory is not used.
+ // b. If not, a default active ICE controller is used, wrapping over the
+ // supplied or the default legacy ICE controller.
+ void set_active_ice_controller_factory(
+ cricket::ActiveIceControllerFactoryInterface*
+ active_ice_controller_factory) {
+ active_ice_controller_factory_ = active_ice_controller_factory;
+ }
+ cricket::ActiveIceControllerFactoryInterface*
+ active_ice_controller_factory() {
+ return active_ice_controller_factory_;
+ }
+
+ const FieldTrialsView* field_trials() { return field_trials_; }
+ void set_field_trials(const FieldTrialsView* field_trials) {
+ field_trials_ = field_trials;
+ }
+
+ private:
+ cricket::PortAllocator* port_allocator_ = nullptr;
+ AsyncDnsResolverFactoryInterface* async_dns_resolver_factory_ = nullptr;
+ // For backwards compatibility. Only one resolver factory can be set.
+ AsyncResolverFactory* async_resolver_factory_ = nullptr;
+ RtcEventLog* event_log_ = nullptr;
+ cricket::IceControllerFactoryInterface* ice_controller_factory_ = nullptr;
+ cricket::ActiveIceControllerFactoryInterface* active_ice_controller_factory_ =
+ nullptr;
+ const FieldTrialsView* field_trials_ = nullptr;
+ // TODO(https://crbug.com/webrtc/12657): Redesign to have const members.
+};
+
+// TODO(qingsi): The factory interface is defined in this file instead of its
+// namesake file ice_transport_factory.h to avoid the extra dependency on p2p/
+// introduced there by the p2p/-dependent factory methods. Move the factory
+// methods to a different file or rename it.
+class IceTransportFactory {
+ public:
+ virtual ~IceTransportFactory() = default;
+ // As a refcounted object, the returned ICE transport may outlive the host
+ // construct into which its reference is given, e.g. a peer connection. As a
+ // result, the returned ICE transport should not hold references to any object
+ // that the transport does not own and that has a lifetime bound to the host
+ // construct. Also, assumptions on the thread safety of the returned transport
+ // should be clarified by implementations. For example, a peer connection
+ // requires the returned transport to be constructed and destroyed on the
+ // network thread and an ICE transport factory that intends to work with a
+ // peer connection should offer transports compatible with these assumptions.
+ virtual rtc::scoped_refptr<IceTransportInterface> CreateIceTransport(
+ const std::string& transport_name,
+ int component,
+ IceTransportInit init) = 0;
+};
+
+} // namespace webrtc
+#endif // API_ICE_TRANSPORT_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/jsep.cc b/third_party/libwebrtc/api/jsep.cc
new file mode 100644
index 0000000000..5fdc8905c7
--- /dev/null
+++ b/third_party/libwebrtc/api/jsep.cc
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/jsep.h"
+
+namespace webrtc {
+
+std::string IceCandidateInterface::server_url() const {
+ return "";
+}
+
+size_t SessionDescriptionInterface::RemoveCandidates(
+ const std::vector<cricket::Candidate>& candidates) {
+ return 0;
+}
+
+const char SessionDescriptionInterface::kOffer[] = "offer";
+const char SessionDescriptionInterface::kPrAnswer[] = "pranswer";
+const char SessionDescriptionInterface::kAnswer[] = "answer";
+const char SessionDescriptionInterface::kRollback[] = "rollback";
+
+const char* SdpTypeToString(SdpType type) {
+ switch (type) {
+ case SdpType::kOffer:
+ return SessionDescriptionInterface::kOffer;
+ case SdpType::kPrAnswer:
+ return SessionDescriptionInterface::kPrAnswer;
+ case SdpType::kAnswer:
+ return SessionDescriptionInterface::kAnswer;
+ case SdpType::kRollback:
+ return SessionDescriptionInterface::kRollback;
+ }
+ return "";
+}
+
+absl::optional<SdpType> SdpTypeFromString(const std::string& type_str) {
+ if (type_str == SessionDescriptionInterface::kOffer) {
+ return SdpType::kOffer;
+ } else if (type_str == SessionDescriptionInterface::kPrAnswer) {
+ return SdpType::kPrAnswer;
+ } else if (type_str == SessionDescriptionInterface::kAnswer) {
+ return SdpType::kAnswer;
+ } else if (type_str == SessionDescriptionInterface::kRollback) {
+ return SdpType::kRollback;
+ } else {
+ return absl::nullopt;
+ }
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/jsep.h b/third_party/libwebrtc/api/jsep.h
new file mode 100644
index 0000000000..d2aa57c784
--- /dev/null
+++ b/third_party/libwebrtc/api/jsep.h
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This file contains declarations of interfaces that wrap SDP-related
+// constructs; session descriptions and ICE candidates. The inner "cricket::"
+// objects shouldn't be accessed directly; the intention is that an application
+// using the PeerConnection API only creates these objects from strings, and
+// them passes them into the PeerConnection.
+//
+// Though in the future, we're planning to provide an SDP parsing API, with a
+// structure more friendly than cricket::SessionDescription.
+
+#ifndef API_JSEP_H_
+#define API_JSEP_H_
+
+#include <stddef.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/rtc_error.h"
+#include "rtc_base/ref_count.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace cricket {
+class Candidate;
+class SessionDescription;
+} // namespace cricket
+
+namespace webrtc {
+
+struct SdpParseError {
+ public:
+ // The sdp line that causes the error.
+ std::string line;
+ // Explains the error.
+ std::string description;
+};
+
+// Class representation of an ICE candidate.
+//
+// An instance of this interface is supposed to be owned by one class at
+// a time and is therefore not expected to be thread safe.
+//
+// An instance can be created by CreateIceCandidate.
+class RTC_EXPORT IceCandidateInterface {
+ public:
+ virtual ~IceCandidateInterface() {}
+ // If present, this is the value of the "a=mid" attribute of the candidate's
+ // m= section in SDP, which identifies the m= section.
+ virtual std::string sdp_mid() const = 0;
+ // This indicates the index (starting at zero) of m= section this candidate
+ // is associated with. Needed when an endpoint doesn't support MIDs.
+ virtual int sdp_mline_index() const = 0;
+ // Only for use internally.
+ virtual const cricket::Candidate& candidate() const = 0;
+ // The URL of the ICE server which this candidate was gathered from.
+ // TODO(zhihuang): Remove the default implementation once the subclasses
+ // implement this method.
+ virtual std::string server_url() const;
+ // Creates a SDP-ized form of this candidate.
+ virtual bool ToString(std::string* out) const = 0;
+};
+
+// Creates a IceCandidateInterface based on SDP string.
+// Returns null if the sdp string can't be parsed.
+// `error` may be null.
+RTC_EXPORT IceCandidateInterface* CreateIceCandidate(const std::string& sdp_mid,
+ int sdp_mline_index,
+ const std::string& sdp,
+ SdpParseError* error);
+
+// Creates an IceCandidateInterface based on a parsed candidate structure.
+RTC_EXPORT std::unique_ptr<IceCandidateInterface> CreateIceCandidate(
+ const std::string& sdp_mid,
+ int sdp_mline_index,
+ const cricket::Candidate& candidate);
+
+// This class represents a collection of candidates for a specific m= section.
+// Used in SessionDescriptionInterface.
+class IceCandidateCollection {
+ public:
+ virtual ~IceCandidateCollection() {}
+ virtual size_t count() const = 0;
+ // Returns true if an equivalent `candidate` exist in the collection.
+ virtual bool HasCandidate(const IceCandidateInterface* candidate) const = 0;
+ virtual const IceCandidateInterface* at(size_t index) const = 0;
+};
+
+// Enum that describes the type of the SessionDescriptionInterface.
+// Corresponds to RTCSdpType in the WebRTC specification.
+// https://w3c.github.io/webrtc-pc/#dom-rtcsdptype
+enum class SdpType {
+ kOffer, // Description must be treated as an SDP offer.
+ kPrAnswer, // Description must be treated as an SDP answer, but not a final
+ // answer.
+ kAnswer, // Description must be treated as an SDP final answer, and the
+ // offer-answer exchange must be considered complete after
+ // receiving this.
+ kRollback // Resets any pending offers and sets signaling state back to
+ // stable.
+};
+
+// Returns the string form of the given SDP type. String forms are defined in
+// SessionDescriptionInterface.
+RTC_EXPORT const char* SdpTypeToString(SdpType type);
+
+// Returns the SdpType from its string form. The string form can be one of the
+// constants defined in SessionDescriptionInterface. Passing in any other string
+// results in nullopt.
+absl::optional<SdpType> SdpTypeFromString(const std::string& type_str);
+
+// Class representation of an SDP session description.
+//
+// An instance of this interface is supposed to be owned by one class at a time
+// and is therefore not expected to be thread safe.
+//
+// An instance can be created by CreateSessionDescription.
+class RTC_EXPORT SessionDescriptionInterface {
+ public:
+ // String representations of the supported SDP types.
+ static const char kOffer[];
+ static const char kPrAnswer[];
+ static const char kAnswer[];
+ static const char kRollback[];
+
+ virtual ~SessionDescriptionInterface() {}
+
+ // Create a new SessionDescriptionInterface object
+ // with the same values as the old object.
+ // TODO(bugs.webrtc.org:12215): Remove default implementation
+ virtual std::unique_ptr<SessionDescriptionInterface> Clone() const {
+ return nullptr;
+ }
+
+ // Only for use internally.
+ virtual cricket::SessionDescription* description() = 0;
+ virtual const cricket::SessionDescription* description() const = 0;
+
+ // Get the session id and session version, which are defined based on
+ // RFC 4566 for the SDP o= line.
+ virtual std::string session_id() const = 0;
+ virtual std::string session_version() const = 0;
+
+ // Returns the type of this session description as an SdpType. Descriptions of
+ // the various types are found in the SdpType documentation.
+ // TODO(steveanton): Remove default implementation once Chromium has been
+ // updated.
+ virtual SdpType GetType() const;
+
+ // kOffer/kPrAnswer/kAnswer
+ // TODO(steveanton): Remove this in favor of `GetType` that returns SdpType.
+ virtual std::string type() const = 0;
+
+ // Adds the specified candidate to the description.
+ //
+ // Ownership is not transferred.
+ //
+ // Returns false if the session description does not have a media section
+ // that corresponds to `candidate.sdp_mid()` or
+ // `candidate.sdp_mline_index()`.
+ virtual bool AddCandidate(const IceCandidateInterface* candidate) = 0;
+
+ // Removes the candidates from the description, if found.
+ //
+ // Returns the number of candidates removed.
+ virtual size_t RemoveCandidates(
+ const std::vector<cricket::Candidate>& candidates);
+
+ // Returns the number of m= sections in the session description.
+ virtual size_t number_of_mediasections() const = 0;
+
+ // Returns a collection of all candidates that belong to a certain m=
+ // section.
+ virtual const IceCandidateCollection* candidates(
+ size_t mediasection_index) const = 0;
+
+ // Serializes the description to SDP.
+ virtual bool ToString(std::string* out) const = 0;
+};
+
+// Creates a SessionDescriptionInterface based on the SDP string and the type.
+// Returns null if the sdp string can't be parsed or the type is unsupported.
+// `error` may be null.
+// TODO(steveanton): This function is deprecated. Please use the functions below
+// which take an SdpType enum instead. Remove this once it is no longer used.
+RTC_EXPORT SessionDescriptionInterface* CreateSessionDescription(
+ const std::string& type,
+ const std::string& sdp,
+ SdpParseError* error);
+
+// Creates a SessionDescriptionInterface based on the SDP string and the type.
+// Returns null if the SDP string cannot be parsed.
+// If using the signature with `error_out`, details of the parsing error may be
+// written to `error_out` if it is not null.
+RTC_EXPORT std::unique_ptr<SessionDescriptionInterface>
+CreateSessionDescription(SdpType type, const std::string& sdp);
+RTC_EXPORT std::unique_ptr<SessionDescriptionInterface>
+CreateSessionDescription(SdpType type,
+ const std::string& sdp,
+ SdpParseError* error_out);
+
+// Creates a SessionDescriptionInterface based on a parsed SDP structure and the
+// given type, ID and version.
+std::unique_ptr<SessionDescriptionInterface> CreateSessionDescription(
+ SdpType type,
+ const std::string& session_id,
+ const std::string& session_version,
+ std::unique_ptr<cricket::SessionDescription> description);
+
+// CreateOffer and CreateAnswer callback interface.
+class RTC_EXPORT CreateSessionDescriptionObserver
+ : public rtc::RefCountInterface {
+ public:
+ // This callback transfers the ownership of the `desc`.
+ // TODO(deadbeef): Make this take an std::unique_ptr<> to avoid confusion
+ // around ownership.
+ virtual void OnSuccess(SessionDescriptionInterface* desc) = 0;
+ // The OnFailure callback takes an RTCError, which consists of an
+ // error code and a string.
+ // RTCError is non-copyable, so it must be passed using std::move.
+ // Earlier versions of the API used a string argument. This version
+ // is removed; its functionality was the same as passing
+ // error.message.
+ virtual void OnFailure(RTCError error) = 0;
+
+ protected:
+ ~CreateSessionDescriptionObserver() override = default;
+};
+
+// SetLocalDescription and SetRemoteDescription callback interface.
+class RTC_EXPORT SetSessionDescriptionObserver : public rtc::RefCountInterface {
+ public:
+ virtual void OnSuccess() = 0;
+ // See description in CreateSessionDescriptionObserver for OnFailure.
+ virtual void OnFailure(RTCError error) = 0;
+
+ protected:
+ ~SetSessionDescriptionObserver() override = default;
+};
+
+} // namespace webrtc
+
+#endif // API_JSEP_H_
diff --git a/third_party/libwebrtc/api/jsep_ice_candidate.cc b/third_party/libwebrtc/api/jsep_ice_candidate.cc
new file mode 100644
index 0000000000..e18e6e28af
--- /dev/null
+++ b/third_party/libwebrtc/api/jsep_ice_candidate.cc
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/jsep_ice_candidate.h"
+
+#include <memory>
+#include <utility>
+
+#include "absl/algorithm/container.h"
+#include "absl/memory/memory.h"
+
+namespace webrtc {
+
+std::string JsepIceCandidate::sdp_mid() const {
+ return sdp_mid_;
+}
+
+int JsepIceCandidate::sdp_mline_index() const {
+ return sdp_mline_index_;
+}
+
+const cricket::Candidate& JsepIceCandidate::candidate() const {
+ return candidate_;
+}
+
+std::string JsepIceCandidate::server_url() const {
+ return candidate_.url();
+}
+
+JsepCandidateCollection::JsepCandidateCollection() = default;
+
+JsepCandidateCollection::JsepCandidateCollection(JsepCandidateCollection&& o)
+ : candidates_(std::move(o.candidates_)) {}
+
+size_t JsepCandidateCollection::count() const {
+ return candidates_.size();
+}
+
+void JsepCandidateCollection::add(JsepIceCandidate* candidate) {
+ candidates_.push_back(absl::WrapUnique(candidate));
+}
+
+const IceCandidateInterface* JsepCandidateCollection::at(size_t index) const {
+ return candidates_[index].get();
+}
+
+bool JsepCandidateCollection::HasCandidate(
+ const IceCandidateInterface* candidate) const {
+ return absl::c_any_of(
+ candidates_, [&](const std::unique_ptr<JsepIceCandidate>& entry) {
+ return entry->sdp_mid() == candidate->sdp_mid() &&
+ entry->sdp_mline_index() == candidate->sdp_mline_index() &&
+ entry->candidate().IsEquivalent(candidate->candidate());
+ });
+}
+
+size_t JsepCandidateCollection::remove(const cricket::Candidate& candidate) {
+ auto iter = absl::c_find_if(
+ candidates_, [&](const std::unique_ptr<JsepIceCandidate>& c) {
+ return candidate.MatchesForRemoval(c->candidate());
+ });
+ if (iter != candidates_.end()) {
+ candidates_.erase(iter);
+ return 1;
+ }
+ return 0;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/jsep_ice_candidate.h b/third_party/libwebrtc/api/jsep_ice_candidate.h
new file mode 100644
index 0000000000..8f47a102e7
--- /dev/null
+++ b/third_party/libwebrtc/api/jsep_ice_candidate.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// TODO(deadbeef): Move this out of api/; it's an implementation detail and
+// shouldn't be used externally.
+
+#ifndef API_JSEP_ICE_CANDIDATE_H_
+#define API_JSEP_ICE_CANDIDATE_H_
+
+#include <stddef.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "api/candidate.h"
+#include "api/jsep.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Implementation of IceCandidateInterface.
+class RTC_EXPORT JsepIceCandidate : public IceCandidateInterface {
+ public:
+ JsepIceCandidate(const std::string& sdp_mid, int sdp_mline_index);
+ JsepIceCandidate(const std::string& sdp_mid,
+ int sdp_mline_index,
+ const cricket::Candidate& candidate);
+ JsepIceCandidate(const JsepIceCandidate&) = delete;
+ JsepIceCandidate& operator=(const JsepIceCandidate&) = delete;
+ ~JsepIceCandidate() override;
+ // `err` may be null.
+ bool Initialize(const std::string& sdp, SdpParseError* err);
+ void SetCandidate(const cricket::Candidate& candidate) {
+ candidate_ = candidate;
+ }
+
+ std::string sdp_mid() const override;
+ int sdp_mline_index() const override;
+ const cricket::Candidate& candidate() const override;
+
+ std::string server_url() const override;
+
+ bool ToString(std::string* out) const override;
+
+ private:
+ std::string sdp_mid_;
+ int sdp_mline_index_;
+ cricket::Candidate candidate_;
+};
+
+// Implementation of IceCandidateCollection which stores JsepIceCandidates.
+class JsepCandidateCollection : public IceCandidateCollection {
+ public:
+ JsepCandidateCollection();
+ // Move constructor is defined so that a vector of JsepCandidateCollections
+ // can be resized.
+ JsepCandidateCollection(JsepCandidateCollection&& o);
+
+ JsepCandidateCollection(const JsepCandidateCollection&) = delete;
+ JsepCandidateCollection& operator=(const JsepCandidateCollection&) = delete;
+
+ // Returns a copy of the candidate collection.
+ JsepCandidateCollection Clone() const;
+ size_t count() const override;
+ bool HasCandidate(const IceCandidateInterface* candidate) const override;
+ // Adds and takes ownership of the JsepIceCandidate.
+ // TODO(deadbeef): Make this use an std::unique_ptr<>, so ownership logic is
+ // more clear.
+ virtual void add(JsepIceCandidate* candidate);
+ const IceCandidateInterface* at(size_t index) const override;
+ // Removes the candidate that has a matching address and protocol.
+ //
+ // Returns the number of candidates that were removed.
+ size_t remove(const cricket::Candidate& candidate);
+
+ private:
+ std::vector<std::unique_ptr<JsepIceCandidate>> candidates_;
+};
+
+} // namespace webrtc
+
+#endif // API_JSEP_ICE_CANDIDATE_H_
diff --git a/third_party/libwebrtc/api/jsep_session_description.h b/third_party/libwebrtc/api/jsep_session_description.h
new file mode 100644
index 0000000000..0b65734ea9
--- /dev/null
+++ b/third_party/libwebrtc/api/jsep_session_description.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// TODO(deadbeef): Move this out of api/; it's an implementation detail and
+// shouldn't be used externally.
+
+#ifndef API_JSEP_SESSION_DESCRIPTION_H_
+#define API_JSEP_SESSION_DESCRIPTION_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/candidate.h"
+#include "api/jsep.h"
+#include "api/jsep_ice_candidate.h"
+
+namespace cricket {
+class SessionDescription;
+}
+
+namespace webrtc {
+
+// Implementation of SessionDescriptionInterface.
+class JsepSessionDescription : public SessionDescriptionInterface {
+ public:
+ explicit JsepSessionDescription(SdpType type);
+ // TODO(steveanton): Remove this once callers have switched to SdpType.
+ explicit JsepSessionDescription(const std::string& type);
+ JsepSessionDescription(
+ SdpType type,
+ std::unique_ptr<cricket::SessionDescription> description,
+ absl::string_view session_id,
+ absl::string_view session_version);
+ virtual ~JsepSessionDescription();
+
+ JsepSessionDescription(const JsepSessionDescription&) = delete;
+ JsepSessionDescription& operator=(const JsepSessionDescription&) = delete;
+
+ // Takes ownership of `description`.
+ bool Initialize(std::unique_ptr<cricket::SessionDescription> description,
+ const std::string& session_id,
+ const std::string& session_version);
+
+ virtual std::unique_ptr<SessionDescriptionInterface> Clone() const;
+
+ virtual cricket::SessionDescription* description() {
+ return description_.get();
+ }
+ virtual const cricket::SessionDescription* description() const {
+ return description_.get();
+ }
+ virtual std::string session_id() const { return session_id_; }
+ virtual std::string session_version() const { return session_version_; }
+ virtual SdpType GetType() const { return type_; }
+ virtual std::string type() const { return SdpTypeToString(type_); }
+ // Allows changing the type. Used for testing.
+ virtual bool AddCandidate(const IceCandidateInterface* candidate);
+ virtual size_t RemoveCandidates(
+ const std::vector<cricket::Candidate>& candidates);
+ virtual size_t number_of_mediasections() const;
+ virtual const IceCandidateCollection* candidates(
+ size_t mediasection_index) const;
+ virtual bool ToString(std::string* out) const;
+
+ static const int kDefaultVideoCodecId;
+ static const char kDefaultVideoCodecName[];
+
+ private:
+ std::unique_ptr<cricket::SessionDescription> description_;
+ std::string session_id_;
+ std::string session_version_;
+ SdpType type_;
+ std::vector<JsepCandidateCollection> candidate_collection_;
+
+ bool GetMediasectionIndex(const IceCandidateInterface* candidate,
+ size_t* index);
+ int GetMediasectionIndex(const cricket::Candidate& candidate);
+};
+
+} // namespace webrtc
+
+#endif // API_JSEP_SESSION_DESCRIPTION_H_
diff --git a/third_party/libwebrtc/api/legacy_stats_types.cc b/third_party/libwebrtc/api/legacy_stats_types.cc
new file mode 100644
index 0000000000..e3b2144edd
--- /dev/null
+++ b/third_party/libwebrtc/api/legacy_stats_types.cc
@@ -0,0 +1,845 @@
+/*
+ * Copyright 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/legacy_stats_types.h"
+
+#include <string.h>
+
+#include "absl/algorithm/container.h"
+#include "api/make_ref_counted.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/string_encode.h"
+
+// TODO(tommi): Could we have a static map of value name -> expected type
+// and use this to RTC_DCHECK on correct usage (somewhat strongly typed values)?
+// Alternatively, we could define the names+type in a separate document and
+// generate strongly typed inline C++ code that forces the correct type to be
+// used for a given name at compile time.
+
+namespace webrtc {
+namespace {
+
+// The id of StatsReport of type kStatsReportTypeBwe.
+const char kStatsReportVideoBweId[] = "bweforvideo";
+
+// NOTE: These names need to be consistent with an external
+// specification (W3C Stats Identifiers).
+const char* InternalTypeToString(StatsReport::StatsType type) {
+ switch (type) {
+ case StatsReport::kStatsReportTypeSession:
+ return "googLibjingleSession";
+ case StatsReport::kStatsReportTypeBwe:
+ return "VideoBwe";
+ case StatsReport::kStatsReportTypeRemoteSsrc:
+ return "remoteSsrc";
+ case StatsReport::kStatsReportTypeSsrc:
+ return "ssrc";
+ case StatsReport::kStatsReportTypeTrack:
+ return "googTrack";
+ case StatsReport::kStatsReportTypeIceLocalCandidate:
+ return "localcandidate";
+ case StatsReport::kStatsReportTypeIceRemoteCandidate:
+ return "remotecandidate";
+ case StatsReport::kStatsReportTypeTransport:
+ return "transport";
+ case StatsReport::kStatsReportTypeComponent:
+ return "googComponent";
+ case StatsReport::kStatsReportTypeCandidatePair:
+ return "googCandidatePair";
+ case StatsReport::kStatsReportTypeCertificate:
+ return "googCertificate";
+ case StatsReport::kStatsReportTypeDataChannel:
+ return "datachannel";
+ }
+ RTC_DCHECK_NOTREACHED();
+ return nullptr;
+}
+
+class BandwidthEstimationId : public StatsReport::IdBase {
+ public:
+ BandwidthEstimationId()
+ : StatsReport::IdBase(StatsReport::kStatsReportTypeBwe) {}
+ std::string ToString() const override { return kStatsReportVideoBweId; }
+};
+
+class TypedId : public StatsReport::IdBase {
+ public:
+ TypedId(StatsReport::StatsType type, const std::string& id)
+ : StatsReport::IdBase(type), id_(id) {}
+
+ bool Equals(const IdBase& other) const override {
+ return IdBase::Equals(other) &&
+ static_cast<const TypedId&>(other).id_ == id_;
+ }
+
+ std::string ToString() const override {
+ return std::string(InternalTypeToString(type_)) + kSeparator + id_;
+ }
+
+ protected:
+ const std::string id_;
+};
+
+class TypedIntId : public StatsReport::IdBase {
+ public:
+ TypedIntId(StatsReport::StatsType type, int id)
+ : StatsReport::IdBase(type), id_(id) {}
+
+ bool Equals(const IdBase& other) const override {
+ return IdBase::Equals(other) &&
+ static_cast<const TypedIntId&>(other).id_ == id_;
+ }
+
+ std::string ToString() const override {
+ return std::string(InternalTypeToString(type_)) + kSeparator +
+ rtc::ToString(id_);
+ }
+
+ protected:
+ const int id_;
+};
+
+class IdWithDirection : public TypedId {
+ public:
+ IdWithDirection(StatsReport::StatsType type,
+ const std::string& id,
+ StatsReport::Direction direction)
+ : TypedId(type, id), direction_(direction) {}
+
+ bool Equals(const IdBase& other) const override {
+ return TypedId::Equals(other) &&
+ static_cast<const IdWithDirection&>(other).direction_ == direction_;
+ }
+
+ std::string ToString() const override {
+ std::string ret(TypedId::ToString());
+ ret += kSeparator;
+ ret += direction_ == StatsReport::kSend ? "send" : "recv";
+ return ret;
+ }
+
+ private:
+ const StatsReport::Direction direction_;
+};
+
+class CandidateId : public TypedId {
+ public:
+ CandidateId(bool local, const std::string& id)
+ : TypedId(local ? StatsReport::kStatsReportTypeIceLocalCandidate
+ : StatsReport::kStatsReportTypeIceRemoteCandidate,
+ id) {}
+
+ std::string ToString() const override { return "Cand-" + id_; }
+};
+
+class ComponentId : public StatsReport::IdBase {
+ public:
+ ComponentId(const std::string& content_name, int component)
+ : ComponentId(StatsReport::kStatsReportTypeComponent,
+ content_name,
+ component) {}
+
+ bool Equals(const IdBase& other) const override {
+ return IdBase::Equals(other) &&
+ static_cast<const ComponentId&>(other).component_ == component_ &&
+ static_cast<const ComponentId&>(other).content_name_ ==
+ content_name_;
+ }
+
+ std::string ToString() const override { return ToString("Channel-"); }
+
+ protected:
+ ComponentId(StatsReport::StatsType type,
+ const std::string& content_name,
+ int component)
+ : IdBase(type), content_name_(content_name), component_(component) {}
+
+ std::string ToString(const char* prefix) const {
+ std::string ret(prefix);
+ ret += content_name_;
+ ret += '-';
+ ret += rtc::ToString(component_);
+ return ret;
+ }
+
+ private:
+ const std::string content_name_;
+ const int component_;
+};
+
+class CandidatePairId : public ComponentId {
+ public:
+ CandidatePairId(const std::string& content_name, int component, int index)
+ : ComponentId(StatsReport::kStatsReportTypeCandidatePair,
+ content_name,
+ component),
+ index_(index) {}
+
+ bool Equals(const IdBase& other) const override {
+ return ComponentId::Equals(other) &&
+ static_cast<const CandidatePairId&>(other).index_ == index_;
+ }
+
+ std::string ToString() const override {
+ std::string ret(ComponentId::ToString("Conn-"));
+ ret += '-';
+ ret += rtc::ToString(index_);
+ return ret;
+ }
+
+ private:
+ const int index_;
+};
+
+} // namespace
+
+StatsReport::IdBase::IdBase(StatsType type) : type_(type) {}
+StatsReport::IdBase::~IdBase() {}
+
+StatsReport::StatsType StatsReport::IdBase::type() const {
+ return type_;
+}
+
+bool StatsReport::IdBase::Equals(const IdBase& other) const {
+ return other.type_ == type_;
+}
+
+StatsReport::Value::Value(StatsValueName name, int64_t value, Type int_type)
+ : name(name), type_(int_type) {
+ RTC_DCHECK(type_ == kInt || type_ == kInt64);
+ type_ == kInt ? value_.int_ = static_cast<int>(value) : value_.int64_ = value;
+}
+
+StatsReport::Value::Value(StatsValueName name, float f)
+ : name(name), type_(kFloat) {
+ value_.float_ = f;
+}
+
+StatsReport::Value::Value(StatsValueName name, const std::string& value)
+ : name(name), type_(kString) {
+ value_.string_ = new std::string(value);
+}
+
+StatsReport::Value::Value(StatsValueName name, const char* value)
+ : name(name), type_(kStaticString) {
+ value_.static_string_ = value;
+}
+
+StatsReport::Value::Value(StatsValueName name, bool b)
+ : name(name), type_(kBool) {
+ value_.bool_ = b;
+}
+
+StatsReport::Value::Value(StatsValueName name, const Id& value)
+ : name(name), type_(kId) {
+ value_.id_ = new Id(value);
+}
+
+StatsReport::Value::~Value() {
+ switch (type_) {
+ case kInt:
+ case kInt64:
+ case kFloat:
+ case kBool:
+ case kStaticString:
+ break;
+ case kString:
+ delete value_.string_;
+ break;
+ case kId:
+ delete value_.id_;
+ break;
+ }
+}
+
+bool StatsReport::Value::Equals(const Value& other) const {
+ if (name != other.name)
+ return false;
+
+ // There's a 1:1 relation between a name and a type, so we don't have to
+ // check that.
+ RTC_DCHECK_EQ(type_, other.type_);
+
+ switch (type_) {
+ case kInt:
+ return value_.int_ == other.value_.int_;
+ case kInt64:
+ return value_.int64_ == other.value_.int64_;
+ case kFloat:
+ return value_.float_ == other.value_.float_;
+ case kStaticString: {
+#if RTC_DCHECK_IS_ON
+ if (value_.static_string_ != other.value_.static_string_) {
+ RTC_DCHECK(strcmp(value_.static_string_, other.value_.static_string_) !=
+ 0)
+ << "Duplicate global?";
+ }
+#endif
+ return value_.static_string_ == other.value_.static_string_;
+ }
+ case kString:
+ return *value_.string_ == *other.value_.string_;
+ case kBool:
+ return value_.bool_ == other.value_.bool_;
+ case kId:
+ return (*value_.id_)->Equals(*other.value_.id_);
+ }
+ RTC_DCHECK_NOTREACHED();
+ return false;
+}
+
+bool StatsReport::Value::operator==(const std::string& value) const {
+ return (type_ == kString && value_.string_->compare(value) == 0) ||
+ (type_ == kStaticString && value.compare(value_.static_string_) == 0);
+}
+
+bool StatsReport::Value::operator==(const char* value) const {
+ if (type_ == kString)
+ return value_.string_->compare(value) == 0;
+ if (type_ != kStaticString)
+ return false;
+#if RTC_DCHECK_IS_ON
+ if (value_.static_string_ != value)
+ RTC_DCHECK(strcmp(value_.static_string_, value) != 0)
+ << "Duplicate global?";
+#endif
+ return value == value_.static_string_;
+}
+
+bool StatsReport::Value::operator==(int64_t value) const {
+ return type_ == kInt ? value_.int_ == static_cast<int>(value)
+ : (type_ == kInt64 ? value_.int64_ == value : false);
+}
+
+bool StatsReport::Value::operator==(bool value) const {
+ return type_ == kBool && value_.bool_ == value;
+}
+
+bool StatsReport::Value::operator==(float value) const {
+ return type_ == kFloat && value_.float_ == value;
+}
+
+bool StatsReport::Value::operator==(const Id& value) const {
+ return type_ == kId && (*value_.id_)->Equals(value);
+}
+
+int StatsReport::Value::int_val() const {
+ RTC_DCHECK_EQ(type_, kInt);
+ return value_.int_;
+}
+
+int64_t StatsReport::Value::int64_val() const {
+ RTC_DCHECK_EQ(type_, kInt64);
+ return value_.int64_;
+}
+
+float StatsReport::Value::float_val() const {
+ RTC_DCHECK_EQ(type_, kFloat);
+ return value_.float_;
+}
+
+const char* StatsReport::Value::static_string_val() const {
+ RTC_DCHECK_EQ(type_, kStaticString);
+ return value_.static_string_;
+}
+
+const std::string& StatsReport::Value::string_val() const {
+ RTC_DCHECK_EQ(type_, kString);
+ return *value_.string_;
+}
+
+bool StatsReport::Value::bool_val() const {
+ RTC_DCHECK_EQ(type_, kBool);
+ return value_.bool_;
+}
+
+const char* StatsReport::Value::display_name() const {
+ switch (name) {
+ case kStatsValueNameAecDivergentFilterFraction:
+ return "aecDivergentFilterFraction";
+ case kStatsValueNameAudioOutputLevel:
+ return "audioOutputLevel";
+ case kStatsValueNameAudioInputLevel:
+ return "audioInputLevel";
+ case kStatsValueNameBytesSent:
+ return "bytesSent";
+ case kStatsValueNameConcealedSamples:
+ return "concealedSamples";
+ case kStatsValueNameConcealmentEvents:
+ return "concealmentEvents";
+ case kStatsValueNamePacketsSent:
+ return "packetsSent";
+ case kStatsValueNameBytesReceived:
+ return "bytesReceived";
+ case kStatsValueNameLabel:
+ return "label";
+ case kStatsValueNamePacketsReceived:
+ return "packetsReceived";
+ case kStatsValueNamePacketsLost:
+ return "packetsLost";
+ case kStatsValueNameProtocol:
+ return "protocol";
+ case kStatsValueNameTotalSamplesReceived:
+ return "totalSamplesReceived";
+ case kStatsValueNameTransportId:
+ return "transportId";
+ case kStatsValueNameSelectedCandidatePairId:
+ return "selectedCandidatePairId";
+ case kStatsValueNameSsrc:
+ return "ssrc";
+ case kStatsValueNameState:
+ return "state";
+ case kStatsValueNameDataChannelId:
+ return "datachannelid";
+ case kStatsValueNameFramesDecoded:
+ return "framesDecoded";
+ case kStatsValueNameFramesEncoded:
+ return "framesEncoded";
+ case kStatsValueNameJitterBufferDelay:
+ return "jitterBufferDelay";
+ case kStatsValueNameCodecImplementationName:
+ return "codecImplementationName";
+ case kStatsValueNameMediaType:
+ return "mediaType";
+ case kStatsValueNameQpSum:
+ return "qpSum";
+ // 'goog' prefixed constants.
+ case kStatsValueNameAccelerateRate:
+ return "googAccelerateRate";
+ case kStatsValueNameActiveConnection:
+ return "googActiveConnection";
+ case kStatsValueNameActualEncBitrate:
+ return "googActualEncBitrate";
+ case kStatsValueNameAvailableReceiveBandwidth:
+ return "googAvailableReceiveBandwidth";
+ case kStatsValueNameAvailableSendBandwidth:
+ return "googAvailableSendBandwidth";
+ case kStatsValueNameAvgEncodeMs:
+ return "googAvgEncodeMs";
+ case kStatsValueNameBucketDelay:
+ return "googBucketDelay";
+ case kStatsValueNameBandwidthLimitedResolution:
+ return "googBandwidthLimitedResolution";
+ // STUN ping related attributes.
+ //
+ // TODO(zhihuang) Rename these stats to follow the standards.
+ // Connectivity checks.
+ case kStatsValueNameSentPingRequestsTotal:
+ return "requestsSent";
+ case kStatsValueNameSentPingRequestsBeforeFirstResponse:
+ return "consentRequestsSent";
+ case kStatsValueNameSentPingResponses:
+ return "responsesSent";
+ case kStatsValueNameRecvPingRequests:
+ return "requestsReceived";
+ case kStatsValueNameRecvPingResponses:
+ return "responsesReceived";
+ // STUN Keepalive pings.
+ case kStatsValueNameSentStunKeepaliveRequests:
+ return "stunKeepaliveRequestsSent";
+ case kStatsValueNameRecvStunKeepaliveResponses:
+ return "stunKeepaliveResponsesReceived";
+ case kStatsValueNameStunKeepaliveRttTotal:
+ return "stunKeepaliveRttTotal";
+ case kStatsValueNameStunKeepaliveRttSquaredTotal:
+ return "stunKeepaliveRttSquaredTotal";
+
+ // Candidate related attributes. Values are taken from
+ // http://w3c.github.io/webrtc-stats/#rtcstatstype-enum*.
+ case kStatsValueNameCandidateIPAddress:
+ return "ipAddress";
+ case kStatsValueNameCandidateNetworkType:
+ return "networkType";
+ case kStatsValueNameCandidatePortNumber:
+ return "portNumber";
+ case kStatsValueNameCandidatePriority:
+ return "priority";
+ case kStatsValueNameCandidateTransportType:
+ return "transport";
+ case kStatsValueNameCandidateType:
+ return "candidateType";
+
+ case kStatsValueNameChannelId:
+ return "googChannelId";
+ case kStatsValueNameCodecName:
+ return "googCodecName";
+ case kStatsValueNameComponent:
+ return "googComponent";
+ case kStatsValueNameContentName:
+ return "googContentName";
+ case kStatsValueNameContentType:
+ return "googContentType";
+ case kStatsValueNameCpuLimitedResolution:
+ return "googCpuLimitedResolution";
+ case kStatsValueNameDecodingCTSG:
+ return "googDecodingCTSG";
+ case kStatsValueNameDecodingCTN:
+ return "googDecodingCTN";
+ case kStatsValueNameDecodingMutedOutput:
+ return "googDecodingMuted";
+ case kStatsValueNameDecodingNormal:
+ return "googDecodingNormal";
+ case kStatsValueNameDecodingPLC:
+ return "googDecodingPLC";
+ case kStatsValueNameDecodingCodecPLC:
+ return "googDecodingCodecPLC";
+ case kStatsValueNameDecodingCNG:
+ return "googDecodingCNG";
+ case kStatsValueNameDecodingPLCCNG:
+ return "googDecodingPLCCNG";
+ case kStatsValueNameDer:
+ return "googDerBase64";
+ case kStatsValueNameDtlsCipher:
+ return "dtlsCipher";
+ case kStatsValueNameEchoDelayMedian:
+ return "googEchoCancellationEchoDelayMedian";
+ case kStatsValueNameEchoDelayStdDev:
+ return "googEchoCancellationEchoDelayStdDev";
+ case kStatsValueNameEchoReturnLoss:
+ return "googEchoCancellationReturnLoss";
+ case kStatsValueNameEchoReturnLossEnhancement:
+ return "googEchoCancellationReturnLossEnhancement";
+ case kStatsValueNameEncodeUsagePercent:
+ return "googEncodeUsagePercent";
+ case kStatsValueNameExpandRate:
+ return "googExpandRate";
+ case kStatsValueNameFingerprint:
+ return "googFingerprint";
+ case kStatsValueNameFingerprintAlgorithm:
+ return "googFingerprintAlgorithm";
+ case kStatsValueNameFirsReceived:
+ return "googFirsReceived";
+ case kStatsValueNameFirsSent:
+ return "googFirsSent";
+ case kStatsValueNameFirstFrameReceivedToDecodedMs:
+ return "googFirstFrameReceivedToDecodedMs";
+ case kStatsValueNameFrameHeightInput:
+ return "googFrameHeightInput";
+ case kStatsValueNameFrameHeightReceived:
+ return "googFrameHeightReceived";
+ case kStatsValueNameFrameHeightSent:
+ return "googFrameHeightSent";
+ case kStatsValueNameFrameRateReceived:
+ return "googFrameRateReceived";
+ case kStatsValueNameFrameRateDecoded:
+ return "googFrameRateDecoded";
+ case kStatsValueNameFrameRateOutput:
+ return "googFrameRateOutput";
+ case kStatsValueNameDecodeMs:
+ return "googDecodeMs";
+ case kStatsValueNameMaxDecodeMs:
+ return "googMaxDecodeMs";
+ case kStatsValueNameCurrentDelayMs:
+ return "googCurrentDelayMs";
+ case kStatsValueNameTargetDelayMs:
+ return "googTargetDelayMs";
+ case kStatsValueNameJitterBufferMs:
+ return "googJitterBufferMs";
+ case kStatsValueNameMinPlayoutDelayMs:
+ return "googMinPlayoutDelayMs";
+ case kStatsValueNameRenderDelayMs:
+ return "googRenderDelayMs";
+ case kStatsValueNameCaptureStartNtpTimeMs:
+ return "googCaptureStartNtpTimeMs";
+ case kStatsValueNameFrameRateInput:
+ return "googFrameRateInput";
+ case kStatsValueNameFrameRateSent:
+ return "googFrameRateSent";
+ case kStatsValueNameFrameWidthInput:
+ return "googFrameWidthInput";
+ case kStatsValueNameFrameWidthReceived:
+ return "googFrameWidthReceived";
+ case kStatsValueNameFrameWidthSent:
+ return "googFrameWidthSent";
+ case kStatsValueNameHasEnteredLowResolution:
+ return "googHasEnteredLowResolution";
+ case kStatsValueNameHugeFramesSent:
+ return "hugeFramesSent";
+ case kStatsValueNameInitiator:
+ return "googInitiator";
+ case kStatsValueNameInterframeDelayMaxMs:
+ return "googInterframeDelayMax";
+ case kStatsValueNameIssuerId:
+ return "googIssuerId";
+ case kStatsValueNameJitterReceived:
+ return "googJitterReceived";
+ case kStatsValueNameLocalAddress:
+ return "googLocalAddress";
+ case kStatsValueNameLocalCandidateId:
+ return "localCandidateId";
+ case kStatsValueNameLocalCandidateType:
+ return "googLocalCandidateType";
+ case kStatsValueNameLocalCertificateId:
+ return "localCertificateId";
+ case kStatsValueNameAdaptationChanges:
+ return "googAdaptationChanges";
+ case kStatsValueNameNacksReceived:
+ return "googNacksReceived";
+ case kStatsValueNameNacksSent:
+ return "googNacksSent";
+ case kStatsValueNamePreemptiveExpandRate:
+ return "googPreemptiveExpandRate";
+ case kStatsValueNamePlisReceived:
+ return "googPlisReceived";
+ case kStatsValueNamePlisSent:
+ return "googPlisSent";
+ case kStatsValueNamePreferredJitterBufferMs:
+ return "googPreferredJitterBufferMs";
+ case kStatsValueNameReceiving:
+ return "googReadable";
+ case kStatsValueNameRemoteAddress:
+ return "googRemoteAddress";
+ case kStatsValueNameRemoteCandidateId:
+ return "remoteCandidateId";
+ case kStatsValueNameRemoteCandidateType:
+ return "googRemoteCandidateType";
+ case kStatsValueNameRemoteCertificateId:
+ return "remoteCertificateId";
+ case kStatsValueNameResidualEchoLikelihood:
+ return "googResidualEchoLikelihood";
+ case kStatsValueNameResidualEchoLikelihoodRecentMax:
+ return "googResidualEchoLikelihoodRecentMax";
+ case kStatsValueNameAnaBitrateActionCounter:
+ return "googAnaBitrateActionCounter";
+ case kStatsValueNameAnaChannelActionCounter:
+ return "googAnaChannelActionCounter";
+ case kStatsValueNameAnaDtxActionCounter:
+ return "googAnaDtxActionCounter";
+ case kStatsValueNameAnaFecActionCounter:
+ return "googAnaFecActionCounter";
+ case kStatsValueNameAnaFrameLengthIncreaseCounter:
+ return "googAnaFrameLengthIncreaseCounter";
+ case kStatsValueNameAnaFrameLengthDecreaseCounter:
+ return "googAnaFrameLengthDecreaseCounter";
+ case kStatsValueNameAnaUplinkPacketLossFraction:
+ return "googAnaUplinkPacketLossFraction";
+ case kStatsValueNameRetransmitBitrate:
+ return "googRetransmitBitrate";
+ case kStatsValueNameRtt:
+ return "googRtt";
+ case kStatsValueNameSecondaryDecodedRate:
+ return "googSecondaryDecodedRate";
+ case kStatsValueNameSecondaryDiscardedRate:
+ return "googSecondaryDiscardedRate";
+ case kStatsValueNameSendPacketsDiscarded:
+ return "packetsDiscardedOnSend";
+ case kStatsValueNameSpeechExpandRate:
+ return "googSpeechExpandRate";
+ case kStatsValueNameSrtpCipher:
+ return "srtpCipher";
+ case kStatsValueNameTargetEncBitrate:
+ return "googTargetEncBitrate";
+ case kStatsValueNameTotalAudioEnergy:
+ return "totalAudioEnergy";
+ case kStatsValueNameTotalSamplesDuration:
+ return "totalSamplesDuration";
+ case kStatsValueNameTransmitBitrate:
+ return "googTransmitBitrate";
+ case kStatsValueNameTransportType:
+ return "googTransportType";
+ case kStatsValueNameTrackId:
+ return "googTrackId";
+ case kStatsValueNameTimingFrameInfo:
+ return "googTimingFrameInfo";
+ case kStatsValueNameWritable:
+ return "googWritable";
+ case kStatsValueNameAudioDeviceUnderrunCounter:
+ return "googAudioDeviceUnderrunCounter";
+ case kStatsValueNameLocalCandidateRelayProtocol:
+ return "googLocalCandidateRelayProtocol";
+ }
+
+ return nullptr;
+}
+
+std::string StatsReport::Value::ToString() const {
+ switch (type_) {
+ case kInt:
+ return rtc::ToString(value_.int_);
+ case kInt64:
+ return rtc::ToString(value_.int64_);
+ case kFloat:
+ return rtc::ToString(value_.float_);
+ case kStaticString:
+ return std::string(value_.static_string_);
+ case kString:
+ return *value_.string_;
+ case kBool:
+ return value_.bool_ ? "true" : "false";
+ case kId:
+ return (*value_.id_)->ToString();
+ }
+ RTC_DCHECK_NOTREACHED();
+ return std::string();
+}
+
+StatsReport::StatsReport(const Id& id) : id_(id), timestamp_(0.0) {
+ RTC_DCHECK(id_.get());
+}
+
+StatsReport::~StatsReport() = default;
+
+// static
+StatsReport::Id StatsReport::NewBandwidthEstimationId() {
+ return rtc::make_ref_counted<BandwidthEstimationId>();
+}
+
+// static
+StatsReport::Id StatsReport::NewTypedId(StatsType type, const std::string& id) {
+ return rtc::make_ref_counted<TypedId>(type, id);
+}
+
+// static
+StatsReport::Id StatsReport::NewTypedIntId(StatsType type, int id) {
+ return rtc::make_ref_counted<TypedIntId>(type, id);
+}
+
+// static
+StatsReport::Id StatsReport::NewIdWithDirection(
+ StatsType type,
+ const std::string& id,
+ StatsReport::Direction direction) {
+ return rtc::make_ref_counted<IdWithDirection>(type, id, direction);
+}
+
+// static
+StatsReport::Id StatsReport::NewCandidateId(bool local, const std::string& id) {
+ return rtc::make_ref_counted<CandidateId>(local, id);
+}
+
+// static
+StatsReport::Id StatsReport::NewComponentId(const std::string& content_name,
+ int component) {
+ return rtc::make_ref_counted<ComponentId>(content_name, component);
+}
+
+// static
+StatsReport::Id StatsReport::NewCandidatePairId(const std::string& content_name,
+ int component,
+ int index) {
+ return rtc::make_ref_counted<CandidatePairId>(content_name, component, index);
+}
+
+const char* StatsReport::TypeToString() const {
+ return InternalTypeToString(id_->type());
+}
+
+void StatsReport::AddString(StatsReport::StatsValueName name,
+ const std::string& value) {
+ const Value* found = FindValue(name);
+ if (!found || !(*found == value))
+ values_[name] = ValuePtr(new Value(name, value));
+}
+
+void StatsReport::AddString(StatsReport::StatsValueName name,
+ const char* value) {
+ const Value* found = FindValue(name);
+ if (!found || !(*found == value))
+ values_[name] = ValuePtr(new Value(name, value));
+}
+
+void StatsReport::AddInt64(StatsReport::StatsValueName name, int64_t value) {
+ const Value* found = FindValue(name);
+ if (!found || !(*found == value))
+ values_[name] = ValuePtr(new Value(name, value, Value::kInt64));
+}
+
+void StatsReport::AddInt(StatsReport::StatsValueName name, int value) {
+ const Value* found = FindValue(name);
+ if (!found || !(*found == static_cast<int64_t>(value)))
+ values_[name] = ValuePtr(new Value(name, value, Value::kInt));
+}
+
+void StatsReport::AddFloat(StatsReport::StatsValueName name, float value) {
+ const Value* found = FindValue(name);
+ if (!found || !(*found == value))
+ values_[name] = ValuePtr(new Value(name, value));
+}
+
+void StatsReport::AddBoolean(StatsReport::StatsValueName name, bool value) {
+ const Value* found = FindValue(name);
+ if (!found || !(*found == value))
+ values_[name] = ValuePtr(new Value(name, value));
+}
+
+void StatsReport::AddId(StatsReport::StatsValueName name, const Id& value) {
+ const Value* found = FindValue(name);
+ if (!found || !(*found == value))
+ values_[name] = ValuePtr(new Value(name, value));
+}
+
+const StatsReport::Value* StatsReport::FindValue(StatsValueName name) const {
+ Values::const_iterator it = values_.find(name);
+ return it == values_.end() ? nullptr : it->second.get();
+}
+
+StatsCollection::StatsCollection() {}
+
+StatsCollection::~StatsCollection() {
+ RTC_DCHECK(thread_checker_.IsCurrent());
+ for (auto* r : list_)
+ delete r;
+}
+
+StatsCollection::const_iterator StatsCollection::begin() const {
+ RTC_DCHECK(thread_checker_.IsCurrent());
+ return list_.begin();
+}
+
+StatsCollection::const_iterator StatsCollection::end() const {
+ RTC_DCHECK(thread_checker_.IsCurrent());
+ return list_.end();
+}
+
+size_t StatsCollection::size() const {
+ RTC_DCHECK(thread_checker_.IsCurrent());
+ return list_.size();
+}
+
+StatsReport* StatsCollection::InsertNew(const StatsReport::Id& id) {
+ RTC_DCHECK(thread_checker_.IsCurrent());
+ RTC_DCHECK(Find(id) == nullptr);
+ StatsReport* report = new StatsReport(id);
+ list_.push_back(report);
+ return report;
+}
+
+StatsReport* StatsCollection::FindOrAddNew(const StatsReport::Id& id) {
+ RTC_DCHECK(thread_checker_.IsCurrent());
+ StatsReport* ret = Find(id);
+ return ret ? ret : InsertNew(id);
+}
+
+StatsReport* StatsCollection::ReplaceOrAddNew(const StatsReport::Id& id) {
+ RTC_DCHECK(thread_checker_.IsCurrent());
+ RTC_DCHECK(id.get());
+ Container::iterator it = absl::c_find_if(
+ list_,
+ [&id](const StatsReport* r) -> bool { return r->id()->Equals(id); });
+ if (it != end()) {
+ StatsReport* report = new StatsReport((*it)->id());
+ delete *it;
+ *it = report;
+ return report;
+ }
+ return InsertNew(id);
+}
+
+// Looks for a report with the given `id`. If one is not found, null
+// will be returned.
+StatsReport* StatsCollection::Find(const StatsReport::Id& id) {
+ RTC_DCHECK(thread_checker_.IsCurrent());
+ Container::iterator it = absl::c_find_if(
+ list_,
+ [&id](const StatsReport* r) -> bool { return r->id()->Equals(id); });
+ return it == list_.end() ? nullptr : *it;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/legacy_stats_types.h b/third_party/libwebrtc/api/legacy_stats_types.h
new file mode 100644
index 0000000000..a62e014834
--- /dev/null
+++ b/third_party/libwebrtc/api/legacy_stats_types.h
@@ -0,0 +1,455 @@
+/*
+ * Copyright 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This file contains structures used for retrieving statistics from an ongoing
+// libjingle session.
+
+#ifndef API_LEGACY_STATS_TYPES_H_
+#define API_LEGACY_STATS_TYPES_H_
+
+#include <algorithm>
+#include <list>
+#include <map>
+#include <string>
+#include <vector>
+
+#include "api/scoped_refptr.h"
+#include "api/sequence_checker.h"
+#include "rtc_base/ref_count.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+class RTC_EXPORT StatsReport {
+ public:
+ // Indicates whether a track is for sending or receiving.
+ // Used in reports for audio/video tracks.
+ enum Direction {
+ kSend = 0,
+ kReceive,
+ };
+
+ enum StatsType {
+ // StatsReport types.
+ // A StatsReport of `type` = "googSession" contains overall information
+ // about the thing libjingle calls a session (which may contain one
+ // or more RTP sessions.
+ kStatsReportTypeSession,
+
+ // A StatsReport of `type` = "googTransport" contains information
+ // about a libjingle "transport".
+ kStatsReportTypeTransport,
+
+ // A StatsReport of `type` = "googComponent" contains information
+ // about a libjingle "channel" (typically, RTP or RTCP for a transport).
+ // This is intended to be the same thing as an ICE "Component".
+ kStatsReportTypeComponent,
+
+ // A StatsReport of `type` = "googCandidatePair" contains information
+ // about a libjingle "connection" - a single source/destination port pair.
+ // This is intended to be the same thing as an ICE "candidate pair".
+ kStatsReportTypeCandidatePair,
+
+ // A StatsReport of `type` = "VideoBWE" is statistics for video Bandwidth
+ // Estimation, which is global per-session. The `id` field is "bweforvideo"
+ // (will probably change in the future).
+ kStatsReportTypeBwe,
+
+ // A StatsReport of `type` = "ssrc" is statistics for a specific rtp stream.
+ // The `id` field is the SSRC in decimal form of the rtp stream.
+ kStatsReportTypeSsrc,
+
+ // A StatsReport of `type` = "remoteSsrc" is statistics for a specific
+ // rtp stream, generated by the remote end of the connection.
+ kStatsReportTypeRemoteSsrc,
+
+ // A StatsReport of `type` = "googTrack" is statistics for a specific media
+ // track. The `id` field is the track id.
+ kStatsReportTypeTrack,
+
+ // A StatsReport of `type` = "localcandidate" or "remotecandidate" is
+ // attributes on a specific ICE Candidate. It links to its connection pair
+ // by candidate id. The string value is taken from
+ // http://w3c.github.io/webrtc-stats/#rtcstatstype-enum*.
+ kStatsReportTypeIceLocalCandidate,
+ kStatsReportTypeIceRemoteCandidate,
+
+ // A StatsReport of `type` = "googCertificate" contains an SSL certificate
+ // transmitted by one of the endpoints of this connection. The `id` is
+ // controlled by the fingerprint, and is used to identify the certificate in
+ // the Channel stats (as "googLocalCertificateId" or
+ // "googRemoteCertificateId") and in any child certificates (as
+ // "googIssuerId").
+ kStatsReportTypeCertificate,
+
+ // A StatsReport of `type` = "datachannel" with statistics for a
+ // particular DataChannel.
+ kStatsReportTypeDataChannel,
+ };
+
+ enum StatsValueName {
+ kStatsValueNameActiveConnection,
+ kStatsValueNameAecDivergentFilterFraction,
+ kStatsValueNameAudioInputLevel,
+ kStatsValueNameAudioOutputLevel,
+ kStatsValueNameBytesReceived,
+ kStatsValueNameBytesSent,
+ kStatsValueNameCodecImplementationName,
+ kStatsValueNameConcealedSamples,
+ kStatsValueNameConcealmentEvents,
+ kStatsValueNameDataChannelId,
+ kStatsValueNameFramesDecoded,
+ kStatsValueNameFramesEncoded,
+ kStatsValueNameJitterBufferDelay,
+ kStatsValueNameMediaType,
+ kStatsValueNamePacketsLost,
+ kStatsValueNamePacketsReceived,
+ kStatsValueNamePacketsSent,
+ kStatsValueNameProtocol,
+ kStatsValueNameQpSum,
+ kStatsValueNameReceiving,
+ kStatsValueNameSelectedCandidatePairId,
+ kStatsValueNameSsrc,
+ kStatsValueNameState,
+ kStatsValueNameTotalAudioEnergy,
+ kStatsValueNameTotalSamplesDuration,
+ kStatsValueNameTotalSamplesReceived,
+ kStatsValueNameTransportId,
+ kStatsValueNameSentPingRequestsTotal,
+ kStatsValueNameSentPingRequestsBeforeFirstResponse,
+ kStatsValueNameSentPingResponses,
+ kStatsValueNameRecvPingRequests,
+ kStatsValueNameRecvPingResponses,
+ kStatsValueNameSentStunKeepaliveRequests,
+ kStatsValueNameRecvStunKeepaliveResponses,
+ kStatsValueNameStunKeepaliveRttTotal,
+ kStatsValueNameStunKeepaliveRttSquaredTotal,
+
+ // Internal StatsValue names.
+ kStatsValueNameAccelerateRate,
+ kStatsValueNameActualEncBitrate,
+ kStatsValueNameAdaptationChanges,
+ kStatsValueNameAvailableReceiveBandwidth,
+ kStatsValueNameAvailableSendBandwidth,
+ kStatsValueNameAvgEncodeMs,
+ kStatsValueNameBandwidthLimitedResolution,
+ kStatsValueNameBucketDelay,
+ kStatsValueNameCaptureStartNtpTimeMs,
+ kStatsValueNameCandidateIPAddress,
+ kStatsValueNameCandidateNetworkType,
+ kStatsValueNameCandidatePortNumber,
+ kStatsValueNameCandidatePriority,
+ kStatsValueNameCandidateTransportType,
+ kStatsValueNameCandidateType,
+ kStatsValueNameChannelId,
+ kStatsValueNameCodecName,
+ kStatsValueNameComponent,
+ kStatsValueNameContentName,
+ kStatsValueNameContentType,
+ kStatsValueNameCpuLimitedResolution,
+ kStatsValueNameCurrentDelayMs,
+ kStatsValueNameDecodeMs,
+ kStatsValueNameDecodingCNG,
+ kStatsValueNameDecodingCTN,
+ kStatsValueNameDecodingCTSG,
+ kStatsValueNameDecodingMutedOutput,
+ kStatsValueNameDecodingNormal,
+ kStatsValueNameDecodingPLC,
+ kStatsValueNameDecodingCodecPLC,
+ kStatsValueNameDecodingPLCCNG,
+ kStatsValueNameDer,
+ kStatsValueNameDtlsCipher,
+ kStatsValueNameEchoDelayMedian,
+ kStatsValueNameEchoDelayStdDev,
+ kStatsValueNameEchoReturnLoss,
+ kStatsValueNameEchoReturnLossEnhancement,
+ kStatsValueNameEncodeUsagePercent,
+ kStatsValueNameExpandRate,
+ kStatsValueNameFingerprint,
+ kStatsValueNameFingerprintAlgorithm,
+ kStatsValueNameFirsReceived,
+ kStatsValueNameFirsSent,
+ kStatsValueNameFirstFrameReceivedToDecodedMs,
+ kStatsValueNameFrameHeightInput,
+ kStatsValueNameFrameHeightReceived,
+ kStatsValueNameFrameHeightSent,
+ kStatsValueNameFrameRateDecoded,
+ kStatsValueNameFrameRateInput,
+ kStatsValueNameFrameRateOutput,
+ kStatsValueNameFrameRateReceived,
+ kStatsValueNameFrameRateSent,
+ kStatsValueNameFrameWidthInput,
+ kStatsValueNameFrameWidthReceived,
+ kStatsValueNameFrameWidthSent,
+ kStatsValueNameHasEnteredLowResolution,
+ kStatsValueNameHugeFramesSent,
+ kStatsValueNameInitiator,
+ kStatsValueNameInterframeDelayMaxMs, // Max over last 10 seconds.
+ kStatsValueNameIssuerId,
+ kStatsValueNameJitterBufferMs,
+ kStatsValueNameJitterReceived,
+ kStatsValueNameLabel,
+ kStatsValueNameLocalAddress,
+ kStatsValueNameLocalCandidateId,
+ kStatsValueNameLocalCandidateType,
+ kStatsValueNameLocalCertificateId,
+ kStatsValueNameMaxDecodeMs,
+ kStatsValueNameMinPlayoutDelayMs,
+ kStatsValueNameNacksReceived,
+ kStatsValueNameNacksSent,
+ kStatsValueNamePlisReceived,
+ kStatsValueNamePlisSent,
+ kStatsValueNamePreemptiveExpandRate,
+ kStatsValueNamePreferredJitterBufferMs,
+ kStatsValueNameRemoteAddress,
+ kStatsValueNameRemoteCandidateId,
+ kStatsValueNameRemoteCandidateType,
+ kStatsValueNameRemoteCertificateId,
+ kStatsValueNameRenderDelayMs,
+ kStatsValueNameResidualEchoLikelihood,
+ kStatsValueNameResidualEchoLikelihoodRecentMax,
+ kStatsValueNameAnaBitrateActionCounter,
+ kStatsValueNameAnaChannelActionCounter,
+ kStatsValueNameAnaDtxActionCounter,
+ kStatsValueNameAnaFecActionCounter,
+ kStatsValueNameAnaFrameLengthIncreaseCounter,
+ kStatsValueNameAnaFrameLengthDecreaseCounter,
+ kStatsValueNameAnaUplinkPacketLossFraction,
+ kStatsValueNameRetransmitBitrate,
+ kStatsValueNameRtt,
+ kStatsValueNameSecondaryDecodedRate,
+ kStatsValueNameSecondaryDiscardedRate,
+ kStatsValueNameSendPacketsDiscarded,
+ kStatsValueNameSpeechExpandRate,
+ kStatsValueNameSrtpCipher,
+ kStatsValueNameTargetDelayMs,
+ kStatsValueNameTargetEncBitrate,
+ kStatsValueNameTimingFrameInfo, // Result of `TimingFrameInfo::ToString`
+ kStatsValueNameTrackId,
+ kStatsValueNameTransmitBitrate,
+ kStatsValueNameTransportType,
+ kStatsValueNameWritable,
+ kStatsValueNameAudioDeviceUnderrunCounter,
+ kStatsValueNameLocalCandidateRelayProtocol,
+ };
+
+ class RTC_EXPORT IdBase : public rtc::RefCountInterface {
+ public:
+ ~IdBase() override;
+ StatsType type() const;
+
+ // Users of IdBase will be using the Id typedef, which is compatible with
+ // this Equals() function. It simply calls the protected (and overridden)
+ // Equals() method.
+ bool Equals(const rtc::scoped_refptr<IdBase>& other) const {
+ return Equals(*other.get());
+ }
+
+ virtual std::string ToString() const = 0;
+
+ protected:
+ // Protected since users of the IdBase type will be using the Id typedef.
+ virtual bool Equals(const IdBase& other) const;
+
+ explicit IdBase(StatsType type); // Only meant for derived classes.
+ const StatsType type_;
+
+ static const char kSeparator = '_';
+ };
+
+ typedef rtc::scoped_refptr<IdBase> Id;
+
+ struct RTC_EXPORT Value {
+ enum Type {
+ kInt, // int.
+ kInt64, // int64_t.
+ kFloat, // float.
+ kString, // std::string
+ kStaticString, // const char*.
+ kBool, // bool.
+ kId, // Id.
+ };
+
+ Value(StatsValueName name, int64_t value, Type int_type);
+ Value(StatsValueName name, float f);
+ Value(StatsValueName name, const std::string& value);
+ Value(StatsValueName name, const char* value);
+ Value(StatsValueName name, bool b);
+ Value(StatsValueName name, const Id& value);
+
+ ~Value();
+
+ Value(const Value&) = delete;
+ Value& operator=(const Value&) = delete;
+
+ // Support ref counting. Note that for performance reasons, we
+ // don't use thread safe operations. Therefore, all operations
+ // affecting the ref count (in practice, creation and copying of
+ // the Values mapping) must occur on webrtc's signalling thread.
+ int AddRef() const {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
+ return ++ref_count_;
+ }
+ int Release() const {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
+ int count = --ref_count_;
+ if (!count)
+ delete this;
+ return count;
+ }
+
+ // TODO(tommi): This compares name as well as value...
+ // I think we should only need to compare the value part and
+ // move the name part into a hash map.
+ bool Equals(const Value& other) const;
+
+ // Comparison operators. Return true iff the current instance is of the
+ // correct type and holds the same value. No conversion is performed so
+ // a string value of "123" is not equal to an int value of 123 and an int
+ // value of 123 is not equal to a float value of 123.0f.
+ // One exception to this is that types kInt and kInt64 can be compared and
+ // kString and kStaticString too.
+ bool operator==(const std::string& value) const;
+ bool operator==(const char* value) const;
+ bool operator==(int64_t value) const;
+ bool operator==(bool value) const;
+ bool operator==(float value) const;
+ bool operator==(const Id& value) const;
+
+ // Getters that allow getting the native value directly.
+ // The caller must know the type beforehand or else hit a check.
+ int int_val() const;
+ int64_t int64_val() const;
+ float float_val() const;
+ const char* static_string_val() const;
+ const std::string& string_val() const;
+ bool bool_val() const;
+ const Id& id_val() const;
+
+ // Returns the string representation of `name`.
+ const char* display_name() const;
+
+ // Converts the native value to a string representation of the value.
+ std::string ToString() const;
+
+ Type type() const { return type_; }
+
+ // TODO(tommi): Move `name` and `display_name` out of the Value struct.
+ const StatsValueName name;
+
+ private:
+ webrtc::SequenceChecker thread_checker_;
+ mutable int ref_count_ RTC_GUARDED_BY(thread_checker_) = 0;
+
+ const Type type_;
+ // TODO(tommi): Use C++ 11 union and make value_ const.
+ union InternalType {
+ int int_;
+ int64_t int64_;
+ float float_;
+ bool bool_;
+ std::string* string_;
+ const char* static_string_;
+ Id* id_;
+ } value_;
+ };
+
+ typedef rtc::scoped_refptr<Value> ValuePtr;
+ typedef std::map<StatsValueName, ValuePtr> Values;
+
+ // Ownership of `id` is passed to `this`.
+ explicit StatsReport(const Id& id);
+ ~StatsReport();
+
+ StatsReport(const StatsReport&) = delete;
+ StatsReport& operator=(const StatsReport&) = delete;
+
+ // Factory functions for various types of stats IDs.
+ static Id NewBandwidthEstimationId();
+ static Id NewTypedId(StatsType type, const std::string& id);
+ static Id NewTypedIntId(StatsType type, int id);
+ static Id NewIdWithDirection(StatsType type,
+ const std::string& id,
+ Direction direction);
+ static Id NewCandidateId(bool local, const std::string& id);
+ static Id NewComponentId(const std::string& content_name, int component);
+ static Id NewCandidatePairId(const std::string& content_name,
+ int component,
+ int index);
+
+ const Id& id() const { return id_; }
+ StatsType type() const { return id_->type(); }
+ double timestamp() const { return timestamp_; }
+ void set_timestamp(double t) { timestamp_ = t; }
+ bool empty() const { return values_.empty(); }
+ const Values& values() const { return values_; }
+
+ const char* TypeToString() const;
+
+ void AddString(StatsValueName name, const std::string& value);
+ void AddString(StatsValueName name, const char* value);
+ void AddInt64(StatsValueName name, int64_t value);
+ void AddInt(StatsValueName name, int value);
+ void AddFloat(StatsValueName name, float value);
+ void AddBoolean(StatsValueName name, bool value);
+ void AddId(StatsValueName name, const Id& value);
+
+ const Value* FindValue(StatsValueName name) const;
+
+ private:
+ // The unique identifier for this object.
+ // This is used as a key for this report in ordered containers,
+ // so it must never be changed.
+ const Id id_;
+ double timestamp_; // Time since 1970-01-01T00:00:00Z in milliseconds.
+ Values values_;
+};
+
+// Typedef for an array of const StatsReport pointers.
+// Ownership of the pointers held by this implementation is assumed to lie
+// elsewhere and lifetime guarantees are made by the implementation that uses
+// this type. In the StatsCollector, object ownership lies with the
+// StatsCollection class.
+typedef std::vector<const StatsReport*> StatsReports;
+
+// A map from the report id to the report.
+// This class wraps an STL container and provides a limited set of
+// functionality in order to keep things simple.
+class StatsCollection {
+ public:
+ StatsCollection();
+ ~StatsCollection();
+
+ typedef std::list<StatsReport*> Container;
+ typedef Container::iterator iterator;
+ typedef Container::const_iterator const_iterator;
+
+ const_iterator begin() const;
+ const_iterator end() const;
+ size_t size() const;
+
+ // Creates a new report object with `id` that does not already
+ // exist in the list of reports.
+ StatsReport* InsertNew(const StatsReport::Id& id);
+ StatsReport* FindOrAddNew(const StatsReport::Id& id);
+ StatsReport* ReplaceOrAddNew(const StatsReport::Id& id);
+
+ // Looks for a report with the given `id`. If one is not found, null
+ // will be returned.
+ StatsReport* Find(const StatsReport::Id& id);
+
+ private:
+ Container list_;
+ webrtc::SequenceChecker thread_checker_;
+};
+
+} // namespace webrtc
+
+#endif // API_LEGACY_STATS_TYPES_H_
diff --git a/third_party/libwebrtc/api/libjingle_logging_api_gn/moz.build b/third_party/libwebrtc/api/libjingle_logging_api_gn/moz.build
new file mode 100644
index 0000000000..5e41eca1b7
--- /dev/null
+++ b/third_party/libwebrtc/api/libjingle_logging_api_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("jingle_logging_api_gn")
diff --git a/third_party/libwebrtc/api/libjingle_peerconnection_api_gn/moz.build b/third_party/libwebrtc/api/libjingle_peerconnection_api_gn/moz.build
new file mode 100644
index 0000000000..579b7f164b
--- /dev/null
+++ b/third_party/libwebrtc/api/libjingle_peerconnection_api_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("jingle_peerconnection_api_gn")
diff --git a/third_party/libwebrtc/api/make_ref_counted.h b/third_party/libwebrtc/api/make_ref_counted.h
new file mode 100644
index 0000000000..cc8871784a
--- /dev/null
+++ b/third_party/libwebrtc/api/make_ref_counted.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2022 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_MAKE_REF_COUNTED_H_
+#define API_MAKE_REF_COUNTED_H_
+
+#include <utility>
+
+#include "rtc_base/ref_counted_object.h"
+
+namespace rtc {
+
+namespace webrtc_make_ref_counted_internal {
+// Determines if the given class has AddRef and Release methods.
+template <typename T>
+class HasAddRefAndRelease {
+ private:
+ template <typename C,
+ decltype(std::declval<C>().AddRef())* = nullptr,
+ decltype(std::declval<C>().Release())* = nullptr>
+ static int Test(int);
+ template <typename>
+ static char Test(...);
+
+ public:
+ static constexpr bool value = std::is_same_v<decltype(Test<T>(0)), int>;
+};
+} // namespace webrtc_make_ref_counted_internal
+
+// General utilities for constructing a reference counted class and the
+// appropriate reference count implementation for that class.
+//
+// These utilities select either the `RefCountedObject` implementation or
+// `FinalRefCountedObject` depending on whether the to-be-shared class is
+// derived from the RefCountInterface interface or not (respectively).
+
+// `make_ref_counted`:
+//
+// Use this when you want to construct a reference counted object of type T and
+// get a `scoped_refptr<>` back. Example:
+//
+// auto p = make_ref_counted<Foo>("bar", 123);
+//
+// For a class that inherits from RefCountInterface, this is equivalent to:
+//
+// auto p = scoped_refptr<Foo>(new RefCountedObject<Foo>("bar", 123));
+//
+// If the class does not inherit from RefCountInterface, but does have
+// AddRef/Release methods (so a T* is convertible to rtc::scoped_refptr), this
+// is equivalent to just
+//
+// auto p = scoped_refptr<Foo>(new Foo("bar", 123));
+//
+// Otherwise, the example is equivalent to:
+//
+// auto p = scoped_refptr<FinalRefCountedObject<Foo>>(
+// new FinalRefCountedObject<Foo>("bar", 123));
+//
+// In these cases, `make_ref_counted` reduces the amount of boilerplate code but
+// also helps with the most commonly intended usage of RefCountedObject whereby
+// methods for reference counting, are virtual and designed to satisfy the need
+// of an interface. When such a need does not exist, it is more efficient to use
+// the `FinalRefCountedObject` template, which does not add the vtable overhead.
+//
+// Note that in some cases, using RefCountedObject directly may still be what's
+// needed.
+
+// `make_ref_counted` for abstract classes that are convertible to
+// RefCountInterface. The is_abstract requirement rejects classes that inherit
+// both RefCountInterface and RefCounted object, which is a a discouraged
+// pattern, and would result in double inheritance of RefCountedObject if this
+// template was applied.
+template <
+ typename T,
+ typename... Args,
+ typename std::enable_if<std::is_convertible_v<T*, RefCountInterface*> &&
+ std::is_abstract_v<T>,
+ T>::type* = nullptr>
+scoped_refptr<T> make_ref_counted(Args&&... args) {
+ return scoped_refptr<T>(new RefCountedObject<T>(std::forward<Args>(args)...));
+}
+
+// `make_ref_counted` for complete classes that are not convertible to
+// RefCountInterface and already carry a ref count.
+template <
+ typename T,
+ typename... Args,
+ typename std::enable_if<
+ !std::is_convertible_v<T*, RefCountInterface*> &&
+ webrtc_make_ref_counted_internal::HasAddRefAndRelease<T>::value,
+ T>::type* = nullptr>
+scoped_refptr<T> make_ref_counted(Args&&... args) {
+ return scoped_refptr<T>(new T(std::forward<Args>(args)...));
+}
+
+// `make_ref_counted` for complete classes that are not convertible to
+// RefCountInterface and have no ref count of their own.
+template <
+ typename T,
+ typename... Args,
+ typename std::enable_if<
+ !std::is_convertible_v<T*, RefCountInterface*> &&
+ !webrtc_make_ref_counted_internal::HasAddRefAndRelease<T>::value,
+
+ T>::type* = nullptr>
+scoped_refptr<FinalRefCountedObject<T>> make_ref_counted(Args&&... args) {
+ return scoped_refptr<FinalRefCountedObject<T>>(
+ new FinalRefCountedObject<T>(std::forward<Args>(args)...));
+}
+
+} // namespace rtc
+
+#endif // API_MAKE_REF_COUNTED_H_
diff --git a/third_party/libwebrtc/api/make_ref_counted_gn/moz.build b/third_party/libwebrtc/api/make_ref_counted_gn/moz.build
new file mode 100644
index 0000000000..8b3a500acb
--- /dev/null
+++ b/third_party/libwebrtc/api/make_ref_counted_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("make_ref_counted_gn")
diff --git a/third_party/libwebrtc/api/media_stream_interface.cc b/third_party/libwebrtc/api/media_stream_interface.cc
new file mode 100644
index 0000000000..e07907917b
--- /dev/null
+++ b/third_party/libwebrtc/api/media_stream_interface.cc
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/media_stream_interface.h"
+#include "api/media_types.h"
+
+namespace webrtc {
+
+const char* const MediaStreamTrackInterface::kVideoKind =
+ cricket::kMediaTypeVideo;
+const char* const MediaStreamTrackInterface::kAudioKind =
+ cricket::kMediaTypeAudio;
+
+VideoTrackInterface::ContentHint VideoTrackInterface::content_hint() const {
+ return ContentHint::kNone;
+}
+
+bool AudioTrackInterface::GetSignalLevel(int* level) {
+ return false;
+}
+
+rtc::scoped_refptr<AudioProcessorInterface>
+AudioTrackInterface::GetAudioProcessor() {
+ return nullptr;
+}
+
+const cricket::AudioOptions AudioSourceInterface::options() const {
+ return {};
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/media_stream_interface.h b/third_party/libwebrtc/api/media_stream_interface.h
new file mode 100644
index 0000000000..9d336739e4
--- /dev/null
+++ b/third_party/libwebrtc/api/media_stream_interface.h
@@ -0,0 +1,376 @@
+/*
+ * Copyright 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This file contains interfaces for MediaStream, MediaTrack and MediaSource.
+// These interfaces are used for implementing MediaStream and MediaTrack as
+// defined in http://dev.w3.org/2011/webrtc/editor/webrtc.html#stream-api. These
+// interfaces must be used only with PeerConnection.
+
+#ifndef API_MEDIA_STREAM_INTERFACE_H_
+#define API_MEDIA_STREAM_INTERFACE_H_
+
+#include <stddef.h>
+
+#include <string>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/audio_options.h"
+#include "api/scoped_refptr.h"
+#include "api/video/recordable_encoded_frame.h"
+#include "api/video/video_frame.h"
+#include "api/video/video_sink_interface.h"
+#include "api/video/video_source_interface.h"
+#include "api/video_track_source_constraints.h"
+#include "modules/audio_processing/include/audio_processing_statistics.h"
+#include "rtc_base/ref_count.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Generic observer interface.
+class ObserverInterface {
+ public:
+ virtual void OnChanged() = 0;
+
+ protected:
+ virtual ~ObserverInterface() {}
+};
+
+class NotifierInterface {
+ public:
+ virtual void RegisterObserver(ObserverInterface* observer) = 0;
+ virtual void UnregisterObserver(ObserverInterface* observer) = 0;
+
+ virtual ~NotifierInterface() {}
+};
+
+// Base class for sources. A MediaStreamTrack has an underlying source that
+// provides media. A source can be shared by multiple tracks.
+class RTC_EXPORT MediaSourceInterface : public rtc::RefCountInterface,
+ public NotifierInterface {
+ public:
+ enum SourceState { kInitializing, kLive, kEnded, kMuted };
+
+ virtual SourceState state() const = 0;
+
+ virtual bool remote() const = 0;
+
+ protected:
+ ~MediaSourceInterface() override = default;
+};
+
+// C++ version of MediaStreamTrack.
+// See: https://www.w3.org/TR/mediacapture-streams/#mediastreamtrack
+class RTC_EXPORT MediaStreamTrackInterface : public rtc::RefCountInterface,
+ public NotifierInterface {
+ public:
+ enum TrackState {
+ kLive,
+ kEnded,
+ };
+
+ static const char* const kAudioKind;
+ static const char* const kVideoKind;
+
+ // The kind() method must return kAudioKind only if the object is a
+ // subclass of AudioTrackInterface, and kVideoKind only if the
+ // object is a subclass of VideoTrackInterface. It is typically used
+ // to protect a static_cast<> to the corresponding subclass.
+ virtual std::string kind() const = 0;
+
+ // Track identifier.
+ virtual std::string id() const = 0;
+
+ // A disabled track will produce silence (if audio) or black frames (if
+ // video). Can be disabled and re-enabled.
+ virtual bool enabled() const = 0;
+ virtual bool set_enabled(bool enable) = 0;
+
+ // Live or ended. A track will never be live again after becoming ended.
+ virtual TrackState state() const = 0;
+
+ protected:
+ ~MediaStreamTrackInterface() override = default;
+};
+
+// VideoTrackSourceInterface is a reference counted source used for
+// VideoTracks. The same source can be used by multiple VideoTracks.
+// VideoTrackSourceInterface is designed to be invoked on the signaling thread
+// except for rtc::VideoSourceInterface<VideoFrame> methods that will be invoked
+// on the worker thread via a VideoTrack. A custom implementation of a source
+// can inherit AdaptedVideoTrackSource instead of directly implementing this
+// interface.
+class VideoTrackSourceInterface : public MediaSourceInterface,
+ public rtc::VideoSourceInterface<VideoFrame> {
+ public:
+ struct Stats {
+ // Original size of captured frame, before video adaptation.
+ int input_width;
+ int input_height;
+ };
+
+ // Indicates that parameters suitable for screencasts should be automatically
+ // applied to RtpSenders.
+ // TODO(perkj): Remove these once all known applications have moved to
+ // explicitly setting suitable parameters for screencasts and don't need this
+ // implicit behavior.
+ virtual bool is_screencast() const = 0;
+
+ // Indicates that the encoder should denoise video before encoding it.
+ // If it is not set, the default configuration is used which is different
+ // depending on video codec.
+ // TODO(perkj): Remove this once denoising is done by the source, and not by
+ // the encoder.
+ virtual absl::optional<bool> needs_denoising() const = 0;
+
+ // Returns false if no stats are available, e.g, for a remote source, or a
+ // source which has not seen its first frame yet.
+ //
+ // Implementation should avoid blocking.
+ virtual bool GetStats(Stats* stats) = 0;
+
+ // Returns true if encoded output can be enabled in the source.
+ virtual bool SupportsEncodedOutput() const = 0;
+
+ // Reliably cause a key frame to be generated in encoded output.
+ // TODO(bugs.webrtc.org/11115): find optimal naming.
+ virtual void GenerateKeyFrame() = 0;
+
+ // Add an encoded video sink to the source and additionally cause
+ // a key frame to be generated from the source. The sink will be
+ // invoked from a decoder queue.
+ virtual void AddEncodedSink(
+ rtc::VideoSinkInterface<RecordableEncodedFrame>* sink) = 0;
+
+ // Removes an encoded video sink from the source.
+ virtual void RemoveEncodedSink(
+ rtc::VideoSinkInterface<RecordableEncodedFrame>* sink) = 0;
+
+ // Notify about constraints set on the source. The information eventually gets
+ // routed to attached sinks via VideoSinkInterface<>::OnConstraintsChanged.
+ // The call is expected to happen on the network thread.
+ // TODO(crbug/1255737): make pure virtual once downstream project adapts.
+ virtual void ProcessConstraints(
+ const webrtc::VideoTrackSourceConstraints& constraints) {}
+
+ protected:
+ ~VideoTrackSourceInterface() override = default;
+};
+
+// VideoTrackInterface is designed to be invoked on the signaling thread except
+// for rtc::VideoSourceInterface<VideoFrame> methods that must be invoked
+// on the worker thread.
+// PeerConnectionFactory::CreateVideoTrack can be used for creating a VideoTrack
+// that ensures thread safety and that all methods are called on the right
+// thread.
+class RTC_EXPORT VideoTrackInterface
+ : public MediaStreamTrackInterface,
+ public rtc::VideoSourceInterface<VideoFrame> {
+ public:
+ // Video track content hint, used to override the source is_screencast
+ // property.
+ // See https://crbug.com/653531 and https://w3c.github.io/mst-content-hint.
+ enum class ContentHint { kNone, kFluid, kDetailed, kText };
+
+ // Register a video sink for this track. Used to connect the track to the
+ // underlying video engine.
+ void AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink,
+ const rtc::VideoSinkWants& wants) override {}
+ void RemoveSink(rtc::VideoSinkInterface<VideoFrame>* sink) override {}
+
+ virtual VideoTrackSourceInterface* GetSource() const = 0;
+
+ virtual ContentHint content_hint() const;
+ virtual void set_content_hint(ContentHint hint) {}
+
+ protected:
+ ~VideoTrackInterface() override = default;
+};
+
+// Interface for receiving audio data from a AudioTrack.
+class AudioTrackSinkInterface {
+ public:
+ virtual void OnData(const void* audio_data,
+ int bits_per_sample,
+ int sample_rate,
+ size_t number_of_channels,
+ size_t number_of_frames) {
+ RTC_DCHECK_NOTREACHED() << "This method must be overridden, or not used.";
+ }
+
+ // In this method, `absolute_capture_timestamp_ms`, when available, is
+ // supposed to deliver the timestamp when this audio frame was originally
+ // captured. This timestamp MUST be based on the same clock as
+ // rtc::TimeMillis().
+ virtual void OnData(const void* audio_data,
+ int bits_per_sample,
+ int sample_rate,
+ size_t number_of_channels,
+ size_t number_of_frames,
+ absl::optional<int64_t> absolute_capture_timestamp_ms) {
+ // TODO(bugs.webrtc.org/10739): Deprecate the old OnData and make this one
+ // pure virtual.
+ return OnData(audio_data, bits_per_sample, sample_rate, number_of_channels,
+ number_of_frames);
+ }
+
+ // Returns the number of channels encoded by the sink. This can be less than
+ // the number_of_channels if down-mixing occur. A value of -1 means an unknown
+ // number.
+ virtual int NumPreferredChannels() const { return -1; }
+
+ protected:
+ virtual ~AudioTrackSinkInterface() {}
+};
+
+// AudioSourceInterface is a reference counted source used for AudioTracks.
+// The same source can be used by multiple AudioTracks.
+class RTC_EXPORT AudioSourceInterface : public MediaSourceInterface {
+ public:
+ class AudioObserver {
+ public:
+ virtual void OnSetVolume(double volume) = 0;
+
+ protected:
+ virtual ~AudioObserver() {}
+ };
+
+ // TODO(deadbeef): Makes all the interfaces pure virtual after they're
+ // implemented in chromium.
+
+ // Sets the volume of the source. `volume` is in the range of [0, 10].
+ // TODO(tommi): This method should be on the track and ideally volume should
+ // be applied in the track in a way that does not affect clones of the track.
+ virtual void SetVolume(double volume) {}
+
+ // Registers/unregisters observers to the audio source.
+ virtual void RegisterAudioObserver(AudioObserver* observer) {}
+ virtual void UnregisterAudioObserver(AudioObserver* observer) {}
+
+ // TODO(tommi): Make pure virtual.
+ virtual void AddSink(AudioTrackSinkInterface* sink) {}
+ virtual void RemoveSink(AudioTrackSinkInterface* sink) {}
+
+ // Returns options for the AudioSource.
+ // (for some of the settings this approach is broken, e.g. setting
+ // audio network adaptation on the source is the wrong layer of abstraction).
+ virtual const cricket::AudioOptions options() const;
+};
+
+// Interface of the audio processor used by the audio track to collect
+// statistics.
+class AudioProcessorInterface : public rtc::RefCountInterface {
+ public:
+ struct AudioProcessorStatistics {
+ bool typing_noise_detected = false;
+ AudioProcessingStats apm_statistics;
+ };
+
+ // Get audio processor statistics. The `has_remote_tracks` argument should be
+ // set if there are active remote tracks (this would usually be true during
+ // a call). If there are no remote tracks some of the stats will not be set by
+ // the AudioProcessor, because they only make sense if there is at least one
+ // remote track.
+ virtual AudioProcessorStatistics GetStats(bool has_remote_tracks) = 0;
+
+ protected:
+ ~AudioProcessorInterface() override = default;
+};
+
+class RTC_EXPORT AudioTrackInterface : public MediaStreamTrackInterface {
+ public:
+ // TODO(deadbeef): Figure out if the following interface should be const or
+ // not.
+ virtual AudioSourceInterface* GetSource() const = 0;
+
+ // Add/Remove a sink that will receive the audio data from the track.
+ virtual void AddSink(AudioTrackSinkInterface* sink) = 0;
+ virtual void RemoveSink(AudioTrackSinkInterface* sink) = 0;
+
+ // Get the signal level from the audio track.
+ // Return true on success, otherwise false.
+ // TODO(deadbeef): Change the interface to int GetSignalLevel() and pure
+ // virtual after it's implemented in chromium.
+ virtual bool GetSignalLevel(int* level);
+
+ // Get the audio processor used by the audio track. Return null if the track
+ // does not have any processor.
+ // TODO(deadbeef): Make the interface pure virtual.
+ virtual rtc::scoped_refptr<AudioProcessorInterface> GetAudioProcessor();
+
+ protected:
+ ~AudioTrackInterface() override = default;
+};
+
+typedef std::vector<rtc::scoped_refptr<AudioTrackInterface> > AudioTrackVector;
+typedef std::vector<rtc::scoped_refptr<VideoTrackInterface> > VideoTrackVector;
+
+// C++ version of https://www.w3.org/TR/mediacapture-streams/#mediastream.
+//
+// A major difference is that remote audio/video tracks (received by a
+// PeerConnection/RtpReceiver) are not synchronized simply by adding them to
+// the same stream; a session description with the correct "a=msid" attributes
+// must be pushed down.
+//
+// Thus, this interface acts as simply a container for tracks.
+class MediaStreamInterface : public rtc::RefCountInterface,
+ public NotifierInterface {
+ public:
+ virtual std::string id() const = 0;
+
+ virtual AudioTrackVector GetAudioTracks() = 0;
+ virtual VideoTrackVector GetVideoTracks() = 0;
+ virtual rtc::scoped_refptr<AudioTrackInterface> FindAudioTrack(
+ const std::string& track_id) = 0;
+ virtual rtc::scoped_refptr<VideoTrackInterface> FindVideoTrack(
+ const std::string& track_id) = 0;
+
+ // Takes ownership of added tracks.
+ // Note: Default implementations are for avoiding link time errors in
+ // implementations that mock this API.
+ // TODO(bugs.webrtc.org/13980): Remove default implementations.
+ virtual bool AddTrack(rtc::scoped_refptr<AudioTrackInterface> track) {
+ RTC_CHECK_NOTREACHED();
+ }
+ virtual bool AddTrack(rtc::scoped_refptr<VideoTrackInterface> track) {
+ RTC_CHECK_NOTREACHED();
+ }
+ virtual bool RemoveTrack(rtc::scoped_refptr<AudioTrackInterface> track) {
+ RTC_CHECK_NOTREACHED();
+ }
+ virtual bool RemoveTrack(rtc::scoped_refptr<VideoTrackInterface> track) {
+ RTC_CHECK_NOTREACHED();
+ }
+ // Deprecated: Should use scoped_refptr versions rather than pointers.
+ [[deprecated("Pass a scoped_refptr")]] virtual bool AddTrack(
+ AudioTrackInterface* track) {
+ return AddTrack(rtc::scoped_refptr<AudioTrackInterface>(track));
+ }
+ [[deprecated("Pass a scoped_refptr")]] virtual bool AddTrack(
+ VideoTrackInterface* track) {
+ return AddTrack(rtc::scoped_refptr<VideoTrackInterface>(track));
+ }
+ [[deprecated("Pass a scoped_refptr")]] virtual bool RemoveTrack(
+ AudioTrackInterface* track) {
+ return RemoveTrack(rtc::scoped_refptr<AudioTrackInterface>(track));
+ }
+ [[deprecated("Pass a scoped_refptr")]] virtual bool RemoveTrack(
+ VideoTrackInterface* track) {
+ return RemoveTrack(rtc::scoped_refptr<VideoTrackInterface>(track));
+ }
+
+ protected:
+ ~MediaStreamInterface() override = default;
+};
+
+} // namespace webrtc
+
+#endif // API_MEDIA_STREAM_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/media_stream_interface_gn/moz.build b/third_party/libwebrtc/api/media_stream_interface_gn/moz.build
new file mode 100644
index 0000000000..b80f10168f
--- /dev/null
+++ b/third_party/libwebrtc/api/media_stream_interface_gn/moz.build
@@ -0,0 +1,225 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/media_stream_interface.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("media_stream_interface_gn")
diff --git a/third_party/libwebrtc/api/media_stream_track.h b/third_party/libwebrtc/api/media_stream_track.h
new file mode 100644
index 0000000000..316dd788ef
--- /dev/null
+++ b/third_party/libwebrtc/api/media_stream_track.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_MEDIA_STREAM_TRACK_H_
+#define API_MEDIA_STREAM_TRACK_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "api/media_stream_interface.h"
+#include "api/notifier.h"
+
+namespace webrtc {
+
+// MediaTrack implements the interface common to AudioTrackInterface and
+// VideoTrackInterface.
+template <typename T>
+class MediaStreamTrack : public Notifier<T> {
+ public:
+ typedef typename T::TrackState TypedTrackState;
+
+ std::string id() const override { return id_; }
+ MediaStreamTrackInterface::TrackState state() const override {
+ return state_;
+ }
+ bool enabled() const override { return enabled_; }
+ bool set_enabled(bool enable) override {
+ bool fire_on_change = (enable != enabled_);
+ enabled_ = enable;
+ if (fire_on_change) {
+ Notifier<T>::FireOnChanged();
+ }
+ return fire_on_change;
+ }
+ void set_ended() { set_state(MediaStreamTrackInterface::TrackState::kEnded); }
+
+ protected:
+ explicit MediaStreamTrack(absl::string_view id)
+ : enabled_(true), id_(id), state_(MediaStreamTrackInterface::kLive) {}
+
+ bool set_state(MediaStreamTrackInterface::TrackState new_state) {
+ bool fire_on_change = (state_ != new_state);
+ state_ = new_state;
+ if (fire_on_change)
+ Notifier<T>::FireOnChanged();
+ return true;
+ }
+
+ private:
+ bool enabled_;
+ const std::string id_;
+ MediaStreamTrackInterface::TrackState state_;
+};
+
+} // namespace webrtc
+
+#endif // API_MEDIA_STREAM_TRACK_H_
diff --git a/third_party/libwebrtc/api/media_types.cc b/third_party/libwebrtc/api/media_types.cc
new file mode 100644
index 0000000000..5c7d55b876
--- /dev/null
+++ b/third_party/libwebrtc/api/media_types.cc
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/media_types.h"
+
+#include "rtc_base/checks.h"
+
+namespace cricket {
+
+const char kMediaTypeVideo[] = "video";
+const char kMediaTypeAudio[] = "audio";
+const char kMediaTypeData[] = "data";
+
+std::string MediaTypeToString(MediaType type) {
+ switch (type) {
+ case MEDIA_TYPE_AUDIO:
+ return kMediaTypeAudio;
+ case MEDIA_TYPE_VIDEO:
+ return kMediaTypeVideo;
+ case MEDIA_TYPE_DATA:
+ return kMediaTypeData;
+ case MEDIA_TYPE_UNSUPPORTED:
+ // Unsupported media stores the m=<mediatype> differently.
+ RTC_DCHECK_NOTREACHED();
+ return "";
+ }
+ RTC_CHECK_NOTREACHED();
+}
+
+} // namespace cricket
diff --git a/third_party/libwebrtc/api/media_types.h b/third_party/libwebrtc/api/media_types.h
new file mode 100644
index 0000000000..b2ff08c0c3
--- /dev/null
+++ b/third_party/libwebrtc/api/media_types.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_MEDIA_TYPES_H_
+#define API_MEDIA_TYPES_H_
+
+#include <string>
+
+#include "rtc_base/system/rtc_export.h"
+
+// The cricket and webrtc have separate definitions for what a media type is.
+// They're not compatible. Watch out for this.
+
+namespace cricket {
+
+enum MediaType {
+ MEDIA_TYPE_AUDIO,
+ MEDIA_TYPE_VIDEO,
+ MEDIA_TYPE_DATA,
+ MEDIA_TYPE_UNSUPPORTED
+};
+
+extern const char kMediaTypeAudio[];
+extern const char kMediaTypeVideo[];
+extern const char kMediaTypeData[];
+
+RTC_EXPORT std::string MediaTypeToString(MediaType type);
+
+} // namespace cricket
+
+namespace webrtc {
+
+enum class MediaType { ANY, AUDIO, VIDEO, DATA };
+
+} // namespace webrtc
+
+#endif // API_MEDIA_TYPES_H_
diff --git a/third_party/libwebrtc/api/metronome/BUILD.gn b/third_party/libwebrtc/api/metronome/BUILD.gn
new file mode 100644
index 0000000000..3d3d876df0
--- /dev/null
+++ b/third_party/libwebrtc/api/metronome/BUILD.gn
@@ -0,0 +1,19 @@
+# Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../webrtc.gni")
+
+rtc_source_set("metronome") {
+ visibility = [ "*" ]
+ sources = [ "metronome.h" ]
+ deps = [
+ "../../rtc_base/system:rtc_export",
+ "../task_queue",
+ "../units:time_delta",
+ ]
+}
diff --git a/third_party/libwebrtc/api/metronome/metronome.cc b/third_party/libwebrtc/api/metronome/metronome.cc
new file mode 100644
index 0000000000..8d74f928a0
--- /dev/null
+++ b/third_party/libwebrtc/api/metronome/metronome.cc
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/metronome/metronome.h"
+
+namespace webrtc {
+
+// TODO(crbug.com/1381982): Remove outdated methods.
+void Metronome::AddListener(TickListener* listener) {}
+void Metronome::RemoveListener(TickListener* listener) {}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/metronome/metronome.h b/third_party/libwebrtc/api/metronome/metronome.h
new file mode 100644
index 0000000000..a312b1c862
--- /dev/null
+++ b/third_party/libwebrtc/api/metronome/metronome.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_METRONOME_METRONOME_H_
+#define API_METRONOME_METRONOME_H_
+
+#include "api/task_queue/task_queue_base.h"
+#include "api/units/time_delta.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// The Metronome posts OnTick() calls requested with RequestCallOnNextTick.
+// The API is designed to be fully used from a single task queue. Scheduled
+// callbacks are executed on the same sequence as they were requested on. There
+// are no features implemented for cancellation. When that's needed, use e.g.
+// ScopedTaskSafety from the client.
+//
+// The metronome concept is still under experimentation, and may not be availble
+// in all platforms or applications. See https://crbug.com/1253787 for more
+// details.
+//
+// Metronome implementations must be thread-compatible.
+class RTC_EXPORT Metronome {
+ public:
+ virtual ~Metronome() = default;
+
+ // Requests a call to `callback` on the next tick. Scheduled callbacks are
+ // executed on the same sequence as they were requested on. There are no
+ // features for cancellation. When that's needed, use e.g. ScopedTaskSafety
+ // from the client.
+ virtual void RequestCallOnNextTick(absl::AnyInvocable<void() &&> callback) {}
+
+ // Returns the current tick period of the metronome.
+ virtual TimeDelta TickPeriod() const = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_METRONOME_METRONOME_H_
diff --git a/third_party/libwebrtc/api/metronome/metronome_gn/moz.build b/third_party/libwebrtc/api/metronome/metronome_gn/moz.build
new file mode 100644
index 0000000000..dce0ca4319
--- /dev/null
+++ b/third_party/libwebrtc/api/metronome/metronome_gn/moz.build
@@ -0,0 +1,205 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("metronome_gn")
diff --git a/third_party/libwebrtc/api/metronome/test/BUILD.gn b/third_party/libwebrtc/api/metronome/test/BUILD.gn
new file mode 100644
index 0000000000..f415d98a0b
--- /dev/null
+++ b/third_party/libwebrtc/api/metronome/test/BUILD.gn
@@ -0,0 +1,30 @@
+# Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+
+rtc_library("fake_metronome") {
+ testonly = true
+ sources = [
+ "fake_metronome.cc",
+ "fake_metronome.h",
+ ]
+ deps = [
+ "..:metronome",
+ "../..:priority",
+ "../..:sequence_checker",
+ "../../../rtc_base:macromagic",
+ "../../../rtc_base:rtc_event",
+ "../../../rtc_base:rtc_task_queue",
+ "../../../rtc_base/synchronization:mutex",
+ "../../../rtc_base/task_utils:repeating_task",
+ "../../../test:test_support",
+ "../../task_queue",
+ "../../units:time_delta",
+ ]
+}
diff --git a/third_party/libwebrtc/api/metronome/test/fake_metronome.cc b/third_party/libwebrtc/api/metronome/test/fake_metronome.cc
new file mode 100644
index 0000000000..025f7ce5a6
--- /dev/null
+++ b/third_party/libwebrtc/api/metronome/test/fake_metronome.cc
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/metronome/test/fake_metronome.h"
+
+#include <utility>
+#include <vector>
+
+#include "api/priority.h"
+#include "api/sequence_checker.h"
+#include "api/task_queue/task_queue_base.h"
+#include "api/task_queue/task_queue_factory.h"
+#include "api/units/time_delta.h"
+#include "rtc_base/event.h"
+#include "rtc_base/task_utils/repeating_task.h"
+
+namespace webrtc::test {
+
+ForcedTickMetronome::ForcedTickMetronome(TimeDelta tick_period)
+ : tick_period_(tick_period) {}
+
+void ForcedTickMetronome::RequestCallOnNextTick(
+ absl::AnyInvocable<void() &&> callback) {
+ callbacks_.push_back(std::move(callback));
+}
+
+TimeDelta ForcedTickMetronome::TickPeriod() const {
+ return tick_period_;
+}
+
+size_t ForcedTickMetronome::NumListeners() {
+ return callbacks_.size();
+}
+
+void ForcedTickMetronome::Tick() {
+ std::vector<absl::AnyInvocable<void() &&>> callbacks;
+ callbacks_.swap(callbacks);
+ for (auto& callback : callbacks)
+ std::move(callback)();
+}
+
+FakeMetronome::FakeMetronome(TimeDelta tick_period)
+ : tick_period_(tick_period) {}
+
+void FakeMetronome::RequestCallOnNextTick(
+ absl::AnyInvocable<void() &&> callback) {
+ TaskQueueBase* current = TaskQueueBase::Current();
+ callbacks_.push_back(std::move(callback));
+ if (callbacks_.size() == 1) {
+ current->PostDelayedTask(
+ [this] {
+ std::vector<absl::AnyInvocable<void() &&>> callbacks;
+ callbacks_.swap(callbacks);
+ for (auto& callback : callbacks)
+ std::move(callback)();
+ },
+ tick_period_);
+ }
+}
+
+TimeDelta FakeMetronome::TickPeriod() const {
+ return tick_period_;
+}
+
+} // namespace webrtc::test
diff --git a/third_party/libwebrtc/api/metronome/test/fake_metronome.h b/third_party/libwebrtc/api/metronome/test/fake_metronome.h
new file mode 100644
index 0000000000..73c938e9cd
--- /dev/null
+++ b/third_party/libwebrtc/api/metronome/test/fake_metronome.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_METRONOME_TEST_FAKE_METRONOME_H_
+#define API_METRONOME_TEST_FAKE_METRONOME_H_
+
+#include <memory>
+#include <set>
+#include <vector>
+
+#include "api/metronome/metronome.h"
+#include "api/task_queue/task_queue_base.h"
+#include "api/task_queue/task_queue_factory.h"
+#include "api/units/time_delta.h"
+#include "rtc_base/synchronization/mutex.h"
+#include "rtc_base/task_queue.h"
+#include "rtc_base/task_utils/repeating_task.h"
+#include "rtc_base/thread_annotations.h"
+
+namespace webrtc::test {
+
+// ForcedTickMetronome is a Metronome that ticks when `Tick()` is invoked.
+// The constructor argument `tick_period` returned in `TickPeriod()`.
+class ForcedTickMetronome : public Metronome {
+ public:
+ explicit ForcedTickMetronome(TimeDelta tick_period);
+
+ // Forces all TickListeners to run `OnTick`.
+ void Tick();
+ size_t NumListeners();
+
+ // Metronome implementation.
+ void RequestCallOnNextTick(absl::AnyInvocable<void() &&> callback) override;
+ TimeDelta TickPeriod() const override;
+
+ private:
+ const TimeDelta tick_period_;
+ std::vector<absl::AnyInvocable<void() &&>> callbacks_;
+};
+
+// FakeMetronome is a metronome that ticks based on a repeating task at the
+// `tick_period` provided in the constructor. It is designed for use with
+// simulated task queues for unit tests.
+//
+// `Stop()` must be called before destruction, as it cancels the metronome tick
+// on the proper task queue.
+class FakeMetronome : public Metronome {
+ public:
+ explicit FakeMetronome(TimeDelta tick_period);
+
+ // Metronome implementation.
+ void RequestCallOnNextTick(absl::AnyInvocable<void() &&> callback) override;
+ TimeDelta TickPeriod() const override;
+
+ private:
+ const TimeDelta tick_period_;
+ std::vector<absl::AnyInvocable<void() &&>> callbacks_;
+};
+
+} // namespace webrtc::test
+
+#endif // API_METRONOME_TEST_FAKE_METRONOME_H_
diff --git a/third_party/libwebrtc/api/neteq/BUILD.gn b/third_party/libwebrtc/api/neteq/BUILD.gn
new file mode 100644
index 0000000000..504fa059bb
--- /dev/null
+++ b/third_party/libwebrtc/api/neteq/BUILD.gn
@@ -0,0 +1,95 @@
+# Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../webrtc.gni")
+
+rtc_source_set("neteq_api") {
+ visibility = [ "*" ]
+ sources = [
+ "neteq.cc",
+ "neteq.h",
+ "neteq_factory.h",
+ ]
+
+ deps = [
+ "..:rtp_headers",
+ "..:rtp_packet_info",
+ "..:scoped_refptr",
+ "../../rtc_base:stringutils",
+ "../../system_wrappers:system_wrappers",
+ "../audio_codecs:audio_codecs_api",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_source_set("custom_neteq_factory") {
+ visibility = [ "*" ]
+ sources = [
+ "custom_neteq_factory.cc",
+ "custom_neteq_factory.h",
+ ]
+
+ deps = [
+ ":neteq_api",
+ ":neteq_controller_api",
+ "..:scoped_refptr",
+ "../../modules/audio_coding:neteq",
+ "../../system_wrappers:system_wrappers",
+ "../audio_codecs:audio_codecs_api",
+ ]
+}
+
+rtc_source_set("neteq_controller_api") {
+ visibility = [ "*" ]
+ sources = [
+ "neteq_controller.h",
+ "neteq_controller_factory.h",
+ ]
+
+ deps = [
+ ":neteq_api",
+ ":tick_timer",
+ "../../system_wrappers:system_wrappers",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_source_set("default_neteq_controller_factory") {
+ visibility = [ "*" ]
+ sources = [
+ "default_neteq_controller_factory.cc",
+ "default_neteq_controller_factory.h",
+ ]
+
+ deps = [
+ ":neteq_controller_api",
+ "../../modules/audio_coding:neteq",
+ ]
+}
+
+rtc_source_set("tick_timer") {
+ visibility = [ "*" ]
+ sources = [
+ "tick_timer.cc",
+ "tick_timer.h",
+ ]
+ deps = [
+ "../../rtc_base:checks",
+ ]
+}
+
+rtc_source_set("tick_timer_unittest") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "tick_timer_unittest.cc" ]
+ deps = [
+ ":tick_timer",
+ "../../test:test_support",
+ "//testing/gtest",
+ ]
+}
diff --git a/third_party/libwebrtc/api/neteq/DEPS b/third_party/libwebrtc/api/neteq/DEPS
new file mode 100644
index 0000000000..6c1c602b42
--- /dev/null
+++ b/third_party/libwebrtc/api/neteq/DEPS
@@ -0,0 +1,14 @@
+specific_include_rules = {
+ "custom_neteq_factory\.h": [
+ "+system_wrappers/include/clock.h",
+ ],
+ "default_neteq_factory\.h": [
+ "+system_wrappers/include/clock.h",
+ ],
+ "neteq_controller\.h": [
+ "+system_wrappers/include/clock.h",
+ ],
+ "neteq_factory\.h": [
+ "+system_wrappers/include/clock.h",
+ ],
+}
diff --git a/third_party/libwebrtc/api/neteq/OWNERS b/third_party/libwebrtc/api/neteq/OWNERS
new file mode 100644
index 0000000000..11257808f2
--- /dev/null
+++ b/third_party/libwebrtc/api/neteq/OWNERS
@@ -0,0 +1,3 @@
+ivoc@webrtc.org
+henrik.lundin@webrtc.org
+jakobi@webrtc.org
diff --git a/third_party/libwebrtc/api/neteq/custom_neteq_factory.cc b/third_party/libwebrtc/api/neteq/custom_neteq_factory.cc
new file mode 100644
index 0000000000..b2df5df9ff
--- /dev/null
+++ b/third_party/libwebrtc/api/neteq/custom_neteq_factory.cc
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/neteq/custom_neteq_factory.h"
+
+#include <utility>
+
+#include "modules/audio_coding/neteq/neteq_impl.h"
+
+namespace webrtc {
+
+CustomNetEqFactory::CustomNetEqFactory(
+ std::unique_ptr<NetEqControllerFactory> controller_factory)
+ : controller_factory_(std::move(controller_factory)) {}
+
+CustomNetEqFactory::~CustomNetEqFactory() = default;
+
+std::unique_ptr<NetEq> CustomNetEqFactory::CreateNetEq(
+ const NetEq::Config& config,
+ const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory,
+ Clock* clock) const {
+ return std::make_unique<NetEqImpl>(
+ config, NetEqImpl::Dependencies(config, clock, decoder_factory,
+ *controller_factory_));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/neteq/custom_neteq_factory.h b/third_party/libwebrtc/api/neteq/custom_neteq_factory.h
new file mode 100644
index 0000000000..d080f68e8e
--- /dev/null
+++ b/third_party/libwebrtc/api/neteq/custom_neteq_factory.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_NETEQ_CUSTOM_NETEQ_FACTORY_H_
+#define API_NETEQ_CUSTOM_NETEQ_FACTORY_H_
+
+#include <memory>
+
+#include "api/audio_codecs/audio_decoder_factory.h"
+#include "api/neteq/neteq_controller_factory.h"
+#include "api/neteq/neteq_factory.h"
+#include "api/scoped_refptr.h"
+#include "system_wrappers/include/clock.h"
+
+namespace webrtc {
+
+// This factory can be used to generate NetEq instances that make use of a
+// custom NetEqControllerFactory.
+class CustomNetEqFactory : public NetEqFactory {
+ public:
+ explicit CustomNetEqFactory(
+ std::unique_ptr<NetEqControllerFactory> controller_factory);
+ ~CustomNetEqFactory() override;
+ CustomNetEqFactory(const CustomNetEqFactory&) = delete;
+ CustomNetEqFactory& operator=(const CustomNetEqFactory&) = delete;
+
+ std::unique_ptr<NetEq> CreateNetEq(
+ const NetEq::Config& config,
+ const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory,
+ Clock* clock) const override;
+
+ private:
+ std::unique_ptr<NetEqControllerFactory> controller_factory_;
+};
+
+} // namespace webrtc
+#endif // API_NETEQ_CUSTOM_NETEQ_FACTORY_H_
diff --git a/third_party/libwebrtc/api/neteq/default_neteq_controller_factory.cc b/third_party/libwebrtc/api/neteq/default_neteq_controller_factory.cc
new file mode 100644
index 0000000000..22274dc7cc
--- /dev/null
+++ b/third_party/libwebrtc/api/neteq/default_neteq_controller_factory.cc
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/neteq/default_neteq_controller_factory.h"
+#include "modules/audio_coding/neteq/decision_logic.h"
+
+namespace webrtc {
+
+DefaultNetEqControllerFactory::DefaultNetEqControllerFactory() = default;
+DefaultNetEqControllerFactory::~DefaultNetEqControllerFactory() = default;
+
+std::unique_ptr<NetEqController>
+DefaultNetEqControllerFactory::CreateNetEqController(
+ const NetEqController::Config& config) const {
+ return std::make_unique<DecisionLogic>(config);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/neteq/default_neteq_controller_factory.h b/third_party/libwebrtc/api/neteq/default_neteq_controller_factory.h
new file mode 100644
index 0000000000..611afc2586
--- /dev/null
+++ b/third_party/libwebrtc/api/neteq/default_neteq_controller_factory.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_NETEQ_DEFAULT_NETEQ_CONTROLLER_FACTORY_H_
+#define API_NETEQ_DEFAULT_NETEQ_CONTROLLER_FACTORY_H_
+
+#include <memory>
+
+#include "api/neteq/neteq_controller_factory.h"
+
+namespace webrtc {
+
+// This NetEqControllerFactory will use WebRTC's built-in controller logic.
+class DefaultNetEqControllerFactory : public NetEqControllerFactory {
+ public:
+ DefaultNetEqControllerFactory();
+ ~DefaultNetEqControllerFactory() override;
+ DefaultNetEqControllerFactory(const DefaultNetEqControllerFactory&) = delete;
+ DefaultNetEqControllerFactory& operator=(
+ const DefaultNetEqControllerFactory&) = delete;
+
+ std::unique_ptr<NetEqController> CreateNetEqController(
+ const NetEqController::Config& config) const override;
+};
+
+} // namespace webrtc
+#endif // API_NETEQ_DEFAULT_NETEQ_CONTROLLER_FACTORY_H_
diff --git a/third_party/libwebrtc/api/neteq/default_neteq_controller_factory_gn/moz.build b/third_party/libwebrtc/api/neteq/default_neteq_controller_factory_gn/moz.build
new file mode 100644
index 0000000000..273be80f73
--- /dev/null
+++ b/third_party/libwebrtc/api/neteq/default_neteq_controller_factory_gn/moz.build
@@ -0,0 +1,232 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/neteq/default_neteq_controller_factory.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "rt"
+ ]
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "crypt32",
+ "iphlpapi",
+ "secur32",
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("default_neteq_controller_factory_gn")
diff --git a/third_party/libwebrtc/api/neteq/neteq.cc b/third_party/libwebrtc/api/neteq/neteq.cc
new file mode 100644
index 0000000000..155ddf2cf3
--- /dev/null
+++ b/third_party/libwebrtc/api/neteq/neteq.cc
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/neteq/neteq.h"
+
+#include "rtc_base/strings/string_builder.h"
+
+namespace webrtc {
+
+NetEq::Config::Config() = default;
+NetEq::Config::Config(const Config&) = default;
+NetEq::Config::Config(Config&&) = default;
+NetEq::Config::~Config() = default;
+NetEq::Config& NetEq::Config::operator=(const Config&) = default;
+NetEq::Config& NetEq::Config::operator=(Config&&) = default;
+
+std::string NetEq::Config::ToString() const {
+ char buf[1024];
+ rtc::SimpleStringBuilder ss(buf);
+ ss << "sample_rate_hz=" << sample_rate_hz << ", enable_post_decode_vad="
+ << (enable_post_decode_vad ? "true" : "false")
+ << ", max_packets_in_buffer=" << max_packets_in_buffer
+ << ", min_delay_ms=" << min_delay_ms << ", enable_fast_accelerate="
+ << (enable_fast_accelerate ? "true" : "false")
+ << ", enable_muted_state=" << (enable_muted_state ? "true" : "false")
+ << ", enable_rtx_handling=" << (enable_rtx_handling ? "true" : "false");
+ return ss.str();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/neteq/neteq.h b/third_party/libwebrtc/api/neteq/neteq.h
new file mode 100644
index 0000000000..5300c5601e
--- /dev/null
+++ b/third_party/libwebrtc/api/neteq/neteq.h
@@ -0,0 +1,322 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_NETEQ_NETEQ_H_
+#define API_NETEQ_NETEQ_H_
+
+#include <stddef.h> // Provide access to size_t.
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/audio_codecs/audio_codec_pair_id.h"
+#include "api/audio_codecs/audio_decoder.h"
+#include "api/audio_codecs/audio_format.h"
+#include "api/rtp_headers.h"
+#include "api/scoped_refptr.h"
+
+namespace webrtc {
+
+// Forward declarations.
+class AudioFrame;
+class AudioDecoderFactory;
+class Clock;
+
+struct NetEqNetworkStatistics {
+ uint16_t current_buffer_size_ms; // Current jitter buffer size in ms.
+ uint16_t preferred_buffer_size_ms; // Target buffer size in ms.
+ uint16_t jitter_peaks_found; // 1 if adding extra delay due to peaky
+ // jitter; 0 otherwise.
+ uint16_t expand_rate; // Fraction (of original stream) of synthesized
+ // audio inserted through expansion (in Q14).
+ uint16_t speech_expand_rate; // Fraction (of original stream) of synthesized
+ // speech inserted through expansion (in Q14).
+ uint16_t preemptive_rate; // Fraction of data inserted through pre-emptive
+ // expansion (in Q14).
+ uint16_t accelerate_rate; // Fraction of data removed through acceleration
+ // (in Q14).
+ uint16_t secondary_decoded_rate; // Fraction of data coming from FEC/RED
+ // decoding (in Q14).
+ uint16_t secondary_discarded_rate; // Fraction of discarded FEC/RED data (in
+ // Q14).
+ // Statistics for packet waiting times, i.e., the time between a packet
+ // arrives until it is decoded.
+ int mean_waiting_time_ms;
+ int median_waiting_time_ms;
+ int min_waiting_time_ms;
+ int max_waiting_time_ms;
+};
+
+// NetEq statistics that persist over the lifetime of the class.
+// These metrics are never reset.
+struct NetEqLifetimeStatistics {
+ // Stats below correspond to similarly-named fields in the WebRTC stats spec.
+ // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats
+ uint64_t total_samples_received = 0;
+ uint64_t concealed_samples = 0;
+ uint64_t concealment_events = 0;
+ uint64_t jitter_buffer_delay_ms = 0;
+ uint64_t jitter_buffer_emitted_count = 0;
+ uint64_t jitter_buffer_target_delay_ms = 0;
+ uint64_t jitter_buffer_minimum_delay_ms = 0;
+ uint64_t inserted_samples_for_deceleration = 0;
+ uint64_t removed_samples_for_acceleration = 0;
+ uint64_t silent_concealed_samples = 0;
+ uint64_t fec_packets_received = 0;
+ uint64_t fec_packets_discarded = 0;
+ uint64_t packets_discarded = 0;
+ // Below stats are not part of the spec.
+ uint64_t delayed_packet_outage_samples = 0;
+ // This is sum of relative packet arrival delays of received packets so far.
+ // Since end-to-end delay of a packet is difficult to measure and is not
+ // necessarily useful for measuring jitter buffer performance, we report a
+ // relative packet arrival delay. The relative packet arrival delay of a
+ // packet is defined as the arrival delay compared to the first packet
+ // received, given that it had zero delay. To avoid clock drift, the "first"
+ // packet can be made dynamic.
+ uint64_t relative_packet_arrival_delay_ms = 0;
+ uint64_t jitter_buffer_packets_received = 0;
+ // An interruption is a loss-concealment event lasting at least 150 ms. The
+ // two stats below count the number os such events and the total duration of
+ // these events.
+ int32_t interruption_count = 0;
+ int32_t total_interruption_duration_ms = 0;
+ // Total number of comfort noise samples generated during DTX.
+ uint64_t generated_noise_samples = 0;
+};
+
+// Metrics that describe the operations performed in NetEq, and the internal
+// state.
+struct NetEqOperationsAndState {
+ // These sample counters are cumulative, and don't reset. As a reference, the
+ // total number of output samples can be found in
+ // NetEqLifetimeStatistics::total_samples_received.
+ uint64_t preemptive_samples = 0;
+ uint64_t accelerate_samples = 0;
+ // Count of the number of buffer flushes.
+ uint64_t packet_buffer_flushes = 0;
+ // The statistics below are not cumulative.
+ // The waiting time of the last decoded packet.
+ uint64_t last_waiting_time_ms = 0;
+ // The sum of the packet and jitter buffer size in ms.
+ uint64_t current_buffer_size_ms = 0;
+ // The current frame size in ms.
+ uint64_t current_frame_size_ms = 0;
+ // Flag to indicate that the next packet is available.
+ bool next_packet_available = false;
+};
+
+// This is the interface class for NetEq.
+class NetEq {
+ public:
+ struct Config {
+ Config();
+ Config(const Config&);
+ Config(Config&&);
+ ~Config();
+ Config& operator=(const Config&);
+ Config& operator=(Config&&);
+
+ std::string ToString() const;
+
+ int sample_rate_hz = 48000; // Initial value. Will change with input data.
+ bool enable_post_decode_vad = false;
+ size_t max_packets_in_buffer = 200;
+ int max_delay_ms = 0;
+ int min_delay_ms = 0;
+ bool enable_fast_accelerate = false;
+ bool enable_muted_state = false;
+ bool enable_rtx_handling = false;
+ absl::optional<AudioCodecPairId> codec_pair_id;
+ bool for_test_no_time_stretching = false; // Use only for testing.
+ };
+
+ enum ReturnCodes { kOK = 0, kFail = -1 };
+
+ enum class Operation {
+ kNormal,
+ kMerge,
+ kExpand,
+ kAccelerate,
+ kFastAccelerate,
+ kPreemptiveExpand,
+ kRfc3389Cng,
+ kRfc3389CngNoPacket,
+ kCodecInternalCng,
+ kDtmf,
+ kUndefined,
+ };
+
+ enum class Mode {
+ kNormal,
+ kExpand,
+ kMerge,
+ kAccelerateSuccess,
+ kAccelerateLowEnergy,
+ kAccelerateFail,
+ kPreemptiveExpandSuccess,
+ kPreemptiveExpandLowEnergy,
+ kPreemptiveExpandFail,
+ kRfc3389Cng,
+ kCodecInternalCng,
+ kCodecPlc,
+ kDtmf,
+ kError,
+ kUndefined,
+ };
+
+ // Return type for GetDecoderFormat.
+ struct DecoderFormat {
+ int sample_rate_hz;
+ int num_channels;
+ SdpAudioFormat sdp_format;
+ };
+
+ virtual ~NetEq() {}
+
+ // Inserts a new packet into NetEq.
+ // Returns 0 on success, -1 on failure.
+ virtual int InsertPacket(const RTPHeader& rtp_header,
+ rtc::ArrayView<const uint8_t> payload) = 0;
+
+ // Lets NetEq know that a packet arrived with an empty payload. This typically
+ // happens when empty packets are used for probing the network channel, and
+ // these packets use RTP sequence numbers from the same series as the actual
+ // audio packets.
+ virtual void InsertEmptyPacket(const RTPHeader& rtp_header) = 0;
+
+ // Instructs NetEq to deliver 10 ms of audio data. The data is written to
+ // `audio_frame`. All data in `audio_frame` is wiped; `data_`, `speech_type_`,
+ // `num_channels_`, `sample_rate_hz_`, `samples_per_channel_`, and
+ // `vad_activity_` are updated upon success. If an error is returned, some
+ // fields may not have been updated, or may contain inconsistent values.
+ // If muted state is enabled (through Config::enable_muted_state), `muted`
+ // may be set to true after a prolonged expand period. When this happens, the
+ // `data_` in `audio_frame` is not written, but should be interpreted as being
+ // all zeros. For testing purposes, an override can be supplied in the
+ // `action_override` argument, which will cause NetEq to take this action
+ // next, instead of the action it would normally choose. An optional output
+ // argument for fetching the current sample rate can be provided, which
+ // will return the same value as last_output_sample_rate_hz() but will avoid
+ // additional synchronization.
+ // Returns kOK on success, or kFail in case of an error.
+ virtual int GetAudio(
+ AudioFrame* audio_frame,
+ bool* muted,
+ int* current_sample_rate_hz = nullptr,
+ absl::optional<Operation> action_override = absl::nullopt) = 0;
+
+ // Replaces the current set of decoders with the given one.
+ virtual void SetCodecs(const std::map<int, SdpAudioFormat>& codecs) = 0;
+
+ // Associates `rtp_payload_type` with the given codec, which NetEq will
+ // instantiate when it needs it. Returns true iff successful.
+ virtual bool RegisterPayloadType(int rtp_payload_type,
+ const SdpAudioFormat& audio_format) = 0;
+
+ // Removes `rtp_payload_type` from the codec database. Returns 0 on success,
+ // -1 on failure. Removing a payload type that is not registered is ok and
+ // will not result in an error.
+ virtual int RemovePayloadType(uint8_t rtp_payload_type) = 0;
+
+ // Removes all payload types from the codec database.
+ virtual void RemoveAllPayloadTypes() = 0;
+
+ // Sets a minimum delay in millisecond for packet buffer. The minimum is
+ // maintained unless a higher latency is dictated by channel condition.
+ // Returns true if the minimum is successfully applied, otherwise false is
+ // returned.
+ virtual bool SetMinimumDelay(int delay_ms) = 0;
+
+ // Sets a maximum delay in milliseconds for packet buffer. The latency will
+ // not exceed the given value, even required delay (given the channel
+ // conditions) is higher. Calling this method has the same effect as setting
+ // the `max_delay_ms` value in the NetEq::Config struct.
+ virtual bool SetMaximumDelay(int delay_ms) = 0;
+
+ // Sets a base minimum delay in milliseconds for packet buffer. The minimum
+ // delay which is set via `SetMinimumDelay` can't be lower than base minimum
+ // delay. Calling this method is similar to setting the `min_delay_ms` value
+ // in the NetEq::Config struct. Returns true if the base minimum is
+ // successfully applied, otherwise false is returned.
+ virtual bool SetBaseMinimumDelayMs(int delay_ms) = 0;
+
+ // Returns current value of base minimum delay in milliseconds.
+ virtual int GetBaseMinimumDelayMs() const = 0;
+
+ // Returns the current target delay in ms. This includes any extra delay
+ // requested through SetMinimumDelay.
+ virtual int TargetDelayMs() const = 0;
+
+ // Returns the current total delay (packet buffer and sync buffer) in ms,
+ // with smoothing applied to even out short-time fluctuations due to jitter.
+ // The packet buffer part of the delay is not updated during DTX/CNG periods.
+ virtual int FilteredCurrentDelayMs() const = 0;
+
+ // Writes the current network statistics to `stats`. The statistics are reset
+ // after the call.
+ virtual int NetworkStatistics(NetEqNetworkStatistics* stats) = 0;
+
+ // Current values only, not resetting any state.
+ virtual NetEqNetworkStatistics CurrentNetworkStatistics() const = 0;
+
+ // Returns a copy of this class's lifetime statistics. These statistics are
+ // never reset.
+ virtual NetEqLifetimeStatistics GetLifetimeStatistics() const = 0;
+
+ // Returns statistics about the performed operations and internal state. These
+ // statistics are never reset.
+ virtual NetEqOperationsAndState GetOperationsAndState() const = 0;
+
+ // Enables post-decode VAD. When enabled, GetAudio() will return
+ // kOutputVADPassive when the signal contains no speech.
+ virtual void EnableVad() = 0;
+
+ // Disables post-decode VAD.
+ virtual void DisableVad() = 0;
+
+ // Returns the RTP timestamp for the last sample delivered by GetAudio().
+ // The return value will be empty if no valid timestamp is available.
+ virtual absl::optional<uint32_t> GetPlayoutTimestamp() const = 0;
+
+ // Returns the sample rate in Hz of the audio produced in the last GetAudio
+ // call. If GetAudio has not been called yet, the configured sample rate
+ // (Config::sample_rate_hz) is returned.
+ virtual int last_output_sample_rate_hz() const = 0;
+
+ // Returns the decoder info for the given payload type. Returns empty if no
+ // such payload type was registered.
+ virtual absl::optional<DecoderFormat> GetDecoderFormat(
+ int payload_type) const = 0;
+
+ // Flushes both the packet buffer and the sync buffer.
+ virtual void FlushBuffers() = 0;
+
+ // Enables NACK and sets the maximum size of the NACK list, which should be
+ // positive and no larger than Nack::kNackListSizeLimit. If NACK is already
+ // enabled then the maximum NACK list size is modified accordingly.
+ virtual void EnableNack(size_t max_nack_list_size) = 0;
+
+ virtual void DisableNack() = 0;
+
+ // Returns a list of RTP sequence numbers corresponding to packets to be
+ // retransmitted, given an estimate of the round-trip time in milliseconds.
+ virtual std::vector<uint16_t> GetNackList(
+ int64_t round_trip_time_ms) const = 0;
+
+ // Returns the length of the audio yet to play in the sync buffer.
+ // Mainly intended for testing.
+ virtual int SyncBufferSizeMs() const = 0;
+};
+
+} // namespace webrtc
+#endif // API_NETEQ_NETEQ_H_
diff --git a/third_party/libwebrtc/api/neteq/neteq_api_gn/moz.build b/third_party/libwebrtc/api/neteq/neteq_api_gn/moz.build
new file mode 100644
index 0000000000..f06937f581
--- /dev/null
+++ b/third_party/libwebrtc/api/neteq/neteq_api_gn/moz.build
@@ -0,0 +1,232 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/neteq/neteq.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "rt"
+ ]
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "crypt32",
+ "iphlpapi",
+ "secur32",
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("neteq_api_gn")
diff --git a/third_party/libwebrtc/api/neteq/neteq_controller.h b/third_party/libwebrtc/api/neteq/neteq_controller.h
new file mode 100644
index 0000000000..f0101d3d1a
--- /dev/null
+++ b/third_party/libwebrtc/api/neteq/neteq_controller.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_NETEQ_NETEQ_CONTROLLER_H_
+#define API_NETEQ_NETEQ_CONTROLLER_H_
+
+#include <cstddef>
+#include <cstdint>
+
+#include <functional>
+#include <memory>
+
+#include "absl/types/optional.h"
+#include "api/neteq/neteq.h"
+#include "api/neteq/tick_timer.h"
+#include "system_wrappers/include/clock.h"
+
+namespace webrtc {
+
+// Decides the actions that NetEq should take. This affects the behavior of the
+// jitter buffer, and how it reacts to network conditions.
+// This class will undergo substantial refactoring in the near future, and the
+// API is expected to undergo significant changes. A target API is given below:
+//
+// class NetEqController {
+// public:
+// // Resets object to a clean state.
+// void Reset();
+// // Given NetEq status, make a decision.
+// Operation GetDecision(NetEqStatus neteq_status);
+// // Register every packet received.
+// void RegisterPacket(PacketInfo packet_info);
+// // Register empty packet.
+// void RegisterEmptyPacket();
+// // Register a codec switching.
+// void CodecSwithed();
+// // Sets the sample rate.
+// void SetSampleRate(int fs_hz);
+// // Sets the packet length in samples.
+// void SetPacketLengthSamples();
+// // Sets maximum delay.
+// void SetMaximumDelay(int delay_ms);
+// // Sets mininum delay.
+// void SetMinimumDelay(int delay_ms);
+// // Sets base mininum delay.
+// void SetBaseMinimumDelay(int delay_ms);
+// // Gets target buffer level.
+// int GetTargetBufferLevelMs() const;
+// // Gets filtered buffer level.
+// int GetFilteredBufferLevel() const;
+// // Gets base minimum delay.
+// int GetBaseMinimumDelay() const;
+// }
+
+class NetEqController {
+ public:
+ // This struct is used to create a NetEqController.
+ struct Config {
+ bool allow_time_stretching;
+ bool enable_rtx_handling;
+ int max_packets_in_buffer;
+ int base_min_delay_ms;
+ TickTimer* tick_timer;
+ webrtc::Clock* clock = nullptr;
+ };
+
+ struct PacketInfo {
+ uint32_t timestamp;
+ bool is_dtx;
+ bool is_cng;
+ };
+
+ struct PacketBufferInfo {
+ bool dtx_or_cng;
+ size_t num_samples;
+ size_t span_samples;
+ size_t span_samples_no_dtx;
+ size_t num_packets;
+ };
+
+ struct NetEqStatus {
+ uint32_t target_timestamp;
+ int16_t expand_mutefactor;
+ size_t last_packet_samples;
+ absl::optional<PacketInfo> next_packet;
+ NetEq::Mode last_mode;
+ bool play_dtmf;
+ size_t generated_noise_samples;
+ PacketBufferInfo packet_buffer_info;
+ size_t sync_buffer_samples;
+ };
+
+ struct PacketArrivedInfo {
+ size_t packet_length_samples;
+ uint32_t main_timestamp;
+ uint16_t main_sequence_number;
+ bool is_cng_or_dtmf;
+ bool is_dtx;
+ bool buffer_flush;
+ };
+
+ virtual ~NetEqController() = default;
+
+ // Resets object to a clean state.
+ virtual void Reset() = 0;
+
+ // Resets parts of the state. Typically done when switching codecs.
+ virtual void SoftReset() = 0;
+
+ // Given info about the latest received packet, and current jitter buffer
+ // status, returns the operation. `target_timestamp` and `expand_mutefactor`
+ // are provided for reference. `last_packet_samples` is the number of samples
+ // obtained from the last decoded frame. If there is a packet available, it
+ // should be supplied in `packet`. The mode resulting from the last call to
+ // NetEqImpl::GetAudio is supplied in `last_mode`. If there is a DTMF event to
+ // play, `play_dtmf` should be set to true. The output variable
+ // `reset_decoder` will be set to true if a reset is required; otherwise it is
+ // left unchanged (i.e., it can remain true if it was true before the call).
+ virtual NetEq::Operation GetDecision(const NetEqStatus& status,
+ bool* reset_decoder) = 0;
+
+ // Inform NetEqController that an empty packet has arrived.
+ virtual void RegisterEmptyPacket() = 0;
+
+ // Sets the sample rate and the output block size.
+ virtual void SetSampleRate(int fs_hz, size_t output_size_samples) = 0;
+
+ // Sets a minimum or maximum delay in millisecond.
+ // Returns true if the delay bound is successfully applied, otherwise false.
+ virtual bool SetMaximumDelay(int delay_ms) = 0;
+ virtual bool SetMinimumDelay(int delay_ms) = 0;
+
+ // Sets a base minimum delay in milliseconds for packet buffer. The effective
+ // minimum delay can't be lower than base minimum delay, even if a lower value
+ // is set using SetMinimumDelay.
+ // Returns true if the base minimum is successfully applied, otherwise false.
+ virtual bool SetBaseMinimumDelay(int delay_ms) = 0;
+ virtual int GetBaseMinimumDelay() const = 0;
+
+ // These methods test the `cng_state_` for different conditions.
+ virtual bool CngRfc3389On() const = 0;
+ virtual bool CngOff() const = 0;
+
+ // Resets the `cng_state_` to kCngOff.
+ virtual void SetCngOff() = 0;
+
+ // Reports back to DecisionLogic whether the decision to do expand remains or
+ // not. Note that this is necessary, since an expand decision can be changed
+ // to kNormal in NetEqImpl::GetDecision if there is still enough data in the
+ // sync buffer.
+ virtual void ExpandDecision(NetEq::Operation operation) = 0;
+
+ // Adds `value` to `sample_memory_`.
+ virtual void AddSampleMemory(int32_t value) = 0;
+
+ // Returns the target buffer level in ms.
+ virtual int TargetLevelMs() const = 0;
+
+ // Returns the target buffer level in ms as it would be if no minimum or
+ // maximum delay was set.
+ // TODO(bugs.webrtc.org/14270): Make pure virtual once all implementations are
+ // updated.
+ virtual int UnlimitedTargetLevelMs() const { return 0; }
+
+ // Notify the NetEqController that a packet has arrived. Returns the relative
+ // arrival delay, if it can be computed.
+ virtual absl::optional<int> PacketArrived(int fs_hz,
+ bool should_update_stats,
+ const PacketArrivedInfo& info) = 0;
+
+ // Notify the NetEqController that we are currently in muted state.
+ // TODO(bugs.webrtc.org/14270): Make pure virtual when downstream is updated.
+ virtual void NotifyMutedState() {}
+
+ // Returns true if a peak was found.
+ virtual bool PeakFound() const = 0;
+
+ // Get the filtered buffer level in samples.
+ virtual int GetFilteredBufferLevel() const = 0;
+
+ // Accessors and mutators.
+ virtual void set_sample_memory(int32_t value) = 0;
+ virtual size_t noise_fast_forward() const = 0;
+ virtual size_t packet_length_samples() const = 0;
+ virtual void set_packet_length_samples(size_t value) = 0;
+ virtual void set_prev_time_scale(bool value) = 0;
+};
+
+} // namespace webrtc
+#endif // API_NETEQ_NETEQ_CONTROLLER_H_
diff --git a/third_party/libwebrtc/api/neteq/neteq_controller_api_gn/moz.build b/third_party/libwebrtc/api/neteq/neteq_controller_api_gn/moz.build
new file mode 100644
index 0000000000..d09b5aed53
--- /dev/null
+++ b/third_party/libwebrtc/api/neteq/neteq_controller_api_gn/moz.build
@@ -0,0 +1,216 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "rt"
+ ]
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "crypt32",
+ "iphlpapi",
+ "secur32",
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("neteq_controller_api_gn")
diff --git a/third_party/libwebrtc/api/neteq/neteq_controller_factory.h b/third_party/libwebrtc/api/neteq/neteq_controller_factory.h
new file mode 100644
index 0000000000..9aba8a21a7
--- /dev/null
+++ b/third_party/libwebrtc/api/neteq/neteq_controller_factory.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_NETEQ_NETEQ_CONTROLLER_FACTORY_H_
+#define API_NETEQ_NETEQ_CONTROLLER_FACTORY_H_
+
+#include <memory>
+
+#include "api/neteq/neteq_controller.h"
+
+namespace webrtc {
+
+// Creates NetEqController instances using the settings provided in the config
+// struct.
+class NetEqControllerFactory {
+ public:
+ virtual ~NetEqControllerFactory() = default;
+
+ // Creates a new NetEqController object, with parameters set in `config`.
+ virtual std::unique_ptr<NetEqController> CreateNetEqController(
+ const NetEqController::Config& config) const = 0;
+};
+
+} // namespace webrtc
+#endif // API_NETEQ_NETEQ_CONTROLLER_FACTORY_H_
diff --git a/third_party/libwebrtc/api/neteq/neteq_factory.h b/third_party/libwebrtc/api/neteq/neteq_factory.h
new file mode 100644
index 0000000000..526a1282f5
--- /dev/null
+++ b/third_party/libwebrtc/api/neteq/neteq_factory.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_NETEQ_NETEQ_FACTORY_H_
+#define API_NETEQ_NETEQ_FACTORY_H_
+
+#include <memory>
+
+#include "api/audio_codecs/audio_decoder_factory.h"
+#include "api/neteq/neteq.h"
+#include "system_wrappers/include/clock.h"
+
+namespace webrtc {
+
+// Creates NetEq instances using the settings provided in the config struct.
+class NetEqFactory {
+ public:
+ virtual ~NetEqFactory() = default;
+
+ // Creates a new NetEq object, with parameters set in `config`. The `config`
+ // object will only have to be valid for the duration of the call to this
+ // method.
+ virtual std::unique_ptr<NetEq> CreateNetEq(
+ const NetEq::Config& config,
+ const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory,
+ Clock* clock) const = 0;
+};
+
+} // namespace webrtc
+#endif // API_NETEQ_NETEQ_FACTORY_H_
diff --git a/third_party/libwebrtc/api/neteq/tick_timer.cc b/third_party/libwebrtc/api/neteq/tick_timer.cc
new file mode 100644
index 0000000000..8f60bf48bf
--- /dev/null
+++ b/third_party/libwebrtc/api/neteq/tick_timer.cc
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/neteq/tick_timer.h"
+
+namespace webrtc {
+
+TickTimer::Stopwatch::Stopwatch(const TickTimer& ticktimer)
+ : ticktimer_(ticktimer), starttick_(ticktimer.ticks()) {}
+
+TickTimer::Countdown::Countdown(const TickTimer& ticktimer,
+ uint64_t ticks_to_count)
+ : stopwatch_(ticktimer.GetNewStopwatch()),
+ ticks_to_count_(ticks_to_count) {}
+
+TickTimer::Countdown::~Countdown() = default;
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/neteq/tick_timer.h b/third_party/libwebrtc/api/neteq/tick_timer.h
new file mode 100644
index 0000000000..e3f54a4522
--- /dev/null
+++ b/third_party/libwebrtc/api/neteq/tick_timer.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_NETEQ_TICK_TIMER_H_
+#define API_NETEQ_TICK_TIMER_H_
+
+#include <stdint.h>
+
+#include <memory>
+
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+// Implements a time counter. The counter is advanced with the Increment()
+// methods, and is queried with the ticks() accessor. It is assumed that one
+// "tick" of the counter corresponds to 10 ms.
+// A TickTimer object can provide two types of associated time-measuring
+// objects: Stopwatch and Countdown.
+class TickTimer {
+ public:
+ // Stopwatch measures time elapsed since it was started, by querying the
+ // associated TickTimer for the current time. The intended use is to request a
+ // new Stopwatch object from a TickTimer object with the GetNewStopwatch()
+ // method. Note: since the Stopwatch object contains a reference to the
+ // TickTimer it is associated with, it cannot outlive the TickTimer.
+ class Stopwatch {
+ public:
+ explicit Stopwatch(const TickTimer& ticktimer);
+
+ uint64_t ElapsedTicks() const { return ticktimer_.ticks() - starttick_; }
+
+ uint64_t ElapsedMs() const {
+ const uint64_t elapsed_ticks = ticktimer_.ticks() - starttick_;
+ const int ms_per_tick = ticktimer_.ms_per_tick();
+ return elapsed_ticks < UINT64_MAX / ms_per_tick
+ ? elapsed_ticks * ms_per_tick
+ : UINT64_MAX;
+ }
+
+ private:
+ const TickTimer& ticktimer_;
+ const uint64_t starttick_;
+ };
+
+ // Countdown counts down from a given start value with each tick of the
+ // associated TickTimer, until zero is reached. The Finished() method will
+ // return true if zero has been reached, false otherwise. The intended use is
+ // to request a new Countdown object from a TickTimer object with the
+ // GetNewCountdown() method. Note: since the Countdown object contains a
+ // reference to the TickTimer it is associated with, it cannot outlive the
+ // TickTimer.
+ class Countdown {
+ public:
+ Countdown(const TickTimer& ticktimer, uint64_t ticks_to_count);
+
+ ~Countdown();
+
+ bool Finished() const {
+ return stopwatch_->ElapsedTicks() >= ticks_to_count_;
+ }
+
+ private:
+ const std::unique_ptr<Stopwatch> stopwatch_;
+ const uint64_t ticks_to_count_;
+ };
+
+ TickTimer() : TickTimer(10) {}
+ explicit TickTimer(int ms_per_tick) : ms_per_tick_(ms_per_tick) {
+ RTC_DCHECK_GT(ms_per_tick_, 0);
+ }
+
+ TickTimer(const TickTimer&) = delete;
+ TickTimer& operator=(const TickTimer&) = delete;
+
+ void Increment() { ++ticks_; }
+
+ // Mainly intended for testing.
+ void Increment(uint64_t x) { ticks_ += x; }
+
+ uint64_t ticks() const { return ticks_; }
+
+ int ms_per_tick() const { return ms_per_tick_; }
+
+ // Returns a new Stopwatch object, based on the current TickTimer. Note that
+ // the new Stopwatch object contains a reference to the current TickTimer,
+ // and must therefore not outlive the TickTimer.
+ std::unique_ptr<Stopwatch> GetNewStopwatch() const {
+ return std::unique_ptr<Stopwatch>(new Stopwatch(*this));
+ }
+
+ // Returns a new Countdown object, based on the current TickTimer. Note that
+ // the new Countdown object contains a reference to the current TickTimer,
+ // and must therefore not outlive the TickTimer.
+ std::unique_ptr<Countdown> GetNewCountdown(uint64_t ticks_to_count) const {
+ return std::unique_ptr<Countdown>(new Countdown(*this, ticks_to_count));
+ }
+
+ private:
+ uint64_t ticks_ = 0;
+ const int ms_per_tick_;
+};
+
+} // namespace webrtc
+#endif // API_NETEQ_TICK_TIMER_H_
diff --git a/third_party/libwebrtc/api/neteq/tick_timer_gn/moz.build b/third_party/libwebrtc/api/neteq/tick_timer_gn/moz.build
new file mode 100644
index 0000000000..0125225509
--- /dev/null
+++ b/third_party/libwebrtc/api/neteq/tick_timer_gn/moz.build
@@ -0,0 +1,221 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/neteq/tick_timer.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("tick_timer_gn")
diff --git a/third_party/libwebrtc/api/neteq/tick_timer_unittest.cc b/third_party/libwebrtc/api/neteq/tick_timer_unittest.cc
new file mode 100644
index 0000000000..863c0117f4
--- /dev/null
+++ b/third_party/libwebrtc/api/neteq/tick_timer_unittest.cc
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/neteq/tick_timer.h"
+
+#include <memory>
+
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+// Verify that the default value for ms_per_tick is 10.
+TEST(TickTimer, DefaultMsPerTick) {
+ TickTimer tt;
+ EXPECT_EQ(10, tt.ms_per_tick());
+}
+
+TEST(TickTimer, CustomMsPerTick) {
+ TickTimer tt(17);
+ EXPECT_EQ(17, tt.ms_per_tick());
+}
+
+TEST(TickTimer, Increment) {
+ TickTimer tt;
+ EXPECT_EQ(0u, tt.ticks());
+ tt.Increment();
+ EXPECT_EQ(1u, tt.ticks());
+
+ for (int i = 0; i < 17; ++i) {
+ tt.Increment();
+ }
+ EXPECT_EQ(18u, tt.ticks());
+
+ tt.Increment(17);
+ EXPECT_EQ(35u, tt.ticks());
+}
+
+TEST(TickTimer, WrapAround) {
+ TickTimer tt;
+ tt.Increment(UINT64_MAX);
+ EXPECT_EQ(UINT64_MAX, tt.ticks());
+ tt.Increment();
+ EXPECT_EQ(0u, tt.ticks());
+}
+
+TEST(TickTimer, Stopwatch) {
+ TickTimer tt;
+ // Increment it a "random" number of steps.
+ tt.Increment(17);
+
+ std::unique_ptr<TickTimer::Stopwatch> sw = tt.GetNewStopwatch();
+ ASSERT_TRUE(sw);
+
+ EXPECT_EQ(0u, sw->ElapsedTicks()); // Starts at zero.
+ EXPECT_EQ(0u, sw->ElapsedMs());
+ tt.Increment();
+ EXPECT_EQ(1u, sw->ElapsedTicks()); // Increases with the TickTimer.
+ EXPECT_EQ(10u, sw->ElapsedMs());
+}
+
+TEST(TickTimer, StopwatchWrapAround) {
+ TickTimer tt;
+ tt.Increment(UINT64_MAX);
+
+ std::unique_ptr<TickTimer::Stopwatch> sw = tt.GetNewStopwatch();
+ ASSERT_TRUE(sw);
+
+ tt.Increment();
+ EXPECT_EQ(0u, tt.ticks());
+ EXPECT_EQ(1u, sw->ElapsedTicks());
+ EXPECT_EQ(10u, sw->ElapsedMs());
+
+ tt.Increment();
+ EXPECT_EQ(1u, tt.ticks());
+ EXPECT_EQ(2u, sw->ElapsedTicks());
+ EXPECT_EQ(20u, sw->ElapsedMs());
+}
+
+TEST(TickTimer, StopwatchMsOverflow) {
+ TickTimer tt;
+ std::unique_ptr<TickTimer::Stopwatch> sw = tt.GetNewStopwatch();
+ ASSERT_TRUE(sw);
+
+ tt.Increment(UINT64_MAX / 10);
+ EXPECT_EQ(UINT64_MAX, sw->ElapsedMs());
+
+ tt.Increment();
+ EXPECT_EQ(UINT64_MAX, sw->ElapsedMs());
+
+ tt.Increment(UINT64_MAX - tt.ticks());
+ EXPECT_EQ(UINT64_MAX, tt.ticks());
+ EXPECT_EQ(UINT64_MAX, sw->ElapsedMs());
+}
+
+TEST(TickTimer, StopwatchWithCustomTicktime) {
+ const int kMsPerTick = 17;
+ TickTimer tt(kMsPerTick);
+ std::unique_ptr<TickTimer::Stopwatch> sw = tt.GetNewStopwatch();
+ ASSERT_TRUE(sw);
+
+ EXPECT_EQ(0u, sw->ElapsedMs());
+ tt.Increment();
+ EXPECT_EQ(static_cast<uint64_t>(kMsPerTick), sw->ElapsedMs());
+}
+
+TEST(TickTimer, Countdown) {
+ TickTimer tt;
+ // Increment it a "random" number of steps.
+ tt.Increment(4711);
+
+ std::unique_ptr<TickTimer::Countdown> cd = tt.GetNewCountdown(17);
+ ASSERT_TRUE(cd);
+
+ EXPECT_FALSE(cd->Finished());
+ tt.Increment();
+ EXPECT_FALSE(cd->Finished());
+
+ tt.Increment(16); // Total increment is now 17.
+ EXPECT_TRUE(cd->Finished());
+
+ // Further increments do not change the state.
+ tt.Increment();
+ EXPECT_TRUE(cd->Finished());
+ tt.Increment(1234);
+ EXPECT_TRUE(cd->Finished());
+}
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/network_state_predictor.h b/third_party/libwebrtc/api/network_state_predictor.h
new file mode 100644
index 0000000000..9cf5ab6f02
--- /dev/null
+++ b/third_party/libwebrtc/api/network_state_predictor.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_NETWORK_STATE_PREDICTOR_H_
+#define API_NETWORK_STATE_PREDICTOR_H_
+
+#include <memory>
+#include <vector>
+
+namespace webrtc {
+
+enum class BandwidthUsage {
+ kBwNormal = 0,
+ kBwUnderusing = 1,
+ kBwOverusing = 2,
+ kLast
+};
+
+// TODO(yinwa): work in progress. API in class NetworkStatePredictor should not
+// be used by other users until this comment is removed.
+
+// NetworkStatePredictor predict network state based on current network metrics.
+// Usage:
+// Setup by calling Initialize.
+// For each update, call Update. Update returns network state
+// prediction.
+class NetworkStatePredictor {
+ public:
+ virtual ~NetworkStatePredictor() {}
+
+ // Returns current network state prediction.
+ // Inputs: send_time_ms - packet send time.
+ // arrival_time_ms - packet arrival time.
+ // network_state - computed network state.
+ virtual BandwidthUsage Update(int64_t send_time_ms,
+ int64_t arrival_time_ms,
+ BandwidthUsage network_state) = 0;
+};
+
+class NetworkStatePredictorFactoryInterface {
+ public:
+ virtual std::unique_ptr<NetworkStatePredictor>
+ CreateNetworkStatePredictor() = 0;
+ virtual ~NetworkStatePredictorFactoryInterface() = default;
+};
+
+} // namespace webrtc
+
+#endif // API_NETWORK_STATE_PREDICTOR_H_
diff --git a/third_party/libwebrtc/api/network_state_predictor_api_gn/moz.build b/third_party/libwebrtc/api/network_state_predictor_api_gn/moz.build
new file mode 100644
index 0000000000..2a95233bda
--- /dev/null
+++ b/third_party/libwebrtc/api/network_state_predictor_api_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("network_state_predictor_api_gn")
diff --git a/third_party/libwebrtc/api/notifier.h b/third_party/libwebrtc/api/notifier.h
new file mode 100644
index 0000000000..fc2480e00a
--- /dev/null
+++ b/third_party/libwebrtc/api/notifier.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_NOTIFIER_H_
+#define API_NOTIFIER_H_
+
+#include <list>
+
+#include "api/media_stream_interface.h"
+#include "api/sequence_checker.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/system/no_unique_address.h"
+
+namespace webrtc {
+
+// Implements a template version of a notifier.
+// TODO(deadbeef): This is an implementation detail; move out of api/.
+template <class T>
+class Notifier : public T {
+ public:
+ Notifier() { sequence_checker_.Detach(); }
+
+ virtual void RegisterObserver(ObserverInterface* observer) {
+ RTC_DCHECK_RUN_ON(&sequence_checker_);
+ RTC_DCHECK(observer != nullptr);
+ observers_.push_back(observer);
+ }
+
+ virtual void UnregisterObserver(ObserverInterface* observer) {
+ RTC_DCHECK_RUN_ON(&sequence_checker_);
+ for (std::list<ObserverInterface*>::iterator it = observers_.begin();
+ it != observers_.end(); it++) {
+ if (*it == observer) {
+ observers_.erase(it);
+ break;
+ }
+ }
+ }
+
+ void FireOnChanged() {
+ RTC_DCHECK_RUN_ON(&sequence_checker_);
+ // Copy the list of observers to avoid a crash if the observer object
+ // unregisters as a result of the OnChanged() call. If the same list is used
+ // UnregisterObserver will affect the list make the iterator invalid.
+ std::list<ObserverInterface*> observers = observers_;
+ for (std::list<ObserverInterface*>::iterator it = observers.begin();
+ it != observers.end(); ++it) {
+ (*it)->OnChanged();
+ }
+ }
+
+ protected:
+ std::list<ObserverInterface*> observers_ RTC_GUARDED_BY(sequence_checker_);
+
+ private:
+ RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
+};
+
+} // namespace webrtc
+
+#endif // API_NOTIFIER_H_
diff --git a/third_party/libwebrtc/api/numerics/BUILD.gn b/third_party/libwebrtc/api/numerics/BUILD.gn
new file mode 100644
index 0000000000..408dc5b9f1
--- /dev/null
+++ b/third_party/libwebrtc/api/numerics/BUILD.gn
@@ -0,0 +1,41 @@
+# Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../webrtc.gni")
+
+rtc_library("numerics") {
+ visibility = [ "*" ]
+
+ sources = [
+ "samples_stats_counter.cc",
+ "samples_stats_counter.h",
+ ]
+ deps = [
+ "..:array_view",
+ "../../rtc_base:checks",
+ "../../rtc_base:rtc_numerics",
+ "../../rtc_base:timeutils",
+ "../units:timestamp",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/algorithm:container" ]
+}
+
+if (rtc_include_tests) {
+ rtc_library("numerics_unittests") {
+ visibility = [ "*" ]
+ testonly = true
+
+ sources = [ "samples_stats_counter_unittest.cc" ]
+
+ deps = [
+ ":numerics",
+ "../../test:test_support",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/algorithm:container" ]
+ }
+}
diff --git a/third_party/libwebrtc/api/numerics/DEPS b/third_party/libwebrtc/api/numerics/DEPS
new file mode 100644
index 0000000000..2d89d57557
--- /dev/null
+++ b/third_party/libwebrtc/api/numerics/DEPS
@@ -0,0 +1,6 @@
+specific_include_rules = {
+ # Some internal headers are allowed even in API headers:
+ "samples_stats_counter\.h": [
+ "+rtc_base/numerics/running_statistics.h",
+ ]
+}
diff --git a/third_party/libwebrtc/api/numerics/samples_stats_counter.cc b/third_party/libwebrtc/api/numerics/samples_stats_counter.cc
new file mode 100644
index 0000000000..4eb0cde299
--- /dev/null
+++ b/third_party/libwebrtc/api/numerics/samples_stats_counter.cc
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/numerics/samples_stats_counter.h"
+
+#include <algorithm>
+#include <cmath>
+
+#include "absl/algorithm/container.h"
+#include "rtc_base/time_utils.h"
+
+namespace webrtc {
+
+SamplesStatsCounter::SamplesStatsCounter() = default;
+SamplesStatsCounter::SamplesStatsCounter(size_t expected_samples_count) {
+ samples_.reserve(expected_samples_count);
+}
+
+SamplesStatsCounter::~SamplesStatsCounter() = default;
+SamplesStatsCounter::SamplesStatsCounter(const SamplesStatsCounter&) = default;
+SamplesStatsCounter& SamplesStatsCounter::operator=(
+ const SamplesStatsCounter&) = default;
+SamplesStatsCounter::SamplesStatsCounter(SamplesStatsCounter&&) = default;
+SamplesStatsCounter& SamplesStatsCounter::operator=(SamplesStatsCounter&&) =
+ default;
+
+void SamplesStatsCounter::AddSample(double value) {
+ AddSample(StatsSample{value, Timestamp::Micros(rtc::TimeMicros())});
+}
+
+void SamplesStatsCounter::AddSample(StatsSample sample) {
+ stats_.AddSample(sample.value);
+ samples_.push_back(sample);
+ sorted_ = false;
+}
+
+void SamplesStatsCounter::AddSamples(const SamplesStatsCounter& other) {
+ stats_.MergeStatistics(other.stats_);
+ samples_.insert(samples_.end(), other.samples_.begin(), other.samples_.end());
+ sorted_ = false;
+}
+
+double SamplesStatsCounter::GetPercentile(double percentile) {
+ RTC_DCHECK(!IsEmpty());
+ RTC_CHECK_GE(percentile, 0);
+ RTC_CHECK_LE(percentile, 1);
+ if (!sorted_) {
+ absl::c_sort(samples_, [](const StatsSample& a, const StatsSample& b) {
+ return a.value < b.value;
+ });
+ sorted_ = true;
+ }
+ const double raw_rank = percentile * (samples_.size() - 1);
+ double int_part;
+ double fract_part = std::modf(raw_rank, &int_part);
+ size_t rank = static_cast<size_t>(int_part);
+ if (fract_part >= 1.0) {
+ // It can happen due to floating point calculation error.
+ rank++;
+ fract_part -= 1.0;
+ }
+
+ RTC_DCHECK_GE(rank, 0);
+ RTC_DCHECK_LT(rank, samples_.size());
+ RTC_DCHECK_GE(fract_part, 0);
+ RTC_DCHECK_LT(fract_part, 1);
+ RTC_DCHECK(rank + fract_part == raw_rank);
+
+ const double low = samples_[rank].value;
+ const double high = samples_[std::min(rank + 1, samples_.size() - 1)].value;
+ return low + fract_part * (high - low);
+}
+
+SamplesStatsCounter operator*(const SamplesStatsCounter& counter,
+ double value) {
+ SamplesStatsCounter out;
+ for (const auto& sample : counter.GetTimedSamples()) {
+ out.AddSample(
+ SamplesStatsCounter::StatsSample{sample.value * value, sample.time});
+ }
+ return out;
+}
+
+SamplesStatsCounter operator/(const SamplesStatsCounter& counter,
+ double value) {
+ SamplesStatsCounter out;
+ for (const auto& sample : counter.GetTimedSamples()) {
+ out.AddSample(
+ SamplesStatsCounter::StatsSample{sample.value / value, sample.time});
+ }
+ return out;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/numerics/samples_stats_counter.h b/third_party/libwebrtc/api/numerics/samples_stats_counter.h
new file mode 100644
index 0000000000..9d72296317
--- /dev/null
+++ b/third_party/libwebrtc/api/numerics/samples_stats_counter.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_NUMERICS_SAMPLES_STATS_COUNTER_H_
+#define API_NUMERICS_SAMPLES_STATS_COUNTER_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "api/array_view.h"
+#include "api/units/timestamp.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/numerics/running_statistics.h"
+
+namespace webrtc {
+
+// This class extends RunningStatistics by providing GetPercentile() method,
+// while slightly adapting the interface.
+class SamplesStatsCounter {
+ public:
+ struct StatsSample {
+ double value;
+ Timestamp time;
+ // Sample's specific metadata.
+ std::map<std::string, std::string> metadata;
+ };
+
+ SamplesStatsCounter();
+ explicit SamplesStatsCounter(size_t expected_samples_count);
+ ~SamplesStatsCounter();
+ SamplesStatsCounter(const SamplesStatsCounter&);
+ SamplesStatsCounter& operator=(const SamplesStatsCounter&);
+ SamplesStatsCounter(SamplesStatsCounter&&);
+ SamplesStatsCounter& operator=(SamplesStatsCounter&&);
+
+ // Adds sample to the stats in amortized O(1) time.
+ void AddSample(double value);
+ void AddSample(StatsSample sample);
+
+ // Adds samples from another counter.
+ void AddSamples(const SamplesStatsCounter& other);
+
+ // Returns if there are any values in O(1) time.
+ bool IsEmpty() const { return samples_.empty(); }
+ // Returns the amount of samples added into counter in O(1) time.
+ int64_t NumSamples() const { return stats_.Size(); }
+
+ // Returns min in O(1) time. This function may not be called if there are no
+ // samples.
+ double GetMin() const {
+ RTC_DCHECK(!IsEmpty());
+ return *stats_.GetMin();
+ }
+ // Returns max in O(1) time. This function may not be called if there are no
+ // samples.
+ double GetMax() const {
+ RTC_DCHECK(!IsEmpty());
+ return *stats_.GetMax();
+ }
+ // Returns average in O(1) time. This function may not be called if there are
+ // no samples.
+ double GetAverage() const {
+ RTC_DCHECK(!IsEmpty());
+ return *stats_.GetMean();
+ }
+ // Returns variance in O(1) time. This function may not be called if there are
+ // no samples.
+ double GetVariance() const {
+ RTC_DCHECK(!IsEmpty());
+ return *stats_.GetVariance();
+ }
+ // Returns standard deviation in O(1) time. This function may not be called if
+ // there are no samples.
+ double GetStandardDeviation() const {
+ RTC_DCHECK(!IsEmpty());
+ return *stats_.GetStandardDeviation();
+ }
+ // Returns percentile in O(nlogn) on first call and in O(1) after, if no
+ // additions were done. This function may not be called if there are no
+ // samples.
+ //
+ // `percentile` has to be in [0; 1]. 0 percentile is the min in the array and
+ // 1 percentile is the max in the array.
+ double GetPercentile(double percentile);
+ // Returns array view with all samples added into counter. There are no
+ // guarantees of order, so samples can be in different order comparing to in
+ // which they were added into counter. Also return value will be invalidate
+ // after call to any non const method.
+ rtc::ArrayView<const StatsSample> GetTimedSamples() const { return samples_; }
+ std::vector<double> GetSamples() const {
+ std::vector<double> out;
+ out.reserve(samples_.size());
+ for (const auto& sample : samples_) {
+ out.push_back(sample.value);
+ }
+ return out;
+ }
+
+ private:
+ webrtc_impl::RunningStatistics<double> stats_;
+ std::vector<StatsSample> samples_;
+ bool sorted_ = false;
+};
+
+// Multiply all sample values on `value` and return new SamplesStatsCounter
+// with resulted samples. Doesn't change origin SamplesStatsCounter.
+SamplesStatsCounter operator*(const SamplesStatsCounter& counter, double value);
+inline SamplesStatsCounter operator*(double value,
+ const SamplesStatsCounter& counter) {
+ return counter * value;
+}
+// Divide all sample values on `value` and return new SamplesStatsCounter with
+// resulted samples. Doesn't change origin SamplesStatsCounter.
+SamplesStatsCounter operator/(const SamplesStatsCounter& counter, double value);
+
+} // namespace webrtc
+
+#endif // API_NUMERICS_SAMPLES_STATS_COUNTER_H_
diff --git a/third_party/libwebrtc/api/numerics/samples_stats_counter_unittest.cc b/third_party/libwebrtc/api/numerics/samples_stats_counter_unittest.cc
new file mode 100644
index 0000000000..1f9cabfb29
--- /dev/null
+++ b/third_party/libwebrtc/api/numerics/samples_stats_counter_unittest.cc
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/numerics/samples_stats_counter.h"
+
+#include <math.h>
+
+#include <random>
+#include <vector>
+
+#include "absl/algorithm/container.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace {
+
+SamplesStatsCounter CreateStatsFilledWithIntsFrom1ToN(int n) {
+ std::vector<double> data;
+ for (int i = 1; i <= n; i++) {
+ data.push_back(i);
+ }
+ absl::c_shuffle(data, std::mt19937(std::random_device()()));
+
+ SamplesStatsCounter stats;
+ for (double v : data) {
+ stats.AddSample(v);
+ }
+ return stats;
+}
+
+// Add n samples drawn from uniform distribution in [a;b].
+SamplesStatsCounter CreateStatsFromUniformDistribution(int n,
+ double a,
+ double b) {
+ std::mt19937 gen{std::random_device()()};
+ std::uniform_real_distribution<> dis(a, b);
+
+ SamplesStatsCounter stats;
+ for (int i = 1; i <= n; i++) {
+ stats.AddSample(dis(gen));
+ }
+ return stats;
+}
+
+class SamplesStatsCounterTest : public ::testing::TestWithParam<int> {};
+
+constexpr int SIZE_FOR_MERGE = 10;
+
+} // namespace
+
+TEST(SamplesStatsCounterTest, FullSimpleTest) {
+ SamplesStatsCounter stats = CreateStatsFilledWithIntsFrom1ToN(100);
+
+ EXPECT_TRUE(!stats.IsEmpty());
+ EXPECT_DOUBLE_EQ(stats.GetMin(), 1.0);
+ EXPECT_DOUBLE_EQ(stats.GetMax(), 100.0);
+ EXPECT_NEAR(stats.GetAverage(), 50.5, 1e-6);
+ for (int i = 1; i <= 100; i++) {
+ double p = i / 100.0;
+ EXPECT_GE(stats.GetPercentile(p), i);
+ EXPECT_LT(stats.GetPercentile(p), i + 1);
+ }
+}
+
+TEST(SamplesStatsCounterTest, VarianceAndDeviation) {
+ SamplesStatsCounter stats;
+ stats.AddSample(2);
+ stats.AddSample(2);
+ stats.AddSample(-1);
+ stats.AddSample(5);
+
+ EXPECT_DOUBLE_EQ(stats.GetAverage(), 2.0);
+ EXPECT_DOUBLE_EQ(stats.GetVariance(), 4.5);
+ EXPECT_DOUBLE_EQ(stats.GetStandardDeviation(), sqrt(4.5));
+}
+
+TEST(SamplesStatsCounterTest, FractionPercentile) {
+ SamplesStatsCounter stats = CreateStatsFilledWithIntsFrom1ToN(5);
+
+ EXPECT_DOUBLE_EQ(stats.GetPercentile(0.5), 3);
+}
+
+TEST(SamplesStatsCounterTest, TestBorderValues) {
+ SamplesStatsCounter stats = CreateStatsFilledWithIntsFrom1ToN(5);
+
+ EXPECT_GE(stats.GetPercentile(0.01), 1);
+ EXPECT_LT(stats.GetPercentile(0.01), 2);
+ EXPECT_DOUBLE_EQ(stats.GetPercentile(1.0), 5);
+}
+
+TEST(SamplesStatsCounterTest, VarianceFromUniformDistribution) {
+ // Check variance converge to 1/12 for [0;1) uniform distribution.
+ // Acts as a sanity check for NumericStabilityForVariance test.
+ SamplesStatsCounter stats = CreateStatsFromUniformDistribution(1e6, 0, 1);
+
+ EXPECT_NEAR(stats.GetVariance(), 1. / 12, 1e-3);
+}
+
+TEST(SamplesStatsCounterTest, NumericStabilityForVariance) {
+ // Same test as VarianceFromUniformDistribution,
+ // except the range is shifted to [1e9;1e9+1).
+ // Variance should also converge to 1/12.
+ // NB: Although we lose precision for the samples themselves, the fractional
+ // part still enjoys 22 bits of mantissa and errors should even out,
+ // so that couldn't explain a mismatch.
+ SamplesStatsCounter stats =
+ CreateStatsFromUniformDistribution(1e6, 1e9, 1e9 + 1);
+
+ EXPECT_NEAR(stats.GetVariance(), 1. / 12, 1e-3);
+}
+
+TEST_P(SamplesStatsCounterTest, AddSamples) {
+ int data[SIZE_FOR_MERGE] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ // Split the data in different partitions.
+ // We have 11 distinct tests:
+ // * Empty merged with full sequence.
+ // * 1 sample merged with 9 last.
+ // * 2 samples merged with 8 last.
+ // [...]
+ // * Full merged with empty sequence.
+ // All must lead to the same result.
+ SamplesStatsCounter stats0, stats1;
+ for (int i = 0; i < GetParam(); ++i) {
+ stats0.AddSample(data[i]);
+ }
+ for (int i = GetParam(); i < SIZE_FOR_MERGE; ++i) {
+ stats1.AddSample(data[i]);
+ }
+ stats0.AddSamples(stats1);
+
+ EXPECT_EQ(stats0.GetMin(), 0);
+ EXPECT_EQ(stats0.GetMax(), 9);
+ EXPECT_DOUBLE_EQ(stats0.GetAverage(), 4.5);
+ EXPECT_DOUBLE_EQ(stats0.GetVariance(), 8.25);
+ EXPECT_DOUBLE_EQ(stats0.GetStandardDeviation(), sqrt(8.25));
+ EXPECT_DOUBLE_EQ(stats0.GetPercentile(0.1), 0.9);
+ EXPECT_DOUBLE_EQ(stats0.GetPercentile(0.5), 4.5);
+ EXPECT_DOUBLE_EQ(stats0.GetPercentile(0.9), 8.1);
+}
+
+TEST(SamplesStatsCounterTest, MultiplyRight) {
+ SamplesStatsCounter stats = CreateStatsFilledWithIntsFrom1ToN(10);
+
+ EXPECT_TRUE(!stats.IsEmpty());
+ EXPECT_DOUBLE_EQ(stats.GetMin(), 1.0);
+ EXPECT_DOUBLE_EQ(stats.GetMax(), 10.0);
+ EXPECT_DOUBLE_EQ(stats.GetAverage(), 5.5);
+
+ SamplesStatsCounter multiplied_stats = stats * 10;
+ EXPECT_TRUE(!multiplied_stats.IsEmpty());
+ EXPECT_DOUBLE_EQ(multiplied_stats.GetMin(), 10.0);
+ EXPECT_DOUBLE_EQ(multiplied_stats.GetMax(), 100.0);
+ EXPECT_DOUBLE_EQ(multiplied_stats.GetAverage(), 55.0);
+ EXPECT_EQ(multiplied_stats.GetSamples().size(), stats.GetSamples().size());
+
+ // Check that origin stats were not modified.
+ EXPECT_TRUE(!stats.IsEmpty());
+ EXPECT_DOUBLE_EQ(stats.GetMin(), 1.0);
+ EXPECT_DOUBLE_EQ(stats.GetMax(), 10.0);
+ EXPECT_DOUBLE_EQ(stats.GetAverage(), 5.5);
+}
+
+TEST(SamplesStatsCounterTest, MultiplyLeft) {
+ SamplesStatsCounter stats = CreateStatsFilledWithIntsFrom1ToN(10);
+
+ EXPECT_TRUE(!stats.IsEmpty());
+ EXPECT_DOUBLE_EQ(stats.GetMin(), 1.0);
+ EXPECT_DOUBLE_EQ(stats.GetMax(), 10.0);
+ EXPECT_DOUBLE_EQ(stats.GetAverage(), 5.5);
+
+ SamplesStatsCounter multiplied_stats = 10 * stats;
+ EXPECT_TRUE(!multiplied_stats.IsEmpty());
+ EXPECT_DOUBLE_EQ(multiplied_stats.GetMin(), 10.0);
+ EXPECT_DOUBLE_EQ(multiplied_stats.GetMax(), 100.0);
+ EXPECT_DOUBLE_EQ(multiplied_stats.GetAverage(), 55.0);
+ EXPECT_EQ(multiplied_stats.GetSamples().size(), stats.GetSamples().size());
+
+ // Check that origin stats were not modified.
+ EXPECT_TRUE(!stats.IsEmpty());
+ EXPECT_DOUBLE_EQ(stats.GetMin(), 1.0);
+ EXPECT_DOUBLE_EQ(stats.GetMax(), 10.0);
+ EXPECT_DOUBLE_EQ(stats.GetAverage(), 5.5);
+}
+
+TEST(SamplesStatsCounterTest, Divide) {
+ SamplesStatsCounter stats;
+ for (int i = 1; i <= 10; i++) {
+ stats.AddSample(i * 10);
+ }
+
+ EXPECT_TRUE(!stats.IsEmpty());
+ EXPECT_DOUBLE_EQ(stats.GetMin(), 10.0);
+ EXPECT_DOUBLE_EQ(stats.GetMax(), 100.0);
+ EXPECT_DOUBLE_EQ(stats.GetAverage(), 55.0);
+
+ SamplesStatsCounter divided_stats = stats / 10;
+ EXPECT_TRUE(!divided_stats.IsEmpty());
+ EXPECT_DOUBLE_EQ(divided_stats.GetMin(), 1.0);
+ EXPECT_DOUBLE_EQ(divided_stats.GetMax(), 10.0);
+ EXPECT_DOUBLE_EQ(divided_stats.GetAverage(), 5.5);
+ EXPECT_EQ(divided_stats.GetSamples().size(), stats.GetSamples().size());
+
+ // Check that origin stats were not modified.
+ EXPECT_TRUE(!stats.IsEmpty());
+ EXPECT_DOUBLE_EQ(stats.GetMin(), 10.0);
+ EXPECT_DOUBLE_EQ(stats.GetMax(), 100.0);
+ EXPECT_DOUBLE_EQ(stats.GetAverage(), 55.0);
+}
+
+INSTANTIATE_TEST_SUITE_P(SamplesStatsCounterTests,
+ SamplesStatsCounterTest,
+ ::testing::Range(0, SIZE_FOR_MERGE + 1));
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/packet_socket_factory.h b/third_party/libwebrtc/api/packet_socket_factory.h
new file mode 100644
index 0000000000..29d2606b9b
--- /dev/null
+++ b/third_party/libwebrtc/api/packet_socket_factory.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_PACKET_SOCKET_FACTORY_H_
+#define API_PACKET_SOCKET_FACTORY_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "api/async_dns_resolver.h"
+#include "api/wrapping_async_dns_resolver.h"
+#include "rtc_base/async_packet_socket.h"
+#include "rtc_base/proxy_info.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace rtc {
+
+class SSLCertificateVerifier;
+class AsyncResolverInterface;
+
+struct PacketSocketTcpOptions {
+ PacketSocketTcpOptions() = default;
+ ~PacketSocketTcpOptions() = default;
+
+ int opts = 0;
+ std::vector<std::string> tls_alpn_protocols;
+ std::vector<std::string> tls_elliptic_curves;
+ // An optional custom SSL certificate verifier that an API user can provide to
+ // inject their own certificate verification logic (not available to users
+ // outside of the WebRTC repo).
+ SSLCertificateVerifier* tls_cert_verifier = nullptr;
+};
+
+class RTC_EXPORT PacketSocketFactory {
+ public:
+ enum Options {
+ OPT_STUN = 0x04,
+
+ // The TLS options below are mutually exclusive.
+ OPT_TLS = 0x02, // Real and secure TLS.
+ OPT_TLS_FAKE = 0x01, // Fake TLS with a dummy SSL handshake.
+ OPT_TLS_INSECURE = 0x08, // Insecure TLS without certificate validation.
+
+ // Deprecated, use OPT_TLS_FAKE.
+ OPT_SSLTCP = OPT_TLS_FAKE,
+ };
+
+ PacketSocketFactory() = default;
+ virtual ~PacketSocketFactory() = default;
+
+ virtual AsyncPacketSocket* CreateUdpSocket(const SocketAddress& address,
+ uint16_t min_port,
+ uint16_t max_port) = 0;
+ virtual AsyncListenSocket* CreateServerTcpSocket(
+ const SocketAddress& local_address,
+ uint16_t min_port,
+ uint16_t max_port,
+ int opts) = 0;
+
+ virtual AsyncPacketSocket* CreateClientTcpSocket(
+ const SocketAddress& local_address,
+ const SocketAddress& remote_address,
+ const ProxyInfo& proxy_info,
+ const std::string& user_agent,
+ const PacketSocketTcpOptions& tcp_options) = 0;
+
+ // The AsyncResolverInterface is deprecated; users are encouraged
+ // to switch to the AsyncDnsResolverInterface.
+ // TODO(bugs.webrtc.org/12598): Remove once all downstream users
+ // are converted.
+ virtual AsyncResolverInterface* CreateAsyncResolver() {
+ // Default implementation, so that downstream users can remove this
+ // immediately after changing to CreateAsyncDnsResolver
+ RTC_DCHECK_NOTREACHED();
+ return nullptr;
+ }
+
+ virtual std::unique_ptr<webrtc::AsyncDnsResolverInterface>
+ CreateAsyncDnsResolver() {
+ // Default implementation, to aid in transition to AsyncDnsResolverInterface
+ return std::make_unique<webrtc::WrappingAsyncDnsResolver>(
+ CreateAsyncResolver());
+ }
+
+ private:
+ PacketSocketFactory(const PacketSocketFactory&) = delete;
+ PacketSocketFactory& operator=(const PacketSocketFactory&) = delete;
+};
+
+} // namespace rtc
+
+#endif // API_PACKET_SOCKET_FACTORY_H_
diff --git a/third_party/libwebrtc/api/peer_connection_interface.cc b/third_party/libwebrtc/api/peer_connection_interface.cc
new file mode 100644
index 0000000000..d01d58d32b
--- /dev/null
+++ b/third_party/libwebrtc/api/peer_connection_interface.cc
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/peer_connection_interface.h"
+
+#include <utility>
+
+namespace webrtc {
+
+PeerConnectionInterface::IceServer::IceServer() = default;
+PeerConnectionInterface::IceServer::IceServer(const IceServer& rhs) = default;
+PeerConnectionInterface::IceServer::~IceServer() = default;
+
+PeerConnectionInterface::RTCConfiguration::RTCConfiguration() = default;
+
+PeerConnectionInterface::RTCConfiguration::RTCConfiguration(
+ const RTCConfiguration& rhs) = default;
+
+PeerConnectionInterface::RTCConfiguration::RTCConfiguration(
+ RTCConfigurationType type) {
+ if (type == RTCConfigurationType::kAggressive) {
+ // These parameters are also defined in Java and IOS configurations,
+ // so their values may be overwritten by the Java or IOS configuration.
+ bundle_policy = kBundlePolicyMaxBundle;
+ rtcp_mux_policy = kRtcpMuxPolicyRequire;
+ ice_connection_receiving_timeout = kAggressiveIceConnectionReceivingTimeout;
+
+ // These parameters are not defined in Java or IOS configuration,
+ // so their values will not be overwritten.
+ enable_ice_renomination = true;
+ redetermine_role_on_ice_restart = false;
+ }
+}
+
+PeerConnectionInterface::RTCConfiguration::~RTCConfiguration() = default;
+
+PeerConnectionDependencies::PeerConnectionDependencies(
+ PeerConnectionObserver* observer_in)
+ : observer(observer_in) {}
+
+PeerConnectionDependencies::PeerConnectionDependencies(
+ PeerConnectionDependencies&&) = default;
+
+PeerConnectionDependencies::~PeerConnectionDependencies() = default;
+
+PeerConnectionFactoryDependencies::PeerConnectionFactoryDependencies() =
+ default;
+
+PeerConnectionFactoryDependencies::PeerConnectionFactoryDependencies(
+ PeerConnectionFactoryDependencies&&) = default;
+
+PeerConnectionFactoryDependencies::~PeerConnectionFactoryDependencies() =
+ default;
+
+rtc::scoped_refptr<PeerConnectionInterface>
+PeerConnectionFactoryInterface::CreatePeerConnection(
+ const PeerConnectionInterface::RTCConfiguration& configuration,
+ std::unique_ptr<cricket::PortAllocator> allocator,
+ std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
+ PeerConnectionObserver* observer) {
+ PeerConnectionDependencies dependencies(observer);
+ dependencies.allocator = std::move(allocator);
+ dependencies.cert_generator = std::move(cert_generator);
+ auto result =
+ CreatePeerConnectionOrError(configuration, std::move(dependencies));
+ if (!result.ok()) {
+ return nullptr;
+ }
+ return result.MoveValue();
+}
+
+rtc::scoped_refptr<PeerConnectionInterface>
+PeerConnectionFactoryInterface::CreatePeerConnection(
+ const PeerConnectionInterface::RTCConfiguration& configuration,
+ PeerConnectionDependencies dependencies) {
+ auto result =
+ CreatePeerConnectionOrError(configuration, std::move(dependencies));
+ if (!result.ok()) {
+ return nullptr;
+ }
+ return result.MoveValue();
+}
+
+RTCErrorOr<rtc::scoped_refptr<PeerConnectionInterface>>
+PeerConnectionFactoryInterface::CreatePeerConnectionOrError(
+ const PeerConnectionInterface::RTCConfiguration& configuration,
+ PeerConnectionDependencies dependencies) {
+ return RTCError(RTCErrorType::INTERNAL_ERROR);
+}
+
+RtpCapabilities PeerConnectionFactoryInterface::GetRtpSenderCapabilities(
+ cricket::MediaType kind) const {
+ return {};
+}
+
+RtpCapabilities PeerConnectionFactoryInterface::GetRtpReceiverCapabilities(
+ cricket::MediaType kind) const {
+ return {};
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/peer_connection_interface.h b/third_party/libwebrtc/api/peer_connection_interface.h
new file mode 100644
index 0000000000..1097a1639c
--- /dev/null
+++ b/third_party/libwebrtc/api/peer_connection_interface.h
@@ -0,0 +1,1696 @@
+/*
+ * Copyright 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This file contains the PeerConnection interface as defined in
+// https://w3c.github.io/webrtc-pc/#peer-to-peer-connections
+//
+// The PeerConnectionFactory class provides factory methods to create
+// PeerConnection, MediaStream and MediaStreamTrack objects.
+//
+// The following steps are needed to setup a typical call using WebRTC:
+//
+// 1. Create a PeerConnectionFactoryInterface. Check constructors for more
+// information about input parameters.
+//
+// 2. Create a PeerConnection object. Provide a configuration struct which
+// points to STUN and/or TURN servers used to generate ICE candidates, and
+// provide an object that implements the PeerConnectionObserver interface,
+// which is used to receive callbacks from the PeerConnection.
+//
+// 3. Create local MediaStreamTracks using the PeerConnectionFactory and add
+// them to PeerConnection by calling AddTrack (or legacy method, AddStream).
+//
+// 4. Create an offer, call SetLocalDescription with it, serialize it, and send
+// it to the remote peer
+//
+// 5. Once an ICE candidate has been gathered, the PeerConnection will call the
+// observer function OnIceCandidate. The candidates must also be serialized and
+// sent to the remote peer.
+//
+// 6. Once an answer is received from the remote peer, call
+// SetRemoteDescription with the remote answer.
+//
+// 7. Once a remote candidate is received from the remote peer, provide it to
+// the PeerConnection by calling AddIceCandidate.
+//
+// The receiver of a call (assuming the application is "call"-based) can decide
+// to accept or reject the call; this decision will be taken by the application,
+// not the PeerConnection.
+//
+// If the application decides to accept the call, it should:
+//
+// 1. Create PeerConnectionFactoryInterface if it doesn't exist.
+//
+// 2. Create a new PeerConnection.
+//
+// 3. Provide the remote offer to the new PeerConnection object by calling
+// SetRemoteDescription.
+//
+// 4. Generate an answer to the remote offer by calling CreateAnswer and send it
+// back to the remote peer.
+//
+// 5. Provide the local answer to the new PeerConnection by calling
+// SetLocalDescription with the answer.
+//
+// 6. Provide the remote ICE candidates by calling AddIceCandidate.
+//
+// 7. Once a candidate has been gathered, the PeerConnection will call the
+// observer function OnIceCandidate. Send these candidates to the remote peer.
+
+#ifndef API_PEER_CONNECTION_INTERFACE_H_
+#define API_PEER_CONNECTION_INTERFACE_H_
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include <functional>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "api/adaptation/resource.h"
+#include "api/async_dns_resolver.h"
+#include "api/async_resolver_factory.h"
+#include "api/audio/audio_mixer.h"
+#include "api/audio_codecs/audio_decoder_factory.h"
+#include "api/audio_codecs/audio_encoder_factory.h"
+#include "api/audio_options.h"
+#include "api/call/call_factory_interface.h"
+#include "api/candidate.h"
+#include "api/crypto/crypto_options.h"
+#include "api/data_channel_interface.h"
+#include "api/dtls_transport_interface.h"
+#include "api/fec_controller.h"
+#include "api/field_trials_view.h"
+#include "api/ice_transport_interface.h"
+#include "api/jsep.h"
+#include "api/legacy_stats_types.h"
+#include "api/media_stream_interface.h"
+#include "api/media_types.h"
+#include "api/metronome/metronome.h"
+#include "api/neteq/neteq_factory.h"
+#include "api/network_state_predictor.h"
+#include "api/packet_socket_factory.h"
+#include "api/rtc_error.h"
+#include "api/rtc_event_log/rtc_event_log_factory_interface.h"
+#include "api/rtc_event_log_output.h"
+#include "api/rtp_parameters.h"
+#include "api/rtp_receiver_interface.h"
+#include "api/rtp_sender_interface.h"
+#include "api/rtp_transceiver_interface.h"
+#include "api/scoped_refptr.h"
+#include "api/sctp_transport_interface.h"
+#include "api/set_local_description_observer_interface.h"
+#include "api/set_remote_description_observer_interface.h"
+#include "api/stats/rtc_stats_collector_callback.h"
+#include "api/task_queue/task_queue_factory.h"
+#include "api/transport/bitrate_settings.h"
+#include "api/transport/enums.h"
+#include "api/transport/network_control.h"
+#include "api/transport/sctp_transport_factory_interface.h"
+#include "api/turn_customizer.h"
+#include "api/video/video_bitrate_allocator_factory.h"
+#include "call/rtp_transport_controller_send_factory_interface.h"
+#include "media/base/media_config.h"
+#include "media/base/media_engine.h"
+// TODO(bugs.webrtc.org/7447): We plan to provide a way to let applications
+// inject a PacketSocketFactory and/or NetworkManager, and not expose
+// PortAllocator in the PeerConnection api.
+#include "p2p/base/port_allocator.h"
+#include "rtc_base/network.h"
+#include "rtc_base/network_constants.h"
+#include "rtc_base/network_monitor_factory.h"
+#include "rtc_base/ref_count.h"
+#include "rtc_base/rtc_certificate.h"
+#include "rtc_base/rtc_certificate_generator.h"
+#include "rtc_base/socket_address.h"
+#include "rtc_base/ssl_certificate.h"
+#include "rtc_base/ssl_stream_adapter.h"
+#include "rtc_base/system/rtc_export.h"
+#include "rtc_base/thread.h"
+
+namespace rtc {
+class Thread;
+} // namespace rtc
+
+namespace webrtc {
+
+// MediaStream container interface.
+class StreamCollectionInterface : public rtc::RefCountInterface {
+ public:
+ // TODO(ronghuawu): Update the function names to c++ style, e.g. find -> Find.
+ virtual size_t count() = 0;
+ virtual MediaStreamInterface* at(size_t index) = 0;
+ virtual MediaStreamInterface* find(const std::string& label) = 0;
+ virtual MediaStreamTrackInterface* FindAudioTrack(const std::string& id) = 0;
+ virtual MediaStreamTrackInterface* FindVideoTrack(const std::string& id) = 0;
+
+ protected:
+ // Dtor protected as objects shouldn't be deleted via this interface.
+ ~StreamCollectionInterface() override = default;
+};
+
+class StatsObserver : public rtc::RefCountInterface {
+ public:
+ virtual void OnComplete(const StatsReports& reports) = 0;
+
+ protected:
+ ~StatsObserver() override = default;
+};
+
+enum class SdpSemantics {
+ // TODO(https://crbug.com/webrtc/13528): Remove support for kPlanB.
+ kPlanB_DEPRECATED,
+ kPlanB [[deprecated]] = kPlanB_DEPRECATED,
+ kUnifiedPlan,
+};
+
+class RTC_EXPORT PeerConnectionInterface : public rtc::RefCountInterface {
+ public:
+ // See https://w3c.github.io/webrtc-pc/#dom-rtcsignalingstate
+ enum SignalingState {
+ kStable,
+ kHaveLocalOffer,
+ kHaveLocalPrAnswer,
+ kHaveRemoteOffer,
+ kHaveRemotePrAnswer,
+ kClosed,
+ };
+ static constexpr absl::string_view AsString(SignalingState);
+
+ // See https://w3c.github.io/webrtc-pc/#dom-rtcicegatheringstate
+ enum IceGatheringState {
+ kIceGatheringNew,
+ kIceGatheringGathering,
+ kIceGatheringComplete
+ };
+ static constexpr absl::string_view AsString(IceGatheringState state);
+
+ // See https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnectionstate
+ enum class PeerConnectionState {
+ kNew,
+ kConnecting,
+ kConnected,
+ kDisconnected,
+ kFailed,
+ kClosed,
+ };
+ static constexpr absl::string_view AsString(PeerConnectionState state);
+
+ // See https://w3c.github.io/webrtc-pc/#dom-rtciceconnectionstate
+ enum IceConnectionState {
+ kIceConnectionNew,
+ kIceConnectionChecking,
+ kIceConnectionConnected,
+ kIceConnectionCompleted,
+ kIceConnectionFailed,
+ kIceConnectionDisconnected,
+ kIceConnectionClosed,
+ kIceConnectionMax,
+ };
+ static constexpr absl::string_view AsString(IceConnectionState state);
+
+ // TLS certificate policy.
+ enum TlsCertPolicy {
+ // For TLS based protocols, ensure the connection is secure by not
+ // circumventing certificate validation.
+ kTlsCertPolicySecure,
+ // For TLS based protocols, disregard security completely by skipping
+ // certificate validation. This is insecure and should never be used unless
+ // security is irrelevant in that particular context.
+ kTlsCertPolicyInsecureNoCheck,
+ };
+
+ struct RTC_EXPORT IceServer {
+ IceServer();
+ IceServer(const IceServer&);
+ ~IceServer();
+
+ // TODO(jbauch): Remove uri when all code using it has switched to urls.
+ // List of URIs associated with this server. Valid formats are described
+ // in RFC7064 and RFC7065, and more may be added in the future. The "host"
+ // part of the URI may contain either an IP address or a hostname.
+ std::string uri;
+ std::vector<std::string> urls;
+ std::string username;
+ std::string password;
+ TlsCertPolicy tls_cert_policy = kTlsCertPolicySecure;
+ // If the URIs in `urls` only contain IP addresses, this field can be used
+ // to indicate the hostname, which may be necessary for TLS (using the SNI
+ // extension). If `urls` itself contains the hostname, this isn't
+ // necessary.
+ std::string hostname;
+ // List of protocols to be used in the TLS ALPN extension.
+ std::vector<std::string> tls_alpn_protocols;
+ // List of elliptic curves to be used in the TLS elliptic curves extension.
+ std::vector<std::string> tls_elliptic_curves;
+
+ bool operator==(const IceServer& o) const {
+ return uri == o.uri && urls == o.urls && username == o.username &&
+ password == o.password && tls_cert_policy == o.tls_cert_policy &&
+ hostname == o.hostname &&
+ tls_alpn_protocols == o.tls_alpn_protocols &&
+ tls_elliptic_curves == o.tls_elliptic_curves;
+ }
+ bool operator!=(const IceServer& o) const { return !(*this == o); }
+ };
+ typedef std::vector<IceServer> IceServers;
+
+ enum IceTransportsType {
+ // TODO(pthatcher): Rename these kTransporTypeXXX, but update
+ // Chromium at the same time.
+ kNone,
+ kRelay,
+ kNoHost,
+ kAll
+ };
+
+ // https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-24#section-4.1.1
+ enum BundlePolicy {
+ kBundlePolicyBalanced,
+ kBundlePolicyMaxBundle,
+ kBundlePolicyMaxCompat
+ };
+
+ // https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-24#section-4.1.1
+ enum RtcpMuxPolicy {
+ kRtcpMuxPolicyNegotiate,
+ kRtcpMuxPolicyRequire,
+ };
+
+ enum TcpCandidatePolicy {
+ kTcpCandidatePolicyEnabled,
+ kTcpCandidatePolicyDisabled
+ };
+
+ enum CandidateNetworkPolicy {
+ kCandidateNetworkPolicyAll,
+ kCandidateNetworkPolicyLowCost
+ };
+
+ enum ContinualGatheringPolicy { GATHER_ONCE, GATHER_CONTINUALLY };
+
+ struct PortAllocatorConfig {
+ // For min_port and max_port, 0 means not specified.
+ int min_port = 0;
+ int max_port = 0;
+ uint32_t flags = 0; // Same as kDefaultPortAllocatorFlags.
+ };
+
+ enum class RTCConfigurationType {
+ // A configuration that is safer to use, despite not having the best
+ // performance. Currently this is the default configuration.
+ kSafe,
+ // An aggressive configuration that has better performance, although it
+ // may be riskier and may need extra support in the application.
+ kAggressive
+ };
+
+ // TODO(hbos): Change into class with private data and public getters.
+ // TODO(nisse): In particular, accessing fields directly from an
+ // application is brittle, since the organization mirrors the
+ // organization of the implementation, which isn't stable. So we
+ // need getters and setters at least for fields which applications
+ // are interested in.
+ struct RTC_EXPORT RTCConfiguration {
+ // This struct is subject to reorganization, both for naming
+ // consistency, and to group settings to match where they are used
+ // in the implementation. To do that, we need getter and setter
+ // methods for all settings which are of interest to applications,
+ // Chrome in particular.
+
+ RTCConfiguration();
+ RTCConfiguration(const RTCConfiguration&);
+ explicit RTCConfiguration(RTCConfigurationType type);
+ ~RTCConfiguration();
+
+ bool operator==(const RTCConfiguration& o) const;
+ bool operator!=(const RTCConfiguration& o) const;
+
+ bool dscp() const { return media_config.enable_dscp; }
+ void set_dscp(bool enable) { media_config.enable_dscp = enable; }
+
+ bool cpu_adaptation() const {
+ return media_config.video.enable_cpu_adaptation;
+ }
+ void set_cpu_adaptation(bool enable) {
+ media_config.video.enable_cpu_adaptation = enable;
+ }
+
+ bool suspend_below_min_bitrate() const {
+ return media_config.video.suspend_below_min_bitrate;
+ }
+ void set_suspend_below_min_bitrate(bool enable) {
+ media_config.video.suspend_below_min_bitrate = enable;
+ }
+
+ bool prerenderer_smoothing() const {
+ return media_config.video.enable_prerenderer_smoothing;
+ }
+ void set_prerenderer_smoothing(bool enable) {
+ media_config.video.enable_prerenderer_smoothing = enable;
+ }
+
+ bool experiment_cpu_load_estimator() const {
+ return media_config.video.experiment_cpu_load_estimator;
+ }
+ void set_experiment_cpu_load_estimator(bool enable) {
+ media_config.video.experiment_cpu_load_estimator = enable;
+ }
+
+ int audio_rtcp_report_interval_ms() const {
+ return media_config.audio.rtcp_report_interval_ms;
+ }
+ void set_audio_rtcp_report_interval_ms(int audio_rtcp_report_interval_ms) {
+ media_config.audio.rtcp_report_interval_ms =
+ audio_rtcp_report_interval_ms;
+ }
+
+ int video_rtcp_report_interval_ms() const {
+ return media_config.video.rtcp_report_interval_ms;
+ }
+ void set_video_rtcp_report_interval_ms(int video_rtcp_report_interval_ms) {
+ media_config.video.rtcp_report_interval_ms =
+ video_rtcp_report_interval_ms;
+ }
+
+ // Settings for the port allcoator. Applied only if the port allocator is
+ // created by PeerConnectionFactory, not if it is injected with
+ // PeerConnectionDependencies
+ int min_port() const { return port_allocator_config.min_port; }
+ void set_min_port(int port) { port_allocator_config.min_port = port; }
+ int max_port() const { return port_allocator_config.max_port; }
+ void set_max_port(int port) { port_allocator_config.max_port = port; }
+ uint32_t port_allocator_flags() { return port_allocator_config.flags; }
+ void set_port_allocator_flags(uint32_t flags) {
+ port_allocator_config.flags = flags;
+ }
+
+ static const int kUndefined = -1;
+ // Default maximum number of packets in the audio jitter buffer.
+ static const int kAudioJitterBufferMaxPackets = 200;
+ // ICE connection receiving timeout for aggressive configuration.
+ static const int kAggressiveIceConnectionReceivingTimeout = 1000;
+
+ ////////////////////////////////////////////////////////////////////////
+ // The below few fields mirror the standard RTCConfiguration dictionary:
+ // https://w3c.github.io/webrtc-pc/#rtcconfiguration-dictionary
+ ////////////////////////////////////////////////////////////////////////
+
+ // TODO(pthatcher): Rename this ice_servers, but update Chromium
+ // at the same time.
+ IceServers servers;
+ // TODO(pthatcher): Rename this ice_transport_type, but update
+ // Chromium at the same time.
+ IceTransportsType type = kAll;
+ BundlePolicy bundle_policy = kBundlePolicyBalanced;
+ RtcpMuxPolicy rtcp_mux_policy = kRtcpMuxPolicyRequire;
+ std::vector<rtc::scoped_refptr<rtc::RTCCertificate>> certificates;
+ int ice_candidate_pool_size = 0;
+
+ //////////////////////////////////////////////////////////////////////////
+ // The below fields correspond to constraints from the deprecated
+ // constraints interface for constructing a PeerConnection.
+ //
+ // absl::optional fields can be "missing", in which case the implementation
+ // default will be used.
+ //////////////////////////////////////////////////////////////////////////
+
+ // If set to true, don't gather IPv6 ICE candidates on Wi-Fi.
+ // Only intended to be used on specific devices. Certain phones disable IPv6
+ // when the screen is turned off and it would be better to just disable the
+ // IPv6 ICE candidates on Wi-Fi in those cases.
+ bool disable_ipv6_on_wifi = false;
+
+ // By default, the PeerConnection will use a limited number of IPv6 network
+ // interfaces, in order to avoid too many ICE candidate pairs being created
+ // and delaying ICE completion.
+ //
+ // Can be set to INT_MAX to effectively disable the limit.
+ int max_ipv6_networks = cricket::kDefaultMaxIPv6Networks;
+
+ // Exclude link-local network interfaces
+ // from consideration for gathering ICE candidates.
+ bool disable_link_local_networks = false;
+
+ // Minimum bitrate at which screencast video tracks will be encoded at.
+ // This means adding padding bits up to this bitrate, which can help
+ // when switching from a static scene to one with motion.
+ absl::optional<int> screencast_min_bitrate;
+
+ // Use new combined audio/video bandwidth estimation?
+ absl::optional<bool> combined_audio_video_bwe;
+
+#if defined(WEBRTC_FUCHSIA)
+ // TODO(bugs.webrtc.org/11066): Remove entirely once Fuchsia does not use.
+ // TODO(bugs.webrtc.org/9891) - Move to crypto_options
+ // Can be used to disable DTLS-SRTP. This should never be done, but can be
+ // useful for testing purposes, for example in setting up a loopback call
+ // with a single PeerConnection.
+ absl::optional<bool> enable_dtls_srtp;
+#endif
+
+ /////////////////////////////////////////////////
+ // The below fields are not part of the standard.
+ /////////////////////////////////////////////////
+
+ // Can be used to disable TCP candidate generation.
+ TcpCandidatePolicy tcp_candidate_policy = kTcpCandidatePolicyEnabled;
+
+ // Can be used to avoid gathering candidates for a "higher cost" network,
+ // if a lower cost one exists. For example, if both Wi-Fi and cellular
+ // interfaces are available, this could be used to avoid using the cellular
+ // interface.
+ CandidateNetworkPolicy candidate_network_policy =
+ kCandidateNetworkPolicyAll;
+
+ // The maximum number of packets that can be stored in the NetEq audio
+ // jitter buffer. Can be reduced to lower tolerated audio latency.
+ int audio_jitter_buffer_max_packets = kAudioJitterBufferMaxPackets;
+
+ // Whether to use the NetEq "fast mode" which will accelerate audio quicker
+ // if it falls behind.
+ bool audio_jitter_buffer_fast_accelerate = false;
+
+ // The minimum delay in milliseconds for the audio jitter buffer.
+ int audio_jitter_buffer_min_delay_ms = 0;
+
+ // Timeout in milliseconds before an ICE candidate pair is considered to be
+ // "not receiving", after which a lower priority candidate pair may be
+ // selected.
+ int ice_connection_receiving_timeout = kUndefined;
+
+ // Interval in milliseconds at which an ICE "backup" candidate pair will be
+ // pinged. This is a candidate pair which is not actively in use, but may
+ // be switched to if the active candidate pair becomes unusable.
+ //
+ // This is relevant mainly to Wi-Fi/cell handoff; the application may not
+ // want this backup cellular candidate pair pinged frequently, since it
+ // consumes data/battery.
+ int ice_backup_candidate_pair_ping_interval = kUndefined;
+
+ // Can be used to enable continual gathering, which means new candidates
+ // will be gathered as network interfaces change. Note that if continual
+ // gathering is used, the candidate removal API should also be used, to
+ // avoid an ever-growing list of candidates.
+ ContinualGatheringPolicy continual_gathering_policy = GATHER_ONCE;
+
+ // If set to true, candidate pairs will be pinged in order of most likely
+ // to work (which means using a TURN server, generally), rather than in
+ // standard priority order.
+ bool prioritize_most_likely_ice_candidate_pairs = false;
+
+ // Implementation defined settings. A public member only for the benefit of
+ // the implementation. Applications must not access it directly, and should
+ // instead use provided accessor methods, e.g., set_cpu_adaptation.
+ struct cricket::MediaConfig media_config;
+
+ // If set to true, only one preferred TURN allocation will be used per
+ // network interface. UDP is preferred over TCP and IPv6 over IPv4. This
+ // can be used to cut down on the number of candidate pairings.
+ // Deprecated. TODO(webrtc:11026) Remove this flag once the downstream
+ // dependency is removed.
+ bool prune_turn_ports = false;
+
+ // The policy used to prune turn port.
+ PortPrunePolicy turn_port_prune_policy = NO_PRUNE;
+
+ PortPrunePolicy GetTurnPortPrunePolicy() const {
+ return prune_turn_ports ? PRUNE_BASED_ON_PRIORITY
+ : turn_port_prune_policy;
+ }
+
+ // If set to true, this means the ICE transport should presume TURN-to-TURN
+ // candidate pairs will succeed, even before a binding response is received.
+ // This can be used to optimize the initial connection time, since the DTLS
+ // handshake can begin immediately.
+ bool presume_writable_when_fully_relayed = false;
+
+ // If true, "renomination" will be added to the ice options in the transport
+ // description.
+ // See: https://tools.ietf.org/html/draft-thatcher-ice-renomination-00
+ bool enable_ice_renomination = false;
+
+ // If true, the ICE role is re-determined when the PeerConnection sets a
+ // local transport description that indicates an ICE restart.
+ //
+ // This is standard RFC5245 ICE behavior, but causes unnecessary role
+ // thrashing, so an application may wish to avoid it. This role
+ // re-determining was removed in ICEbis (ICE v2).
+ bool redetermine_role_on_ice_restart = true;
+
+ // This flag is only effective when `continual_gathering_policy` is
+ // GATHER_CONTINUALLY.
+ //
+ // If true, after the ICE transport type is changed such that new types of
+ // ICE candidates are allowed by the new transport type, e.g. from
+ // IceTransportsType::kRelay to IceTransportsType::kAll, candidates that
+ // have been gathered by the ICE transport but not matching the previous
+ // transport type and as a result not observed by PeerConnectionObserver,
+ // will be surfaced to the observer.
+ bool surface_ice_candidates_on_ice_transport_type_changed = false;
+
+ // The following fields define intervals in milliseconds at which ICE
+ // connectivity checks are sent.
+ //
+ // We consider ICE is "strongly connected" for an agent when there is at
+ // least one candidate pair that currently succeeds in connectivity check
+ // from its direction i.e. sending a STUN ping and receives a STUN ping
+ // response, AND all candidate pairs have sent a minimum number of pings for
+ // connectivity (this number is implementation-specific). Otherwise, ICE is
+ // considered in "weak connectivity".
+ //
+ // Note that the above notion of strong and weak connectivity is not defined
+ // in RFC 5245, and they apply to our current ICE implementation only.
+ //
+ // 1) ice_check_interval_strong_connectivity defines the interval applied to
+ // ALL candidate pairs when ICE is strongly connected, and it overrides the
+ // default value of this interval in the ICE implementation;
+ // 2) ice_check_interval_weak_connectivity defines the counterpart for ALL
+ // pairs when ICE is weakly connected, and it overrides the default value of
+ // this interval in the ICE implementation;
+ // 3) ice_check_min_interval defines the minimal interval (equivalently the
+ // maximum rate) that overrides the above two intervals when either of them
+ // is less.
+ absl::optional<int> ice_check_interval_strong_connectivity;
+ absl::optional<int> ice_check_interval_weak_connectivity;
+ absl::optional<int> ice_check_min_interval;
+
+ // The min time period for which a candidate pair must wait for response to
+ // connectivity checks before it becomes unwritable. This parameter
+ // overrides the default value in the ICE implementation if set.
+ absl::optional<int> ice_unwritable_timeout;
+
+ // The min number of connectivity checks that a candidate pair must sent
+ // without receiving response before it becomes unwritable. This parameter
+ // overrides the default value in the ICE implementation if set.
+ absl::optional<int> ice_unwritable_min_checks;
+
+ // The min time period for which a candidate pair must wait for response to
+ // connectivity checks it becomes inactive. This parameter overrides the
+ // default value in the ICE implementation if set.
+ absl::optional<int> ice_inactive_timeout;
+
+ // The interval in milliseconds at which STUN candidates will resend STUN
+ // binding requests to keep NAT bindings open.
+ absl::optional<int> stun_candidate_keepalive_interval;
+
+ // Optional TurnCustomizer.
+ // With this class one can modify outgoing TURN messages.
+ // The object passed in must remain valid until PeerConnection::Close() is
+ // called.
+ webrtc::TurnCustomizer* turn_customizer = nullptr;
+
+ // Preferred network interface.
+ // A candidate pair on a preferred network has a higher precedence in ICE
+ // than one on an un-preferred network, regardless of priority or network
+ // cost.
+ absl::optional<rtc::AdapterType> network_preference;
+
+ // Configure the SDP semantics used by this PeerConnection. By default, this
+ // is Unified Plan which is compliant to the WebRTC 1.0 specification. It is
+ // possible to overrwite this to the deprecated Plan B SDP format, but note
+ // that kPlanB will be deleted at some future date, see
+ // https://crbug.com/webrtc/13528.
+ //
+ // kUnifiedPlan will cause the PeerConnection to create offers and answers
+ // with multiple m= sections where each m= section maps to one RtpSender and
+ // one RtpReceiver (an RtpTransceiver), either both audio or both video.
+ // This will also cause the PeerConnection to ignore all but the first
+ // a=ssrc lines that form a Plan B streams (if the PeerConnection is given
+ // Plan B SDP to process).
+ //
+ // kPlanB will cause the PeerConnection to create offers and answers with at
+ // most one audio and one video m= section with multiple RtpSenders and
+ // RtpReceivers specified as multiple a=ssrc lines within the section. This
+ // will also cause PeerConnection to ignore all but the first m= section of
+ // the same media type (if the PeerConnection is given Unified Plan SDP to
+ // process).
+ SdpSemantics sdp_semantics = SdpSemantics::kUnifiedPlan;
+
+ // TODO(bugs.webrtc.org/9891) - Move to crypto_options or remove.
+ // Actively reset the SRTP parameters whenever the DTLS transports
+ // underneath are reset for every offer/answer negotiation.
+ // This is only intended to be a workaround for crbug.com/835958
+ // WARNING: This would cause RTP/RTCP packets decryption failure if not used
+ // correctly. This flag will be deprecated soon. Do not rely on it.
+ bool active_reset_srtp_params = false;
+
+ // Defines advanced optional cryptographic settings related to SRTP and
+ // frame encryption for native WebRTC. Setting this will overwrite any
+ // settings set in PeerConnectionFactory (which is deprecated).
+ absl::optional<CryptoOptions> crypto_options;
+
+ // Configure if we should include the SDP attribute extmap-allow-mixed in
+ // our offer on session level.
+ bool offer_extmap_allow_mixed = true;
+
+ // TURN logging identifier.
+ // This identifier is added to a TURN allocation
+ // and it intended to be used to be able to match client side
+ // logs with TURN server logs. It will not be added if it's an empty string.
+ std::string turn_logging_id;
+
+ // Added to be able to control rollout of this feature.
+ bool enable_implicit_rollback = false;
+
+ // Whether network condition based codec switching is allowed.
+ absl::optional<bool> allow_codec_switching;
+
+ // The delay before doing a usage histogram report for long-lived
+ // PeerConnections. Used for testing only.
+ absl::optional<int> report_usage_pattern_delay_ms;
+
+ // The ping interval (ms) when the connection is stable and writable. This
+ // parameter overrides the default value in the ICE implementation if set.
+ absl::optional<int> stable_writable_connection_ping_interval_ms;
+
+ // Whether this PeerConnection will avoid VPNs (kAvoidVpn), prefer VPNs
+ // (kPreferVpn), only work over VPN (kOnlyUseVpn) or only work over non-VPN
+ // (kNeverUseVpn) interfaces. This controls which local interfaces the
+ // PeerConnection will prefer to connect over. Since VPN detection is not
+ // perfect, adherence to this preference cannot be guaranteed.
+ VpnPreference vpn_preference = VpnPreference::kDefault;
+
+ // List of address/length subnets that should be treated like
+ // VPN (in case webrtc fails to auto detect them).
+ std::vector<rtc::NetworkMask> vpn_list;
+
+ PortAllocatorConfig port_allocator_config;
+
+ // The burst interval of the pacer, see TaskQueuePacedSender constructor.
+ absl::optional<TimeDelta> pacer_burst_interval;
+
+ //
+ // Don't forget to update operator== if adding something.
+ //
+ };
+
+ // See: https://www.w3.org/TR/webrtc/#idl-def-rtcofferansweroptions
+ struct RTCOfferAnswerOptions {
+ static const int kUndefined = -1;
+ static const int kMaxOfferToReceiveMedia = 1;
+
+ // The default value for constraint offerToReceiveX:true.
+ static const int kOfferToReceiveMediaTrue = 1;
+
+ // These options are left as backwards compatibility for clients who need
+ // "Plan B" semantics. Clients who have switched to "Unified Plan" semantics
+ // should use the RtpTransceiver API (AddTransceiver) instead.
+ //
+ // offer_to_receive_X set to 1 will cause a media description to be
+ // generated in the offer, even if no tracks of that type have been added.
+ // Values greater than 1 are treated the same.
+ //
+ // If set to 0, the generated directional attribute will not include the
+ // "recv" direction (meaning it will be "sendonly" or "inactive".
+ int offer_to_receive_video = kUndefined;
+ int offer_to_receive_audio = kUndefined;
+
+ bool voice_activity_detection = true;
+ bool ice_restart = false;
+
+ // If true, will offer to BUNDLE audio/video/data together. Not to be
+ // confused with RTCP mux (multiplexing RTP and RTCP together).
+ bool use_rtp_mux = true;
+
+ // If true, "a=packetization:<payload_type> raw" attribute will be offered
+ // in the SDP for all video payload and accepted in the answer if offered.
+ bool raw_packetization_for_video = false;
+
+ // This will apply to all video tracks with a Plan B SDP offer/answer.
+ int num_simulcast_layers = 1;
+
+ // If true: Use SDP format from draft-ietf-mmusic-scdp-sdp-03
+ // If false: Use SDP format from draft-ietf-mmusic-sdp-sdp-26 or later
+ bool use_obsolete_sctp_sdp = false;
+
+ RTCOfferAnswerOptions() = default;
+
+ RTCOfferAnswerOptions(int offer_to_receive_video,
+ int offer_to_receive_audio,
+ bool voice_activity_detection,
+ bool ice_restart,
+ bool use_rtp_mux)
+ : offer_to_receive_video(offer_to_receive_video),
+ offer_to_receive_audio(offer_to_receive_audio),
+ voice_activity_detection(voice_activity_detection),
+ ice_restart(ice_restart),
+ use_rtp_mux(use_rtp_mux) {}
+ };
+
+ // Used by GetStats to decide which stats to include in the stats reports.
+ // `kStatsOutputLevelStandard` includes the standard stats for Javascript API;
+ // `kStatsOutputLevelDebug` includes both the standard stats and additional
+ // stats for debugging purposes.
+ enum StatsOutputLevel {
+ kStatsOutputLevelStandard,
+ kStatsOutputLevelDebug,
+ };
+
+ // Accessor methods to active local streams.
+ // This method is not supported with kUnifiedPlan semantics. Please use
+ // GetSenders() instead.
+ virtual rtc::scoped_refptr<StreamCollectionInterface> local_streams() = 0;
+
+ // Accessor methods to remote streams.
+ // This method is not supported with kUnifiedPlan semantics. Please use
+ // GetReceivers() instead.
+ virtual rtc::scoped_refptr<StreamCollectionInterface> remote_streams() = 0;
+
+ // Add a new MediaStream to be sent on this PeerConnection.
+ // Note that a SessionDescription negotiation is needed before the
+ // remote peer can receive the stream.
+ //
+ // This has been removed from the standard in favor of a track-based API. So,
+ // this is equivalent to simply calling AddTrack for each track within the
+ // stream, with the one difference that if "stream->AddTrack(...)" is called
+ // later, the PeerConnection will automatically pick up the new track. Though
+ // this functionality will be deprecated in the future.
+ //
+ // This method is not supported with kUnifiedPlan semantics. Please use
+ // AddTrack instead.
+ virtual bool AddStream(MediaStreamInterface* stream) = 0;
+
+ // Remove a MediaStream from this PeerConnection.
+ // Note that a SessionDescription negotiation is needed before the
+ // remote peer is notified.
+ //
+ // This method is not supported with kUnifiedPlan semantics. Please use
+ // RemoveTrack instead.
+ virtual void RemoveStream(MediaStreamInterface* stream) = 0;
+
+ // Add a new MediaStreamTrack to be sent on this PeerConnection, and return
+ // the newly created RtpSender. The RtpSender will be associated with the
+ // streams specified in the `stream_ids` list.
+ //
+ // Errors:
+ // - INVALID_PARAMETER: `track` is null, has a kind other than audio or video,
+ // or a sender already exists for the track.
+ // - INVALID_STATE: The PeerConnection is closed.
+ virtual RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> AddTrack(
+ rtc::scoped_refptr<MediaStreamTrackInterface> track,
+ const std::vector<std::string>& stream_ids) = 0;
+
+ // Add a new MediaStreamTrack as above, but with an additional parameter,
+ // `init_send_encodings` : initial RtpEncodingParameters for RtpSender,
+ // similar to init_send_encodings in RtpTransceiverInit.
+ // Note that a new transceiver will always be created.
+ //
+ virtual RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> AddTrack(
+ rtc::scoped_refptr<MediaStreamTrackInterface> track,
+ const std::vector<std::string>& stream_ids,
+ const std::vector<RtpEncodingParameters>& init_send_encodings) = 0;
+
+ // Removes the connection between a MediaStreamTrack and the PeerConnection.
+ // Stops sending on the RtpSender and marks the
+ // corresponding RtpTransceiver direction as no longer sending.
+ // https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-removetrack
+ //
+ // Errors:
+ // - INVALID_PARAMETER: `sender` is null or (Plan B only) the sender is not
+ // associated with this PeerConnection.
+ // - INVALID_STATE: PeerConnection is closed.
+ //
+ // Plan B semantics: Removes the RtpSender from this PeerConnection.
+ //
+ // TODO(bugs.webrtc.org/9534): Rename to RemoveTrack once the other signature
+ // is removed; remove default implementation once upstream is updated.
+ virtual RTCError RemoveTrackOrError(
+ rtc::scoped_refptr<RtpSenderInterface> sender) {
+ RTC_CHECK_NOTREACHED();
+ return RTCError();
+ }
+
+ // AddTransceiver creates a new RtpTransceiver and adds it to the set of
+ // transceivers. Adding a transceiver will cause future calls to CreateOffer
+ // to add a media description for the corresponding transceiver.
+ //
+ // The initial value of `mid` in the returned transceiver is null. Setting a
+ // new session description may change it to a non-null value.
+ //
+ // https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addtransceiver
+ //
+ // Optionally, an RtpTransceiverInit structure can be specified to configure
+ // the transceiver from construction. If not specified, the transceiver will
+ // default to having a direction of kSendRecv and not be part of any streams.
+ //
+ // These methods are only available when Unified Plan is enabled (see
+ // RTCConfiguration).
+ //
+ // Common errors:
+ // - INTERNAL_ERROR: The configuration does not have Unified Plan enabled.
+
+ // Adds a transceiver with a sender set to transmit the given track. The kind
+ // of the transceiver (and sender/receiver) will be derived from the kind of
+ // the track.
+ // Errors:
+ // - INVALID_PARAMETER: `track` is null.
+ virtual RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
+ AddTransceiver(rtc::scoped_refptr<MediaStreamTrackInterface> track) = 0;
+ virtual RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
+ AddTransceiver(rtc::scoped_refptr<MediaStreamTrackInterface> track,
+ const RtpTransceiverInit& init) = 0;
+
+ // Adds a transceiver with the given kind. Can either be MEDIA_TYPE_AUDIO or
+ // MEDIA_TYPE_VIDEO.
+ // Errors:
+ // - INVALID_PARAMETER: `media_type` is not MEDIA_TYPE_AUDIO or
+ // MEDIA_TYPE_VIDEO.
+ virtual RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
+ AddTransceiver(cricket::MediaType media_type) = 0;
+ virtual RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
+ AddTransceiver(cricket::MediaType media_type,
+ const RtpTransceiverInit& init) = 0;
+
+ // Creates a sender without a track. Can be used for "early media"/"warmup"
+ // use cases, where the application may want to negotiate video attributes
+ // before a track is available to send.
+ //
+ // The standard way to do this would be through "addTransceiver", but we
+ // don't support that API yet.
+ //
+ // `kind` must be "audio" or "video".
+ //
+ // `stream_id` is used to populate the msid attribute; if empty, one will
+ // be generated automatically.
+ //
+ // This method is not supported with kUnifiedPlan semantics. Please use
+ // AddTransceiver instead.
+ virtual rtc::scoped_refptr<RtpSenderInterface> CreateSender(
+ const std::string& kind,
+ const std::string& stream_id) = 0;
+
+ // If Plan B semantics are specified, gets all RtpSenders, created either
+ // through AddStream, AddTrack, or CreateSender. All senders of a specific
+ // media type share the same media description.
+ //
+ // If Unified Plan semantics are specified, gets the RtpSender for each
+ // RtpTransceiver.
+ virtual std::vector<rtc::scoped_refptr<RtpSenderInterface>> GetSenders()
+ const = 0;
+
+ // If Plan B semantics are specified, gets all RtpReceivers created when a
+ // remote description is applied. All receivers of a specific media type share
+ // the same media description. It is also possible to have a media description
+ // with no associated RtpReceivers, if the directional attribute does not
+ // indicate that the remote peer is sending any media.
+ //
+ // If Unified Plan semantics are specified, gets the RtpReceiver for each
+ // RtpTransceiver.
+ virtual std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceivers()
+ const = 0;
+
+ // Get all RtpTransceivers, created either through AddTransceiver, AddTrack or
+ // by a remote description applied with SetRemoteDescription.
+ //
+ // Note: This method is only available when Unified Plan is enabled (see
+ // RTCConfiguration).
+ virtual std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>
+ GetTransceivers() const = 0;
+
+ // The legacy non-compliant GetStats() API. This correspond to the
+ // callback-based version of getStats() in JavaScript. The returned metrics
+ // are UNDOCUMENTED and many of them rely on implementation-specific details.
+ // The goal is to DELETE THIS VERSION but we can't today because it is heavily
+ // relied upon by third parties. See https://crbug.com/822696.
+ //
+ // This version is wired up into Chrome. Any stats implemented are
+ // automatically exposed to the Web Platform. This has BYPASSED the Chrome
+ // release processes for years and lead to cross-browser incompatibility
+ // issues and web application reliance on Chrome-only behavior.
+ //
+ // This API is in "maintenance mode", serious regressions should be fixed but
+ // adding new stats is highly discouraged.
+ //
+ // TODO(hbos): Deprecate and remove this when third parties have migrated to
+ // the spec-compliant GetStats() API. https://crbug.com/822696
+ virtual bool GetStats(StatsObserver* observer,
+ MediaStreamTrackInterface* track, // Optional
+ StatsOutputLevel level) = 0;
+ // The spec-compliant GetStats() API. This correspond to the promise-based
+ // version of getStats() in JavaScript. Implementation status is described in
+ // api/stats/rtcstats_objects.h. For more details on stats, see spec:
+ // https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-getstats
+ // TODO(hbos): Takes shared ownership, use rtc::scoped_refptr<> instead. This
+ // requires stop overriding the current version in third party or making third
+ // party calls explicit to avoid ambiguity during switch. Make the future
+ // version abstract as soon as third party projects implement it.
+ virtual void GetStats(RTCStatsCollectorCallback* callback) = 0;
+ // Spec-compliant getStats() performing the stats selection algorithm with the
+ // sender. https://w3c.github.io/webrtc-pc/#dom-rtcrtpsender-getstats
+ virtual void GetStats(
+ rtc::scoped_refptr<RtpSenderInterface> selector,
+ rtc::scoped_refptr<RTCStatsCollectorCallback> callback) = 0;
+ // Spec-compliant getStats() performing the stats selection algorithm with the
+ // receiver. https://w3c.github.io/webrtc-pc/#dom-rtcrtpreceiver-getstats
+ virtual void GetStats(
+ rtc::scoped_refptr<RtpReceiverInterface> selector,
+ rtc::scoped_refptr<RTCStatsCollectorCallback> callback) = 0;
+ // Clear cached stats in the RTCStatsCollector.
+ virtual void ClearStatsCache() {}
+
+ // Create a data channel with the provided config, or default config if none
+ // is provided. Note that an offer/answer negotiation is still necessary
+ // before the data channel can be used.
+ //
+ // Also, calling CreateDataChannel is the only way to get a data "m=" section
+ // in SDP, so it should be done before CreateOffer is called, if the
+ // application plans to use data channels.
+ virtual RTCErrorOr<rtc::scoped_refptr<DataChannelInterface>>
+ CreateDataChannelOrError(const std::string& label,
+ const DataChannelInit* config) {
+ return RTCError(RTCErrorType::INTERNAL_ERROR, "dummy function called");
+ }
+ // TODO(crbug.com/788659): Remove "virtual" below and default implementation
+ // above once mock in Chrome is fixed.
+ ABSL_DEPRECATED("Use CreateDataChannelOrError")
+ virtual rtc::scoped_refptr<DataChannelInterface> CreateDataChannel(
+ const std::string& label,
+ const DataChannelInit* config) {
+ auto result = CreateDataChannelOrError(label, config);
+ if (!result.ok()) {
+ return nullptr;
+ } else {
+ return result.MoveValue();
+ }
+ }
+
+ // NOTE: For the following 6 methods, it's only safe to dereference the
+ // SessionDescriptionInterface on signaling_thread() (for example, calling
+ // ToString).
+
+ // Returns the more recently applied description; "pending" if it exists, and
+ // otherwise "current". See below.
+ virtual const SessionDescriptionInterface* local_description() const = 0;
+ virtual const SessionDescriptionInterface* remote_description() const = 0;
+
+ // A "current" description the one currently negotiated from a complete
+ // offer/answer exchange.
+ virtual const SessionDescriptionInterface* current_local_description()
+ const = 0;
+ virtual const SessionDescriptionInterface* current_remote_description()
+ const = 0;
+
+ // A "pending" description is one that's part of an incomplete offer/answer
+ // exchange (thus, either an offer or a pranswer). Once the offer/answer
+ // exchange is finished, the "pending" description will become "current".
+ virtual const SessionDescriptionInterface* pending_local_description()
+ const = 0;
+ virtual const SessionDescriptionInterface* pending_remote_description()
+ const = 0;
+
+ // Tells the PeerConnection that ICE should be restarted. This triggers a need
+ // for negotiation and subsequent CreateOffer() calls will act as if
+ // RTCOfferAnswerOptions::ice_restart is true.
+ // https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-restartice
+ // TODO(hbos): Remove default implementation when downstream projects
+ // implement this.
+ virtual void RestartIce() = 0;
+
+ // Create a new offer.
+ // The CreateSessionDescriptionObserver callback will be called when done.
+ virtual void CreateOffer(CreateSessionDescriptionObserver* observer,
+ const RTCOfferAnswerOptions& options) = 0;
+
+ // Create an answer to an offer.
+ // The CreateSessionDescriptionObserver callback will be called when done.
+ virtual void CreateAnswer(CreateSessionDescriptionObserver* observer,
+ const RTCOfferAnswerOptions& options) = 0;
+
+ // Sets the local session description.
+ //
+ // According to spec, the local session description MUST be the same as was
+ // returned by CreateOffer() or CreateAnswer() or else the operation should
+ // fail. Our implementation however allows some amount of "SDP munging", but
+ // please note that this is HIGHLY DISCOURAGED. If you do not intent to munge
+ // SDP, the method below that doesn't take `desc` as an argument will create
+ // the offer or answer for you.
+ //
+ // The observer is invoked as soon as the operation completes, which could be
+ // before or after the SetLocalDescription() method has exited.
+ virtual void SetLocalDescription(
+ std::unique_ptr<SessionDescriptionInterface> desc,
+ rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {}
+ // Creates an offer or answer (depending on current signaling state) and sets
+ // it as the local session description.
+ //
+ // The observer is invoked as soon as the operation completes, which could be
+ // before or after the SetLocalDescription() method has exited.
+ virtual void SetLocalDescription(
+ rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {}
+ // Like SetLocalDescription() above, but the observer is invoked with a delay
+ // after the operation completes. This helps avoid recursive calls by the
+ // observer but also makes it possible for states to change in-between the
+ // operation completing and the observer getting called. This makes them racy
+ // for synchronizing peer connection states to the application.
+ // TODO(https://crbug.com/webrtc/11798): Delete these methods in favor of the
+ // ones taking SetLocalDescriptionObserverInterface as argument.
+ virtual void SetLocalDescription(SetSessionDescriptionObserver* observer,
+ SessionDescriptionInterface* desc) = 0;
+ virtual void SetLocalDescription(SetSessionDescriptionObserver* observer) {}
+
+ // Sets the remote session description.
+ //
+ // (Unlike "SDP munging" before SetLocalDescription(), modifying a remote
+ // offer or answer is allowed by the spec.)
+ //
+ // The observer is invoked as soon as the operation completes, which could be
+ // before or after the SetRemoteDescription() method has exited.
+ virtual void SetRemoteDescription(
+ std::unique_ptr<SessionDescriptionInterface> desc,
+ rtc::scoped_refptr<SetRemoteDescriptionObserverInterface> observer) = 0;
+ // Like SetRemoteDescription() above, but the observer is invoked with a delay
+ // after the operation completes. This helps avoid recursive calls by the
+ // observer but also makes it possible for states to change in-between the
+ // operation completing and the observer getting called. This makes them racy
+ // for synchronizing peer connection states to the application.
+ // TODO(https://crbug.com/webrtc/11798): Delete this method in favor of the
+ // ones taking SetRemoteDescriptionObserverInterface as argument.
+ virtual void SetRemoteDescription(SetSessionDescriptionObserver* observer,
+ SessionDescriptionInterface* desc) {}
+
+ // According to spec, we must only fire "negotiationneeded" if the Operations
+ // Chain is empty. This method takes care of validating an event previously
+ // generated with PeerConnectionObserver::OnNegotiationNeededEvent() to make
+ // sure that even if there was a delay (e.g. due to a PostTask) between the
+ // event being generated and the time of firing, the Operations Chain is empty
+ // and the event is still valid to be fired.
+ virtual bool ShouldFireNegotiationNeededEvent(uint32_t event_id) {
+ return true;
+ }
+
+ virtual PeerConnectionInterface::RTCConfiguration GetConfiguration() = 0;
+
+ // Sets the PeerConnection's global configuration to `config`.
+ //
+ // The members of `config` that may be changed are `type`, `servers`,
+ // `ice_candidate_pool_size` and `prune_turn_ports` (though the candidate
+ // pool size can't be changed after the first call to SetLocalDescription).
+ // Note that this means the BUNDLE and RTCP-multiplexing policies cannot be
+ // changed with this method.
+ //
+ // Any changes to STUN/TURN servers or ICE candidate policy will affect the
+ // next gathering phase, and cause the next call to createOffer to generate
+ // new ICE credentials, as described in JSEP. This also occurs when
+ // `prune_turn_ports` changes, for the same reasoning.
+ //
+ // If an error occurs, returns false and populates `error` if non-null:
+ // - INVALID_MODIFICATION if `config` contains a modified parameter other
+ // than one of the parameters listed above.
+ // - INVALID_RANGE if `ice_candidate_pool_size` is out of range.
+ // - SYNTAX_ERROR if parsing an ICE server URL failed.
+ // - INVALID_PARAMETER if a TURN server is missing `username` or `password`.
+ // - INTERNAL_ERROR if an unexpected error occurred.
+ virtual RTCError SetConfiguration(
+ const PeerConnectionInterface::RTCConfiguration& config) = 0;
+
+ // Provides a remote candidate to the ICE Agent.
+ // A copy of the `candidate` will be created and added to the remote
+ // description. So the caller of this method still has the ownership of the
+ // `candidate`.
+ // TODO(hbos): The spec mandates chaining this operation onto the operations
+ // chain; deprecate and remove this version in favor of the callback-based
+ // signature.
+ virtual bool AddIceCandidate(const IceCandidateInterface* candidate) = 0;
+ // TODO(hbos): Remove default implementation once implemented by downstream
+ // projects.
+ virtual void AddIceCandidate(std::unique_ptr<IceCandidateInterface> candidate,
+ std::function<void(RTCError)> callback) {}
+
+ // Removes a group of remote candidates from the ICE agent. Needed mainly for
+ // continual gathering, to avoid an ever-growing list of candidates as
+ // networks come and go. Note that the candidates' transport_name must be set
+ // to the MID of the m= section that generated the candidate.
+ // TODO(bugs.webrtc.org/8395): Use IceCandidateInterface instead of
+ // cricket::Candidate, which would avoid the transport_name oddity.
+ virtual bool RemoveIceCandidates(
+ const std::vector<cricket::Candidate>& candidates) = 0;
+
+ // SetBitrate limits the bandwidth allocated for all RTP streams sent by
+ // this PeerConnection. Other limitations might affect these limits and
+ // are respected (for example "b=AS" in SDP).
+ //
+ // Setting `current_bitrate_bps` will reset the current bitrate estimate
+ // to the provided value.
+ virtual RTCError SetBitrate(const BitrateSettings& bitrate) = 0;
+
+ // Enable/disable playout of received audio streams. Enabled by default. Note
+ // that even if playout is enabled, streams will only be played out if the
+ // appropriate SDP is also applied. Setting `playout` to false will stop
+ // playout of the underlying audio device but starts a task which will poll
+ // for audio data every 10ms to ensure that audio processing happens and the
+ // audio statistics are updated.
+ virtual void SetAudioPlayout(bool playout) {}
+
+ // Enable/disable recording of transmitted audio streams. Enabled by default.
+ // Note that even if recording is enabled, streams will only be recorded if
+ // the appropriate SDP is also applied.
+ virtual void SetAudioRecording(bool recording) {}
+
+ // Looks up the DtlsTransport associated with a MID value.
+ // In the Javascript API, DtlsTransport is a property of a sender, but
+ // because the PeerConnection owns the DtlsTransport in this implementation,
+ // it is better to look them up on the PeerConnection.
+ virtual rtc::scoped_refptr<DtlsTransportInterface> LookupDtlsTransportByMid(
+ const std::string& mid) = 0;
+
+ // Returns the SCTP transport, if any.
+ virtual rtc::scoped_refptr<SctpTransportInterface> GetSctpTransport()
+ const = 0;
+
+ // Returns the current SignalingState.
+ virtual SignalingState signaling_state() = 0;
+
+ // Returns an aggregate state of all ICE *and* DTLS transports.
+ // This is left in place to avoid breaking native clients who expect our old,
+ // nonstandard behavior.
+ // TODO(jonasolsson): deprecate and remove this.
+ virtual IceConnectionState ice_connection_state() = 0;
+
+ // Returns an aggregated state of all ICE transports.
+ virtual IceConnectionState standardized_ice_connection_state() = 0;
+
+ // Returns an aggregated state of all ICE and DTLS transports.
+ virtual PeerConnectionState peer_connection_state() = 0;
+
+ virtual IceGatheringState ice_gathering_state() = 0;
+
+ // Returns the current state of canTrickleIceCandidates per
+ // https://w3c.github.io/webrtc-pc/#attributes-1
+ virtual absl::optional<bool> can_trickle_ice_candidates() {
+ // TODO(crbug.com/708484): Remove default implementation.
+ return absl::nullopt;
+ }
+
+ // When a resource is overused, the PeerConnection will try to reduce the load
+ // on the sysem, for example by reducing the resolution or frame rate of
+ // encoded streams. The Resource API allows injecting platform-specific usage
+ // measurements. The conditions to trigger kOveruse or kUnderuse are up to the
+ // implementation.
+ // TODO(hbos): Make pure virtual when implemented by downstream projects.
+ virtual void AddAdaptationResource(rtc::scoped_refptr<Resource> resource) {}
+
+ // Start RtcEventLog using an existing output-sink. Takes ownership of
+ // `output` and passes it on to Call, which will take the ownership. If the
+ // operation fails the output will be closed and deallocated. The event log
+ // will send serialized events to the output object every `output_period_ms`.
+ // Applications using the event log should generally make their own trade-off
+ // regarding the output period. A long period is generally more efficient,
+ // with potential drawbacks being more bursty thread usage, and more events
+ // lost in case the application crashes. If the `output_period_ms` argument is
+ // omitted, webrtc selects a default deemed to be workable in most cases.
+ virtual bool StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output,
+ int64_t output_period_ms) = 0;
+ virtual bool StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output) = 0;
+
+ // Stops logging the RtcEventLog.
+ virtual void StopRtcEventLog() = 0;
+
+ // Terminates all media, closes the transports, and in general releases any
+ // resources used by the PeerConnection. This is an irreversible operation.
+ //
+ // Note that after this method completes, the PeerConnection will no longer
+ // use the PeerConnectionObserver interface passed in on construction, and
+ // thus the observer object can be safely destroyed.
+ virtual void Close() = 0;
+
+ // The thread on which all PeerConnectionObserver callbacks will be invoked,
+ // as well as callbacks for other classes such as DataChannelObserver.
+ //
+ // Also the only thread on which it's safe to use SessionDescriptionInterface
+ // pointers.
+ // TODO(deadbeef): Make pure virtual when all subclasses implement it.
+ virtual rtc::Thread* signaling_thread() const { return nullptr; }
+
+ protected:
+ // Dtor protected as objects shouldn't be deleted via this interface.
+ ~PeerConnectionInterface() override = default;
+};
+
+// PeerConnection callback interface, used for RTCPeerConnection events.
+// Application should implement these methods.
+class PeerConnectionObserver {
+ public:
+ virtual ~PeerConnectionObserver() = default;
+
+ // Triggered when the SignalingState changed.
+ virtual void OnSignalingChange(
+ PeerConnectionInterface::SignalingState new_state) = 0;
+
+ // Triggered when media is received on a new stream from remote peer.
+ virtual void OnAddStream(rtc::scoped_refptr<MediaStreamInterface> stream) {}
+
+ // Triggered when a remote peer closes a stream.
+ virtual void OnRemoveStream(rtc::scoped_refptr<MediaStreamInterface> stream) {
+ }
+
+ // Triggered when a remote peer opens a data channel.
+ virtual void OnDataChannel(
+ rtc::scoped_refptr<DataChannelInterface> data_channel) = 0;
+
+ // Triggered when renegotiation is needed. For example, an ICE restart
+ // has begun.
+ // TODO(hbos): Delete in favor of OnNegotiationNeededEvent() when downstream
+ // projects have migrated.
+ virtual void OnRenegotiationNeeded() {}
+ // Used to fire spec-compliant onnegotiationneeded events, which should only
+ // fire when the Operations Chain is empty. The observer is responsible for
+ // queuing a task (e.g. Chromium: jump to main thread) to maybe fire the
+ // event. The event identified using `event_id` must only fire if
+ // PeerConnection::ShouldFireNegotiationNeededEvent() returns true since it is
+ // possible for the event to become invalidated by operations subsequently
+ // chained.
+ virtual void OnNegotiationNeededEvent(uint32_t event_id) {}
+
+ // Called any time the legacy IceConnectionState changes.
+ //
+ // Note that our ICE states lag behind the standard slightly. The most
+ // notable differences include the fact that "failed" occurs after 15
+ // seconds, not 30, and this actually represents a combination ICE + DTLS
+ // state, so it may be "failed" if DTLS fails while ICE succeeds.
+ //
+ // TODO(jonasolsson): deprecate and remove this.
+ virtual void OnIceConnectionChange(
+ PeerConnectionInterface::IceConnectionState new_state) {}
+
+ // Called any time the standards-compliant IceConnectionState changes.
+ virtual void OnStandardizedIceConnectionChange(
+ PeerConnectionInterface::IceConnectionState new_state) {}
+
+ // Called any time the PeerConnectionState changes.
+ virtual void OnConnectionChange(
+ PeerConnectionInterface::PeerConnectionState new_state) {}
+
+ // Called any time the IceGatheringState changes.
+ virtual void OnIceGatheringChange(
+ PeerConnectionInterface::IceGatheringState new_state) = 0;
+
+ // A new ICE candidate has been gathered.
+ virtual void OnIceCandidate(const IceCandidateInterface* candidate) = 0;
+
+ // Gathering of an ICE candidate failed.
+ // See https://w3c.github.io/webrtc-pc/#event-icecandidateerror
+ virtual void OnIceCandidateError(const std::string& address,
+ int port,
+ const std::string& url,
+ int error_code,
+ const std::string& error_text) {}
+
+ // Ice candidates have been removed.
+ // TODO(honghaiz): Make this a pure virtual method when all its subclasses
+ // implement it.
+ virtual void OnIceCandidatesRemoved(
+ const std::vector<cricket::Candidate>& candidates) {}
+
+ // Called when the ICE connection receiving status changes.
+ virtual void OnIceConnectionReceivingChange(bool receiving) {}
+
+ // Called when the selected candidate pair for the ICE connection changes.
+ virtual void OnIceSelectedCandidatePairChanged(
+ const cricket::CandidatePairChangeEvent& event) {}
+
+ // This is called when a receiver and its track are created.
+ // TODO(zhihuang): Make this pure virtual when all subclasses implement it.
+ // Note: This is called with both Plan B and Unified Plan semantics. Unified
+ // Plan users should prefer OnTrack, OnAddTrack is only called as backwards
+ // compatibility (and is called in the exact same situations as OnTrack).
+ virtual void OnAddTrack(
+ rtc::scoped_refptr<RtpReceiverInterface> receiver,
+ const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {}
+
+ // This is called when signaling indicates a transceiver will be receiving
+ // media from the remote endpoint. This is fired during a call to
+ // SetRemoteDescription. The receiving track can be accessed by:
+ // `transceiver->receiver()->track()` and its associated streams by
+ // `transceiver->receiver()->streams()`.
+ // Note: This will only be called if Unified Plan semantics are specified.
+ // This behavior is specified in section 2.2.8.2.5 of the "Set the
+ // RTCSessionDescription" algorithm:
+ // https://w3c.github.io/webrtc-pc/#set-description
+ virtual void OnTrack(
+ rtc::scoped_refptr<RtpTransceiverInterface> transceiver) {}
+
+ // Called when signaling indicates that media will no longer be received on a
+ // track.
+ // With Plan B semantics, the given receiver will have been removed from the
+ // PeerConnection and the track muted.
+ // With Unified Plan semantics, the receiver will remain but the transceiver
+ // will have changed direction to either sendonly or inactive.
+ // https://w3c.github.io/webrtc-pc/#process-remote-track-removal
+ // TODO(hbos,deadbeef): Make pure virtual when all subclasses implement it.
+ virtual void OnRemoveTrack(
+ rtc::scoped_refptr<RtpReceiverInterface> receiver) {}
+
+ // Called when an interesting usage is detected by WebRTC.
+ // An appropriate action is to add information about the context of the
+ // PeerConnection and write the event to some kind of "interesting events"
+ // log function.
+ // The heuristics for defining what constitutes "interesting" are
+ // implementation-defined.
+ virtual void OnInterestingUsage(int usage_pattern) {}
+};
+
+// PeerConnectionDependencies holds all of PeerConnections dependencies.
+// A dependency is distinct from a configuration as it defines significant
+// executable code that can be provided by a user of the API.
+//
+// All new dependencies should be added as a unique_ptr to allow the
+// PeerConnection object to be the definitive owner of the dependencies
+// lifetime making injection safer.
+struct RTC_EXPORT PeerConnectionDependencies final {
+ explicit PeerConnectionDependencies(PeerConnectionObserver* observer_in);
+ // This object is not copyable or assignable.
+ PeerConnectionDependencies(const PeerConnectionDependencies&) = delete;
+ PeerConnectionDependencies& operator=(const PeerConnectionDependencies&) =
+ delete;
+ // This object is only moveable.
+ PeerConnectionDependencies(PeerConnectionDependencies&&);
+ PeerConnectionDependencies& operator=(PeerConnectionDependencies&&) = default;
+ ~PeerConnectionDependencies();
+ // Mandatory dependencies
+ PeerConnectionObserver* observer = nullptr;
+ // Optional dependencies
+ // TODO(bugs.webrtc.org/7447): remove port allocator once downstream is
+ // updated. The recommended way to inject networking components is to pass a
+ // PacketSocketFactory when creating the PeerConnectionFactory.
+ std::unique_ptr<cricket::PortAllocator> allocator;
+ // Factory for creating resolvers that look up hostnames in DNS
+ std::unique_ptr<webrtc::AsyncDnsResolverFactoryInterface>
+ async_dns_resolver_factory;
+ // Deprecated - use async_dns_resolver_factory
+ std::unique_ptr<webrtc::AsyncResolverFactory> async_resolver_factory;
+ std::unique_ptr<webrtc::IceTransportFactory> ice_transport_factory;
+ std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator;
+ std::unique_ptr<rtc::SSLCertificateVerifier> tls_cert_verifier;
+ std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
+ video_bitrate_allocator_factory;
+ // Optional field trials to use.
+ // Overrides those from PeerConnectionFactoryDependencies.
+ std::unique_ptr<FieldTrialsView> trials;
+};
+
+// PeerConnectionFactoryDependencies holds all of the PeerConnectionFactory
+// dependencies. All new dependencies should be added here instead of
+// overloading the function. This simplifies dependency injection and makes it
+// clear which are mandatory and optional. If possible please allow the peer
+// connection factory to take ownership of the dependency by adding a unique_ptr
+// to this structure.
+struct RTC_EXPORT PeerConnectionFactoryDependencies final {
+ PeerConnectionFactoryDependencies();
+ // This object is not copyable or assignable.
+ PeerConnectionFactoryDependencies(const PeerConnectionFactoryDependencies&) =
+ delete;
+ PeerConnectionFactoryDependencies& operator=(
+ const PeerConnectionFactoryDependencies&) = delete;
+ // This object is only moveable.
+ PeerConnectionFactoryDependencies(PeerConnectionFactoryDependencies&&);
+ PeerConnectionFactoryDependencies& operator=(
+ PeerConnectionFactoryDependencies&&) = default;
+ ~PeerConnectionFactoryDependencies();
+
+ // Optional dependencies
+ rtc::Thread* network_thread = nullptr;
+ rtc::Thread* worker_thread = nullptr;
+ rtc::Thread* signaling_thread = nullptr;
+ rtc::SocketFactory* socket_factory = nullptr;
+ // The `packet_socket_factory` will only be used if CreatePeerConnection is
+ // called without a `port_allocator`.
+ std::unique_ptr<rtc::PacketSocketFactory> packet_socket_factory;
+ std::unique_ptr<TaskQueueFactory> task_queue_factory;
+ std::unique_ptr<cricket::MediaEngineInterface> media_engine;
+ std::unique_ptr<CallFactoryInterface> call_factory;
+ std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory;
+ std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory;
+ std::unique_ptr<NetworkStatePredictorFactoryInterface>
+ network_state_predictor_factory;
+ std::unique_ptr<NetworkControllerFactoryInterface> network_controller_factory;
+ // The `network_manager` will only be used if CreatePeerConnection is called
+ // without a `port_allocator`, causing the default allocator and network
+ // manager to be used.
+ std::unique_ptr<rtc::NetworkManager> network_manager;
+ // The `network_monitor_factory` will only be used if CreatePeerConnection is
+ // called without a `port_allocator`, and the above `network_manager' is null.
+ std::unique_ptr<rtc::NetworkMonitorFactory> network_monitor_factory;
+ std::unique_ptr<NetEqFactory> neteq_factory;
+ std::unique_ptr<SctpTransportFactoryInterface> sctp_factory;
+ std::unique_ptr<FieldTrialsView> trials;
+ std::unique_ptr<RtpTransportControllerSendFactoryInterface>
+ transport_controller_send_factory;
+ std::unique_ptr<Metronome> metronome;
+};
+
+// PeerConnectionFactoryInterface is the factory interface used for creating
+// PeerConnection, MediaStream and MediaStreamTrack objects.
+//
+// The simplest method for obtaiing one, CreatePeerConnectionFactory will
+// create the required libjingle threads, socket and network manager factory
+// classes for networking if none are provided, though it requires that the
+// application runs a message loop on the thread that called the method (see
+// explanation below)
+//
+// If an application decides to provide its own threads and/or implementation
+// of networking classes, it should use the alternate
+// CreatePeerConnectionFactory method which accepts threads as input, and use
+// the CreatePeerConnection version that takes a PortAllocator as an argument.
+class RTC_EXPORT PeerConnectionFactoryInterface
+ : public rtc::RefCountInterface {
+ public:
+ class Options {
+ public:
+ Options() {}
+
+ // If set to true, created PeerConnections won't enforce any SRTP
+ // requirement, allowing unsecured media. Should only be used for
+ // testing/debugging.
+ bool disable_encryption = false;
+
+ // If set to true, any platform-supported network monitoring capability
+ // won't be used, and instead networks will only be updated via polling.
+ //
+ // This only has an effect if a PeerConnection is created with the default
+ // PortAllocator implementation.
+ bool disable_network_monitor = false;
+
+ // Sets the network types to ignore. For instance, calling this with
+ // ADAPTER_TYPE_ETHERNET | ADAPTER_TYPE_LOOPBACK will ignore Ethernet and
+ // loopback interfaces.
+ int network_ignore_mask = rtc::kDefaultNetworkIgnoreMask;
+
+ // Sets the maximum supported protocol version. The highest version
+ // supported by both ends will be used for the connection, i.e. if one
+ // party supports DTLS 1.0 and the other DTLS 1.2, DTLS 1.0 will be used.
+ rtc::SSLProtocolVersion ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
+
+ // Sets crypto related options, e.g. enabled cipher suites.
+ CryptoOptions crypto_options = CryptoOptions::NoGcm();
+ };
+
+ // Set the options to be used for subsequently created PeerConnections.
+ virtual void SetOptions(const Options& options) = 0;
+
+ // The preferred way to create a new peer connection. Simply provide the
+ // configuration and a PeerConnectionDependencies structure.
+ // TODO(benwright): Make pure virtual once downstream mock PC factory classes
+ // are updated.
+ virtual RTCErrorOr<rtc::scoped_refptr<PeerConnectionInterface>>
+ CreatePeerConnectionOrError(
+ const PeerConnectionInterface::RTCConfiguration& configuration,
+ PeerConnectionDependencies dependencies);
+ // Deprecated creator - does not return an error code on error.
+ // TODO(bugs.webrtc.org:12238): Deprecate and remove.
+ ABSL_DEPRECATED("Use CreatePeerConnectionOrError")
+ virtual rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection(
+ const PeerConnectionInterface::RTCConfiguration& configuration,
+ PeerConnectionDependencies dependencies);
+
+ // Deprecated; `allocator` and `cert_generator` may be null, in which case
+ // default implementations will be used.
+ //
+ // `observer` must not be null.
+ //
+ // Note that this method does not take ownership of `observer`; it's the
+ // responsibility of the caller to delete it. It can be safely deleted after
+ // Close has been called on the returned PeerConnection, which ensures no
+ // more observer callbacks will be invoked.
+ ABSL_DEPRECATED("Use CreatePeerConnectionOrError")
+ virtual rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection(
+ const PeerConnectionInterface::RTCConfiguration& configuration,
+ std::unique_ptr<cricket::PortAllocator> allocator,
+ std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
+ PeerConnectionObserver* observer);
+
+ // Returns the capabilities of an RTP sender of type `kind`.
+ // If for some reason you pass in MEDIA_TYPE_DATA, returns an empty structure.
+ // TODO(orphis): Make pure virtual when all subclasses implement it.
+ virtual RtpCapabilities GetRtpSenderCapabilities(
+ cricket::MediaType kind) const;
+
+ // Returns the capabilities of an RTP receiver of type `kind`.
+ // If for some reason you pass in MEDIA_TYPE_DATA, returns an empty structure.
+ // TODO(orphis): Make pure virtual when all subclasses implement it.
+ virtual RtpCapabilities GetRtpReceiverCapabilities(
+ cricket::MediaType kind) const;
+
+ virtual rtc::scoped_refptr<MediaStreamInterface> CreateLocalMediaStream(
+ const std::string& stream_id) = 0;
+
+ // Creates an AudioSourceInterface.
+ // `options` decides audio processing settings.
+ virtual rtc::scoped_refptr<AudioSourceInterface> CreateAudioSource(
+ const cricket::AudioOptions& options) = 0;
+
+ // Creates a new local VideoTrack. The same `source` can be used in several
+ // tracks.
+ virtual rtc::scoped_refptr<VideoTrackInterface> CreateVideoTrack(
+ const std::string& label,
+ VideoTrackSourceInterface* source) = 0;
+
+ // Creates an new AudioTrack. At the moment `source` can be null.
+ virtual rtc::scoped_refptr<AudioTrackInterface> CreateAudioTrack(
+ const std::string& label,
+ AudioSourceInterface* source) = 0;
+
+ // Starts AEC dump using existing file. Takes ownership of `file` and passes
+ // it on to VoiceEngine (via other objects) immediately, which will take
+ // the ownerhip. If the operation fails, the file will be closed.
+ // A maximum file size in bytes can be specified. When the file size limit is
+ // reached, logging is stopped automatically. If max_size_bytes is set to a
+ // value <= 0, no limit will be used, and logging will continue until the
+ // StopAecDump function is called.
+ // TODO(webrtc:6463): Delete default implementation when downstream mocks
+ // classes are updated.
+ virtual bool StartAecDump(FILE* file, int64_t max_size_bytes) {
+ return false;
+ }
+
+ // Stops logging the AEC dump.
+ virtual void StopAecDump() = 0;
+
+ protected:
+ // Dtor and ctor protected as objects shouldn't be created or deleted via
+ // this interface.
+ PeerConnectionFactoryInterface() {}
+ ~PeerConnectionFactoryInterface() override = default;
+};
+
+// CreateModularPeerConnectionFactory is implemented in the "peerconnection"
+// build target, which doesn't pull in the implementations of every module
+// webrtc may use.
+//
+// If an application knows it will only require certain modules, it can reduce
+// webrtc's impact on its binary size by depending only on the "peerconnection"
+// target and the modules the application requires, using
+// CreateModularPeerConnectionFactory. For example, if an application
+// only uses WebRTC for audio, it can pass in null pointers for the
+// video-specific interfaces, and omit the corresponding modules from its
+// build.
+//
+// If `network_thread` or `worker_thread` are null, the PeerConnectionFactory
+// will create the necessary thread internally. If `signaling_thread` is null,
+// the PeerConnectionFactory will use the thread on which this method is called
+// as the signaling thread, wrapping it in an rtc::Thread object if needed.
+RTC_EXPORT rtc::scoped_refptr<PeerConnectionFactoryInterface>
+CreateModularPeerConnectionFactory(
+ PeerConnectionFactoryDependencies dependencies);
+
+// https://w3c.github.io/webrtc-pc/#dom-rtcsignalingstate
+inline constexpr absl::string_view PeerConnectionInterface::AsString(
+ SignalingState state) {
+ switch (state) {
+ case SignalingState::kStable:
+ return "stable";
+ case SignalingState::kHaveLocalOffer:
+ return "have-local-offer";
+ case SignalingState::kHaveLocalPrAnswer:
+ return "have-local-pranswer";
+ case SignalingState::kHaveRemoteOffer:
+ return "have-remote-offer";
+ case SignalingState::kHaveRemotePrAnswer:
+ return "have-remote-pranswer";
+ case SignalingState::kClosed:
+ return "closed";
+ }
+ // This cannot happen.
+ // Not using "RTC_CHECK_NOTREACHED()" because AsString() is constexpr.
+ return "";
+}
+
+// https://w3c.github.io/webrtc-pc/#dom-rtcicegatheringstate
+inline constexpr absl::string_view PeerConnectionInterface::AsString(
+ IceGatheringState state) {
+ switch (state) {
+ case IceGatheringState::kIceGatheringNew:
+ return "new";
+ case IceGatheringState::kIceGatheringGathering:
+ return "gathering";
+ case IceGatheringState::kIceGatheringComplete:
+ return "complete";
+ }
+ // This cannot happen.
+ // Not using "RTC_CHECK_NOTREACHED()" because AsString() is constexpr.
+ return "";
+}
+
+// https://w3c.github.io/webrtc-pc/#dom-rtciceconnectionstate
+inline constexpr absl::string_view PeerConnectionInterface::AsString(
+ PeerConnectionState state) {
+ switch (state) {
+ case PeerConnectionState::kNew:
+ return "new";
+ case PeerConnectionState::kConnecting:
+ return "connecting";
+ case PeerConnectionState::kConnected:
+ return "connected";
+ case PeerConnectionState::kDisconnected:
+ return "disconnected";
+ case PeerConnectionState::kFailed:
+ return "failed";
+ case PeerConnectionState::kClosed:
+ return "closed";
+ }
+ // This cannot happen.
+ // Not using "RTC_CHECK_NOTREACHED()" because AsString() is constexpr.
+ return "";
+}
+
+inline constexpr absl::string_view PeerConnectionInterface::AsString(
+ IceConnectionState state) {
+ switch (state) {
+ case kIceConnectionNew:
+ return "new";
+ case kIceConnectionChecking:
+ return "checking";
+ case kIceConnectionConnected:
+ return "connected";
+ case kIceConnectionCompleted:
+ return "completed";
+ case kIceConnectionFailed:
+ return "failed";
+ case kIceConnectionDisconnected:
+ return "disconnected";
+ case kIceConnectionClosed:
+ return "closed";
+ case kIceConnectionMax:
+ // This cannot happen.
+ // Not using "RTC_CHECK_NOTREACHED()" because AsString() is constexpr.
+ return "";
+ }
+ // This cannot happen.
+ // Not using "RTC_CHECK_NOTREACHED()" because AsString() is constexpr.
+ return "";
+}
+
+} // namespace webrtc
+
+#endif // API_PEER_CONNECTION_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/priority.h b/third_party/libwebrtc/api/priority.h
new file mode 100644
index 0000000000..4953e453a3
--- /dev/null
+++ b/third_party/libwebrtc/api/priority.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_PRIORITY_H_
+#define API_PRIORITY_H_
+
+namespace webrtc {
+
+// GENERATED_JAVA_ENUM_PACKAGE: org.webrtc
+enum class Priority {
+ kVeryLow,
+ kLow,
+ kMedium,
+ kHigh,
+};
+
+} // namespace webrtc
+
+#endif // API_PRIORITY_H_
diff --git a/third_party/libwebrtc/api/priority_gn/moz.build b/third_party/libwebrtc/api/priority_gn/moz.build
new file mode 100644
index 0000000000..08cb5bf2d5
--- /dev/null
+++ b/third_party/libwebrtc/api/priority_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("priority_gn")
diff --git a/third_party/libwebrtc/api/ref_counted_base.h b/third_party/libwebrtc/api/ref_counted_base.h
new file mode 100644
index 0000000000..f20228b740
--- /dev/null
+++ b/third_party/libwebrtc/api/ref_counted_base.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2017 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_REF_COUNTED_BASE_H_
+#define API_REF_COUNTED_BASE_H_
+
+#include <type_traits>
+
+#include "rtc_base/ref_counter.h"
+
+namespace rtc {
+
+class RefCountedBase {
+ public:
+ RefCountedBase() = default;
+
+ RefCountedBase(const RefCountedBase&) = delete;
+ RefCountedBase& operator=(const RefCountedBase&) = delete;
+
+ void AddRef() const { ref_count_.IncRef(); }
+ RefCountReleaseStatus Release() const {
+ const auto status = ref_count_.DecRef();
+ if (status == RefCountReleaseStatus::kDroppedLastRef) {
+ delete this;
+ }
+ return status;
+ }
+
+ protected:
+ // Provided for internal webrtc subclasses for corner cases where it's
+ // necessary to know whether or not a reference is exclusively held.
+ bool HasOneRef() const { return ref_count_.HasOneRef(); }
+
+ virtual ~RefCountedBase() = default;
+
+ private:
+ mutable webrtc::webrtc_impl::RefCounter ref_count_{0};
+};
+
+// Template based version of `RefCountedBase` for simple implementations that do
+// not need (or want) destruction via virtual destructor or the overhead of a
+// vtable.
+//
+// To use:
+// struct MyInt : public rtc::RefCountedNonVirtual<MyInt> {
+// int foo_ = 0;
+// };
+//
+// rtc::scoped_refptr<MyInt> my_int(new MyInt());
+//
+// sizeof(MyInt) on a 32 bit system would then be 8, int + refcount and no
+// vtable generated.
+template <typename T>
+class RefCountedNonVirtual {
+ public:
+ RefCountedNonVirtual() = default;
+
+ RefCountedNonVirtual(const RefCountedNonVirtual&) = delete;
+ RefCountedNonVirtual& operator=(const RefCountedNonVirtual&) = delete;
+
+ void AddRef() const { ref_count_.IncRef(); }
+ RefCountReleaseStatus Release() const {
+ // If you run into this assert, T has virtual methods. There are two
+ // options:
+ // 1) The class doesn't actually need virtual methods, the type is complete
+ // so the virtual attribute(s) can be removed.
+ // 2) The virtual methods are a part of the design of the class. In this
+ // case you can consider using `RefCountedBase` instead or alternatively
+ // use `rtc::RefCountedObject`.
+ static_assert(!std::is_polymorphic<T>::value,
+ "T has virtual methods. RefCountedBase is a better fit.");
+ const auto status = ref_count_.DecRef();
+ if (status == RefCountReleaseStatus::kDroppedLastRef) {
+ delete static_cast<const T*>(this);
+ }
+ return status;
+ }
+
+ protected:
+ // Provided for internal webrtc subclasses for corner cases where it's
+ // necessary to know whether or not a reference is exclusively held.
+ bool HasOneRef() const { return ref_count_.HasOneRef(); }
+
+ ~RefCountedNonVirtual() = default;
+
+ private:
+ mutable webrtc::webrtc_impl::RefCounter ref_count_{0};
+};
+
+} // namespace rtc
+
+#endif // API_REF_COUNTED_BASE_H_
diff --git a/third_party/libwebrtc/api/refcountedbase_gn/moz.build b/third_party/libwebrtc/api/refcountedbase_gn/moz.build
new file mode 100644
index 0000000000..f2a22be846
--- /dev/null
+++ b/third_party/libwebrtc/api/refcountedbase_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("refcountedbase_gn")
diff --git a/third_party/libwebrtc/api/rtc_error.cc b/third_party/libwebrtc/api/rtc_error.cc
new file mode 100644
index 0000000000..4d3033baf5
--- /dev/null
+++ b/third_party/libwebrtc/api/rtc_error.cc
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/rtc_error.h"
+
+#include "rtc_base/arraysize.h"
+
+namespace {
+
+const char* kRTCErrorTypeNames[] = {
+ "NONE",
+ "UNSUPPORTED_OPERATION",
+ "UNSUPPORTED_PARAMETER",
+ "INVALID_PARAMETER",
+ "INVALID_RANGE",
+ "SYNTAX_ERROR",
+ "INVALID_STATE",
+ "INVALID_MODIFICATION",
+ "NETWORK_ERROR",
+ "RESOURCE_EXHAUSTED",
+ "INTERNAL_ERROR",
+ "OPERATION_ERROR_WITH_DATA",
+};
+static_assert(
+ static_cast<int>(webrtc::RTCErrorType::OPERATION_ERROR_WITH_DATA) ==
+ (arraysize(kRTCErrorTypeNames) - 1),
+ "kRTCErrorTypeNames must have as many strings as RTCErrorType "
+ "has values.");
+
+const char* kRTCErrorDetailTypeNames[] = {
+ "NONE",
+ "DATA_CHANNEL_FAILURE",
+ "DTLS_FAILURE",
+ "FINGERPRINT_FAILURE",
+ "SCTP_FAILURE",
+ "SDP_SYNTAX_ERROR",
+ "HARDWARE_ENCODER_NOT_AVAILABLE",
+ "HARDWARE_ENCODER_ERROR",
+};
+static_assert(
+ static_cast<int>(webrtc::RTCErrorDetailType::HARDWARE_ENCODER_ERROR) ==
+ (arraysize(kRTCErrorDetailTypeNames) - 1),
+ "kRTCErrorDetailTypeNames must have as many strings as "
+ "RTCErrorDetailType has values.");
+
+} // namespace
+
+namespace webrtc {
+
+// static
+RTCError RTCError::OK() {
+ return RTCError();
+}
+
+const char* RTCError::message() const {
+ return message_.c_str();
+}
+
+void RTCError::set_message(std::string message) {
+ message_ = std::move(message);
+}
+
+const char* ToString(RTCErrorType error) {
+ int index = static_cast<int>(error);
+ return kRTCErrorTypeNames[index];
+}
+
+const char* ToString(RTCErrorDetailType error) {
+ int index = static_cast<int>(error);
+ return kRTCErrorDetailTypeNames[index];
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/rtc_error.h b/third_party/libwebrtc/api/rtc_error.h
new file mode 100644
index 0000000000..42ceed18d9
--- /dev/null
+++ b/third_party/libwebrtc/api/rtc_error.h
@@ -0,0 +1,331 @@
+/*
+ * Copyright 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_RTC_ERROR_H_
+#define API_RTC_ERROR_H_
+
+#ifdef WEBRTC_UNIT_TEST
+#include <ostream>
+#endif // WEBRTC_UNIT_TEST
+#include <string>
+#include <utility> // For std::move.
+
+#include "absl/types/optional.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Enumeration to represent distinct classes of errors that an application
+// may wish to act upon differently. These roughly map to DOMExceptions or
+// RTCError "errorDetailEnum" values in the web API, as described in the
+// comments below.
+enum class RTCErrorType {
+ // No error.
+ NONE,
+
+ // An operation is valid, but currently unsupported.
+ // Maps to OperationError DOMException.
+ UNSUPPORTED_OPERATION,
+
+ // A supplied parameter is valid, but currently unsupported.
+ // Maps to OperationError DOMException.
+ UNSUPPORTED_PARAMETER,
+
+ // General error indicating that a supplied parameter is invalid.
+ // Maps to InvalidAccessError or TypeError DOMException depending on context.
+ INVALID_PARAMETER,
+
+ // Slightly more specific than INVALID_PARAMETER; a parameter's value was
+ // outside the allowed range.
+ // Maps to RangeError DOMException.
+ INVALID_RANGE,
+
+ // Slightly more specific than INVALID_PARAMETER; an error occurred while
+ // parsing string input.
+ // Maps to SyntaxError DOMException.
+ SYNTAX_ERROR,
+
+ // The object does not support this operation in its current state.
+ // Maps to InvalidStateError DOMException.
+ INVALID_STATE,
+
+ // An attempt was made to modify the object in an invalid way.
+ // Maps to InvalidModificationError DOMException.
+ INVALID_MODIFICATION,
+
+ // An error occurred within an underlying network protocol.
+ // Maps to NetworkError DOMException.
+ NETWORK_ERROR,
+
+ // Some resource has been exhausted; file handles, hardware resources, ports,
+ // etc.
+ // Maps to OperationError DOMException.
+ RESOURCE_EXHAUSTED,
+
+ // The operation failed due to an internal error.
+ // Maps to OperationError DOMException.
+ INTERNAL_ERROR,
+
+ // An error occured that has additional data.
+ // The additional data is specified in
+ // https://w3c.github.io/webrtc-pc/#rtcerror-interface
+ // Maps to RTCError DOMException.
+ OPERATION_ERROR_WITH_DATA,
+};
+
+// Detail information, showing what further information should be present.
+// https://w3c.github.io/webrtc-pc/#rtcerrordetailtype-enum
+enum class RTCErrorDetailType {
+ NONE,
+ DATA_CHANNEL_FAILURE,
+ DTLS_FAILURE,
+ FINGERPRINT_FAILURE,
+ SCTP_FAILURE,
+ SDP_SYNTAX_ERROR,
+ HARDWARE_ENCODER_NOT_AVAILABLE,
+ HARDWARE_ENCODER_ERROR,
+};
+
+// Roughly corresponds to RTCError in the web api. Holds an error type, a
+// message, and possibly additional information specific to that error.
+//
+// Doesn't contain anything beyond a type and message now, but will in the
+// future as more errors are implemented.
+class RTC_EXPORT RTCError {
+ public:
+ // Constructors.
+
+ // Creates a "no error" error.
+ RTCError() {}
+ explicit RTCError(RTCErrorType type) : type_(type) {}
+
+ RTCError(RTCErrorType type, std::string message)
+ : type_(type), message_(std::move(message)) {}
+
+ // In many use cases, it is better to use move than copy,
+ // but copy and assignment are provided for those cases that need it.
+ // Note that this has extra overhead because it copies strings.
+ RTCError(const RTCError& other) = default;
+ RTCError(RTCError&&) = default;
+ RTCError& operator=(const RTCError& other) = default;
+ RTCError& operator=(RTCError&&) = default;
+
+ // Identical to default constructed error.
+ //
+ // Preferred over the default constructor for code readability.
+ static RTCError OK();
+
+ // Error type.
+ RTCErrorType type() const { return type_; }
+ void set_type(RTCErrorType type) { type_ = type; }
+
+ // Human-readable message describing the error. Shouldn't be used for
+ // anything but logging/diagnostics, since messages are not guaranteed to be
+ // stable.
+ const char* message() const;
+
+ void set_message(std::string message);
+
+ RTCErrorDetailType error_detail() const { return error_detail_; }
+ void set_error_detail(RTCErrorDetailType detail) { error_detail_ = detail; }
+ absl::optional<uint16_t> sctp_cause_code() const { return sctp_cause_code_; }
+ void set_sctp_cause_code(uint16_t cause_code) {
+ sctp_cause_code_ = cause_code;
+ }
+
+ // Convenience method for situations where you only care whether or not an
+ // error occurred.
+ bool ok() const { return type_ == RTCErrorType::NONE; }
+
+ private:
+ RTCErrorType type_ = RTCErrorType::NONE;
+ std::string message_;
+ RTCErrorDetailType error_detail_ = RTCErrorDetailType::NONE;
+ absl::optional<uint16_t> sctp_cause_code_;
+};
+
+// Outputs the error as a friendly string. Update this method when adding a new
+// error type.
+//
+// Only intended to be used for logging/diagnostics. The returned char* points
+// to literal string that lives for the whole duration of the program.
+RTC_EXPORT const char* ToString(RTCErrorType error);
+RTC_EXPORT const char* ToString(RTCErrorDetailType error);
+
+#ifdef WEBRTC_UNIT_TEST
+inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982)
+ std::ostream& stream, // no-presubmit-check TODO(webrtc:8982)
+ RTCErrorType error) {
+ return stream << ToString(error);
+}
+
+inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982)
+ std::ostream& stream, // no-presubmit-check TODO(webrtc:8982)
+ RTCErrorDetailType error) {
+ return stream << ToString(error);
+}
+#endif // WEBRTC_UNIT_TEST
+
+// Helper macro that can be used by implementations to create an error with a
+// message and log it. `message` should be a string literal or movable
+// std::string.
+#define LOG_AND_RETURN_ERROR_EX(type, message, severity) \
+ { \
+ RTC_DCHECK(type != RTCErrorType::NONE); \
+ RTC_LOG(severity) << message << " (" << ::webrtc::ToString(type) << ")"; \
+ return ::webrtc::RTCError(type, message); \
+ }
+
+#define LOG_AND_RETURN_ERROR(type, message) \
+ LOG_AND_RETURN_ERROR_EX(type, message, LS_ERROR)
+
+// RTCErrorOr<T> is the union of an RTCError object and a T object. RTCErrorOr
+// models the concept of an object that is either a usable value, or an error
+// Status explaining why such a value is not present. To this end RTCErrorOr<T>
+// does not allow its RTCErrorType value to be RTCErrorType::NONE. This is
+// enforced by a debug check in most cases.
+//
+// The primary use-case for RTCErrorOr<T> is as the return value of a function
+// which may fail. For example, CreateRtpSender will fail if the parameters
+// could not be successfully applied at the media engine level, but if
+// successful will return a unique_ptr to an RtpSender.
+//
+// Example client usage for a RTCErrorOr<std::unique_ptr<T>>:
+//
+// RTCErrorOr<std::unique_ptr<Foo>> result = FooFactory::MakeNewFoo(arg);
+// if (result.ok()) {
+// std::unique_ptr<Foo> foo = result.ConsumeValue();
+// foo->DoSomethingCool();
+// } else {
+// RTC_LOG(LS_ERROR) << result.error();
+// }
+//
+// Example factory implementation returning RTCErrorOr<std::unique_ptr<T>>:
+//
+// RTCErrorOr<std::unique_ptr<Foo>> FooFactory::MakeNewFoo(int arg) {
+// if (arg <= 0) {
+// return RTCError(RTCErrorType::INVALID_RANGE, "Arg must be positive");
+// } else {
+// return std::unique_ptr<Foo>(new Foo(arg));
+// }
+// }
+//
+template <typename T>
+class RTCErrorOr {
+ // Used to convert between RTCErrorOr<Foo>/RtcErrorOr<Bar>, when an implicit
+ // conversion from Foo to Bar exists.
+ template <typename U>
+ friend class RTCErrorOr;
+
+ public:
+ typedef T element_type;
+
+ // Constructs a new RTCErrorOr with RTCErrorType::INTERNAL_ERROR error. This
+ // is marked 'explicit' to try to catch cases like 'return {};', where people
+ // think RTCErrorOr<std::vector<int>> will be initialized with an empty
+ // vector, instead of a RTCErrorType::INTERNAL_ERROR error.
+ RTCErrorOr() : error_(RTCErrorType::INTERNAL_ERROR) {}
+
+ // Constructs a new RTCErrorOr with the given non-ok error. After calling
+ // this constructor, calls to value() will DCHECK-fail.
+ //
+ // NOTE: Not explicit - we want to use RTCErrorOr<T> as a return
+ // value, so it is convenient and sensible to be able to do 'return
+ // RTCError(...)' when the return type is RTCErrorOr<T>.
+ //
+ // REQUIRES: !error.ok(). This requirement is DCHECKed.
+ RTCErrorOr(RTCError&& error) : error_(std::move(error)) { // NOLINT
+ RTC_DCHECK(!error_.ok());
+ }
+
+ // Constructs a new RTCErrorOr with the given value. After calling this
+ // constructor, calls to value() will succeed, and calls to error() will
+ // return a default-constructed RTCError.
+ //
+ // NOTE: Not explicit - we want to use RTCErrorOr<T> as a return type
+ // so it is convenient and sensible to be able to do 'return T()'
+ // when the return type is RTCErrorOr<T>.
+ RTCErrorOr(const T& value) : value_(value) {} // NOLINT
+ RTCErrorOr(T&& value) : value_(std::move(value)) {} // NOLINT
+
+ // Delete the copy constructor and assignment operator; there aren't any use
+ // cases where you should need to copy an RTCErrorOr, as opposed to moving
+ // it. Can revisit this decision if use cases arise in the future.
+ RTCErrorOr(const RTCErrorOr& other) = delete;
+ RTCErrorOr& operator=(const RTCErrorOr& other) = delete;
+
+ // Move constructor and move-assignment operator.
+ //
+ // Visual Studio doesn't support "= default" with move constructors or
+ // assignment operators (even though they compile, they segfault), so define
+ // them explicitly.
+ RTCErrorOr(RTCErrorOr&& other)
+ : error_(std::move(other.error_)), value_(std::move(other.value_)) {}
+ RTCErrorOr& operator=(RTCErrorOr&& other) {
+ error_ = std::move(other.error_);
+ value_ = std::move(other.value_);
+ return *this;
+ }
+
+ // Conversion constructor and assignment operator; T must be copy or move
+ // constructible from U.
+ template <typename U>
+ RTCErrorOr(RTCErrorOr<U> other) // NOLINT
+ : error_(std::move(other.error_)), value_(std::move(other.value_)) {}
+ template <typename U>
+ RTCErrorOr& operator=(RTCErrorOr<U> other) {
+ error_ = std::move(other.error_);
+ value_ = std::move(other.value_);
+ return *this;
+ }
+
+ // Returns a reference to our error. If this contains a T, then returns
+ // default-constructed RTCError.
+ const RTCError& error() const { return error_; }
+
+ // Moves the error. Can be useful if, say "CreateFoo" returns an
+ // RTCErrorOr<Foo>, and internally calls "CreateBar" which returns an
+ // RTCErrorOr<Bar>, and wants to forward the error up the stack.
+ RTCError MoveError() { return std::move(error_); }
+
+ // Returns this->error().ok()
+ bool ok() const { return error_.ok(); }
+
+ // Returns a reference to our current value, or DCHECK-fails if !this->ok().
+ //
+ // Can be convenient for the implementation; for example, a method may want
+ // to access the value in some way before returning it to the next method on
+ // the stack.
+ const T& value() const {
+ RTC_DCHECK(ok());
+ return value_;
+ }
+ T& value() {
+ RTC_DCHECK(ok());
+ return value_;
+ }
+
+ // Moves our current value out of this object and returns it, or DCHECK-fails
+ // if !this->ok().
+ T MoveValue() {
+ RTC_DCHECK(ok());
+ return std::move(value_);
+ }
+
+ private:
+ RTCError error_;
+ T value_;
+};
+
+} // namespace webrtc
+
+#endif // API_RTC_ERROR_H_
diff --git a/third_party/libwebrtc/api/rtc_error_gn/moz.build b/third_party/libwebrtc/api/rtc_error_gn/moz.build
new file mode 100644
index 0000000000..07efa1cf55
--- /dev/null
+++ b/third_party/libwebrtc/api/rtc_error_gn/moz.build
@@ -0,0 +1,225 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/rtc_error.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("rtc_error_gn")
diff --git a/third_party/libwebrtc/api/rtc_error_unittest.cc b/third_party/libwebrtc/api/rtc_error_unittest.cc
new file mode 100644
index 0000000000..ba307d8f71
--- /dev/null
+++ b/third_party/libwebrtc/api/rtc_error_unittest.cc
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2017 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/rtc_error.h"
+
+#include <utility>
+
+#include "test/gtest.h"
+
+namespace {
+
+const int kDefaultMoveOnlyIntValue = 0xbadf00d;
+
+// Class that has no copy constructor, ensuring that RTCErrorOr can
+struct MoveOnlyInt {
+ MoveOnlyInt() {}
+ explicit MoveOnlyInt(int value) : value(value) {}
+ MoveOnlyInt(const MoveOnlyInt& other) = delete;
+ MoveOnlyInt& operator=(const MoveOnlyInt& other) = delete;
+ MoveOnlyInt(MoveOnlyInt&& other) : value(other.value) {}
+ MoveOnlyInt& operator=(MoveOnlyInt&& other) {
+ value = other.value;
+ return *this;
+ }
+
+ int value = kDefaultMoveOnlyIntValue;
+};
+
+// Same as above. Used to test conversion from RTCErrorOr<A> to RTCErrorOr<B>
+// when A can be converted to B.
+struct MoveOnlyInt2 {
+ MoveOnlyInt2() {}
+ explicit MoveOnlyInt2(int value) : value(value) {}
+ MoveOnlyInt2(const MoveOnlyInt2& other) = delete;
+ MoveOnlyInt2& operator=(const MoveOnlyInt2& other) = delete;
+ MoveOnlyInt2(MoveOnlyInt2&& other) : value(other.value) {}
+ MoveOnlyInt2& operator=(MoveOnlyInt2&& other) {
+ value = other.value;
+ return *this;
+ }
+
+ explicit MoveOnlyInt2(MoveOnlyInt&& other) : value(other.value) {}
+ MoveOnlyInt2& operator=(MoveOnlyInt&& other) {
+ value = other.value;
+ return *this;
+ }
+
+ int value = kDefaultMoveOnlyIntValue;
+};
+
+} // namespace
+
+namespace webrtc {
+
+// Test that the default constructor creates a "no error" error.
+TEST(RTCErrorTest, DefaultConstructor) {
+ RTCError e;
+ EXPECT_EQ(RTCErrorType::NONE, e.type());
+ EXPECT_EQ(std::string(), e.message());
+ EXPECT_TRUE(e.ok());
+}
+
+TEST(RTCErrorTest, NormalConstructors) {
+ RTCError a(RTCErrorType::INVALID_PARAMETER);
+ EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, a.type());
+ EXPECT_EQ(std::string(), a.message());
+
+ // Constructor that takes const char* message.
+ RTCError b(RTCErrorType::UNSUPPORTED_PARAMETER, "foobar");
+ EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, b.type());
+ EXPECT_EQ(std::string("foobar"), b.message());
+
+ // Constructor that takes std::string message.
+ RTCError c(RTCErrorType::INVALID_RANGE, std::string("new"));
+ EXPECT_EQ(RTCErrorType::INVALID_RANGE, c.type());
+ EXPECT_EQ(std::string("new"), c.message());
+}
+
+TEST(RTCErrorTest, MoveConstructor) {
+ // Static string.
+ RTCError a(RTCErrorType::INVALID_PARAMETER, "foo");
+ RTCError b(std::move(a));
+ EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, b.type());
+ EXPECT_EQ(std::string("foo"), b.message());
+
+ // Non-static string.
+ RTCError c(RTCErrorType::UNSUPPORTED_PARAMETER, std::string("bar"));
+ RTCError d(std::move(c));
+ EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, d.type());
+ EXPECT_EQ(std::string("bar"), d.message());
+}
+
+TEST(RTCErrorTest, MoveAssignment) {
+ // Try all combinations of "is static string"/"is non-static string" moves.
+ RTCError e(RTCErrorType::INVALID_PARAMETER, "foo");
+
+ e = RTCError(RTCErrorType::UNSUPPORTED_PARAMETER, "bar");
+ EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, e.type());
+ EXPECT_EQ(std::string("bar"), e.message());
+
+ e = RTCError(RTCErrorType::SYNTAX_ERROR, std::string("baz"));
+ EXPECT_EQ(std::string("baz"), e.message());
+
+ e = RTCError(RTCErrorType::SYNTAX_ERROR, std::string("another"));
+ EXPECT_EQ(std::string("another"), e.message());
+
+ e = RTCError(RTCErrorType::SYNTAX_ERROR, "last");
+ EXPECT_EQ(std::string("last"), e.message());
+}
+
+// Test that the error returned by RTCError::OK() is a "no error" error.
+TEST(RTCErrorTest, OKConstant) {
+ RTCError ok = RTCError::OK();
+ EXPECT_EQ(RTCErrorType::NONE, ok.type());
+ EXPECT_EQ(std::string(), ok.message());
+ EXPECT_TRUE(ok.ok());
+}
+
+// Test that "error.ok()" behaves as expected.
+TEST(RTCErrorTest, OkMethod) {
+ RTCError success;
+ RTCError failure(RTCErrorType::INTERNAL_ERROR);
+ EXPECT_TRUE(success.ok());
+ EXPECT_FALSE(failure.ok());
+}
+
+// Test that a message can be set using either static const strings or
+// std::strings.
+TEST(RTCErrorTest, SetMessage) {
+ RTCError e;
+ // Try all combinations of "is static string"/"is non-static string" calls.
+ e.set_message("foo");
+ EXPECT_EQ(std::string("foo"), e.message());
+
+ e.set_message("bar");
+ EXPECT_EQ(std::string("bar"), e.message());
+
+ e.set_message(std::string("string"));
+ EXPECT_EQ(std::string("string"), e.message());
+
+ e.set_message(std::string("more"));
+ EXPECT_EQ(std::string("more"), e.message());
+
+ e.set_message("love to test");
+ EXPECT_EQ(std::string("love to test"), e.message());
+}
+
+// Test that the default constructor creates an "INTERNAL_ERROR".
+TEST(RTCErrorOrTest, DefaultConstructor) {
+ RTCErrorOr<MoveOnlyInt> e;
+ EXPECT_EQ(RTCErrorType::INTERNAL_ERROR, e.error().type());
+}
+
+// Test that an RTCErrorOr can be implicitly constructed from a value.
+TEST(RTCErrorOrTest, ImplicitValueConstructor) {
+ RTCErrorOr<MoveOnlyInt> e = [] { return MoveOnlyInt(100); }();
+ EXPECT_EQ(100, e.value().value);
+}
+
+// Test that an RTCErrorOr can be implicitly constructed from an RTCError.
+TEST(RTCErrorOrTest, ImplicitErrorConstructor) {
+ RTCErrorOr<MoveOnlyInt> e = [] {
+ return RTCError(RTCErrorType::SYNTAX_ERROR);
+ }();
+ EXPECT_EQ(RTCErrorType::SYNTAX_ERROR, e.error().type());
+}
+
+TEST(RTCErrorOrTest, MoveConstructor) {
+ RTCErrorOr<MoveOnlyInt> a(MoveOnlyInt(5));
+ RTCErrorOr<MoveOnlyInt> b(std::move(a));
+ EXPECT_EQ(5, b.value().value);
+}
+
+TEST(RTCErrorOrTest, MoveAssignment) {
+ RTCErrorOr<MoveOnlyInt> a(MoveOnlyInt(5));
+ RTCErrorOr<MoveOnlyInt> b(MoveOnlyInt(10));
+ a = std::move(b);
+ EXPECT_EQ(10, a.value().value);
+}
+
+TEST(RTCErrorOrTest, ConversionConstructor) {
+ RTCErrorOr<MoveOnlyInt> a(MoveOnlyInt(1));
+ RTCErrorOr<MoveOnlyInt2> b(std::move(a));
+}
+
+TEST(RTCErrorOrTest, ConversionAssignment) {
+ RTCErrorOr<MoveOnlyInt> a(MoveOnlyInt(5));
+ RTCErrorOr<MoveOnlyInt2> b(MoveOnlyInt2(10));
+ b = std::move(a);
+ EXPECT_EQ(5, b.value().value);
+}
+
+TEST(RTCErrorOrTest, OkMethod) {
+ RTCErrorOr<int> success(1337);
+ RTCErrorOr<int> error = RTCError(RTCErrorType::INTERNAL_ERROR);
+ EXPECT_TRUE(success.ok());
+ EXPECT_FALSE(error.ok());
+}
+
+TEST(RTCErrorOrTest, MoveError) {
+ RTCErrorOr<int> e({RTCErrorType::SYNTAX_ERROR, "message"});
+ RTCError err = e.MoveError();
+ EXPECT_EQ(RTCErrorType::SYNTAX_ERROR, err.type());
+ EXPECT_EQ(std::string("message"), err.message());
+}
+
+TEST(RTCErrorOrTest, MoveValue) {
+ RTCErrorOr<MoveOnlyInt> e(MoveOnlyInt(88));
+ MoveOnlyInt value = e.MoveValue();
+ EXPECT_EQ(88, value.value);
+}
+
+// Death tests.
+// Disabled on Android because death tests misbehave on Android, see
+// base/test/gtest_util.h.
+#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
+
+TEST(RTCErrorOrDeathTest, ConstructWithOkError) {
+ RTCErrorOr<int> err;
+ EXPECT_DEATH(err = RTCError::OK(), "");
+}
+
+TEST(RTCErrorOrDeathTest, DereferenceErrorValue) {
+ RTCErrorOr<int> error = RTCError(RTCErrorType::INTERNAL_ERROR);
+ EXPECT_DEATH(error.value(), "");
+}
+
+TEST(RTCErrorOrDeathTest, MoveErrorValue) {
+ RTCErrorOr<int> error = RTCError(RTCErrorType::INTERNAL_ERROR);
+ EXPECT_DEATH(error.MoveValue(), "");
+}
+
+#endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/rtc_event_log/BUILD.gn b/third_party/libwebrtc/api/rtc_event_log/BUILD.gn
new file mode 100644
index 0000000000..158dc06a7b
--- /dev/null
+++ b/third_party/libwebrtc/api/rtc_event_log/BUILD.gn
@@ -0,0 +1,48 @@
+# Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../webrtc.gni")
+
+rtc_library("rtc_event_log") {
+ visibility = [ "*" ]
+ sources = [
+ "rtc_event.cc",
+ "rtc_event.h",
+ "rtc_event_log.cc",
+ "rtc_event_log.h",
+ "rtc_event_log_factory_interface.h",
+ ]
+
+ deps = [
+ "..:libjingle_logging_api",
+ "../../rtc_base:checks",
+ "../../rtc_base:timeutils",
+ "../task_queue",
+ ]
+}
+
+rtc_library("rtc_event_log_factory") {
+ visibility = [ "*" ]
+ sources = [
+ "rtc_event_log_factory.cc",
+ "rtc_event_log_factory.h",
+ ]
+
+ deps = [
+ ":rtc_event_log",
+ "../../rtc_base:checks",
+ "../../rtc_base/system:rtc_export",
+ "../../system_wrappers:field_trial",
+ "../task_queue",
+ ]
+
+ if (rtc_enable_protobuf) {
+ defines = [ "WEBRTC_ENABLE_RTC_EVENT_LOG" ]
+ deps += [ "../../logging:rtc_event_log_impl" ]
+ }
+}
diff --git a/third_party/libwebrtc/api/rtc_event_log/rtc_event.cc b/third_party/libwebrtc/api/rtc_event_log/rtc_event.cc
new file mode 100644
index 0000000000..631188b915
--- /dev/null
+++ b/third_party/libwebrtc/api/rtc_event_log/rtc_event.cc
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/rtc_event_log/rtc_event.h"
+
+#include "rtc_base/time_utils.h"
+
+namespace webrtc {
+
+RtcEvent::RtcEvent() : timestamp_us_(rtc::TimeMillis() * 1000) {}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/rtc_event_log/rtc_event.h b/third_party/libwebrtc/api/rtc_event_log/rtc_event.h
new file mode 100644
index 0000000000..aa74944fe5
--- /dev/null
+++ b/third_party/libwebrtc/api/rtc_event_log/rtc_event.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_RTC_EVENT_LOG_RTC_EVENT_H_
+#define API_RTC_EVENT_LOG_RTC_EVENT_H_
+
+#include <cstdint>
+
+namespace webrtc {
+
+// This class allows us to store unencoded RTC events. Subclasses of this class
+// store the actual information. This allows us to keep all unencoded events,
+// even when their type and associated information differ, in the same buffer.
+// Additionally, it prevents dependency leaking - a module that only logs
+// events of type RtcEvent_A doesn't need to know about anything associated
+// with events of type RtcEvent_B.
+class RtcEvent {
+ public:
+ // Subclasses of this class have to associate themselves with a unique value
+ // of Type. This leaks the information of existing subclasses into the
+ // superclass, but the *actual* information - rtclog::StreamConfig, etc. -
+ // is kept separate.
+ enum class Type : uint32_t {
+ AlrStateEvent,
+ RouteChangeEvent,
+ RemoteEstimateEvent,
+ AudioNetworkAdaptation,
+ AudioPlayout,
+ AudioReceiveStreamConfig,
+ AudioSendStreamConfig,
+ BweUpdateDelayBased,
+ BweUpdateLossBased,
+ DtlsTransportState,
+ DtlsWritableState,
+ IceCandidatePairConfig,
+ IceCandidatePairEvent,
+ ProbeClusterCreated,
+ ProbeResultFailure,
+ ProbeResultSuccess,
+ RtcpPacketIncoming,
+ RtcpPacketOutgoing,
+ RtpPacketIncoming,
+ RtpPacketOutgoing,
+ VideoReceiveStreamConfig,
+ VideoSendStreamConfig,
+ GenericPacketSent,
+ GenericPacketReceived,
+ GenericAckReceived,
+ FrameDecoded,
+ NetEqSetMinimumDelay,
+ BeginV3Log = 0x2501580,
+ EndV3Log = 0x2501581,
+ FakeEvent, // For unit testing.
+ };
+
+ RtcEvent();
+ virtual ~RtcEvent() = default;
+
+ virtual Type GetType() const = 0;
+
+ virtual bool IsConfigEvent() const = 0;
+
+ // Events are grouped by Type before being encoded.
+ // Optionally, `GetGroupKey` can be overloaded to group the
+ // events by a secondary key (in addition to the event type.)
+ // This can, in some cases, improve compression efficiency
+ // e.g. by grouping events by SSRC.
+ virtual uint32_t GetGroupKey() const { return 0; }
+
+ int64_t timestamp_ms() const { return timestamp_us_ / 1000; }
+ int64_t timestamp_us() const { return timestamp_us_; }
+
+ protected:
+ explicit RtcEvent(int64_t timestamp_us) : timestamp_us_(timestamp_us) {}
+
+ const int64_t timestamp_us_;
+};
+
+} // namespace webrtc
+
+#endif // API_RTC_EVENT_LOG_RTC_EVENT_H_
diff --git a/third_party/libwebrtc/api/rtc_event_log/rtc_event_log.cc b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log.cc
new file mode 100644
index 0000000000..56189c0ff7
--- /dev/null
+++ b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log.cc
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/rtc_event_log/rtc_event_log.h"
+
+namespace webrtc {
+
+bool RtcEventLogNull::StartLogging(
+ std::unique_ptr<RtcEventLogOutput> /*output*/,
+ int64_t /*output_period_ms*/) {
+ return false;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/rtc_event_log/rtc_event_log.h b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log.h
new file mode 100644
index 0000000000..7b42cdc028
--- /dev/null
+++ b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_RTC_EVENT_LOG_RTC_EVENT_LOG_H_
+#define API_RTC_EVENT_LOG_RTC_EVENT_LOG_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <functional>
+#include <memory>
+
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/rtc_event_log_output.h"
+#include "api/task_queue/task_queue_factory.h"
+
+namespace webrtc {
+
+class RtcEventLog {
+ public:
+ enum : size_t { kUnlimitedOutput = 0 };
+ enum : int64_t { kImmediateOutput = 0 };
+
+ // TODO(eladalon): Get rid of the legacy encoding and this enum once all
+ // clients have migrated to the new format.
+ enum class EncodingType { Legacy, NewFormat, ProtoFree };
+
+ virtual ~RtcEventLog() = default;
+
+ // Starts logging to a given output. The output might be limited in size,
+ // and may close itself once it has reached the maximum size.
+ virtual bool StartLogging(std::unique_ptr<RtcEventLogOutput> output,
+ int64_t output_period_ms) = 0;
+
+ // Stops logging to file and waits until the file has been closed, after
+ // which it would be permissible to read and/or modify it.
+ virtual void StopLogging() = 0;
+
+ // Stops logging to file and calls `callback` when the file has been closed.
+ // Note that it is not safe to call any other members, including the
+ // destructor, until the callback has been called.
+ // TODO(srte): Remove default implementation when it's safe to do so.
+ virtual void StopLogging(std::function<void()> callback) {
+ StopLogging();
+ callback();
+ }
+
+ // Log an RTC event (the type of event is determined by the subclass).
+ virtual void Log(std::unique_ptr<RtcEvent> event) = 0;
+};
+
+// No-op implementation is used if flag is not set, or in tests.
+class RtcEventLogNull final : public RtcEventLog {
+ public:
+ bool StartLogging(std::unique_ptr<RtcEventLogOutput> output,
+ int64_t output_period_ms) override;
+ void StopLogging() override {}
+ void Log(std::unique_ptr<RtcEvent> event) override {}
+};
+
+} // namespace webrtc
+
+#endif // API_RTC_EVENT_LOG_RTC_EVENT_LOG_H_
diff --git a/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory.cc b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory.cc
new file mode 100644
index 0000000000..a3cb68cf54
--- /dev/null
+++ b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory.cc
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/rtc_event_log/rtc_event_log_factory.h"
+
+#include <memory>
+#include <utility>
+
+#include "rtc_base/checks.h"
+#include "system_wrappers/include/field_trial.h"
+
+#ifdef WEBRTC_ENABLE_RTC_EVENT_LOG
+#include "logging/rtc_event_log/rtc_event_log_impl.h"
+#endif
+
+namespace webrtc {
+
+RtcEventLogFactory::RtcEventLogFactory(TaskQueueFactory* task_queue_factory)
+ : task_queue_factory_(task_queue_factory) {
+ RTC_DCHECK(task_queue_factory_);
+}
+
+std::unique_ptr<RtcEventLog> RtcEventLogFactory::Create(
+ RtcEventLog::EncodingType encoding_type) const {
+#ifdef WEBRTC_ENABLE_RTC_EVENT_LOG
+ if (field_trial::IsEnabled("WebRTC-RtcEventLogKillSwitch")) {
+ return std::make_unique<RtcEventLogNull>();
+ }
+ return std::make_unique<RtcEventLogImpl>(
+ RtcEventLogImpl::CreateEncoder(encoding_type), task_queue_factory_);
+#else
+ return std::make_unique<RtcEventLogNull>();
+#endif
+}
+
+std::unique_ptr<RtcEventLog> RtcEventLogFactory::CreateRtcEventLog(
+ RtcEventLog::EncodingType encoding_type) {
+ return Create(encoding_type);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory.h b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory.h
new file mode 100644
index 0000000000..fd1db3c728
--- /dev/null
+++ b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_RTC_EVENT_LOG_RTC_EVENT_LOG_FACTORY_H_
+#define API_RTC_EVENT_LOG_RTC_EVENT_LOG_FACTORY_H_
+
+#include <memory>
+
+#include "api/rtc_event_log/rtc_event_log.h"
+#include "api/rtc_event_log/rtc_event_log_factory_interface.h"
+#include "api/task_queue/task_queue_factory.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+class RTC_EXPORT RtcEventLogFactory : public RtcEventLogFactoryInterface {
+ public:
+ explicit RtcEventLogFactory(TaskQueueFactory* task_queue_factory);
+ ~RtcEventLogFactory() override {}
+
+ std::unique_ptr<RtcEventLog> Create(
+ RtcEventLog::EncodingType encoding_type) const override;
+ std::unique_ptr<RtcEventLog> CreateRtcEventLog(
+ RtcEventLog::EncodingType encoding_type) override;
+
+ private:
+ TaskQueueFactory* const task_queue_factory_;
+};
+
+} // namespace webrtc
+
+#endif // API_RTC_EVENT_LOG_RTC_EVENT_LOG_FACTORY_H_
diff --git a/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory_interface.h b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory_interface.h
new file mode 100644
index 0000000000..a6f4dee92f
--- /dev/null
+++ b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory_interface.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_RTC_EVENT_LOG_RTC_EVENT_LOG_FACTORY_INTERFACE_H_
+#define API_RTC_EVENT_LOG_RTC_EVENT_LOG_FACTORY_INTERFACE_H_
+
+#include <memory>
+
+#include "api/rtc_event_log/rtc_event_log.h"
+
+namespace webrtc {
+
+// This interface exists to allow webrtc to be optionally built without
+// RtcEventLog support. A PeerConnectionFactory is constructed with an
+// RtcEventLogFactoryInterface, which may or may not be null.
+class RtcEventLogFactoryInterface {
+ public:
+ virtual ~RtcEventLogFactoryInterface() = default;
+
+ virtual std::unique_ptr<RtcEventLog> Create(
+ RtcEventLog::EncodingType encoding_type) const = 0;
+ [[deprecated]] virtual std::unique_ptr<RtcEventLog> CreateRtcEventLog(
+ RtcEventLog::EncodingType encoding_type) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_RTC_EVENT_LOG_RTC_EVENT_LOG_FACTORY_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_gn/moz.build b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_gn/moz.build
new file mode 100644
index 0000000000..a96be6791f
--- /dev/null
+++ b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_gn/moz.build
@@ -0,0 +1,226 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/rtc_event_log/rtc_event.cc",
+ "/third_party/libwebrtc/api/rtc_event_log/rtc_event_log.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("rtc_event_log_gn")
diff --git a/third_party/libwebrtc/api/rtc_event_log_output.h b/third_party/libwebrtc/api/rtc_event_log_output.h
new file mode 100644
index 0000000000..f1f84a5f3a
--- /dev/null
+++ b/third_party/libwebrtc/api/rtc_event_log_output.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_RTC_EVENT_LOG_OUTPUT_H_
+#define API_RTC_EVENT_LOG_OUTPUT_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+
+namespace webrtc {
+
+// NOTE: This class is still under development and may change without notice.
+class RtcEventLogOutput {
+ public:
+ virtual ~RtcEventLogOutput() = default;
+
+ // An output normally starts out active, though that might not always be
+ // the case (e.g. failed to open a file for writing).
+ // Once an output has become inactive (e.g. maximum file size reached), it can
+ // never become active again.
+ virtual bool IsActive() const = 0;
+
+ // Write encoded events to an output. Returns true if the output was
+ // successfully written in its entirety. Otherwise, no guarantee is given
+ // about how much data was written, if any. The output sink becomes inactive
+ // after the first time `false` is returned. Write() may not be called on
+ // an inactive output sink.
+ virtual bool Write(absl::string_view output) = 0;
+
+ // Indicates that buffers should be written to disk if applicable.
+ virtual void Flush() {}
+};
+
+} // namespace webrtc
+
+#endif // API_RTC_EVENT_LOG_OUTPUT_H_
diff --git a/third_party/libwebrtc/api/rtc_event_log_output_file.cc b/third_party/libwebrtc/api/rtc_event_log_output_file.cc
new file mode 100644
index 0000000000..e1d4c7c711
--- /dev/null
+++ b/third_party/libwebrtc/api/rtc_event_log_output_file.cc
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/rtc_event_log_output_file.h"
+
+#include <limits>
+#include <utility>
+
+#include "api/rtc_event_log/rtc_event_log.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/logging.h"
+
+namespace webrtc {
+
+// Together with the assumption of no single Write() would ever be called on
+// an input with length greater-than-or-equal-to (max(size_t) / 2), this
+// guarantees no overflow of the check for remaining file capacity in Write().
+// This does *not* apply to files with unlimited size.
+const size_t RtcEventLogOutputFile::kMaxReasonableFileSize =
+ std::numeric_limits<size_t>::max() / 2;
+
+RtcEventLogOutputFile::RtcEventLogOutputFile(const std::string& file_name)
+ : RtcEventLogOutputFile(FileWrapper::OpenWriteOnly(file_name),
+ RtcEventLog::kUnlimitedOutput) {}
+
+RtcEventLogOutputFile::RtcEventLogOutputFile(const std::string& file_name,
+ size_t max_size_bytes)
+
+ // Unlike plain fopen, FileWrapper takes care of filename utf8 ->
+ // wchar conversion on Windows.
+ : RtcEventLogOutputFile(FileWrapper::OpenWriteOnly(file_name),
+ max_size_bytes) {}
+
+RtcEventLogOutputFile::RtcEventLogOutputFile(FILE* file, size_t max_size_bytes)
+ : RtcEventLogOutputFile(FileWrapper(file), max_size_bytes) {}
+
+RtcEventLogOutputFile::RtcEventLogOutputFile(FileWrapper file,
+ size_t max_size_bytes)
+ : max_size_bytes_(max_size_bytes), file_(std::move(file)) {
+ RTC_CHECK_LE(max_size_bytes_, kMaxReasonableFileSize);
+ if (!file_.is_open()) {
+ RTC_LOG(LS_ERROR) << "Invalid file. WebRTC event log not started.";
+ }
+}
+
+bool RtcEventLogOutputFile::IsActive() const {
+ return IsActiveInternal();
+}
+
+bool RtcEventLogOutputFile::Write(absl::string_view output) {
+ RTC_DCHECK(IsActiveInternal());
+ // No single write may be so big, that it would risk overflowing the
+ // calculation of (written_bytes_ + output.length()).
+ RTC_DCHECK_LT(output.size(), kMaxReasonableFileSize);
+
+ if (max_size_bytes_ == RtcEventLog::kUnlimitedOutput ||
+ written_bytes_ + output.size() <= max_size_bytes_) {
+ if (file_.Write(output.data(), output.size())) {
+ written_bytes_ += output.size();
+ return true;
+ } else {
+ RTC_LOG(LS_ERROR) << "Write to WebRtcEventLog file failed.";
+ }
+ } else {
+ RTC_LOG(LS_VERBOSE) << "Max file size reached.";
+ }
+
+ // Failed, for one of above reasons. Close output file.
+ file_.Close();
+ return false;
+}
+
+// Internal non-virtual method.
+bool RtcEventLogOutputFile::IsActiveInternal() const {
+ return file_.is_open();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/rtc_event_log_output_file.h b/third_party/libwebrtc/api/rtc_event_log_output_file.h
new file mode 100644
index 0000000000..c9ae0a8ede
--- /dev/null
+++ b/third_party/libwebrtc/api/rtc_event_log_output_file.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_RTC_EVENT_LOG_OUTPUT_FILE_H_
+#define API_RTC_EVENT_LOG_OUTPUT_FILE_H_
+
+#include <stddef.h>
+#include <stdio.h>
+
+#include <string>
+
+#include "api/rtc_event_log_output.h"
+#include "rtc_base/system/file_wrapper.h"
+
+namespace webrtc {
+
+class RtcEventLogOutputFile final : public RtcEventLogOutput {
+ public:
+ static const size_t kMaxReasonableFileSize; // Explanation at declaration.
+
+ // Unlimited/limited-size output file (by filename).
+ explicit RtcEventLogOutputFile(const std::string& file_name);
+ RtcEventLogOutputFile(const std::string& file_name, size_t max_size_bytes);
+
+ // Limited-size output file (by FILE*). This class takes ownership
+ // of the FILE*, and closes it on destruction.
+ RtcEventLogOutputFile(FILE* file, size_t max_size_bytes);
+
+ ~RtcEventLogOutputFile() override = default;
+
+ bool IsActive() const override;
+
+ bool Write(absl::string_view output) override;
+
+ private:
+ RtcEventLogOutputFile(FileWrapper file, size_t max_size_bytes);
+
+ // IsActive() can be called either from outside or from inside, but we don't
+ // want to incur the overhead of a virtual function call if called from inside
+ // some other function of this class.
+ inline bool IsActiveInternal() const;
+
+ // Maximum size, or zero for no limit.
+ const size_t max_size_bytes_;
+ size_t written_bytes_{0};
+ FileWrapper file_;
+};
+
+} // namespace webrtc
+
+#endif // API_RTC_EVENT_LOG_OUTPUT_FILE_H_
diff --git a/third_party/libwebrtc/api/rtc_event_log_output_file_unittest.cc b/third_party/libwebrtc/api/rtc_event_log_output_file_unittest.cc
new file mode 100644
index 0000000000..0aff57fbbc
--- /dev/null
+++ b/third_party/libwebrtc/api/rtc_event_log_output_file_unittest.cc
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/rtc_event_log_output_file.h"
+
+#include <fstream>
+#include <iterator>
+#include <memory>
+#include <string>
+
+#include "rtc_base/checks.h"
+#include "test/gtest.h"
+#include "test/testsupport/file_utils.h"
+
+namespace webrtc {
+
+class RtcEventLogOutputFileTest : public ::testing::Test {
+ public:
+ RtcEventLogOutputFileTest() : output_file_name_(GetOutputFilePath()) {
+ // Ensure no leftovers from previous runs, which might not have terminated
+ // in an orderly fashion.
+ remove(output_file_name_.c_str());
+ }
+
+ ~RtcEventLogOutputFileTest() override { remove(output_file_name_.c_str()); }
+
+ protected:
+ std::string GetOutputFilePath() const {
+ auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
+ return test::OutputPath() + test_info->test_case_name() + test_info->name();
+ }
+
+ std::string GetOutputFileContents() const {
+ std::ifstream file(output_file_name_,
+ std::ios_base::in | std::ios_base::binary);
+ RTC_CHECK(file.is_open());
+ RTC_CHECK(file.good());
+ std::string file_str((std::istreambuf_iterator<char>(file)),
+ std::istreambuf_iterator<char>());
+ return file_str;
+ }
+
+ const std::string output_file_name_;
+};
+
+TEST_F(RtcEventLogOutputFileTest, NonDefectiveOutputsStartOutActive) {
+ auto output_file = std::make_unique<RtcEventLogOutputFile>(output_file_name_);
+ EXPECT_TRUE(output_file->IsActive());
+}
+
+TEST_F(RtcEventLogOutputFileTest, DefectiveOutputsStartOutInactive) {
+ const std::string illegal_filename = "/////////";
+ auto output_file = std::make_unique<RtcEventLogOutputFile>(illegal_filename);
+ EXPECT_FALSE(output_file->IsActive());
+}
+
+// Sanity over opening a file (by filename) with an unlimited size.
+TEST_F(RtcEventLogOutputFileTest, UnlimitedOutputFile) {
+ const std::string output_str = "one two three";
+
+ auto output_file = std::make_unique<RtcEventLogOutputFile>(output_file_name_);
+ output_file->Write(output_str);
+ output_file.reset(); // Closing the file flushes the buffer to disk.
+
+ EXPECT_EQ(GetOutputFileContents(), output_str);
+}
+
+// Do not allow writing more bytes to the file than max file size.
+TEST_F(RtcEventLogOutputFileTest, LimitedOutputFileCappedToCapacity) {
+ // Fit two bytes, then the third should be rejected.
+ auto output_file =
+ std::make_unique<RtcEventLogOutputFile>(output_file_name_, 2);
+
+ output_file->Write("1");
+ output_file->Write("2");
+ output_file->Write("3");
+ // Unsuccessful writes close the file; no need to delete the output to flush.
+
+ EXPECT_EQ(GetOutputFileContents(), "12");
+}
+
+// Make sure that calls to Write() either write everything to the file, or
+// nothing (short of underlying issues in the module that handles the file,
+// which would be beyond our control).
+TEST_F(RtcEventLogOutputFileTest, DoNotWritePartialLines) {
+ const std::string output_str_1 = "0123456789";
+ const std::string output_str_2 = "abcdefghij";
+
+ // Set a file size limit just shy of fitting the entire second line.
+ const size_t size_limit = output_str_1.length() + output_str_2.length() - 1;
+ auto output_file =
+ std::make_unique<RtcEventLogOutputFile>(output_file_name_, size_limit);
+
+ output_file->Write(output_str_1);
+ output_file->Write(output_str_2);
+ // Unsuccessful writes close the file; no need to delete the output to flush.
+
+ EXPECT_EQ(GetOutputFileContents(), output_str_1);
+}
+
+TEST_F(RtcEventLogOutputFileTest, UnsuccessfulWriteReturnsFalse) {
+ auto output_file =
+ std::make_unique<RtcEventLogOutputFile>(output_file_name_, 2);
+ EXPECT_FALSE(output_file->Write("abc"));
+}
+
+TEST_F(RtcEventLogOutputFileTest, SuccessfulWriteReturnsTrue) {
+ auto output_file =
+ std::make_unique<RtcEventLogOutputFile>(output_file_name_, 3);
+ EXPECT_TRUE(output_file->Write("abc"));
+}
+
+// Even if capacity is reached, a successful write leaves the output active.
+TEST_F(RtcEventLogOutputFileTest, FileStillActiveAfterSuccessfulWrite) {
+ auto output_file =
+ std::make_unique<RtcEventLogOutputFile>(output_file_name_, 3);
+ ASSERT_TRUE(output_file->Write("abc"));
+ EXPECT_TRUE(output_file->IsActive());
+}
+
+// Unsuccessful writes switch the output to inactive, even if capacity has
+// not yet been reached.
+TEST_F(RtcEventLogOutputFileTest, FileInactiveAfterUnsuccessfulWrite) {
+ auto output_file =
+ std::make_unique<RtcEventLogOutputFile>(output_file_name_, 2);
+ ASSERT_FALSE(output_file->Write("abc"));
+ EXPECT_FALSE(output_file->IsActive());
+}
+
+TEST_F(RtcEventLogOutputFileTest, AllowReasonableFileSizeLimits) {
+ auto output_file = std::make_unique<RtcEventLogOutputFile>(
+ output_file_name_, RtcEventLogOutputFile::kMaxReasonableFileSize);
+ EXPECT_TRUE(output_file->IsActive());
+}
+
+#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
+class RtcEventLogOutputFileDeathTest : public RtcEventLogOutputFileTest {};
+
+TEST_F(RtcEventLogOutputFileDeathTest, WritingToInactiveFileForbidden) {
+ RtcEventLogOutputFile output_file(output_file_name_, 2);
+ ASSERT_FALSE(output_file.Write("abc"));
+ ASSERT_FALSE(output_file.IsActive());
+ EXPECT_DEATH(output_file.Write("abc"), "");
+}
+
+TEST_F(RtcEventLogOutputFileDeathTest, DisallowUnreasonableFileSizeLimits) {
+ // Keeping in a temporary unique_ptr to make it clearer that the death is
+ // triggered by construction, not destruction.
+ std::unique_ptr<RtcEventLogOutputFile> output_file;
+ auto create_output_file = [&] {
+ const size_t unreasonable_size =
+ RtcEventLogOutputFile::kMaxReasonableFileSize + 1;
+ output_file = std::make_unique<RtcEventLogOutputFile>(output_file_name_,
+ unreasonable_size);
+ };
+ EXPECT_DEATH(create_output_file(), "");
+}
+#endif
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/rtp_headers.cc b/third_party/libwebrtc/api/rtp_headers.cc
new file mode 100644
index 0000000000..8e1efc7262
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_headers.cc
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/rtp_headers.h"
+
+namespace webrtc {
+
+RTPHeaderExtension::RTPHeaderExtension()
+ : hasTransmissionTimeOffset(false),
+ transmissionTimeOffset(0),
+ hasAbsoluteSendTime(false),
+ absoluteSendTime(0),
+ hasTransportSequenceNumber(false),
+ transportSequenceNumber(0),
+ hasAudioLevel(false),
+ voiceActivity(false),
+ audioLevel(0),
+ hasVideoRotation(false),
+ videoRotation(kVideoRotation_0),
+ hasVideoContentType(false),
+ videoContentType(VideoContentType::UNSPECIFIED),
+ has_video_timing(false),
+ csrcAudioLevels() {}
+
+RTPHeaderExtension::RTPHeaderExtension(const RTPHeaderExtension& other) =
+ default;
+
+RTPHeaderExtension& RTPHeaderExtension::operator=(
+ const RTPHeaderExtension& other) = default;
+
+RTPHeader::RTPHeader()
+ : markerBit(false),
+ payloadType(0),
+ sequenceNumber(0),
+ timestamp(0),
+ ssrc(0),
+ numCSRCs(0),
+ arrOfCSRCs(),
+ paddingLength(0),
+ headerLength(0),
+ payload_type_frequency(0),
+ extension() {}
+
+RTPHeader::RTPHeader(const RTPHeader& other) = default;
+
+RTPHeader& RTPHeader::operator=(const RTPHeader& other) = default;
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/rtp_headers.h b/third_party/libwebrtc/api/rtp_headers.h
new file mode 100644
index 0000000000..261c984d05
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_headers.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_RTP_HEADERS_H_
+#define API_RTP_HEADERS_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <string>
+
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/units/timestamp.h"
+#include "api/video/color_space.h"
+#include "api/video/video_content_type.h"
+#include "api/video/video_rotation.h"
+#include "api/video/video_timing.h"
+
+namespace webrtc {
+
+struct FeedbackRequest {
+ // Determines whether the recv delta as specified in
+ // https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01
+ // should be included.
+ bool include_timestamps;
+ // Include feedback of received packets in the range [sequence_number -
+ // sequence_count + 1, sequence_number]. That is, no feedback will be sent if
+ // sequence_count is zero.
+ int sequence_count;
+};
+
+// The Absolute Capture Time extension is used to stamp RTP packets with a NTP
+// timestamp showing when the first audio or video frame in a packet was
+// originally captured. The intent of this extension is to provide a way to
+// accomplish audio-to-video synchronization when RTCP-terminating intermediate
+// systems (e.g. mixers) are involved. See:
+// http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time
+struct AbsoluteCaptureTime {
+ // Absolute capture timestamp is the NTP timestamp of when the first frame in
+ // a packet was originally captured. This timestamp MUST be based on the same
+ // clock as the clock used to generate NTP timestamps for RTCP sender reports
+ // on the capture system.
+ //
+ // It’s not always possible to do an NTP clock readout at the exact moment of
+ // when a media frame is captured. A capture system MAY postpone the readout
+ // until a more convenient time. A capture system SHOULD have known delays
+ // (e.g. from hardware buffers) subtracted from the readout to make the final
+ // timestamp as close to the actual capture time as possible.
+ //
+ // This field is encoded as a 64-bit unsigned fixed-point number with the high
+ // 32 bits for the timestamp in seconds and low 32 bits for the fractional
+ // part. This is also known as the UQ32.32 format and is what the RTP
+ // specification defines as the canonical format to represent NTP timestamps.
+ uint64_t absolute_capture_timestamp;
+
+ // Estimated capture clock offset is the sender’s estimate of the offset
+ // between its own NTP clock and the capture system’s NTP clock. The sender is
+ // here defined as the system that owns the NTP clock used to generate the NTP
+ // timestamps for the RTCP sender reports on this stream. The sender system is
+ // typically either the capture system or a mixer.
+ //
+ // This field is encoded as a 64-bit two’s complement signed fixed-point
+ // number with the high 32 bits for the seconds and low 32 bits for the
+ // fractional part. It’s intended to make it easy for a receiver, that knows
+ // how to estimate the sender system’s NTP clock, to also estimate the capture
+ // system’s NTP clock:
+ //
+ // Capture NTP Clock = Sender NTP Clock + Capture Clock Offset
+ absl::optional<int64_t> estimated_capture_clock_offset;
+};
+
+inline bool operator==(const AbsoluteCaptureTime& lhs,
+ const AbsoluteCaptureTime& rhs) {
+ return (lhs.absolute_capture_timestamp == rhs.absolute_capture_timestamp) &&
+ (lhs.estimated_capture_clock_offset ==
+ rhs.estimated_capture_clock_offset);
+}
+
+inline bool operator!=(const AbsoluteCaptureTime& lhs,
+ const AbsoluteCaptureTime& rhs) {
+ return !(lhs == rhs);
+}
+
+enum { kRtpCsrcSize = 15 }; // RFC 3550 page 13
+
+// Audio level of CSRCs See:
+// https://tools.ietf.org/html/rfc6465
+struct CsrcAudioLevelList {
+ CsrcAudioLevelList() : numAudioLevels(0) { }
+ CsrcAudioLevelList(const CsrcAudioLevelList&) = default;
+ CsrcAudioLevelList& operator=(const CsrcAudioLevelList&) = default;
+ uint8_t numAudioLevels;
+ // arrOfAudioLevels has the same ordering as RTPHeader.arrOfCSRCs
+ uint8_t arrOfAudioLevels[kRtpCsrcSize];
+};
+
+struct RTPHeaderExtension {
+ RTPHeaderExtension();
+ RTPHeaderExtension(const RTPHeaderExtension& other);
+ RTPHeaderExtension& operator=(const RTPHeaderExtension& other);
+
+ static constexpr int kAbsSendTimeFraction = 18;
+
+ Timestamp GetAbsoluteSendTimestamp() const {
+ RTC_DCHECK(hasAbsoluteSendTime);
+ RTC_DCHECK(absoluteSendTime < (1ul << 24));
+ return Timestamp::Micros((absoluteSendTime * 1000000ll) /
+ (1 << kAbsSendTimeFraction));
+ }
+
+ bool hasTransmissionTimeOffset;
+ int32_t transmissionTimeOffset;
+ bool hasAbsoluteSendTime;
+ uint32_t absoluteSendTime;
+ absl::optional<AbsoluteCaptureTime> absolute_capture_time;
+ bool hasTransportSequenceNumber;
+ uint16_t transportSequenceNumber;
+ absl::optional<FeedbackRequest> feedback_request;
+
+ // Audio Level includes both level in dBov and voiced/unvoiced bit. See:
+ // https://tools.ietf.org/html/rfc6464#section-3
+ bool hasAudioLevel;
+ bool voiceActivity;
+ uint8_t audioLevel;
+
+ // For Coordination of Video Orientation. See
+ // http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/
+ // ts_126114v120700p.pdf
+ bool hasVideoRotation;
+ VideoRotation videoRotation;
+
+ // TODO(ilnik): Refactor this and one above to be absl::optional() and remove
+ // a corresponding bool flag.
+ bool hasVideoContentType;
+ VideoContentType videoContentType;
+
+ bool has_video_timing;
+ VideoSendTiming video_timing;
+
+ VideoPlayoutDelay playout_delay;
+
+ // For identification of a stream when ssrc is not signaled. See
+ // https://tools.ietf.org/html/rfc8852
+ std::string stream_id;
+ std::string repaired_stream_id;
+
+ // For identifying the media section used to interpret this RTP packet. See
+ // https://tools.ietf.org/html/rfc8843
+ std::string mid;
+
+ absl::optional<ColorSpace> color_space;
+
+ CsrcAudioLevelList csrcAudioLevels;
+};
+
+struct RTC_EXPORT RTPHeader {
+ RTPHeader();
+ RTPHeader(const RTPHeader& other);
+ RTPHeader& operator=(const RTPHeader& other);
+
+ bool markerBit;
+ uint8_t payloadType;
+ uint16_t sequenceNumber;
+ uint32_t timestamp;
+ uint32_t ssrc;
+ uint8_t numCSRCs;
+ uint32_t arrOfCSRCs[kRtpCsrcSize];
+ size_t paddingLength;
+ size_t headerLength;
+ int payload_type_frequency;
+ RTPHeaderExtension extension;
+};
+
+// RTCP mode to use. Compound mode is described by RFC 4585 and reduced-size
+// RTCP mode is described by RFC 5506.
+enum class RtcpMode { kOff, kCompound, kReducedSize };
+
+enum NetworkState {
+ kNetworkUp,
+ kNetworkDown,
+};
+
+} // namespace webrtc
+
+#endif // API_RTP_HEADERS_H_
diff --git a/third_party/libwebrtc/api/rtp_headers_gn/moz.build b/third_party/libwebrtc/api/rtp_headers_gn/moz.build
new file mode 100644
index 0000000000..d26fa6a026
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_headers_gn/moz.build
@@ -0,0 +1,225 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/rtp_headers.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("rtp_headers_gn")
diff --git a/third_party/libwebrtc/api/rtp_packet_info.cc b/third_party/libwebrtc/api/rtp_packet_info.cc
new file mode 100644
index 0000000000..cba274ec38
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_packet_info.cc
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/rtp_packet_info.h"
+
+#include <algorithm>
+#include <utility>
+
+namespace webrtc {
+
+RtpPacketInfo::RtpPacketInfo()
+ : ssrc_(0), rtp_timestamp_(0), receive_time_(Timestamp::MinusInfinity()) {}
+
+RtpPacketInfo::RtpPacketInfo(uint32_t ssrc,
+ std::vector<uint32_t> csrcs,
+ uint32_t rtp_timestamp,
+ Timestamp receive_time)
+ : ssrc_(ssrc),
+ csrcs_(std::move(csrcs)),
+ rtp_timestamp_(rtp_timestamp),
+ receive_time_(receive_time) {}
+
+RtpPacketInfo::RtpPacketInfo(const RTPHeader& rtp_header,
+ Timestamp receive_time)
+ : ssrc_(rtp_header.ssrc),
+ rtp_timestamp_(rtp_header.timestamp),
+ receive_time_(receive_time) {
+ const auto& extension = rtp_header.extension;
+ const auto csrcs_count = std::min<size_t>(rtp_header.numCSRCs, kRtpCsrcSize);
+
+ csrcs_.assign(&rtp_header.arrOfCSRCs[0], &rtp_header.arrOfCSRCs[csrcs_count]);
+
+ if (extension.hasAudioLevel) {
+ audio_level_ = extension.audioLevel;
+ }
+
+ absolute_capture_time_ = extension.absolute_capture_time;
+}
+
+bool operator==(const RtpPacketInfo& lhs, const RtpPacketInfo& rhs) {
+ return (lhs.ssrc() == rhs.ssrc()) && (lhs.csrcs() == rhs.csrcs()) &&
+ (lhs.rtp_timestamp() == rhs.rtp_timestamp()) &&
+ (lhs.receive_time() == rhs.receive_time()) &&
+ (lhs.audio_level() == rhs.audio_level()) &&
+ (lhs.absolute_capture_time() == rhs.absolute_capture_time()) &&
+ (lhs.local_capture_clock_offset() == rhs.local_capture_clock_offset());
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/rtp_packet_info.h b/third_party/libwebrtc/api/rtp_packet_info.h
new file mode 100644
index 0000000000..8df12a36cf
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_packet_info.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_RTP_PACKET_INFO_H_
+#define API_RTP_PACKET_INFO_H_
+
+#include <cstdint>
+#include <utility>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/rtp_headers.h"
+#include "api/units/time_delta.h"
+#include "api/units/timestamp.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+//
+// Structure to hold information about a received `RtpPacket`. It is primarily
+// used to carry per-packet information from when a packet is received until
+// the information is passed to `SourceTracker`.
+//
+class RTC_EXPORT RtpPacketInfo {
+ public:
+ RtpPacketInfo();
+
+ RtpPacketInfo(uint32_t ssrc,
+ std::vector<uint32_t> csrcs,
+ uint32_t rtp_timestamp,
+ Timestamp receive_time);
+
+ RtpPacketInfo(const RTPHeader& rtp_header, Timestamp receive_time);
+
+ RtpPacketInfo(const RtpPacketInfo& other) = default;
+ RtpPacketInfo(RtpPacketInfo&& other) = default;
+ RtpPacketInfo& operator=(const RtpPacketInfo& other) = default;
+ RtpPacketInfo& operator=(RtpPacketInfo&& other) = default;
+
+ uint32_t ssrc() const { return ssrc_; }
+ void set_ssrc(uint32_t value) { ssrc_ = value; }
+
+ const std::vector<uint32_t>& csrcs() const { return csrcs_; }
+ void set_csrcs(std::vector<uint32_t> value) { csrcs_ = std::move(value); }
+
+ uint32_t rtp_timestamp() const { return rtp_timestamp_; }
+ void set_rtp_timestamp(uint32_t value) { rtp_timestamp_ = value; }
+
+ Timestamp receive_time() const { return receive_time_; }
+ void set_receive_time(Timestamp value) { receive_time_ = value; }
+
+ absl::optional<uint8_t> audio_level() const { return audio_level_; }
+ RtpPacketInfo& set_audio_level(absl::optional<uint8_t> value) {
+ audio_level_ = value;
+ return *this;
+ }
+
+ const absl::optional<AbsoluteCaptureTime>& absolute_capture_time() const {
+ return absolute_capture_time_;
+ }
+ RtpPacketInfo& set_absolute_capture_time(
+ const absl::optional<AbsoluteCaptureTime>& value) {
+ absolute_capture_time_ = value;
+ return *this;
+ }
+
+ const absl::optional<TimeDelta>& local_capture_clock_offset() const {
+ return local_capture_clock_offset_;
+ }
+ RtpPacketInfo& set_local_capture_clock_offset(
+ absl::optional<TimeDelta> value) {
+ local_capture_clock_offset_ = value;
+ return *this;
+ }
+
+ private:
+ // Fields from the RTP header:
+ // https://tools.ietf.org/html/rfc3550#section-5.1
+ uint32_t ssrc_;
+ std::vector<uint32_t> csrcs_;
+ uint32_t rtp_timestamp_;
+
+ // Local `webrtc::Clock`-based timestamp of when the packet was received.
+ Timestamp receive_time_;
+
+ // Fields from the Audio Level header extension:
+ // https://tools.ietf.org/html/rfc6464#section-3
+ absl::optional<uint8_t> audio_level_;
+
+ // Fields from the Absolute Capture Time header extension:
+ // http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time
+ absl::optional<AbsoluteCaptureTime> absolute_capture_time_;
+
+ // Clock offset between the local clock and the capturer's clock.
+ // Do not confuse with `AbsoluteCaptureTime::estimated_capture_clock_offset`
+ // which instead represents the clock offset between a remote sender and the
+ // capturer. The following holds:
+ // Capture's NTP Clock = Local NTP Clock + Local-Capture Clock Offset
+ absl::optional<TimeDelta> local_capture_clock_offset_;
+};
+
+bool operator==(const RtpPacketInfo& lhs, const RtpPacketInfo& rhs);
+
+inline bool operator!=(const RtpPacketInfo& lhs, const RtpPacketInfo& rhs) {
+ return !(lhs == rhs);
+}
+
+} // namespace webrtc
+
+#endif // API_RTP_PACKET_INFO_H_
diff --git a/third_party/libwebrtc/api/rtp_packet_info_gn/moz.build b/third_party/libwebrtc/api/rtp_packet_info_gn/moz.build
new file mode 100644
index 0000000000..99c25cbbae
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_packet_info_gn/moz.build
@@ -0,0 +1,225 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/rtp_packet_info.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("rtp_packet_info_gn")
diff --git a/third_party/libwebrtc/api/rtp_packet_info_unittest.cc b/third_party/libwebrtc/api/rtp_packet_info_unittest.cc
new file mode 100644
index 0000000000..d35edf75db
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_packet_info_unittest.cc
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/rtp_packet_infos.h"
+#include "api/units/time_delta.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+TEST(RtpPacketInfoTest, Ssrc) {
+ constexpr uint32_t kValue = 4038189233;
+
+ RtpPacketInfo lhs;
+ RtpPacketInfo rhs;
+
+ EXPECT_TRUE(lhs == rhs);
+ EXPECT_FALSE(lhs != rhs);
+
+ rhs.set_ssrc(kValue);
+ EXPECT_EQ(rhs.ssrc(), kValue);
+
+ EXPECT_FALSE(lhs == rhs);
+ EXPECT_TRUE(lhs != rhs);
+
+ lhs = rhs;
+
+ EXPECT_TRUE(lhs == rhs);
+ EXPECT_FALSE(lhs != rhs);
+
+ rhs = RtpPacketInfo();
+ EXPECT_NE(rhs.ssrc(), kValue);
+
+ rhs = RtpPacketInfo(/*ssrc=*/kValue, /*csrcs=*/{}, /*rtp_timestamp=*/{},
+ /*receive_time=*/Timestamp::Zero());
+ EXPECT_EQ(rhs.ssrc(), kValue);
+}
+
+TEST(RtpPacketInfoTest, Csrcs) {
+ const std::vector<uint32_t> value = {4038189233, 3016333617, 1207992985};
+
+ RtpPacketInfo lhs;
+ RtpPacketInfo rhs;
+
+ EXPECT_TRUE(lhs == rhs);
+ EXPECT_FALSE(lhs != rhs);
+
+ rhs.set_csrcs(value);
+ EXPECT_EQ(rhs.csrcs(), value);
+
+ EXPECT_FALSE(lhs == rhs);
+ EXPECT_TRUE(lhs != rhs);
+
+ lhs = rhs;
+
+ EXPECT_TRUE(lhs == rhs);
+ EXPECT_FALSE(lhs != rhs);
+
+ rhs = RtpPacketInfo();
+ EXPECT_NE(rhs.csrcs(), value);
+
+ rhs = RtpPacketInfo(/*ssrc=*/{}, /*csrcs=*/value, /*rtp_timestamp=*/{},
+ /*receive_time=*/Timestamp::Zero());
+ EXPECT_EQ(rhs.csrcs(), value);
+}
+
+TEST(RtpPacketInfoTest, RtpTimestamp) {
+ constexpr uint32_t kValue = 4038189233;
+
+ RtpPacketInfo lhs;
+ RtpPacketInfo rhs;
+
+ EXPECT_TRUE(lhs == rhs);
+ EXPECT_FALSE(lhs != rhs);
+
+ rhs.set_rtp_timestamp(kValue);
+ EXPECT_EQ(rhs.rtp_timestamp(), kValue);
+
+ EXPECT_FALSE(lhs == rhs);
+ EXPECT_TRUE(lhs != rhs);
+
+ lhs = rhs;
+
+ EXPECT_TRUE(lhs == rhs);
+ EXPECT_FALSE(lhs != rhs);
+
+ rhs = RtpPacketInfo();
+ EXPECT_NE(rhs.rtp_timestamp(), kValue);
+
+ rhs = RtpPacketInfo(/*ssrc=*/{}, /*csrcs=*/{}, /*rtp_timestamp=*/kValue,
+ /*receive_time=*/Timestamp::Zero());
+ EXPECT_EQ(rhs.rtp_timestamp(), kValue);
+}
+
+TEST(RtpPacketInfoTest, ReceiveTimeMs) {
+ constexpr Timestamp kValue = Timestamp::Micros(8868963877546349045LL);
+
+ RtpPacketInfo lhs;
+ RtpPacketInfo rhs;
+
+ EXPECT_TRUE(lhs == rhs);
+ EXPECT_FALSE(lhs != rhs);
+
+ rhs.set_receive_time(kValue);
+ EXPECT_EQ(rhs.receive_time(), kValue);
+
+ EXPECT_FALSE(lhs == rhs);
+ EXPECT_TRUE(lhs != rhs);
+
+ lhs = rhs;
+
+ EXPECT_TRUE(lhs == rhs);
+ EXPECT_FALSE(lhs != rhs);
+
+ rhs = RtpPacketInfo();
+ EXPECT_NE(rhs.receive_time(), kValue);
+
+ rhs = RtpPacketInfo(/*ssrc=*/{}, /*csrcs=*/{}, /*rtp_timestamp=*/{},
+ /*receive_time=*/kValue);
+ EXPECT_EQ(rhs.receive_time(), kValue);
+}
+
+TEST(RtpPacketInfoTest, AudioLevel) {
+ constexpr absl::optional<uint8_t> kValue = 31;
+
+ RtpPacketInfo lhs;
+ RtpPacketInfo rhs;
+
+ EXPECT_TRUE(lhs == rhs);
+ EXPECT_FALSE(lhs != rhs);
+
+ rhs.set_audio_level(kValue);
+ EXPECT_EQ(rhs.audio_level(), kValue);
+
+ EXPECT_FALSE(lhs == rhs);
+ EXPECT_TRUE(lhs != rhs);
+
+ lhs = rhs;
+
+ EXPECT_TRUE(lhs == rhs);
+ EXPECT_FALSE(lhs != rhs);
+
+ rhs = RtpPacketInfo();
+ EXPECT_NE(rhs.audio_level(), kValue);
+
+ rhs = RtpPacketInfo(/*ssrc=*/{}, /*csrcs=*/{}, /*rtp_timestamp=*/{},
+ /*receive_time=*/Timestamp::Zero());
+ rhs.set_audio_level(kValue);
+ EXPECT_EQ(rhs.audio_level(), kValue);
+}
+
+TEST(RtpPacketInfoTest, AbsoluteCaptureTime) {
+ constexpr absl::optional<AbsoluteCaptureTime> kValue = AbsoluteCaptureTime{
+ .absolute_capture_timestamp = 12, .estimated_capture_clock_offset = 34};
+
+ RtpPacketInfo lhs;
+ RtpPacketInfo rhs;
+
+ EXPECT_TRUE(lhs == rhs);
+ EXPECT_FALSE(lhs != rhs);
+
+ rhs.set_absolute_capture_time(kValue);
+ EXPECT_EQ(rhs.absolute_capture_time(), kValue);
+
+ EXPECT_FALSE(lhs == rhs);
+ EXPECT_TRUE(lhs != rhs);
+
+ lhs = rhs;
+
+ EXPECT_TRUE(lhs == rhs);
+ EXPECT_FALSE(lhs != rhs);
+
+ rhs = RtpPacketInfo();
+ EXPECT_NE(rhs.absolute_capture_time(), kValue);
+
+ rhs = RtpPacketInfo(/*ssrc=*/{}, /*csrcs=*/{}, /*rtp_timestamp=*/{},
+ /*receive_time=*/Timestamp::Zero());
+ rhs.set_absolute_capture_time(kValue);
+ EXPECT_EQ(rhs.absolute_capture_time(), kValue);
+}
+
+TEST(RtpPacketInfoTest, LocalCaptureClockOffset) {
+ constexpr TimeDelta kValue = TimeDelta::Micros(8868963877546349045LL);
+
+ RtpPacketInfo lhs;
+ RtpPacketInfo rhs;
+
+ EXPECT_TRUE(lhs == rhs);
+ EXPECT_FALSE(lhs != rhs);
+
+ rhs.set_local_capture_clock_offset(kValue);
+ EXPECT_EQ(rhs.local_capture_clock_offset(), kValue);
+
+ EXPECT_FALSE(lhs == rhs);
+ EXPECT_TRUE(lhs != rhs);
+
+ lhs = rhs;
+
+ EXPECT_TRUE(lhs == rhs);
+ EXPECT_FALSE(lhs != rhs);
+
+ rhs = RtpPacketInfo();
+ EXPECT_EQ(rhs.local_capture_clock_offset(), absl::nullopt);
+
+ rhs = RtpPacketInfo(/*ssrc=*/{}, /*csrcs=*/{}, /*rtp_timestamp=*/{},
+ /*receive_time=*/Timestamp::Zero());
+ rhs.set_local_capture_clock_offset(kValue);
+ EXPECT_EQ(rhs.local_capture_clock_offset(), kValue);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/rtp_packet_infos.h b/third_party/libwebrtc/api/rtp_packet_infos.h
new file mode 100644
index 0000000000..7445729fbb
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_packet_infos.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_RTP_PACKET_INFOS_H_
+#define API_RTP_PACKET_INFOS_H_
+
+#include <cstdint>
+#include <utility>
+#include <vector>
+
+#include "api/make_ref_counted.h"
+#include "api/ref_counted_base.h"
+#include "api/rtp_packet_info.h"
+#include "api/scoped_refptr.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Semi-immutable structure to hold information about packets used to assemble
+// an audio or video frame. Uses internal reference counting to make it very
+// cheap to copy.
+//
+// We should ideally just use `std::vector<RtpPacketInfo>` and have it
+// `std::move()`-ed as the per-packet information is transferred from one object
+// to another. But moving the info, instead of copying it, is not easily done
+// for the current video code.
+class RTC_EXPORT RtpPacketInfos {
+ public:
+ using vector_type = std::vector<RtpPacketInfo>;
+
+ using value_type = vector_type::value_type;
+ using size_type = vector_type::size_type;
+ using difference_type = vector_type::difference_type;
+ using const_reference = vector_type::const_reference;
+ using const_pointer = vector_type::const_pointer;
+ using const_iterator = vector_type::const_iterator;
+ using const_reverse_iterator = vector_type::const_reverse_iterator;
+
+ using reference = const_reference;
+ using pointer = const_pointer;
+ using iterator = const_iterator;
+ using reverse_iterator = const_reverse_iterator;
+
+ RtpPacketInfos() {}
+ explicit RtpPacketInfos(const vector_type& entries)
+ : data_(Data::Create(entries)) {}
+
+ explicit RtpPacketInfos(vector_type&& entries)
+ : data_(Data::Create(std::move(entries))) {}
+
+ RtpPacketInfos(const RtpPacketInfos& other) = default;
+ RtpPacketInfos(RtpPacketInfos&& other) = default;
+ RtpPacketInfos& operator=(const RtpPacketInfos& other) = default;
+ RtpPacketInfos& operator=(RtpPacketInfos&& other) = default;
+
+ const_reference operator[](size_type pos) const { return entries()[pos]; }
+
+ const_reference at(size_type pos) const { return entries().at(pos); }
+ const_reference front() const { return entries().front(); }
+ const_reference back() const { return entries().back(); }
+
+ const_iterator begin() const { return entries().begin(); }
+ const_iterator end() const { return entries().end(); }
+ const_reverse_iterator rbegin() const { return entries().rbegin(); }
+ const_reverse_iterator rend() const { return entries().rend(); }
+
+ const_iterator cbegin() const { return entries().cbegin(); }
+ const_iterator cend() const { return entries().cend(); }
+ const_reverse_iterator crbegin() const { return entries().crbegin(); }
+ const_reverse_iterator crend() const { return entries().crend(); }
+
+ bool empty() const { return entries().empty(); }
+ size_type size() const { return entries().size(); }
+
+ private:
+ class Data final : public rtc::RefCountedNonVirtual<Data> {
+ public:
+ static rtc::scoped_refptr<Data> Create(const vector_type& entries) {
+ // Performance optimization for the empty case.
+ if (entries.empty()) {
+ return nullptr;
+ }
+
+ return rtc::make_ref_counted<Data>(entries);
+ }
+
+ static rtc::scoped_refptr<Data> Create(vector_type&& entries) {
+ // Performance optimization for the empty case.
+ if (entries.empty()) {
+ return nullptr;
+ }
+
+ return rtc::make_ref_counted<Data>(std::move(entries));
+ }
+
+ const vector_type& entries() const { return entries_; }
+
+ explicit Data(const vector_type& entries) : entries_(entries) {}
+ explicit Data(vector_type&& entries) : entries_(std::move(entries)) {}
+ ~Data() = default;
+
+ private:
+ const vector_type entries_;
+ };
+
+ static const vector_type& empty_entries() {
+ static const vector_type& value = *new vector_type();
+ return value;
+ }
+
+ const vector_type& entries() const {
+ if (data_ != nullptr) {
+ return data_->entries();
+ } else {
+ return empty_entries();
+ }
+ }
+
+ rtc::scoped_refptr<Data> data_;
+};
+
+} // namespace webrtc
+
+#endif // API_RTP_PACKET_INFOS_H_
diff --git a/third_party/libwebrtc/api/rtp_packet_infos_unittest.cc b/third_party/libwebrtc/api/rtp_packet_infos_unittest.cc
new file mode 100644
index 0000000000..a90cfa03e2
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_packet_infos_unittest.cc
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/rtp_packet_infos.h"
+
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace {
+
+using ::testing::ElementsAre;
+using ::testing::SizeIs;
+
+template <typename Iterator>
+RtpPacketInfos::vector_type ToVector(Iterator begin, Iterator end) {
+ return RtpPacketInfos::vector_type(begin, end);
+}
+
+} // namespace
+
+TEST(RtpPacketInfosTest, BasicFunctionality) {
+ RtpPacketInfo p0(/*ssrc=*/123, /*csrcs=*/{1, 2}, /*rtp_timestamp=*/89,
+ /*receive_time=*/Timestamp::Millis(7));
+ p0.set_audio_level(5);
+ p0.set_absolute_capture_time(AbsoluteCaptureTime{
+ .absolute_capture_timestamp = 45, .estimated_capture_clock_offset = 78});
+
+ RtpPacketInfo p1(/*ssrc=*/456, /*csrcs=*/{3, 4}, /*rtp_timestamp=*/89,
+ /*receive_time=*/Timestamp::Millis(1));
+ p1.set_audio_level(4);
+ p1.set_absolute_capture_time(AbsoluteCaptureTime{
+ .absolute_capture_timestamp = 13, .estimated_capture_clock_offset = 21});
+
+ RtpPacketInfo p2(/*ssrc=*/789, /*csrcs=*/{5, 6}, /*rtp_timestamp=*/88,
+ /*receive_time=*/Timestamp::Millis(7));
+ p2.set_audio_level(1);
+ p2.set_absolute_capture_time(AbsoluteCaptureTime{
+ .absolute_capture_timestamp = 99, .estimated_capture_clock_offset = 78});
+
+ RtpPacketInfos x({p0, p1, p2});
+
+ ASSERT_THAT(x, SizeIs(3));
+
+ EXPECT_EQ(x[0], p0);
+ EXPECT_EQ(x[1], p1);
+ EXPECT_EQ(x[2], p2);
+
+ EXPECT_EQ(x.front(), p0);
+ EXPECT_EQ(x.back(), p2);
+
+ EXPECT_THAT(ToVector(x.begin(), x.end()), ElementsAre(p0, p1, p2));
+ EXPECT_THAT(ToVector(x.rbegin(), x.rend()), ElementsAre(p2, p1, p0));
+
+ EXPECT_THAT(ToVector(x.cbegin(), x.cend()), ElementsAre(p0, p1, p2));
+ EXPECT_THAT(ToVector(x.crbegin(), x.crend()), ElementsAre(p2, p1, p0));
+
+ EXPECT_FALSE(x.empty());
+}
+
+TEST(RtpPacketInfosTest, CopyShareData) {
+ RtpPacketInfo p0(/*ssrc=*/123, /*csrcs=*/{1, 2}, /*rtp_timestamp=*/89,
+ /*receive_time=*/Timestamp::Millis(7));
+ p0.set_audio_level(5);
+ p0.set_absolute_capture_time(AbsoluteCaptureTime{
+ .absolute_capture_timestamp = 45, .estimated_capture_clock_offset = 78});
+
+ RtpPacketInfo p1(/*ssrc=*/456, /*csrcs=*/{3, 4}, /*rtp_timestamp=*/89,
+ /*receive_time=*/Timestamp::Millis(1));
+ p1.set_audio_level(4);
+ p1.set_absolute_capture_time(AbsoluteCaptureTime{
+ .absolute_capture_timestamp = 13, .estimated_capture_clock_offset = 21});
+
+ RtpPacketInfo p2(/*ssrc=*/789, /*csrcs=*/{5, 6}, /*rtp_timestamp=*/88,
+ /*receive_time=*/Timestamp::Millis(7));
+ p2.set_audio_level(1);
+ p2.set_absolute_capture_time(AbsoluteCaptureTime{
+ .absolute_capture_timestamp = 99, .estimated_capture_clock_offset = 78});
+
+ RtpPacketInfos lhs({p0, p1, p2});
+ RtpPacketInfos rhs = lhs;
+
+ ASSERT_THAT(lhs, SizeIs(3));
+ ASSERT_THAT(rhs, SizeIs(3));
+
+ for (size_t i = 0; i < lhs.size(); ++i) {
+ EXPECT_EQ(lhs[i], rhs[i]);
+ }
+
+ EXPECT_EQ(lhs.front(), rhs.front());
+ EXPECT_EQ(lhs.back(), rhs.back());
+
+ EXPECT_EQ(lhs.begin(), rhs.begin());
+ EXPECT_EQ(lhs.end(), rhs.end());
+ EXPECT_EQ(lhs.rbegin(), rhs.rbegin());
+ EXPECT_EQ(lhs.rend(), rhs.rend());
+
+ EXPECT_EQ(lhs.cbegin(), rhs.cbegin());
+ EXPECT_EQ(lhs.cend(), rhs.cend());
+ EXPECT_EQ(lhs.crbegin(), rhs.crbegin());
+ EXPECT_EQ(lhs.crend(), rhs.crend());
+
+ EXPECT_EQ(lhs.empty(), rhs.empty());
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/rtp_parameters.cc b/third_party/libwebrtc/api/rtp_parameters.cc
new file mode 100644
index 0000000000..c1d12e5d8d
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_parameters.cc
@@ -0,0 +1,295 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/rtp_parameters.h"
+
+#include <algorithm>
+#include <string>
+#include <tuple>
+#include <utility>
+
+#include "api/array_view.h"
+#include "rtc_base/strings/string_builder.h"
+
+namespace webrtc {
+
+const char* DegradationPreferenceToString(
+ DegradationPreference degradation_preference) {
+ switch (degradation_preference) {
+ case DegradationPreference::DISABLED:
+ return "disabled";
+ case DegradationPreference::MAINTAIN_FRAMERATE:
+ return "maintain-framerate";
+ case DegradationPreference::MAINTAIN_RESOLUTION:
+ return "maintain-resolution";
+ case DegradationPreference::BALANCED:
+ return "balanced";
+ }
+ RTC_CHECK_NOTREACHED();
+}
+
+const double kDefaultBitratePriority = 1.0;
+
+RtcpFeedback::RtcpFeedback() = default;
+RtcpFeedback::RtcpFeedback(RtcpFeedbackType type) : type(type) {}
+RtcpFeedback::RtcpFeedback(RtcpFeedbackType type,
+ RtcpFeedbackMessageType message_type)
+ : type(type), message_type(message_type) {}
+RtcpFeedback::RtcpFeedback(const RtcpFeedback& rhs) = default;
+RtcpFeedback::~RtcpFeedback() = default;
+
+RtpCodecCapability::RtpCodecCapability() = default;
+RtpCodecCapability::~RtpCodecCapability() = default;
+
+RtpHeaderExtensionCapability::RtpHeaderExtensionCapability() = default;
+RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
+ absl::string_view uri)
+ : uri(uri) {}
+RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
+ absl::string_view uri,
+ int preferred_id)
+ : uri(uri), preferred_id(preferred_id) {}
+RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
+ absl::string_view uri,
+ int preferred_id,
+ RtpTransceiverDirection direction)
+ : uri(uri), preferred_id(preferred_id), direction(direction) {}
+RtpHeaderExtensionCapability::~RtpHeaderExtensionCapability() = default;
+
+RtpExtension::RtpExtension() = default;
+RtpExtension::RtpExtension(absl::string_view uri, int id) : uri(uri), id(id) {}
+RtpExtension::RtpExtension(absl::string_view uri, int id, bool encrypt)
+ : uri(uri), id(id), encrypt(encrypt) {}
+RtpExtension::~RtpExtension() = default;
+
+RtpFecParameters::RtpFecParameters() = default;
+RtpFecParameters::RtpFecParameters(FecMechanism mechanism)
+ : mechanism(mechanism) {}
+RtpFecParameters::RtpFecParameters(FecMechanism mechanism, uint32_t ssrc)
+ : ssrc(ssrc), mechanism(mechanism) {}
+RtpFecParameters::RtpFecParameters(const RtpFecParameters& rhs) = default;
+RtpFecParameters::~RtpFecParameters() = default;
+
+RtpRtxParameters::RtpRtxParameters() = default;
+RtpRtxParameters::RtpRtxParameters(uint32_t ssrc) : ssrc(ssrc) {}
+RtpRtxParameters::RtpRtxParameters(const RtpRtxParameters& rhs) = default;
+RtpRtxParameters::~RtpRtxParameters() = default;
+
+RtpEncodingParameters::RtpEncodingParameters() = default;
+RtpEncodingParameters::RtpEncodingParameters(const RtpEncodingParameters& rhs) =
+ default;
+RtpEncodingParameters::~RtpEncodingParameters() = default;
+
+RtpCodecParameters::RtpCodecParameters() = default;
+RtpCodecParameters::RtpCodecParameters(const RtpCodecParameters& rhs) = default;
+RtpCodecParameters::~RtpCodecParameters() = default;
+
+RtpCapabilities::RtpCapabilities() = default;
+RtpCapabilities::~RtpCapabilities() = default;
+
+RtcpParameters::RtcpParameters() = default;
+RtcpParameters::RtcpParameters(const RtcpParameters& rhs) = default;
+RtcpParameters::~RtcpParameters() = default;
+
+RtpParameters::RtpParameters() = default;
+RtpParameters::RtpParameters(const RtpParameters& rhs) = default;
+RtpParameters::~RtpParameters() = default;
+
+std::string RtpExtension::ToString() const {
+ char buf[256];
+ rtc::SimpleStringBuilder sb(buf);
+ sb << "{uri: " << uri;
+ sb << ", id: " << id;
+ if (encrypt) {
+ sb << ", encrypt";
+ }
+ sb << '}';
+ return sb.str();
+}
+
+constexpr char RtpExtension::kEncryptHeaderExtensionsUri[];
+constexpr char RtpExtension::kAudioLevelUri[];
+constexpr char RtpExtension::kTimestampOffsetUri[];
+constexpr char RtpExtension::kAbsSendTimeUri[];
+constexpr char RtpExtension::kAbsoluteCaptureTimeUri[];
+constexpr char RtpExtension::kVideoRotationUri[];
+constexpr char RtpExtension::kVideoContentTypeUri[];
+constexpr char RtpExtension::kVideoTimingUri[];
+constexpr char RtpExtension::kGenericFrameDescriptorUri00[];
+constexpr char RtpExtension::kDependencyDescriptorUri[];
+constexpr char RtpExtension::kVideoLayersAllocationUri[];
+constexpr char RtpExtension::kTransportSequenceNumberUri[];
+constexpr char RtpExtension::kTransportSequenceNumberV2Uri[];
+constexpr char RtpExtension::kPlayoutDelayUri[];
+constexpr char RtpExtension::kColorSpaceUri[];
+constexpr char RtpExtension::kMidUri[];
+constexpr char RtpExtension::kRidUri[];
+constexpr char RtpExtension::kRepairedRidUri[];
+constexpr char RtpExtension::kVideoFrameTrackingIdUri[];
+constexpr char RtpExtension::kCsrcAudioLevelsUri[];
+
+constexpr int RtpExtension::kMinId;
+constexpr int RtpExtension::kMaxId;
+constexpr int RtpExtension::kMaxValueSize;
+constexpr int RtpExtension::kOneByteHeaderExtensionMaxId;
+constexpr int RtpExtension::kOneByteHeaderExtensionMaxValueSize;
+
+bool RtpExtension::IsSupportedForAudio(absl::string_view uri) {
+ return uri == webrtc::RtpExtension::kAudioLevelUri ||
+ uri == webrtc::RtpExtension::kAbsSendTimeUri ||
+ uri == webrtc::RtpExtension::kAbsoluteCaptureTimeUri ||
+ uri == webrtc::RtpExtension::kTransportSequenceNumberUri ||
+ uri == webrtc::RtpExtension::kTransportSequenceNumberV2Uri ||
+ uri == webrtc::RtpExtension::kMidUri ||
+ uri == webrtc::RtpExtension::kRidUri ||
+ uri == webrtc::RtpExtension::kRepairedRidUri ||
+ uri == webrtc::RtpExtension::kCsrcAudioLevelsUri;
+}
+
+bool RtpExtension::IsSupportedForVideo(absl::string_view uri) {
+ return uri == webrtc::RtpExtension::kTimestampOffsetUri ||
+ uri == webrtc::RtpExtension::kAbsSendTimeUri ||
+ uri == webrtc::RtpExtension::kAbsoluteCaptureTimeUri ||
+ uri == webrtc::RtpExtension::kVideoRotationUri ||
+ uri == webrtc::RtpExtension::kTransportSequenceNumberUri ||
+ uri == webrtc::RtpExtension::kTransportSequenceNumberV2Uri ||
+ uri == webrtc::RtpExtension::kPlayoutDelayUri ||
+ uri == webrtc::RtpExtension::kVideoContentTypeUri ||
+ uri == webrtc::RtpExtension::kVideoTimingUri ||
+ uri == webrtc::RtpExtension::kMidUri ||
+ uri == webrtc::RtpExtension::kGenericFrameDescriptorUri00 ||
+ uri == webrtc::RtpExtension::kDependencyDescriptorUri ||
+ uri == webrtc::RtpExtension::kColorSpaceUri ||
+ uri == webrtc::RtpExtension::kRidUri ||
+ uri == webrtc::RtpExtension::kRepairedRidUri ||
+ uri == webrtc::RtpExtension::kVideoLayersAllocationUri ||
+ uri == webrtc::RtpExtension::kVideoFrameTrackingIdUri;
+}
+
+bool RtpExtension::IsEncryptionSupported(absl::string_view uri) {
+ return
+#if defined(ENABLE_EXTERNAL_AUTH)
+ // TODO(jbauch): Figure out a way to always allow "kAbsSendTimeUri"
+ // here and filter out later if external auth is really used in
+ // srtpfilter. External auth is used by Chromium and replaces the
+ // extension header value of "kAbsSendTimeUri", so it must not be
+ // encrypted (which can't be done by Chromium).
+ uri != webrtc::RtpExtension::kAbsSendTimeUri &&
+#endif
+ uri != webrtc::RtpExtension::kEncryptHeaderExtensionsUri;
+}
+
+// Returns whether a header extension with the given URI exists.
+// Note: This does not differentiate between encrypted and non-encrypted
+// extensions, so use with care!
+static bool HeaderExtensionWithUriExists(
+ const std::vector<RtpExtension>& extensions,
+ absl::string_view uri) {
+ for (const auto& extension : extensions) {
+ if (extension.uri == uri) {
+ return true;
+ }
+ }
+ return false;
+}
+
+const RtpExtension* RtpExtension::FindHeaderExtensionByUri(
+ const std::vector<RtpExtension>& extensions,
+ absl::string_view uri,
+ Filter filter) {
+ const webrtc::RtpExtension* fallback_extension = nullptr;
+ for (const auto& extension : extensions) {
+ if (extension.uri != uri) {
+ continue;
+ }
+
+ switch (filter) {
+ case kDiscardEncryptedExtension:
+ // We only accept an unencrypted extension.
+ if (!extension.encrypt) {
+ return &extension;
+ }
+ break;
+
+ case kPreferEncryptedExtension:
+ // We prefer an encrypted extension but we can fall back to an
+ // unencrypted extension.
+ if (extension.encrypt) {
+ return &extension;
+ } else {
+ fallback_extension = &extension;
+ }
+ break;
+
+ case kRequireEncryptedExtension:
+ // We only accept an encrypted extension.
+ if (extension.encrypt) {
+ return &extension;
+ }
+ break;
+ }
+ }
+
+ // Returning fallback extension (if any)
+ return fallback_extension;
+}
+
+const RtpExtension* RtpExtension::FindHeaderExtensionByUriAndEncryption(
+ const std::vector<RtpExtension>& extensions,
+ absl::string_view uri,
+ bool encrypt) {
+ for (const auto& extension : extensions) {
+ if (extension.uri == uri && extension.encrypt == encrypt) {
+ return &extension;
+ }
+ }
+ return nullptr;
+}
+
+const std::vector<RtpExtension> RtpExtension::DeduplicateHeaderExtensions(
+ const std::vector<RtpExtension>& extensions,
+ Filter filter) {
+ std::vector<RtpExtension> filtered;
+
+ // If we do not discard encrypted extensions, add them first
+ if (filter != kDiscardEncryptedExtension) {
+ for (const auto& extension : extensions) {
+ if (!extension.encrypt) {
+ continue;
+ }
+ if (!HeaderExtensionWithUriExists(filtered, extension.uri)) {
+ filtered.push_back(extension);
+ }
+ }
+ }
+
+ // If we do not require encrypted extensions, add missing, non-encrypted
+ // extensions.
+ if (filter != kRequireEncryptedExtension) {
+ for (const auto& extension : extensions) {
+ if (extension.encrypt) {
+ continue;
+ }
+ if (!HeaderExtensionWithUriExists(filtered, extension.uri)) {
+ filtered.push_back(extension);
+ }
+ }
+ }
+
+ // Sort the returned vector to make comparisons of header extensions reliable.
+ // In order of priority, we sort by uri first, then encrypt and id last.
+ std::sort(filtered.begin(), filtered.end(),
+ [](const RtpExtension& a, const RtpExtension& b) {
+ return std::tie(a.uri, a.encrypt, a.id) <
+ std::tie(b.uri, b.encrypt, b.id);
+ });
+
+ return filtered;
+}
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/rtp_parameters.h b/third_party/libwebrtc/api/rtp_parameters.h
new file mode 100644
index 0000000000..0d3c9dfd22
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_parameters.h
@@ -0,0 +1,719 @@
+/*
+ * Copyright 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_RTP_PARAMETERS_H_
+#define API_RTP_PARAMETERS_H_
+
+#include <stdint.h>
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "absl/container/inlined_vector.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "api/media_types.h"
+#include "api/priority.h"
+#include "api/rtp_transceiver_direction.h"
+#include "api/video/resolution.h"
+#include "api/video_codecs/scalability_mode.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// These structures are intended to mirror those defined by:
+// http://draft.ortc.org/#rtcrtpdictionaries*
+// Contains everything specified as of 2017 Jan 24.
+//
+// They are used when retrieving or modifying the parameters of an
+// RtpSender/RtpReceiver, or retrieving capabilities.
+//
+// Note on conventions: Where ORTC may use "octet", "short" and "unsigned"
+// types, we typically use "int", in keeping with our style guidelines. The
+// parameter's actual valid range will be enforced when the parameters are set,
+// rather than when the parameters struct is built. An exception is made for
+// SSRCs, since they use the full unsigned 32-bit range, and aren't expected to
+// be used for any numeric comparisons/operations.
+//
+// Additionally, where ORTC uses strings, we may use enums for things that have
+// a fixed number of supported values. However, for things that can be extended
+// (such as codecs, by providing an external encoder factory), a string
+// identifier is used.
+
+enum class FecMechanism {
+ RED,
+ RED_AND_ULPFEC,
+ FLEXFEC,
+};
+
+// Used in RtcpFeedback struct.
+enum class RtcpFeedbackType {
+ CCM,
+ LNTF, // "goog-lntf"
+ NACK,
+ REMB, // "goog-remb"
+ TRANSPORT_CC,
+};
+
+// Used in RtcpFeedback struct when type is NACK or CCM.
+enum class RtcpFeedbackMessageType {
+ // Equivalent to {type: "nack", parameter: undefined} in ORTC.
+ GENERIC_NACK,
+ PLI, // Usable with NACK.
+ FIR, // Usable with CCM.
+};
+
+enum class DtxStatus {
+ DISABLED,
+ ENABLED,
+};
+
+// Based on the spec in
+// https://w3c.github.io/webrtc-pc/#idl-def-rtcdegradationpreference.
+// These options are enforced on a best-effort basis. For instance, all of
+// these options may suffer some frame drops in order to avoid queuing.
+// TODO(sprang): Look into possibility of more strictly enforcing the
+// maintain-framerate option.
+// TODO(deadbeef): Default to "balanced", as the spec indicates?
+enum class DegradationPreference {
+ // Don't take any actions based on over-utilization signals. Not part of the
+ // web API.
+ DISABLED,
+ // On over-use, request lower resolution, possibly causing down-scaling.
+ MAINTAIN_FRAMERATE,
+ // On over-use, request lower frame rate, possibly causing frame drops.
+ MAINTAIN_RESOLUTION,
+ // Try to strike a "pleasing" balance between frame rate or resolution.
+ BALANCED,
+};
+
+RTC_EXPORT const char* DegradationPreferenceToString(
+ DegradationPreference degradation_preference);
+
+RTC_EXPORT extern const double kDefaultBitratePriority;
+
+struct RTC_EXPORT RtcpFeedback {
+ RtcpFeedbackType type = RtcpFeedbackType::CCM;
+
+ // Equivalent to ORTC "parameter" field with slight differences:
+ // 1. It's an enum instead of a string.
+ // 2. Generic NACK feedback is represented by a GENERIC_NACK message type,
+ // rather than an unset "parameter" value.
+ absl::optional<RtcpFeedbackMessageType> message_type;
+
+ // Constructors for convenience.
+ RtcpFeedback();
+ explicit RtcpFeedback(RtcpFeedbackType type);
+ RtcpFeedback(RtcpFeedbackType type, RtcpFeedbackMessageType message_type);
+ RtcpFeedback(const RtcpFeedback&);
+ ~RtcpFeedback();
+
+ bool operator==(const RtcpFeedback& o) const {
+ return type == o.type && message_type == o.message_type;
+ }
+ bool operator!=(const RtcpFeedback& o) const { return !(*this == o); }
+};
+
+// RtpCodecCapability is to RtpCodecParameters as RtpCapabilities is to
+// RtpParameters. This represents the static capabilities of an endpoint's
+// implementation of a codec.
+struct RTC_EXPORT RtpCodecCapability {
+ RtpCodecCapability();
+ ~RtpCodecCapability();
+
+ // Build MIME "type/subtype" string from `name` and `kind`.
+ std::string mime_type() const { return MediaTypeToString(kind) + "/" + name; }
+
+ // Used to identify the codec. Equivalent to MIME subtype.
+ std::string name;
+
+ // The media type of this codec. Equivalent to MIME top-level type.
+ cricket::MediaType kind = cricket::MEDIA_TYPE_AUDIO;
+
+ // Clock rate in Hertz. If unset, the codec is applicable to any clock rate.
+ absl::optional<int> clock_rate;
+
+ // Default payload type for this codec. Mainly needed for codecs that use
+ // that have statically assigned payload types.
+ absl::optional<int> preferred_payload_type;
+
+ // Maximum packetization time supported by an RtpReceiver for this codec.
+ // TODO(deadbeef): Not implemented.
+ absl::optional<int> max_ptime;
+
+ // Preferred packetization time for an RtpReceiver or RtpSender of this codec.
+ // TODO(deadbeef): Not implemented.
+ absl::optional<int> ptime;
+
+ // The number of audio channels supported. Unused for video codecs.
+ absl::optional<int> num_channels;
+
+ // Feedback mechanisms supported for this codec.
+ std::vector<RtcpFeedback> rtcp_feedback;
+
+ // Codec-specific parameters that must be signaled to the remote party.
+ //
+ // Corresponds to "a=fmtp" parameters in SDP.
+ //
+ // Contrary to ORTC, these parameters are named using all lowercase strings.
+ // This helps make the mapping to SDP simpler, if an application is using SDP.
+ // Boolean values are represented by the string "1".
+ std::map<std::string, std::string> parameters;
+
+ // Codec-specific parameters that may optionally be signaled to the remote
+ // party.
+ // TODO(deadbeef): Not implemented.
+ std::map<std::string, std::string> options;
+
+ // Maximum number of temporal layer extensions supported by this codec.
+ // For example, a value of 1 indicates that 2 total layers are supported.
+ // TODO(deadbeef): Not implemented.
+ int max_temporal_layer_extensions = 0;
+
+ // Maximum number of spatial layer extensions supported by this codec.
+ // For example, a value of 1 indicates that 2 total layers are supported.
+ // TODO(deadbeef): Not implemented.
+ int max_spatial_layer_extensions = 0;
+
+ // Whether the implementation can send/receive SVC layers with distinct SSRCs.
+ // Always false for audio codecs. True for video codecs that support scalable
+ // video coding with MRST.
+ // TODO(deadbeef): Not implemented.
+ bool svc_multi_stream_support = false;
+
+ // https://w3c.github.io/webrtc-svc/#dom-rtcrtpcodeccapability-scalabilitymodes
+ absl::InlinedVector<ScalabilityMode, kScalabilityModeCount> scalability_modes;
+
+ bool operator==(const RtpCodecCapability& o) const {
+ return name == o.name && kind == o.kind && clock_rate == o.clock_rate &&
+ preferred_payload_type == o.preferred_payload_type &&
+ max_ptime == o.max_ptime && ptime == o.ptime &&
+ num_channels == o.num_channels && rtcp_feedback == o.rtcp_feedback &&
+ parameters == o.parameters && options == o.options &&
+ max_temporal_layer_extensions == o.max_temporal_layer_extensions &&
+ max_spatial_layer_extensions == o.max_spatial_layer_extensions &&
+ svc_multi_stream_support == o.svc_multi_stream_support &&
+ scalability_modes == o.scalability_modes;
+ }
+ bool operator!=(const RtpCodecCapability& o) const { return !(*this == o); }
+};
+
+// Used in RtpCapabilities and RtpTransceiverInterface's header extensions query
+// and setup methods; represents the capabilities/preferences of an
+// implementation for a header extension.
+//
+// Just called "RtpHeaderExtension" in ORTC, but the "Capability" suffix was
+// added here for consistency and to avoid confusion with
+// RtpHeaderExtensionParameters.
+//
+// Note that ORTC includes a "kind" field, but we omit this because it's
+// redundant; if you call "RtpReceiver::GetCapabilities(MEDIA_TYPE_AUDIO)",
+// you know you're getting audio capabilities.
+struct RTC_EXPORT RtpHeaderExtensionCapability {
+ // URI of this extension, as defined in RFC8285.
+ std::string uri;
+
+ // Preferred value of ID that goes in the packet.
+ absl::optional<int> preferred_id;
+
+ // If true, it's preferred that the value in the header is encrypted.
+ // TODO(deadbeef): Not implemented.
+ bool preferred_encrypt = false;
+
+ // The direction of the extension. The kStopped value is only used with
+ // RtpTransceiverInterface::HeaderExtensionsToOffer() and
+ // SetOfferedRtpHeaderExtensions().
+ RtpTransceiverDirection direction = RtpTransceiverDirection::kSendRecv;
+
+ // Constructors for convenience.
+ RtpHeaderExtensionCapability();
+ explicit RtpHeaderExtensionCapability(absl::string_view uri);
+ RtpHeaderExtensionCapability(absl::string_view uri, int preferred_id);
+ RtpHeaderExtensionCapability(absl::string_view uri,
+ int preferred_id,
+ RtpTransceiverDirection direction);
+ ~RtpHeaderExtensionCapability();
+
+ bool operator==(const RtpHeaderExtensionCapability& o) const {
+ return uri == o.uri && preferred_id == o.preferred_id &&
+ preferred_encrypt == o.preferred_encrypt && direction == o.direction;
+ }
+ bool operator!=(const RtpHeaderExtensionCapability& o) const {
+ return !(*this == o);
+ }
+};
+
+// RTP header extension, see RFC8285.
+struct RTC_EXPORT RtpExtension {
+ enum Filter {
+ // Encrypted extensions will be ignored and only non-encrypted extensions
+ // will be considered.
+ kDiscardEncryptedExtension,
+ // Encrypted extensions will be preferred but will fall back to
+ // non-encrypted extensions if necessary.
+ kPreferEncryptedExtension,
+ // Encrypted extensions will be required, so any non-encrypted extensions
+ // will be discarded.
+ kRequireEncryptedExtension,
+ };
+
+ RtpExtension();
+ RtpExtension(absl::string_view uri, int id);
+ RtpExtension(absl::string_view uri, int id, bool encrypt);
+ ~RtpExtension();
+
+ std::string ToString() const;
+ bool operator==(const RtpExtension& rhs) const {
+ return uri == rhs.uri && id == rhs.id && encrypt == rhs.encrypt;
+ }
+ static bool IsSupportedForAudio(absl::string_view uri);
+ static bool IsSupportedForVideo(absl::string_view uri);
+ // Return "true" if the given RTP header extension URI may be encrypted.
+ static bool IsEncryptionSupported(absl::string_view uri);
+
+ // Returns the header extension with the given URI or nullptr if not found.
+ static const RtpExtension* FindHeaderExtensionByUri(
+ const std::vector<RtpExtension>& extensions,
+ absl::string_view uri,
+ Filter filter);
+
+ // Returns the header extension with the given URI and encrypt parameter,
+ // if found, otherwise nullptr.
+ static const RtpExtension* FindHeaderExtensionByUriAndEncryption(
+ const std::vector<RtpExtension>& extensions,
+ absl::string_view uri,
+ bool encrypt);
+
+ // Returns a list of extensions where any extension URI is unique.
+ // The returned list will be sorted by uri first, then encrypt and id last.
+ // Having the list sorted allows the caller fo compare filtered lists for
+ // equality to detect when changes have been made.
+ static const std::vector<RtpExtension> DeduplicateHeaderExtensions(
+ const std::vector<RtpExtension>& extensions,
+ Filter filter);
+
+ // Encryption of Header Extensions, see RFC 6904 for details:
+ // https://tools.ietf.org/html/rfc6904
+ static constexpr char kEncryptHeaderExtensionsUri[] =
+ "urn:ietf:params:rtp-hdrext:encrypt";
+
+ // Header extension for audio levels, as defined in:
+ // https://tools.ietf.org/html/rfc6464
+ static constexpr char kAudioLevelUri[] =
+ "urn:ietf:params:rtp-hdrext:ssrc-audio-level";
+
+ // Header extension for RTP timestamp offset, see RFC 5450 for details:
+ // http://tools.ietf.org/html/rfc5450
+ static constexpr char kTimestampOffsetUri[] =
+ "urn:ietf:params:rtp-hdrext:toffset";
+
+ // Header extension for absolute send time, see url for details:
+ // http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
+ static constexpr char kAbsSendTimeUri[] =
+ "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time";
+
+ // Header extension for absolute capture time, see url for details:
+ // http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time
+ static constexpr char kAbsoluteCaptureTimeUri[] =
+ "http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time";
+
+ // Header extension for coordination of video orientation, see url for
+ // details:
+ // http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/ts_126114v120700p.pdf
+ static constexpr char kVideoRotationUri[] = "urn:3gpp:video-orientation";
+
+ // Header extension for video content type. E.g. default or screenshare.
+ static constexpr char kVideoContentTypeUri[] =
+ "http://www.webrtc.org/experiments/rtp-hdrext/video-content-type";
+
+ // Header extension for video timing.
+ static constexpr char kVideoTimingUri[] =
+ "http://www.webrtc.org/experiments/rtp-hdrext/video-timing";
+
+ // Experimental codec agnostic frame descriptor.
+ static constexpr char kGenericFrameDescriptorUri00[] =
+ "http://www.webrtc.org/experiments/rtp-hdrext/"
+ "generic-frame-descriptor-00";
+ static constexpr char kDependencyDescriptorUri[] =
+ "https://aomediacodec.github.io/av1-rtp-spec/"
+ "#dependency-descriptor-rtp-header-extension";
+
+ // Experimental extension for signalling target bitrate per layer.
+ static constexpr char kVideoLayersAllocationUri[] =
+ "http://www.webrtc.org/experiments/rtp-hdrext/video-layers-allocation00";
+
+ // Header extension for transport sequence number, see url for details:
+ // http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions
+ static constexpr char kTransportSequenceNumberUri[] =
+ "http://www.ietf.org/id/"
+ "draft-holmer-rmcat-transport-wide-cc-extensions-01";
+ static constexpr char kTransportSequenceNumberV2Uri[] =
+ "http://www.webrtc.org/experiments/rtp-hdrext/transport-wide-cc-02";
+
+ // This extension allows applications to adaptively limit the playout delay
+ // on frames as per the current needs. For example, a gaming application
+ // has very different needs on end-to-end delay compared to a video-conference
+ // application.
+ static constexpr char kPlayoutDelayUri[] =
+ "http://www.webrtc.org/experiments/rtp-hdrext/playout-delay";
+
+ // Header extension for color space information.
+ static constexpr char kColorSpaceUri[] =
+ "http://www.webrtc.org/experiments/rtp-hdrext/color-space";
+
+ // Header extension for identifying media section within a transport.
+ // https://tools.ietf.org/html/draft-ietf-mmusic-sdp-bundle-negotiation-49#section-15
+ static constexpr char kMidUri[] = "urn:ietf:params:rtp-hdrext:sdes:mid";
+
+ // Header extension for RIDs and Repaired RIDs
+ // https://tools.ietf.org/html/draft-ietf-avtext-rid-09
+ // https://tools.ietf.org/html/draft-ietf-mmusic-rid-15
+ static constexpr char kRidUri[] =
+ "urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id";
+ static constexpr char kRepairedRidUri[] =
+ "urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id";
+
+ // Header extension to propagate webrtc::VideoFrame id field
+ static constexpr char kVideoFrameTrackingIdUri[] =
+ "http://www.webrtc.org/experiments/rtp-hdrext/video-frame-tracking-id";
+
+ // Header extension for Mixer-to-Client audio levels per CSRC as defined in
+ // https://tools.ietf.org/html/rfc6465
+ static constexpr char kCsrcAudioLevelsUri[] =
+ "urn:ietf:params:rtp-hdrext:csrc-audio-level";
+
+ // Inclusive min and max IDs for two-byte header extensions and one-byte
+ // header extensions, per RFC8285 Section 4.2-4.3.
+ static constexpr int kMinId = 1;
+ static constexpr int kMaxId = 255;
+ static constexpr int kMaxValueSize = 255;
+ static constexpr int kOneByteHeaderExtensionMaxId = 14;
+ static constexpr int kOneByteHeaderExtensionMaxValueSize = 16;
+
+ std::string uri;
+ int id = 0;
+ bool encrypt = false;
+};
+
+struct RTC_EXPORT RtpFecParameters {
+ // If unset, a value is chosen by the implementation.
+ // Works just like RtpEncodingParameters::ssrc.
+ absl::optional<uint32_t> ssrc;
+
+ FecMechanism mechanism = FecMechanism::RED;
+
+ // Constructors for convenience.
+ RtpFecParameters();
+ explicit RtpFecParameters(FecMechanism mechanism);
+ RtpFecParameters(FecMechanism mechanism, uint32_t ssrc);
+ RtpFecParameters(const RtpFecParameters&);
+ ~RtpFecParameters();
+
+ bool operator==(const RtpFecParameters& o) const {
+ return ssrc == o.ssrc && mechanism == o.mechanism;
+ }
+ bool operator!=(const RtpFecParameters& o) const { return !(*this == o); }
+};
+
+struct RTC_EXPORT RtpRtxParameters {
+ // If unset, a value is chosen by the implementation.
+ // Works just like RtpEncodingParameters::ssrc.
+ absl::optional<uint32_t> ssrc;
+
+ // Constructors for convenience.
+ RtpRtxParameters();
+ explicit RtpRtxParameters(uint32_t ssrc);
+ RtpRtxParameters(const RtpRtxParameters&);
+ ~RtpRtxParameters();
+
+ bool operator==(const RtpRtxParameters& o) const { return ssrc == o.ssrc; }
+ bool operator!=(const RtpRtxParameters& o) const { return !(*this == o); }
+};
+
+struct RTC_EXPORT RtpEncodingParameters {
+ RtpEncodingParameters();
+ RtpEncodingParameters(const RtpEncodingParameters&);
+ ~RtpEncodingParameters();
+
+ // If unset, a value is chosen by the implementation.
+ //
+ // Note that the chosen value is NOT returned by GetParameters, because it
+ // may change due to an SSRC conflict, in which case the conflict is handled
+ // internally without any event. Another way of looking at this is that an
+ // unset SSRC acts as a "wildcard" SSRC.
+ absl::optional<uint32_t> ssrc;
+
+ // The relative bitrate priority of this encoding. Currently this is
+ // implemented for the entire rtp sender by using the value of the first
+ // encoding parameter.
+ // See: https://w3c.github.io/webrtc-priority/#enumdef-rtcprioritytype
+ // "very-low" = 0.5
+ // "low" = 1.0
+ // "medium" = 2.0
+ // "high" = 4.0
+ // TODO(webrtc.bugs.org/8630): Implement this per encoding parameter.
+ // Currently there is logic for how bitrate is distributed per simulcast layer
+ // in the VideoBitrateAllocator. This must be updated to incorporate relative
+ // bitrate priority.
+ double bitrate_priority = kDefaultBitratePriority;
+
+ // The relative DiffServ Code Point priority for this encoding, allowing
+ // packets to be marked relatively higher or lower without affecting
+ // bandwidth allocations. See https://w3c.github.io/webrtc-dscp-exp/ .
+ // TODO(http://crbug.com/webrtc/8630): Implement this per encoding parameter.
+ // TODO(http://crbug.com/webrtc/11379): TCP connections should use a single
+ // DSCP value even if shared by multiple senders; this is not implemented.
+ Priority network_priority = Priority::kLow;
+
+ // If set, this represents the Transport Independent Application Specific
+ // maximum bandwidth defined in RFC3890. If unset, there is no maximum
+ // bitrate. Currently this is implemented for the entire rtp sender by using
+ // the value of the first encoding parameter.
+ //
+ // Just called "maxBitrate" in ORTC spec.
+ //
+ // TODO(deadbeef): With ORTC RtpSenders, this currently sets the total
+ // bandwidth for the entire bandwidth estimator (audio and video). This is
+ // just always how "b=AS" was handled, but it's not correct and should be
+ // fixed.
+ absl::optional<int> max_bitrate_bps;
+
+ // Specifies the minimum bitrate in bps for video.
+ absl::optional<int> min_bitrate_bps;
+
+ // Specifies the maximum framerate in fps for video.
+ absl::optional<double> max_framerate;
+
+ // Specifies the number of temporal layers for video (if the feature is
+ // supported by the codec implementation).
+ // Screencast support is experimental.
+ absl::optional<int> num_temporal_layers;
+
+ // For video, scale the resolution down by this factor.
+ absl::optional<double> scale_resolution_down_by;
+
+ // https://w3c.github.io/webrtc-svc/#rtcrtpencodingparameters
+ absl::optional<std::string> scalability_mode;
+
+ // Requested encode resolution.
+ //
+ // This field provides an alternative to `scale_resolution_down_by`
+ // that is not dependent on the video source.
+ //
+ // When setting requested_resolution it is not necessary to adapt the
+ // video source using OnOutputFormatRequest, since the VideoStreamEncoder
+ // will apply downscaling if necessary. requested_resolution will also be
+ // propagated to the video source, this allows downscaling earlier in the
+ // pipeline which can be beneficial if the source is consumed by multiple
+ // encoders, but is not strictly necessary.
+ //
+ // The `requested_resolution` is subject to resource adaptation.
+ //
+ // It is an error to set both `requested_resolution` and
+ // `scale_resolution_down_by`.
+ absl::optional<Resolution> requested_resolution;
+
+ // For an RtpSender, set to true to cause this encoding to be encoded and
+ // sent, and false for it not to be encoded and sent. This allows control
+ // across multiple encodings of a sender for turning simulcast layers on and
+ // off.
+ // TODO(webrtc.bugs.org/8807): Updating this parameter will trigger an encoder
+ // reset, but this isn't necessarily required.
+ bool active = true;
+
+ // Value to use for RID RTP header extension.
+ // Called "encodingId" in ORTC.
+ std::string rid;
+
+ // Allow dynamic frame length changes for audio:
+ // https://w3c.github.io/webrtc-extensions/#dom-rtcrtpencodingparameters-adaptiveptime
+ bool adaptive_ptime = false;
+
+ bool operator==(const RtpEncodingParameters& o) const {
+ return ssrc == o.ssrc && bitrate_priority == o.bitrate_priority &&
+ network_priority == o.network_priority &&
+ max_bitrate_bps == o.max_bitrate_bps &&
+ min_bitrate_bps == o.min_bitrate_bps &&
+ max_framerate == o.max_framerate &&
+ num_temporal_layers == o.num_temporal_layers &&
+ scale_resolution_down_by == o.scale_resolution_down_by &&
+ active == o.active && rid == o.rid &&
+ adaptive_ptime == o.adaptive_ptime &&
+ requested_resolution == o.requested_resolution;
+ }
+ bool operator!=(const RtpEncodingParameters& o) const {
+ return !(*this == o);
+ }
+};
+
+struct RTC_EXPORT RtpCodecParameters {
+ RtpCodecParameters();
+ RtpCodecParameters(const RtpCodecParameters&);
+ ~RtpCodecParameters();
+
+ // Build MIME "type/subtype" string from `name` and `kind`.
+ std::string mime_type() const { return MediaTypeToString(kind) + "/" + name; }
+
+ // Used to identify the codec. Equivalent to MIME subtype.
+ std::string name;
+
+ // The media type of this codec. Equivalent to MIME top-level type.
+ cricket::MediaType kind = cricket::MEDIA_TYPE_AUDIO;
+
+ // Payload type used to identify this codec in RTP packets.
+ // This must always be present, and must be unique across all codecs using
+ // the same transport.
+ int payload_type = 0;
+
+ // If unset, the implementation default is used.
+ absl::optional<int> clock_rate;
+
+ // The number of audio channels used. Unset for video codecs. If unset for
+ // audio, the implementation default is used.
+ // TODO(deadbeef): The "implementation default" part isn't fully implemented.
+ // Only defaults to 1, even though some codecs (such as opus) should really
+ // default to 2.
+ absl::optional<int> num_channels;
+
+ // The maximum packetization time to be used by an RtpSender.
+ // If `ptime` is also set, this will be ignored.
+ // TODO(deadbeef): Not implemented.
+ absl::optional<int> max_ptime;
+
+ // The packetization time to be used by an RtpSender.
+ // If unset, will use any time up to max_ptime.
+ // TODO(deadbeef): Not implemented.
+ absl::optional<int> ptime;
+
+ // Feedback mechanisms to be used for this codec.
+ // TODO(deadbeef): Not implemented with PeerConnection senders/receivers.
+ std::vector<RtcpFeedback> rtcp_feedback;
+
+ // Codec-specific parameters that must be signaled to the remote party.
+ //
+ // Corresponds to "a=fmtp" parameters in SDP.
+ //
+ // Contrary to ORTC, these parameters are named using all lowercase strings.
+ // This helps make the mapping to SDP simpler, if an application is using SDP.
+ // Boolean values are represented by the string "1".
+ std::map<std::string, std::string> parameters;
+
+ bool operator==(const RtpCodecParameters& o) const {
+ return name == o.name && kind == o.kind && payload_type == o.payload_type &&
+ clock_rate == o.clock_rate && num_channels == o.num_channels &&
+ max_ptime == o.max_ptime && ptime == o.ptime &&
+ rtcp_feedback == o.rtcp_feedback && parameters == o.parameters;
+ }
+ bool operator!=(const RtpCodecParameters& o) const { return !(*this == o); }
+};
+
+// RtpCapabilities is used to represent the static capabilities of an endpoint.
+// An application can use these capabilities to construct an RtpParameters.
+struct RTC_EXPORT RtpCapabilities {
+ RtpCapabilities();
+ ~RtpCapabilities();
+
+ // Supported codecs.
+ std::vector<RtpCodecCapability> codecs;
+
+ // Supported RTP header extensions.
+ std::vector<RtpHeaderExtensionCapability> header_extensions;
+
+ // Supported Forward Error Correction (FEC) mechanisms. Note that the RED,
+ // ulpfec and flexfec codecs used by these mechanisms will still appear in
+ // `codecs`.
+ std::vector<FecMechanism> fec;
+
+ bool operator==(const RtpCapabilities& o) const {
+ return codecs == o.codecs && header_extensions == o.header_extensions &&
+ fec == o.fec;
+ }
+ bool operator!=(const RtpCapabilities& o) const { return !(*this == o); }
+};
+
+struct RtcpParameters final {
+ RtcpParameters();
+ RtcpParameters(const RtcpParameters&);
+ ~RtcpParameters();
+
+ // The SSRC to be used in the "SSRC of packet sender" field. If not set, one
+ // will be chosen by the implementation.
+ // TODO(deadbeef): Not implemented.
+ absl::optional<uint32_t> ssrc;
+
+ // The Canonical Name (CNAME) used by RTCP (e.g. in SDES messages).
+ //
+ // If empty in the construction of the RtpTransport, one will be generated by
+ // the implementation, and returned in GetRtcpParameters. Multiple
+ // RtpTransports created by the same OrtcFactory will use the same generated
+ // CNAME.
+ //
+ // If empty when passed into SetParameters, the CNAME simply won't be
+ // modified.
+ std::string cname;
+
+ // Send reduced-size RTCP?
+ bool reduced_size = false;
+
+ // Send RTCP multiplexed on the RTP transport?
+ // Not used with PeerConnection senders/receivers
+ bool mux = true;
+
+ bool operator==(const RtcpParameters& o) const {
+ return ssrc == o.ssrc && cname == o.cname &&
+ reduced_size == o.reduced_size && mux == o.mux;
+ }
+ bool operator!=(const RtcpParameters& o) const { return !(*this == o); }
+};
+
+struct RTC_EXPORT RtpParameters {
+ RtpParameters();
+ RtpParameters(const RtpParameters&);
+ ~RtpParameters();
+
+ // Used when calling getParameters/setParameters with a PeerConnection
+ // RtpSender, to ensure that outdated parameters are not unintentionally
+ // applied successfully.
+ std::string transaction_id;
+
+ // Value to use for MID RTP header extension.
+ // Called "muxId" in ORTC.
+ // TODO(deadbeef): Not implemented.
+ std::string mid;
+
+ std::vector<RtpCodecParameters> codecs;
+
+ std::vector<RtpExtension> header_extensions;
+
+ std::vector<RtpEncodingParameters> encodings;
+
+ // Only available with a Peerconnection RtpSender.
+ // In ORTC, our API includes an additional "RtpTransport"
+ // abstraction on which RTCP parameters are set.
+ RtcpParameters rtcp;
+
+ // When bandwidth is constrained and the RtpSender needs to choose between
+ // degrading resolution or degrading framerate, degradationPreference
+ // indicates which is preferred. Only for video tracks.
+ absl::optional<DegradationPreference> degradation_preference;
+
+ bool operator==(const RtpParameters& o) const {
+ return mid == o.mid && codecs == o.codecs &&
+ header_extensions == o.header_extensions &&
+ encodings == o.encodings && rtcp == o.rtcp &&
+ degradation_preference == o.degradation_preference;
+ }
+ bool operator!=(const RtpParameters& o) const { return !(*this == o); }
+};
+
+} // namespace webrtc
+
+#endif // API_RTP_PARAMETERS_H_
diff --git a/third_party/libwebrtc/api/rtp_parameters_gn/moz.build b/third_party/libwebrtc/api/rtp_parameters_gn/moz.build
new file mode 100644
index 0000000000..4dc6e4a743
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_parameters_gn/moz.build
@@ -0,0 +1,222 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/media_types.cc",
+ "/third_party/libwebrtc/api/rtp_parameters.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("rtp_parameters_gn")
diff --git a/third_party/libwebrtc/api/rtp_parameters_unittest.cc b/third_party/libwebrtc/api/rtp_parameters_unittest.cc
new file mode 100644
index 0000000000..234c3c9b6d
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_parameters_unittest.cc
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/rtp_parameters.h"
+
+#include "test/gtest.h"
+
+namespace webrtc {
+
+using webrtc::RtpExtension;
+
+static const char kExtensionUri1[] = "extension-uri1";
+static const char kExtensionUri2[] = "extension-uri2";
+
+static const RtpExtension kExtension1(kExtensionUri1, 1);
+static const RtpExtension kExtension1Encrypted(kExtensionUri1, 10, true);
+static const RtpExtension kExtension2(kExtensionUri2, 2);
+
+TEST(RtpExtensionTest, DeduplicateHeaderExtensions) {
+ std::vector<RtpExtension> extensions;
+ std::vector<RtpExtension> filtered;
+
+ extensions.clear();
+ extensions.push_back(kExtension1);
+ extensions.push_back(kExtension1Encrypted);
+ filtered = RtpExtension::DeduplicateHeaderExtensions(
+ extensions, RtpExtension::Filter::kDiscardEncryptedExtension);
+ EXPECT_EQ(1u, filtered.size());
+ EXPECT_EQ(std::vector<RtpExtension>{kExtension1}, filtered);
+
+ extensions.clear();
+ extensions.push_back(kExtension1);
+ extensions.push_back(kExtension1Encrypted);
+ filtered = RtpExtension::DeduplicateHeaderExtensions(
+ extensions, RtpExtension::Filter::kPreferEncryptedExtension);
+ EXPECT_EQ(1u, filtered.size());
+ EXPECT_EQ(std::vector<RtpExtension>{kExtension1Encrypted}, filtered);
+
+ extensions.clear();
+ extensions.push_back(kExtension1);
+ extensions.push_back(kExtension1Encrypted);
+ filtered = RtpExtension::DeduplicateHeaderExtensions(
+ extensions, RtpExtension::Filter::kRequireEncryptedExtension);
+ EXPECT_EQ(1u, filtered.size());
+ EXPECT_EQ(std::vector<RtpExtension>{kExtension1Encrypted}, filtered);
+
+ extensions.clear();
+ extensions.push_back(kExtension1Encrypted);
+ extensions.push_back(kExtension1);
+ filtered = RtpExtension::DeduplicateHeaderExtensions(
+ extensions, RtpExtension::Filter::kDiscardEncryptedExtension);
+ EXPECT_EQ(1u, filtered.size());
+ EXPECT_EQ(std::vector<RtpExtension>{kExtension1}, filtered);
+
+ extensions.clear();
+ extensions.push_back(kExtension1Encrypted);
+ extensions.push_back(kExtension1);
+ filtered = RtpExtension::DeduplicateHeaderExtensions(
+ extensions, RtpExtension::Filter::kPreferEncryptedExtension);
+ EXPECT_EQ(1u, filtered.size());
+ EXPECT_EQ(std::vector<RtpExtension>{kExtension1Encrypted}, filtered);
+
+ extensions.clear();
+ extensions.push_back(kExtension1Encrypted);
+ extensions.push_back(kExtension1);
+ filtered = RtpExtension::DeduplicateHeaderExtensions(
+ extensions, RtpExtension::Filter::kRequireEncryptedExtension);
+ EXPECT_EQ(1u, filtered.size());
+ EXPECT_EQ(std::vector<RtpExtension>{kExtension1Encrypted}, filtered);
+
+ extensions.clear();
+ extensions.push_back(kExtension1);
+ extensions.push_back(kExtension2);
+ filtered = RtpExtension::DeduplicateHeaderExtensions(
+ extensions, RtpExtension::Filter::kDiscardEncryptedExtension);
+ EXPECT_EQ(2u, filtered.size());
+ EXPECT_EQ(extensions, filtered);
+ filtered = RtpExtension::DeduplicateHeaderExtensions(
+ extensions, RtpExtension::Filter::kPreferEncryptedExtension);
+ EXPECT_EQ(2u, filtered.size());
+ EXPECT_EQ(extensions, filtered);
+ filtered = RtpExtension::DeduplicateHeaderExtensions(
+ extensions, RtpExtension::Filter::kRequireEncryptedExtension);
+ EXPECT_EQ(0u, filtered.size());
+
+ extensions.clear();
+ extensions.push_back(kExtension1);
+ extensions.push_back(kExtension2);
+ extensions.push_back(kExtension1Encrypted);
+ filtered = RtpExtension::DeduplicateHeaderExtensions(
+ extensions, RtpExtension::Filter::kDiscardEncryptedExtension);
+ EXPECT_EQ(2u, filtered.size());
+ EXPECT_EQ((std::vector<RtpExtension>{kExtension1, kExtension2}), filtered);
+ filtered = RtpExtension::DeduplicateHeaderExtensions(
+ extensions, RtpExtension::Filter::kPreferEncryptedExtension);
+ EXPECT_EQ(2u, filtered.size());
+ EXPECT_EQ((std::vector<RtpExtension>{kExtension1Encrypted, kExtension2}),
+ filtered);
+ filtered = RtpExtension::DeduplicateHeaderExtensions(
+ extensions, RtpExtension::Filter::kRequireEncryptedExtension);
+ EXPECT_EQ(1u, filtered.size());
+ EXPECT_EQ((std::vector<RtpExtension>{kExtension1Encrypted}), filtered);
+}
+
+// Test that the filtered vector is sorted so that for a given unsorted array of
+// extensions, the filtered vector will always be laied out the same (for easy
+// comparison).
+TEST(RtpExtensionTest, DeduplicateHeaderExtensionsSorted) {
+ const std::vector<RtpExtension> extensions = {
+ RtpExtension("cde1", 11, false), RtpExtension("cde2", 12, true),
+ RtpExtension("abc1", 3, false), RtpExtension("abc2", 4, true),
+ RtpExtension("cde3", 9, true), RtpExtension("cde4", 10, false),
+ RtpExtension("abc3", 1, true), RtpExtension("abc4", 2, false),
+ RtpExtension("bcd3", 7, false), RtpExtension("bcd1", 8, true),
+ RtpExtension("bcd2", 5, true), RtpExtension("bcd4", 6, false),
+ };
+
+ auto encrypted = RtpExtension::DeduplicateHeaderExtensions(
+ extensions, RtpExtension::Filter::kRequireEncryptedExtension);
+
+ const std::vector<RtpExtension> expected_sorted_encrypted = {
+ RtpExtension("abc2", 4, true), RtpExtension("abc3", 1, true),
+ RtpExtension("bcd1", 8, true), RtpExtension("bcd2", 5, true),
+ RtpExtension("cde2", 12, true), RtpExtension("cde3", 9, true)};
+ EXPECT_EQ(expected_sorted_encrypted, encrypted);
+
+ auto unencypted = RtpExtension::DeduplicateHeaderExtensions(
+ extensions, RtpExtension::Filter::kDiscardEncryptedExtension);
+
+ const std::vector<RtpExtension> expected_sorted_unencrypted = {
+ RtpExtension("abc1", 3, false), RtpExtension("abc4", 2, false),
+ RtpExtension("bcd3", 7, false), RtpExtension("bcd4", 6, false),
+ RtpExtension("cde1", 11, false), RtpExtension("cde4", 10, false)};
+ EXPECT_EQ(expected_sorted_unencrypted, unencypted);
+}
+
+TEST(RtpExtensionTest, FindHeaderExtensionByUriAndEncryption) {
+ std::vector<RtpExtension> extensions;
+
+ extensions.clear();
+ EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUriAndEncryption(
+ extensions, kExtensionUri1, false));
+
+ extensions.clear();
+ extensions.push_back(kExtension1);
+ EXPECT_EQ(kExtension1, *RtpExtension::FindHeaderExtensionByUriAndEncryption(
+ extensions, kExtensionUri1, false));
+ EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUriAndEncryption(
+ extensions, kExtensionUri1, true));
+ EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUriAndEncryption(
+ extensions, kExtensionUri2, false));
+
+ extensions.clear();
+ extensions.push_back(kExtension1);
+ extensions.push_back(kExtension2);
+ extensions.push_back(kExtension1Encrypted);
+ EXPECT_EQ(kExtension1, *RtpExtension::FindHeaderExtensionByUriAndEncryption(
+ extensions, kExtensionUri1, false));
+ EXPECT_EQ(kExtension2, *RtpExtension::FindHeaderExtensionByUriAndEncryption(
+ extensions, kExtensionUri2, false));
+ EXPECT_EQ(kExtension1Encrypted,
+ *RtpExtension::FindHeaderExtensionByUriAndEncryption(
+ extensions, kExtensionUri1, true));
+ EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUriAndEncryption(
+ extensions, kExtensionUri2, true));
+}
+
+TEST(RtpExtensionTest, FindHeaderExtensionByUri) {
+ std::vector<RtpExtension> extensions;
+
+ extensions.clear();
+ EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri1,
+ RtpExtension::Filter::kDiscardEncryptedExtension));
+ EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri1,
+ RtpExtension::Filter::kPreferEncryptedExtension));
+ EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri1,
+ RtpExtension::Filter::kRequireEncryptedExtension));
+
+ extensions.clear();
+ extensions.push_back(kExtension1);
+ EXPECT_EQ(kExtension1, *RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri1,
+ RtpExtension::Filter::kDiscardEncryptedExtension));
+ EXPECT_EQ(kExtension1, *RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri1,
+ RtpExtension::Filter::kPreferEncryptedExtension));
+ EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri1,
+ RtpExtension::Filter::kRequireEncryptedExtension));
+ EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri2,
+ RtpExtension::Filter::kDiscardEncryptedExtension));
+ EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri2,
+ RtpExtension::Filter::kPreferEncryptedExtension));
+ EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri2,
+ RtpExtension::Filter::kRequireEncryptedExtension));
+
+ extensions.clear();
+ extensions.push_back(kExtension1);
+ extensions.push_back(kExtension1Encrypted);
+ EXPECT_EQ(kExtension1, *RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri1,
+ RtpExtension::Filter::kDiscardEncryptedExtension));
+
+ extensions.clear();
+ extensions.push_back(kExtension1);
+ extensions.push_back(kExtension1Encrypted);
+ EXPECT_EQ(kExtension1Encrypted,
+ *RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri1,
+ RtpExtension::Filter::kPreferEncryptedExtension));
+
+ extensions.clear();
+ extensions.push_back(kExtension1);
+ extensions.push_back(kExtension1Encrypted);
+ EXPECT_EQ(kExtension1Encrypted,
+ *RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri1,
+ RtpExtension::Filter::kRequireEncryptedExtension));
+
+ extensions.clear();
+ extensions.push_back(kExtension1Encrypted);
+ extensions.push_back(kExtension1);
+ EXPECT_EQ(kExtension1, *RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri1,
+ RtpExtension::Filter::kDiscardEncryptedExtension));
+
+ extensions.clear();
+ extensions.push_back(kExtension1Encrypted);
+ extensions.push_back(kExtension1);
+ EXPECT_EQ(kExtension1Encrypted,
+ *RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri1,
+ RtpExtension::Filter::kPreferEncryptedExtension));
+
+ extensions.clear();
+ extensions.push_back(kExtension1Encrypted);
+ extensions.push_back(kExtension1);
+ EXPECT_EQ(kExtension1Encrypted,
+ *RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri1,
+ RtpExtension::Filter::kRequireEncryptedExtension));
+
+ extensions.clear();
+ extensions.push_back(kExtension1);
+ extensions.push_back(kExtension2);
+ EXPECT_EQ(kExtension1, *RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri1,
+ RtpExtension::Filter::kDiscardEncryptedExtension));
+ EXPECT_EQ(kExtension1, *RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri1,
+ RtpExtension::Filter::kPreferEncryptedExtension));
+ EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri1,
+ RtpExtension::Filter::kRequireEncryptedExtension));
+ EXPECT_EQ(kExtension2, *RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri2,
+ RtpExtension::Filter::kDiscardEncryptedExtension));
+ EXPECT_EQ(kExtension2, *RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri2,
+ RtpExtension::Filter::kPreferEncryptedExtension));
+ EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri2,
+ RtpExtension::Filter::kRequireEncryptedExtension));
+
+ extensions.clear();
+ extensions.push_back(kExtension1);
+ extensions.push_back(kExtension2);
+ extensions.push_back(kExtension1Encrypted);
+ EXPECT_EQ(kExtension1, *RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri1,
+ RtpExtension::Filter::kDiscardEncryptedExtension));
+ EXPECT_EQ(kExtension1Encrypted,
+ *RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri1,
+ RtpExtension::Filter::kPreferEncryptedExtension));
+ EXPECT_EQ(kExtension1Encrypted,
+ *RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri1,
+ RtpExtension::Filter::kRequireEncryptedExtension));
+ EXPECT_EQ(kExtension2, *RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri2,
+ RtpExtension::Filter::kDiscardEncryptedExtension));
+ EXPECT_EQ(kExtension2, *RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri2,
+ RtpExtension::Filter::kPreferEncryptedExtension));
+ EXPECT_EQ(nullptr, RtpExtension::FindHeaderExtensionByUri(
+ extensions, kExtensionUri2,
+ RtpExtension::Filter::kRequireEncryptedExtension));
+}
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/rtp_receiver_interface.cc b/third_party/libwebrtc/api/rtp_receiver_interface.cc
new file mode 100644
index 0000000000..bc9aef5aef
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_receiver_interface.cc
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2018 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/rtp_receiver_interface.h"
+
+namespace webrtc {
+
+std::vector<std::string> RtpReceiverInterface::stream_ids() const {
+ return {};
+}
+
+std::vector<rtc::scoped_refptr<MediaStreamInterface>>
+RtpReceiverInterface::streams() const {
+ return {};
+}
+
+std::vector<RtpSource> RtpReceiverInterface::GetSources() const {
+ return {};
+}
+
+void RtpReceiverInterface::SetFrameDecryptor(
+ rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) {}
+
+rtc::scoped_refptr<FrameDecryptorInterface>
+RtpReceiverInterface::GetFrameDecryptor() const {
+ return nullptr;
+}
+
+rtc::scoped_refptr<DtlsTransportInterface>
+RtpReceiverInterface::dtls_transport() const {
+ return nullptr;
+}
+
+void RtpReceiverInterface::SetDepacketizerToDecoderFrameTransformer(
+ rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) {}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/rtp_receiver_interface.h b/third_party/libwebrtc/api/rtp_receiver_interface.h
new file mode 100644
index 0000000000..e4ec9b5986
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_receiver_interface.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This file contains interfaces for RtpReceivers
+// http://w3c.github.io/webrtc-pc/#rtcrtpreceiver-interface
+
+#ifndef API_RTP_RECEIVER_INTERFACE_H_
+#define API_RTP_RECEIVER_INTERFACE_H_
+
+#include <string>
+#include <vector>
+
+#include "api/crypto/frame_decryptor_interface.h"
+#include "api/dtls_transport_interface.h"
+#include "api/frame_transformer_interface.h"
+#include "api/media_stream_interface.h"
+#include "api/media_types.h"
+#include "api/rtp_parameters.h"
+#include "api/scoped_refptr.h"
+#include "api/transport/rtp/rtp_source.h"
+#include "rtc_base/ref_count.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+class RtpReceiverObserverInterface {
+ public:
+ // Note: Currently if there are multiple RtpReceivers of the same media type,
+ // they will all call OnFirstPacketReceived at once.
+ //
+ // In the future, it's likely that an RtpReceiver will only call
+ // OnFirstPacketReceived when a packet is received specifically for its
+ // SSRC/mid.
+ virtual void OnFirstPacketReceived(cricket::MediaType media_type) = 0;
+
+ protected:
+ virtual ~RtpReceiverObserverInterface() {}
+};
+
+class RTC_EXPORT RtpReceiverInterface : public rtc::RefCountInterface {
+ public:
+ virtual rtc::scoped_refptr<MediaStreamTrackInterface> track() const = 0;
+
+ // The dtlsTransport attribute exposes the DTLS transport on which the
+ // media is received. It may be null.
+ // https://w3c.github.io/webrtc-pc/#dom-rtcrtpreceiver-transport
+ // TODO(https://bugs.webrtc.org/907849) remove default implementation
+ virtual rtc::scoped_refptr<DtlsTransportInterface> dtls_transport() const;
+
+ // The list of streams that `track` is associated with. This is the same as
+ // the [[AssociatedRemoteMediaStreams]] internal slot in the spec.
+ // https://w3c.github.io/webrtc-pc/#dfn-associatedremotemediastreams
+ // TODO(hbos): Make pure virtual as soon as Chromium's mock implements this.
+ // TODO(https://crbug.com/webrtc/9480): Remove streams() in favor of
+ // stream_ids() as soon as downstream projects are no longer dependent on
+ // stream objects.
+ virtual std::vector<std::string> stream_ids() const;
+ virtual std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams() const;
+
+ // Audio or video receiver?
+ virtual cricket::MediaType media_type() const = 0;
+
+ // Not to be confused with "mid", this is a field we can temporarily use
+ // to uniquely identify a receiver until we implement Unified Plan SDP.
+ virtual std::string id() const = 0;
+
+ // The WebRTC specification only defines RTCRtpParameters in terms of senders,
+ // but this API also applies them to receivers, similar to ORTC:
+ // http://ortc.org/wp-content/uploads/2016/03/ortc.html#rtcrtpparameters*.
+ virtual RtpParameters GetParameters() const = 0;
+ // TODO(dinosaurav): Delete SetParameters entirely after rolling to Chromium.
+ // Currently, doesn't support changing any parameters.
+ virtual bool SetParameters(const RtpParameters& parameters) { return false; }
+
+ // Does not take ownership of observer.
+ // Must call SetObserver(nullptr) before the observer is destroyed.
+ virtual void SetObserver(RtpReceiverObserverInterface* observer) = 0;
+
+ // Sets the jitter buffer minimum delay until media playout. Actual observed
+ // delay may differ depending on the congestion control. `delay_seconds` is a
+ // positive value including 0.0 measured in seconds. `nullopt` means default
+ // value must be used.
+ virtual void SetJitterBufferMinimumDelay(
+ absl::optional<double> delay_seconds) = 0;
+
+ // TODO(zhihuang): Remove the default implementation once the subclasses
+ // implement this. Currently, the only relevant subclass is the
+ // content::FakeRtpReceiver in Chromium.
+ virtual std::vector<RtpSource> GetSources() const;
+
+ // Sets a user defined frame decryptor that will decrypt the entire frame
+ // before it is sent across the network. This will decrypt the entire frame
+ // using the user provided decryption mechanism regardless of whether SRTP is
+ // enabled or not.
+ // TODO(bugs.webrtc.org/12772): Remove.
+ virtual void SetFrameDecryptor(
+ rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor);
+
+ // Returns a pointer to the frame decryptor set previously by the
+ // user. This can be used to update the state of the object.
+ // TODO(bugs.webrtc.org/12772): Remove.
+ virtual rtc::scoped_refptr<FrameDecryptorInterface> GetFrameDecryptor() const;
+
+ // Sets a frame transformer between the depacketizer and the decoder to enable
+ // client code to transform received frames according to their own processing
+ // logic.
+ virtual void SetDepacketizerToDecoderFrameTransformer(
+ rtc::scoped_refptr<FrameTransformerInterface> frame_transformer);
+
+ protected:
+ ~RtpReceiverInterface() override = default;
+};
+
+} // namespace webrtc
+
+#endif // API_RTP_RECEIVER_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/rtp_sender_interface.cc b/third_party/libwebrtc/api/rtp_sender_interface.cc
new file mode 100644
index 0000000000..f1ca5c2203
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_sender_interface.cc
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/rtp_sender_interface.h"
+
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+void RtpSenderInterface::SetParametersAsync(const RtpParameters& parameters,
+ SetParametersCallback callback) {
+ RTC_DCHECK_NOTREACHED() << "Default implementation called";
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/rtp_sender_interface.h b/third_party/libwebrtc/api/rtp_sender_interface.h
new file mode 100644
index 0000000000..98ee91b1cc
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_sender_interface.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This file contains interfaces for RtpSenders
+// http://w3c.github.io/webrtc-pc/#rtcrtpsender-interface
+
+#ifndef API_RTP_SENDER_INTERFACE_H_
+#define API_RTP_SENDER_INTERFACE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/functional/any_invocable.h"
+#include "api/crypto/frame_encryptor_interface.h"
+#include "api/dtls_transport_interface.h"
+#include "api/dtmf_sender_interface.h"
+#include "api/frame_transformer_interface.h"
+#include "api/media_stream_interface.h"
+#include "api/media_types.h"
+#include "api/rtc_error.h"
+#include "api/rtp_parameters.h"
+#include "api/scoped_refptr.h"
+#include "api/video_codecs/video_encoder_factory.h"
+#include "rtc_base/ref_count.h"
+#include "rtc_base/system/rtc_export.h"
+
+#include "api/rtp_sender_setparameters_callback.h"
+
+namespace webrtc {
+
+class RTC_EXPORT RtpSenderInterface : public rtc::RefCountInterface {
+ public:
+ // Returns true if successful in setting the track.
+ // Fails if an audio track is set on a video RtpSender, or vice-versa.
+ virtual bool SetTrack(MediaStreamTrackInterface* track) = 0;
+ virtual rtc::scoped_refptr<MediaStreamTrackInterface> track() const = 0;
+
+ // The dtlsTransport attribute exposes the DTLS transport on which the
+ // media is sent. It may be null.
+ // https://w3c.github.io/webrtc-pc/#dom-rtcrtpsender-transport
+ virtual rtc::scoped_refptr<DtlsTransportInterface> dtls_transport() const = 0;
+
+ // Returns primary SSRC used by this sender for sending media.
+ // Returns 0 if not yet determined.
+ // TODO(deadbeef): Change to absl::optional.
+ // TODO(deadbeef): Remove? With GetParameters this should be redundant.
+ virtual uint32_t ssrc() const = 0;
+
+ // Audio or video sender?
+ virtual cricket::MediaType media_type() const = 0;
+
+ // Not to be confused with "mid", this is a field we can temporarily use
+ // to uniquely identify a receiver until we implement Unified Plan SDP.
+ virtual std::string id() const = 0;
+
+ // Returns a list of media stream ids associated with this sender's track.
+ // These are signalled in the SDP so that the remote side can associate
+ // tracks.
+ virtual std::vector<std::string> stream_ids() const = 0;
+
+ // Sets the IDs of the media streams associated with this sender's track.
+ // These are signalled in the SDP so that the remote side can associate
+ // tracks.
+ virtual void SetStreams(const std::vector<std::string>& stream_ids) = 0;
+
+ // Returns the list of encoding parameters that will be applied when the SDP
+ // local description is set. These initial encoding parameters can be set by
+ // PeerConnection::AddTransceiver, and later updated with Get/SetParameters.
+ // TODO(orphis): Make it pure virtual once Chrome has updated
+ virtual std::vector<RtpEncodingParameters> init_send_encodings() const = 0;
+
+ virtual RtpParameters GetParameters() const = 0;
+ // Note that only a subset of the parameters can currently be changed. See
+ // rtpparameters.h
+ // The encodings are in increasing quality order for simulcast.
+ virtual RTCError SetParameters(const RtpParameters& parameters) = 0;
+ virtual void SetParametersAsync(const RtpParameters& parameters,
+ SetParametersCallback callback);
+
+ // Returns null for a video sender.
+ virtual rtc::scoped_refptr<DtmfSenderInterface> GetDtmfSender() const = 0;
+
+ // Sets a user defined frame encryptor that will encrypt the entire frame
+ // before it is sent across the network. This will encrypt the entire frame
+ // using the user provided encryption mechanism regardless of whether SRTP is
+ // enabled or not.
+ virtual void SetFrameEncryptor(
+ rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor) = 0;
+
+ // Returns a pointer to the frame encryptor set previously by the
+ // user. This can be used to update the state of the object.
+ virtual rtc::scoped_refptr<FrameEncryptorInterface> GetFrameEncryptor()
+ const = 0;
+
+ virtual void SetEncoderToPacketizerFrameTransformer(
+ rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) = 0;
+
+ // Sets a user defined encoder selector.
+ // Overrides selector that is (optionally) provided by VideoEncoderFactory.
+ virtual void SetEncoderSelector(
+ std::unique_ptr<VideoEncoderFactory::EncoderSelectorInterface>
+ encoder_selector) = 0;
+
+ // TODO(crbug.com/1354101): make pure virtual again after Chrome roll.
+ virtual RTCError GenerateKeyFrame(const std::vector<std::string>& rids) {
+ return RTCError::OK();
+ }
+
+ protected:
+ ~RtpSenderInterface() override = default;
+};
+
+} // namespace webrtc
+
+#endif // API_RTP_SENDER_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/rtp_sender_interface_gn/moz.build b/third_party/libwebrtc/api/rtp_sender_interface_gn/moz.build
new file mode 100644
index 0000000000..9712e13ddd
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_sender_interface_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("rtp_sender_interface_gn")
diff --git a/third_party/libwebrtc/api/rtp_sender_setparameters_callback.cc b/third_party/libwebrtc/api/rtp_sender_setparameters_callback.cc
new file mode 100644
index 0000000000..99728ef95e
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_sender_setparameters_callback.cc
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// File added by mozilla, to decouple this from libwebrtc's implementation of
+// RTCRtpSender.
+
+#include "api/rtp_sender_setparameters_callback.h"
+
+namespace webrtc {
+
+webrtc::RTCError InvokeSetParametersCallback(SetParametersCallback& callback,
+ RTCError error) {
+ if (callback) {
+ std::move(callback)(error);
+ callback = nullptr;
+ }
+ return error;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/rtp_sender_setparameters_callback.h b/third_party/libwebrtc/api/rtp_sender_setparameters_callback.h
new file mode 100644
index 0000000000..45194f5ace
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_sender_setparameters_callback.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// File added by mozilla, to decouple this from libwebrtc's implementation of
+// RTCRtpSender.
+
+#ifndef API_RTP_SENDER_SETPARAMETERS_CALLBACK_H_
+#define API_RTP_SENDER_SETPARAMETERS_CALLBACK_H_
+
+#include "api/rtc_error.h"
+#include "absl/functional/any_invocable.h"
+
+namespace webrtc {
+
+using SetParametersCallback = absl::AnyInvocable<void(RTCError) &&>;
+
+webrtc::RTCError InvokeSetParametersCallback(SetParametersCallback& callback,
+ RTCError error);
+} // namespace webrtc
+
+#endif // API_RTP_SENDER_SETPARAMETERS_CALLBACK_H_
diff --git a/third_party/libwebrtc/api/rtp_sender_setparameters_callback_gn/moz.build b/third_party/libwebrtc/api/rtp_sender_setparameters_callback_gn/moz.build
new file mode 100644
index 0000000000..5cc94b1d99
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_sender_setparameters_callback_gn/moz.build
@@ -0,0 +1,225 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/rtp_sender_setparameters_callback.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("rtp_sender_setparameters_callback_gn")
diff --git a/third_party/libwebrtc/api/rtp_transceiver_direction.h b/third_party/libwebrtc/api/rtp_transceiver_direction.h
new file mode 100644
index 0000000000..3c7d4cb0ad
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_transceiver_direction.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_RTP_TRANSCEIVER_DIRECTION_H_
+#define API_RTP_TRANSCEIVER_DIRECTION_H_
+
+namespace webrtc {
+
+// https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiverdirection
+enum class RtpTransceiverDirection {
+ kSendRecv,
+ kSendOnly,
+ kRecvOnly,
+ kInactive,
+ kStopped,
+};
+
+} // namespace webrtc
+
+#endif // API_RTP_TRANSCEIVER_DIRECTION_H_
diff --git a/third_party/libwebrtc/api/rtp_transceiver_direction_gn/moz.build b/third_party/libwebrtc/api/rtp_transceiver_direction_gn/moz.build
new file mode 100644
index 0000000000..1ca9b4be66
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_transceiver_direction_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("rtp_transceiver_direction_gn")
diff --git a/third_party/libwebrtc/api/rtp_transceiver_interface.cc b/third_party/libwebrtc/api/rtp_transceiver_interface.cc
new file mode 100644
index 0000000000..7267b286be
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_transceiver_interface.cc
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/rtp_transceiver_interface.h"
+
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+RtpTransceiverInit::RtpTransceiverInit() = default;
+
+RtpTransceiverInit::RtpTransceiverInit(const RtpTransceiverInit& rhs) = default;
+
+RtpTransceiverInit::~RtpTransceiverInit() = default;
+
+absl::optional<RtpTransceiverDirection>
+RtpTransceiverInterface::fired_direction() const {
+ return absl::nullopt;
+}
+
+bool RtpTransceiverInterface::stopping() const {
+ return false;
+}
+
+void RtpTransceiverInterface::Stop() {
+ StopInternal();
+}
+
+RTCError RtpTransceiverInterface::StopStandard() {
+ RTC_DCHECK_NOTREACHED()
+ << "DEBUG: RtpTransceiverInterface::StopStandard called";
+ return RTCError::OK();
+}
+
+void RtpTransceiverInterface::StopInternal() {
+ RTC_DCHECK_NOTREACHED()
+ << "DEBUG: RtpTransceiverInterface::StopInternal called";
+}
+
+// TODO(bugs.webrtc.org/11839) Remove default implementations when clients
+// are updated.
+void RtpTransceiverInterface::SetDirection(
+ RtpTransceiverDirection new_direction) {
+ SetDirectionWithError(new_direction);
+}
+
+RTCError RtpTransceiverInterface::SetDirectionWithError(
+ RtpTransceiverDirection new_direction) {
+ RTC_DCHECK_NOTREACHED() << "Default implementation called";
+ return RTCError::OK();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/rtp_transceiver_interface.h b/third_party/libwebrtc/api/rtp_transceiver_interface.h
new file mode 100644
index 0000000000..c9d911fac1
--- /dev/null
+++ b/third_party/libwebrtc/api/rtp_transceiver_interface.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_RTP_TRANSCEIVER_INTERFACE_H_
+#define API_RTP_TRANSCEIVER_INTERFACE_H_
+
+#include <string>
+#include <vector>
+
+#include "absl/base/attributes.h"
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/media_types.h"
+#include "api/rtp_parameters.h"
+#include "api/rtp_receiver_interface.h"
+#include "api/rtp_sender_interface.h"
+#include "api/rtp_transceiver_direction.h"
+#include "api/scoped_refptr.h"
+#include "rtc_base/ref_count.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Structure for initializing an RtpTransceiver in a call to
+// PeerConnectionInterface::AddTransceiver.
+// https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiverinit
+struct RTC_EXPORT RtpTransceiverInit final {
+ RtpTransceiverInit();
+ RtpTransceiverInit(const RtpTransceiverInit&);
+ ~RtpTransceiverInit();
+ // Direction of the RtpTransceiver. See RtpTransceiverInterface::direction().
+ RtpTransceiverDirection direction = RtpTransceiverDirection::kSendRecv;
+
+ // The added RtpTransceiver will be added to these streams.
+ std::vector<std::string> stream_ids;
+
+ // TODO(bugs.webrtc.org/7600): Not implemented.
+ std::vector<RtpEncodingParameters> send_encodings;
+};
+
+// The RtpTransceiverInterface maps to the RTCRtpTransceiver defined by the
+// WebRTC specification. A transceiver represents a combination of an RtpSender
+// and an RtpReceiver than share a common mid. As defined in JSEP, an
+// RtpTransceiver is said to be associated with a media description if its mid
+// property is non-null; otherwise, it is said to be disassociated.
+// JSEP: https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-24
+//
+// Note that RtpTransceivers are only supported when using PeerConnection with
+// Unified Plan SDP.
+//
+// This class is thread-safe.
+//
+// WebRTC specification for RTCRtpTransceiver, the JavaScript analog:
+// https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver
+class RTC_EXPORT RtpTransceiverInterface : public rtc::RefCountInterface {
+ public:
+ // Media type of the transceiver. Any sender(s)/receiver(s) will have this
+ // type as well.
+ virtual cricket::MediaType media_type() const = 0;
+
+ // The mid attribute is the mid negotiated and present in the local and
+ // remote descriptions. Before negotiation is complete, the mid value may be
+ // null. After rollbacks, the value may change from a non-null value to null.
+ // https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-mid
+ virtual absl::optional<std::string> mid() const = 0;
+
+ // The sender attribute exposes the RtpSender corresponding to the RTP media
+ // that may be sent with the transceiver's mid. The sender is always present,
+ // regardless of the direction of media.
+ // https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-sender
+ virtual rtc::scoped_refptr<RtpSenderInterface> sender() const = 0;
+
+ // The receiver attribute exposes the RtpReceiver corresponding to the RTP
+ // media that may be received with the transceiver's mid. The receiver is
+ // always present, regardless of the direction of media.
+ // https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-receiver
+ virtual rtc::scoped_refptr<RtpReceiverInterface> receiver() const = 0;
+
+ // The stopped attribute indicates that the sender of this transceiver will no
+ // longer send, and that the receiver will no longer receive. It is true if
+ // either stop has been called or if setting the local or remote description
+ // has caused the RtpTransceiver to be stopped.
+ // https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-stopped
+ virtual bool stopped() const = 0;
+
+ // The stopping attribute indicates that the user has indicated that the
+ // sender of this transceiver will stop sending, and that the receiver will
+ // no longer receive. It is always true if stopped() is true.
+ // If stopping() is true and stopped() is false, it means that the
+ // transceiver's stop() method has been called, but the negotiation with
+ // the other end for shutting down the transceiver is not yet done.
+ // https://w3c.github.io/webrtc-pc/#dfn-stopping-0
+ virtual bool stopping() const = 0;
+
+ // The direction attribute indicates the preferred direction of this
+ // transceiver, which will be used in calls to CreateOffer and CreateAnswer.
+ // https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-direction
+ virtual RtpTransceiverDirection direction() const = 0;
+
+ // Sets the preferred direction of this transceiver. An update of
+ // directionality does not take effect immediately. Instead, future calls to
+ // CreateOffer and CreateAnswer mark the corresponding media descriptions as
+ // sendrecv, sendonly, recvonly, or inactive.
+ // https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-direction
+ // TODO(hta): Deprecate SetDirection without error and rename
+ // SetDirectionWithError to SetDirection, remove default implementations.
+ ABSL_DEPRECATED("Use SetDirectionWithError instead")
+ virtual void SetDirection(RtpTransceiverDirection new_direction);
+ virtual RTCError SetDirectionWithError(RtpTransceiverDirection new_direction);
+
+ // The current_direction attribute indicates the current direction negotiated
+ // for this transceiver. If this transceiver has never been represented in an
+ // offer/answer exchange, or if the transceiver is stopped, the value is null.
+ // https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-currentdirection
+ virtual absl::optional<RtpTransceiverDirection> current_direction() const = 0;
+
+ // An internal slot designating for which direction the relevant
+ // PeerConnection events have been fired. This is to ensure that events like
+ // OnAddTrack only get fired once even if the same session description is
+ // applied again.
+ // Exposed in the public interface for use by Chromium.
+ virtual absl::optional<RtpTransceiverDirection> fired_direction() const;
+
+ // Initiates a stop of the transceiver.
+ // The stop is complete when stopped() returns true.
+ // A stopped transceiver can be reused for a different track.
+ // https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-stop
+ // TODO(hta): Rename to Stop() when users of the non-standard Stop() are
+ // updated.
+ virtual RTCError StopStandard();
+
+ // Stops a transceiver immediately, without waiting for signalling.
+ // This is an internal function, and is exposed for historical reasons.
+ // https://w3c.github.io/webrtc-pc/#dfn-stop-the-rtcrtptransceiver
+ virtual void StopInternal();
+ ABSL_DEPRECATED("Use StopStandard instead") virtual void Stop();
+
+ // The SetCodecPreferences method overrides the default codec preferences used
+ // by WebRTC for this transceiver.
+ // https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-setcodecpreferences
+ virtual RTCError SetCodecPreferences(
+ rtc::ArrayView<RtpCodecCapability> codecs) = 0;
+ virtual std::vector<RtpCodecCapability> codec_preferences() const = 0;
+
+ // Readonly attribute which contains the set of header extensions that was set
+ // with SetOfferedRtpHeaderExtensions, or a default set if it has not been
+ // called.
+ // https://w3c.github.io/webrtc-extensions/#rtcrtptransceiver-interface
+ virtual std::vector<RtpHeaderExtensionCapability> HeaderExtensionsToOffer()
+ const = 0;
+
+ // Readonly attribute which is either empty if negotation has not yet
+ // happened, or a vector of the negotiated header extensions.
+ // https://w3c.github.io/webrtc-extensions/#rtcrtptransceiver-interface
+ virtual std::vector<RtpHeaderExtensionCapability> HeaderExtensionsNegotiated()
+ const = 0;
+
+ // The SetOfferedRtpHeaderExtensions method modifies the next SDP negotiation
+ // so that it negotiates use of header extensions which are not kStopped.
+ // https://w3c.github.io/webrtc-extensions/#rtcrtptransceiver-interface
+ virtual webrtc::RTCError SetOfferedRtpHeaderExtensions(
+ rtc::ArrayView<const RtpHeaderExtensionCapability>
+ header_extensions_to_offer) = 0;
+
+ protected:
+ ~RtpTransceiverInterface() override = default;
+};
+
+} // namespace webrtc
+
+#endif // API_RTP_TRANSCEIVER_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/scoped_refptr.h b/third_party/libwebrtc/api/scoped_refptr.h
new file mode 100644
index 0000000000..e145509127
--- /dev/null
+++ b/third_party/libwebrtc/api/scoped_refptr.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2011 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// Originally these classes are from Chromium.
+// http://src.chromium.org/viewvc/chrome/trunk/src/base/memory/ref_counted.h?view=markup
+
+//
+// A smart pointer class for reference counted objects. Use this class instead
+// of calling AddRef and Release manually on a reference counted object to
+// avoid common memory leaks caused by forgetting to Release an object
+// reference. Sample usage:
+//
+// class MyFoo : public RefCounted<MyFoo> {
+// ...
+// };
+//
+// void some_function() {
+// scoped_refptr<MyFoo> foo = new MyFoo();
+// foo->Method(param);
+// // `foo` is released when this function returns
+// }
+//
+// void some_other_function() {
+// scoped_refptr<MyFoo> foo = new MyFoo();
+// ...
+// foo = nullptr; // explicitly releases `foo`
+// ...
+// if (foo)
+// foo->Method(param);
+// }
+//
+// The above examples show how scoped_refptr<T> acts like a pointer to T.
+// Given two scoped_refptr<T> classes, it is also possible to exchange
+// references between the two objects, like so:
+//
+// {
+// scoped_refptr<MyFoo> a = new MyFoo();
+// scoped_refptr<MyFoo> b;
+//
+// b.swap(a);
+// // now, `b` references the MyFoo object, and `a` references null.
+// }
+//
+// To make both `a` and `b` in the above example reference the same MyFoo
+// object, simply use the assignment operator:
+//
+// {
+// scoped_refptr<MyFoo> a = new MyFoo();
+// scoped_refptr<MyFoo> b;
+//
+// b = a;
+// // now, `a` and `b` each own a reference to the same MyFoo object.
+// }
+//
+
+#ifndef API_SCOPED_REFPTR_H_
+#define API_SCOPED_REFPTR_H_
+
+#include <memory>
+#include <utility>
+
+namespace rtc {
+
+template <class T>
+class scoped_refptr {
+ public:
+ typedef T element_type;
+
+ scoped_refptr() : ptr_(nullptr) {}
+ scoped_refptr(std::nullptr_t) : ptr_(nullptr) {} // NOLINT(runtime/explicit)
+
+ explicit scoped_refptr(T* p) : ptr_(p) {
+ if (ptr_)
+ ptr_->AddRef();
+ }
+
+ scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
+ if (ptr_)
+ ptr_->AddRef();
+ }
+
+ template <typename U>
+ scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
+ if (ptr_)
+ ptr_->AddRef();
+ }
+
+ // Move constructors.
+ scoped_refptr(scoped_refptr<T>&& r) noexcept : ptr_(r.release()) {}
+
+ template <typename U>
+ scoped_refptr(scoped_refptr<U>&& r) noexcept : ptr_(r.release()) {}
+
+ ~scoped_refptr() {
+ if (ptr_)
+ ptr_->Release();
+ }
+
+ T* get() const { return ptr_; }
+ explicit operator bool() const { return ptr_ != nullptr; }
+ T& operator*() const { return *ptr_; }
+ T* operator->() const { return ptr_; }
+
+ // Returns the (possibly null) raw pointer, and makes the scoped_refptr hold a
+ // null pointer, all without touching the reference count of the underlying
+ // pointed-to object. The object is still reference counted, and the caller of
+ // release() is now the proud owner of one reference, so it is responsible for
+ // calling Release() once on the object when no longer using it.
+ T* release() {
+ T* retVal = ptr_;
+ ptr_ = nullptr;
+ return retVal;
+ }
+
+ scoped_refptr<T>& operator=(T* p) {
+ // AddRef first so that self assignment should work
+ if (p)
+ p->AddRef();
+ if (ptr_)
+ ptr_->Release();
+ ptr_ = p;
+ return *this;
+ }
+
+ scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
+ return *this = r.ptr_;
+ }
+
+ template <typename U>
+ scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
+ return *this = r.get();
+ }
+
+ scoped_refptr<T>& operator=(scoped_refptr<T>&& r) noexcept {
+ scoped_refptr<T>(std::move(r)).swap(*this);
+ return *this;
+ }
+
+ template <typename U>
+ scoped_refptr<T>& operator=(scoped_refptr<U>&& r) noexcept {
+ scoped_refptr<T>(std::move(r)).swap(*this);
+ return *this;
+ }
+
+ void swap(T** pp) noexcept {
+ T* p = ptr_;
+ ptr_ = *pp;
+ *pp = p;
+ }
+
+ void swap(scoped_refptr<T>& r) noexcept { swap(&r.ptr_); }
+
+ protected:
+ T* ptr_;
+};
+
+template <typename T, typename U>
+bool operator==(const rtc::scoped_refptr<T>& a,
+ const rtc::scoped_refptr<U>& b) {
+ return a.get() == b.get();
+}
+template <typename T, typename U>
+bool operator!=(const rtc::scoped_refptr<T>& a,
+ const rtc::scoped_refptr<U>& b) {
+ return !(a == b);
+}
+
+template <typename T>
+bool operator==(const rtc::scoped_refptr<T>& a, std::nullptr_t) {
+ return a.get() == nullptr;
+}
+
+template <typename T>
+bool operator!=(const rtc::scoped_refptr<T>& a, std::nullptr_t) {
+ return !(a == nullptr);
+}
+
+template <typename T>
+bool operator==(std::nullptr_t, const rtc::scoped_refptr<T>& a) {
+ return a.get() == nullptr;
+}
+
+template <typename T>
+bool operator!=(std::nullptr_t, const rtc::scoped_refptr<T>& a) {
+ return !(a == nullptr);
+}
+
+// Comparison with raw pointer.
+template <typename T, typename U>
+bool operator==(const rtc::scoped_refptr<T>& a, const U* b) {
+ return a.get() == b;
+}
+template <typename T, typename U>
+bool operator!=(const rtc::scoped_refptr<T>& a, const U* b) {
+ return !(a == b);
+}
+
+template <typename T, typename U>
+bool operator==(const T* a, const rtc::scoped_refptr<U>& b) {
+ return a == b.get();
+}
+template <typename T, typename U>
+bool operator!=(const T* a, const rtc::scoped_refptr<U>& b) {
+ return !(a == b);
+}
+
+// Ordered comparison, needed for use as a std::map key.
+template <typename T, typename U>
+bool operator<(const rtc::scoped_refptr<T>& a, const rtc::scoped_refptr<U>& b) {
+ return a.get() < b.get();
+}
+
+} // namespace rtc
+
+#endif // API_SCOPED_REFPTR_H_
diff --git a/third_party/libwebrtc/api/scoped_refptr_gn/moz.build b/third_party/libwebrtc/api/scoped_refptr_gn/moz.build
new file mode 100644
index 0000000000..d4dbda2c18
--- /dev/null
+++ b/third_party/libwebrtc/api/scoped_refptr_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("scoped_refptr_gn")
diff --git a/third_party/libwebrtc/api/scoped_refptr_unittest.cc b/third_party/libwebrtc/api/scoped_refptr_unittest.cc
new file mode 100644
index 0000000000..22b61209cd
--- /dev/null
+++ b/third_party/libwebrtc/api/scoped_refptr_unittest.cc
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/scoped_refptr.h"
+
+#include <utility>
+#include <vector>
+
+#include "test/gtest.h"
+
+namespace rtc {
+namespace {
+
+struct FunctionsCalled {
+ int addref = 0;
+ int release = 0;
+};
+
+class ScopedRefCounted {
+ public:
+ explicit ScopedRefCounted(FunctionsCalled* called) : called_(*called) {}
+ ScopedRefCounted(const ScopedRefCounted&) = delete;
+ ScopedRefCounted& operator=(const ScopedRefCounted&) = delete;
+
+ void AddRef() {
+ ++called_.addref;
+ ++ref_count_;
+ }
+ void Release() {
+ ++called_.release;
+ if (0 == --ref_count_)
+ delete this;
+ }
+
+ private:
+ ~ScopedRefCounted() = default;
+
+ FunctionsCalled& called_;
+ int ref_count_ = 0;
+};
+
+TEST(ScopedRefptrTest, IsCopyConstructable) {
+ FunctionsCalled called;
+ scoped_refptr<ScopedRefCounted> ptr(new ScopedRefCounted(&called));
+ scoped_refptr<ScopedRefCounted> another_ptr = ptr;
+
+ EXPECT_TRUE(ptr);
+ EXPECT_TRUE(another_ptr);
+ EXPECT_EQ(called.addref, 2);
+}
+
+TEST(ScopedRefptrTest, IsCopyAssignable) {
+ FunctionsCalled called;
+ scoped_refptr<ScopedRefCounted> another_ptr;
+ scoped_refptr<ScopedRefCounted> ptr(new ScopedRefCounted(&called));
+ another_ptr = ptr;
+
+ EXPECT_TRUE(ptr);
+ EXPECT_TRUE(another_ptr);
+ EXPECT_EQ(called.addref, 2);
+}
+
+TEST(ScopedRefptrTest, IsMoveConstructableWithoutExtraAddRefRelease) {
+ FunctionsCalled called;
+ scoped_refptr<ScopedRefCounted> ptr(new ScopedRefCounted(&called));
+ scoped_refptr<ScopedRefCounted> another_ptr = std::move(ptr);
+
+ EXPECT_FALSE(ptr);
+ EXPECT_TRUE(another_ptr);
+ EXPECT_EQ(called.addref, 1);
+ EXPECT_EQ(called.release, 0);
+}
+
+TEST(ScopedRefptrTest, IsMoveAssignableWithoutExtraAddRefRelease) {
+ FunctionsCalled called;
+ scoped_refptr<ScopedRefCounted> another_ptr;
+ scoped_refptr<ScopedRefCounted> ptr(new ScopedRefCounted(&called));
+ another_ptr = std::move(ptr);
+
+ EXPECT_FALSE(ptr);
+ EXPECT_TRUE(another_ptr);
+ EXPECT_EQ(called.addref, 1);
+ EXPECT_EQ(called.release, 0);
+}
+
+TEST(ScopedRefptrTest, MovableDuringVectorReallocation) {
+ static_assert(
+ std::is_nothrow_move_constructible<scoped_refptr<ScopedRefCounted>>(),
+ "");
+ // Test below describes a scenario where it is helpful for move constructor
+ // to be noexcept.
+ FunctionsCalled called;
+ std::vector<scoped_refptr<ScopedRefCounted>> ptrs;
+ ptrs.reserve(1);
+ // Insert more elements than reserved to provoke reallocation.
+ ptrs.emplace_back(new ScopedRefCounted(&called));
+ ptrs.emplace_back(new ScopedRefCounted(&called));
+
+ EXPECT_EQ(called.addref, 2);
+ EXPECT_EQ(called.release, 0);
+}
+
+} // namespace
+} // namespace rtc
diff --git a/third_party/libwebrtc/api/sctp_transport_interface.cc b/third_party/libwebrtc/api/sctp_transport_interface.cc
new file mode 100644
index 0000000000..8a0a866e85
--- /dev/null
+++ b/third_party/libwebrtc/api/sctp_transport_interface.cc
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/sctp_transport_interface.h"
+
+#include <utility>
+
+namespace webrtc {
+
+SctpTransportInformation::SctpTransportInformation(SctpTransportState state)
+ : state_(state) {}
+
+SctpTransportInformation::SctpTransportInformation(
+ SctpTransportState state,
+ rtc::scoped_refptr<DtlsTransportInterface> dtls_transport,
+ absl::optional<double> max_message_size,
+ absl::optional<int> max_channels)
+ : state_(state),
+ dtls_transport_(std::move(dtls_transport)),
+ max_message_size_(max_message_size),
+ max_channels_(max_channels) {}
+
+SctpTransportInformation::~SctpTransportInformation() {}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/sctp_transport_interface.h b/third_party/libwebrtc/api/sctp_transport_interface.h
new file mode 100644
index 0000000000..7080889fcf
--- /dev/null
+++ b/third_party/libwebrtc/api/sctp_transport_interface.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_SCTP_TRANSPORT_INTERFACE_H_
+#define API_SCTP_TRANSPORT_INTERFACE_H_
+
+#include "absl/types/optional.h"
+#include "api/dtls_transport_interface.h"
+#include "api/rtc_error.h"
+#include "api/scoped_refptr.h"
+#include "rtc_base/ref_count.h"
+
+namespace webrtc {
+
+// States of a SCTP transport, corresponding to the JS API specification.
+// http://w3c.github.io/webrtc-pc/#dom-rtcsctptransportstate
+enum class SctpTransportState {
+ kNew, // Has not started negotiating yet. Non-standard state.
+ kConnecting, // In the process of negotiating an association.
+ kConnected, // Completed negotiation of an association.
+ kClosed, // Closed by local or remote party.
+ kNumValues
+};
+
+// This object gives snapshot information about the changeable state of a
+// SctpTransport.
+// It reflects the readonly attributes of the object in the specification.
+// http://w3c.github.io/webrtc-pc/#rtcsctptransport-interface
+class RTC_EXPORT SctpTransportInformation {
+ public:
+ SctpTransportInformation() = default;
+ SctpTransportInformation(const SctpTransportInformation&) = default;
+ explicit SctpTransportInformation(SctpTransportState state);
+ SctpTransportInformation(
+ SctpTransportState state,
+ rtc::scoped_refptr<DtlsTransportInterface> dtls_transport,
+ absl::optional<double> max_message_size,
+ absl::optional<int> max_channels);
+ ~SctpTransportInformation();
+ // The DTLS transport that supports this SCTP transport.
+ rtc::scoped_refptr<DtlsTransportInterface> dtls_transport() const {
+ return dtls_transport_;
+ }
+ SctpTransportState state() const { return state_; }
+ absl::optional<double> MaxMessageSize() const { return max_message_size_; }
+ absl::optional<int> MaxChannels() const { return max_channels_; }
+
+ private:
+ SctpTransportState state_;
+ rtc::scoped_refptr<DtlsTransportInterface> dtls_transport_;
+ absl::optional<double> max_message_size_;
+ absl::optional<int> max_channels_;
+};
+
+class SctpTransportObserverInterface {
+ public:
+ // This callback carries information about the state of the transport.
+ // The argument is a pass-by-value snapshot of the state.
+ // The callback will be called on the network thread.
+ virtual void OnStateChange(SctpTransportInformation info) = 0;
+
+ protected:
+ virtual ~SctpTransportObserverInterface() = default;
+};
+
+// A SCTP transport, as represented to the outside world.
+// This object is created on the network thread, and can only be
+// accessed on that thread, except for functions explicitly marked otherwise.
+// References can be held by other threads, and destruction can therefore
+// be initiated by other threads.
+class SctpTransportInterface : public rtc::RefCountInterface {
+ public:
+ // This function can be called from other threads.
+ virtual rtc::scoped_refptr<DtlsTransportInterface> dtls_transport() const = 0;
+ // Returns information on the state of the SctpTransport.
+ // This function can be called from other threads.
+ virtual SctpTransportInformation Information() const = 0;
+ // Observer management.
+ virtual void RegisterObserver(SctpTransportObserverInterface* observer) = 0;
+ virtual void UnregisterObserver() = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_SCTP_TRANSPORT_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/sequence_checker.h b/third_party/libwebrtc/api/sequence_checker.h
new file mode 100644
index 0000000000..33e0f3c074
--- /dev/null
+++ b/third_party/libwebrtc/api/sequence_checker.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_SEQUENCE_CHECKER_H_
+#define API_SEQUENCE_CHECKER_H_
+
+#include "rtc_base/checks.h"
+#include "rtc_base/synchronization/sequence_checker_internal.h"
+#include "rtc_base/thread_annotations.h"
+
+namespace webrtc {
+
+// SequenceChecker is a helper class used to help verify that some methods
+// of a class are called on the same task queue or thread. A
+// SequenceChecker is bound to a a task queue if the object is
+// created on a task queue, or a thread otherwise.
+//
+//
+// Example:
+// class MyClass {
+// public:
+// void Foo() {
+// RTC_DCHECK_RUN_ON(&sequence_checker_);
+// ... (do stuff) ...
+// }
+//
+// private:
+// SequenceChecker sequence_checker_;
+// }
+//
+// In Release mode, IsCurrent will always return true.
+class RTC_LOCKABLE SequenceChecker
+#if RTC_DCHECK_IS_ON
+ : public webrtc_sequence_checker_internal::SequenceCheckerImpl {
+ using Impl = webrtc_sequence_checker_internal::SequenceCheckerImpl;
+#else
+ : public webrtc_sequence_checker_internal::SequenceCheckerDoNothing {
+ using Impl = webrtc_sequence_checker_internal::SequenceCheckerDoNothing;
+#endif
+ public:
+ enum InitialState : bool { kDetached = false, kAttached = true };
+
+ explicit SequenceChecker(InitialState initial_state = kAttached)
+ : Impl(initial_state) {}
+
+ // Returns true if sequence checker is attached to the current sequence.
+ bool IsCurrent() const { return Impl::IsCurrent(); }
+ // Detaches checker from sequence to which it is attached. Next attempt
+ // to do a check with this checker will result in attaching this checker
+ // to the sequence on which check was performed.
+ void Detach() { Impl::Detach(); }
+};
+
+} // namespace webrtc
+
+// RTC_RUN_ON/RTC_GUARDED_BY/RTC_DCHECK_RUN_ON macros allows to annotate
+// variables are accessed from same thread/task queue.
+// Using tools designed to check mutexes, it checks at compile time everywhere
+// variable is access, there is a run-time dcheck thread/task queue is correct.
+//
+// class SequenceCheckerExample {
+// public:
+// int CalledFromPacer() RTC_RUN_ON(pacer_sequence_checker_) {
+// return var2_;
+// }
+//
+// void CallMeFromPacer() {
+// RTC_DCHECK_RUN_ON(&pacer_sequence_checker_)
+// << "Should be called from pacer";
+// CalledFromPacer();
+// }
+//
+// private:
+// int pacer_var_ RTC_GUARDED_BY(pacer_sequence_checker_);
+// SequenceChecker pacer_sequence_checker_;
+// };
+//
+// class TaskQueueExample {
+// public:
+// class Encoder {
+// public:
+// rtc::TaskQueueBase& Queue() { return encoder_queue_; }
+// void Encode() {
+// RTC_DCHECK_RUN_ON(&encoder_queue_);
+// DoSomething(var_);
+// }
+//
+// private:
+// rtc::TaskQueueBase& encoder_queue_;
+// Frame var_ RTC_GUARDED_BY(encoder_queue_);
+// };
+//
+// void Encode() {
+// // Will fail at runtime when DCHECK is enabled:
+// // encoder_->Encode();
+// // Will work:
+// rtc::scoped_refptr<Encoder> encoder = encoder_;
+// encoder_->Queue().PostTask([encoder] { encoder->Encode(); });
+// }
+//
+// private:
+// rtc::scoped_refptr<Encoder> encoder_;
+// }
+
+// Document if a function expected to be called from same thread/task queue.
+#define RTC_RUN_ON(x) \
+ RTC_THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(x))
+
+// Checks current code is running on the desired sequence.
+//
+// First statement validates it is running on the sequence `x`.
+// Second statement annotates for the thread safety analyzer the check was done.
+// Such annotation has to be attached to a function, and that function has to be
+// called. Thus current implementation creates a noop lambda and calls it.
+#define RTC_DCHECK_RUN_ON(x) \
+ RTC_DCHECK((x)->IsCurrent()) \
+ << webrtc::webrtc_sequence_checker_internal::ExpectationToString(x); \
+ []() RTC_ASSERT_EXCLUSIVE_LOCK(x) {}()
+
+#endif // API_SEQUENCE_CHECKER_H_
diff --git a/third_party/libwebrtc/api/sequence_checker_gn/moz.build b/third_party/libwebrtc/api/sequence_checker_gn/moz.build
new file mode 100644
index 0000000000..d3dd3980f8
--- /dev/null
+++ b/third_party/libwebrtc/api/sequence_checker_gn/moz.build
@@ -0,0 +1,205 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("sequence_checker_gn")
diff --git a/third_party/libwebrtc/api/sequence_checker_unittest.cc b/third_party/libwebrtc/api/sequence_checker_unittest.cc
new file mode 100644
index 0000000000..f117926d73
--- /dev/null
+++ b/third_party/libwebrtc/api/sequence_checker_unittest.cc
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/sequence_checker.h"
+
+#include <memory>
+#include <utility>
+
+#include "api/function_view.h"
+#include "api/units/time_delta.h"
+#include "rtc_base/event.h"
+#include "rtc_base/platform_thread.h"
+#include "rtc_base/task_queue_for_test.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+using testing::HasSubstr;
+
+namespace webrtc {
+namespace {
+
+// This class is dead code, but its purpose is to make sure that
+// SequenceChecker is compatible with the RTC_GUARDED_BY and RTC_RUN_ON
+// attributes that are checked at compile-time.
+class CompileTimeTestForGuardedBy {
+ public:
+ int CalledOnSequence() RTC_RUN_ON(sequence_checker_) { return guarded_; }
+
+ void CallMeFromSequence() {
+ RTC_DCHECK_RUN_ON(&sequence_checker_);
+ guarded_ = 41;
+ }
+
+ private:
+ int guarded_ RTC_GUARDED_BY(sequence_checker_);
+ ::webrtc::SequenceChecker sequence_checker_;
+};
+
+void RunOnDifferentThread(rtc::FunctionView<void()> run) {
+ rtc::Event thread_has_run_event;
+ rtc::PlatformThread::SpawnJoinable(
+ [&] {
+ run();
+ thread_has_run_event.Set();
+ },
+ "thread");
+ EXPECT_TRUE(thread_has_run_event.Wait(TimeDelta::Seconds(1)));
+}
+
+} // namespace
+
+TEST(SequenceCheckerTest, CallsAllowedOnSameThread) {
+ SequenceChecker sequence_checker;
+ EXPECT_TRUE(sequence_checker.IsCurrent());
+}
+
+TEST(SequenceCheckerTest, DestructorAllowedOnDifferentThread) {
+ auto sequence_checker = std::make_unique<SequenceChecker>();
+ RunOnDifferentThread([&] {
+ // Verify that the destructor doesn't assert when called on a different
+ // thread.
+ sequence_checker.reset();
+ });
+}
+
+TEST(SequenceCheckerTest, Detach) {
+ SequenceChecker sequence_checker;
+ sequence_checker.Detach();
+ RunOnDifferentThread([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); });
+}
+
+TEST(SequenceCheckerTest, DetachFromThreadAndUseOnTaskQueue) {
+ SequenceChecker sequence_checker;
+ sequence_checker.Detach();
+ TaskQueueForTest queue;
+ queue.SendTask([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); });
+}
+
+TEST(SequenceCheckerTest, DetachFromTaskQueueAndUseOnThread) {
+ TaskQueueForTest queue;
+ queue.SendTask([] {
+ SequenceChecker sequence_checker;
+ sequence_checker.Detach();
+ RunOnDifferentThread([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); });
+ });
+}
+
+TEST(SequenceCheckerTest, MethodNotAllowedOnDifferentThreadInDebug) {
+ SequenceChecker sequence_checker;
+ RunOnDifferentThread(
+ [&] { EXPECT_EQ(sequence_checker.IsCurrent(), !RTC_DCHECK_IS_ON); });
+}
+
+#if RTC_DCHECK_IS_ON
+TEST(SequenceCheckerTest, OnlyCurrentOnOneThread) {
+ SequenceChecker sequence_checker(SequenceChecker::kDetached);
+ RunOnDifferentThread([&] {
+ EXPECT_TRUE(sequence_checker.IsCurrent());
+ // Spawn a new thread from within the first one to guarantee that we have
+ // two concurrently active threads (and that there's no chance of the
+ // thread ref being reused).
+ RunOnDifferentThread([&] { EXPECT_FALSE(sequence_checker.IsCurrent()); });
+ });
+}
+#endif
+
+TEST(SequenceCheckerTest, MethodNotAllowedOnDifferentTaskQueueInDebug) {
+ SequenceChecker sequence_checker;
+ TaskQueueForTest queue;
+ queue.SendTask(
+ [&] { EXPECT_EQ(sequence_checker.IsCurrent(), !RTC_DCHECK_IS_ON); });
+}
+
+TEST(SequenceCheckerTest, DetachFromTaskQueueInDebug) {
+ SequenceChecker sequence_checker;
+ sequence_checker.Detach();
+
+ TaskQueueForTest queue1;
+ queue1.SendTask([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); });
+
+ // IsCurrent should return false in debug builds after moving to
+ // another task queue.
+ TaskQueueForTest queue2;
+ queue2.SendTask(
+ [&] { EXPECT_EQ(sequence_checker.IsCurrent(), !RTC_DCHECK_IS_ON); });
+}
+
+TEST(SequenceCheckerTest, ExpectationToString) {
+ TaskQueueForTest queue1;
+
+ SequenceChecker sequence_checker(SequenceChecker::kDetached);
+
+ rtc::Event blocker;
+ queue1.PostTask([&blocker, &sequence_checker]() {
+ (void)sequence_checker.IsCurrent();
+ blocker.Set();
+ });
+
+ blocker.Wait(rtc::Event::kForever);
+
+#if RTC_DCHECK_IS_ON
+
+ EXPECT_THAT(ExpectationToString(&sequence_checker),
+ HasSubstr("# Expected: TQ:"));
+
+ // Test for the base class
+ webrtc_sequence_checker_internal::SequenceCheckerImpl* sequence_checker_base =
+ &sequence_checker;
+ EXPECT_THAT(ExpectationToString(sequence_checker_base),
+ HasSubstr("# Expected: TQ:"));
+
+#else
+ GTEST_ASSERT_EQ(ExpectationToString(&sequence_checker), "");
+#endif
+}
+
+TEST(SequenceCheckerTest, InitiallyDetached) {
+ TaskQueueForTest queue1;
+
+ SequenceChecker sequence_checker(SequenceChecker::kDetached);
+
+ rtc::Event blocker;
+ queue1.PostTask([&blocker, &sequence_checker]() {
+ EXPECT_TRUE(sequence_checker.IsCurrent());
+ blocker.Set();
+ });
+
+ blocker.Wait(rtc::Event::kForever);
+
+#if RTC_DCHECK_IS_ON
+ EXPECT_FALSE(sequence_checker.IsCurrent());
+#endif
+}
+
+class TestAnnotations {
+ public:
+ TestAnnotations() : test_var_(false) {}
+
+ void ModifyTestVar() {
+ RTC_DCHECK_RUN_ON(&checker_);
+ test_var_ = true;
+ }
+
+ private:
+ bool test_var_ RTC_GUARDED_BY(&checker_);
+ SequenceChecker checker_;
+};
+
+TEST(SequenceCheckerTest, TestAnnotations) {
+ TestAnnotations annotations;
+ annotations.ModifyTestVar();
+}
+
+#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
+
+void TestAnnotationsOnWrongQueue() {
+ TestAnnotations annotations;
+ TaskQueueForTest queue;
+ queue.SendTask([&] { annotations.ModifyTestVar(); });
+}
+
+#if RTC_DCHECK_IS_ON
+// Note: Ending the test suite name with 'DeathTest' is important as it causes
+// gtest to order this test before any other non-death-tests, to avoid potential
+// global process state pollution such as shared worker threads being started
+// (e.g. a side effect of calling InitCocoaMultiThreading() on Mac causes one or
+// two additional threads to be created).
+TEST(SequenceCheckerDeathTest, TestAnnotationsOnWrongQueueDebug) {
+ ASSERT_DEATH({ TestAnnotationsOnWrongQueue(); }, "");
+}
+#else
+TEST(SequenceCheckerTest, TestAnnotationsOnWrongQueueRelease) {
+ TestAnnotationsOnWrongQueue();
+}
+#endif
+#endif // GTEST_HAS_DEATH_TEST
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/set_local_description_observer_interface.h b/third_party/libwebrtc/api/set_local_description_observer_interface.h
new file mode 100644
index 0000000000..8e7b6258d3
--- /dev/null
+++ b/third_party/libwebrtc/api/set_local_description_observer_interface.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_SET_LOCAL_DESCRIPTION_OBSERVER_INTERFACE_H_
+#define API_SET_LOCAL_DESCRIPTION_OBSERVER_INTERFACE_H_
+
+#include "api/rtc_error.h"
+#include "rtc_base/ref_count.h"
+
+namespace webrtc {
+
+// OnSetLocalDescriptionComplete() invokes as soon as
+// PeerConnectionInterface::SetLocalDescription() operation completes, allowing
+// the observer to examine the effects of the operation without delay.
+class SetLocalDescriptionObserverInterface : public rtc::RefCountInterface {
+ public:
+ // On success, `error.ok()` is true.
+ virtual void OnSetLocalDescriptionComplete(RTCError error) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_SET_LOCAL_DESCRIPTION_OBSERVER_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/set_remote_description_observer_interface.h b/third_party/libwebrtc/api/set_remote_description_observer_interface.h
new file mode 100644
index 0000000000..d1c075309f
--- /dev/null
+++ b/third_party/libwebrtc/api/set_remote_description_observer_interface.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_SET_REMOTE_DESCRIPTION_OBSERVER_INTERFACE_H_
+#define API_SET_REMOTE_DESCRIPTION_OBSERVER_INTERFACE_H_
+
+#include "api/rtc_error.h"
+#include "rtc_base/ref_count.h"
+
+namespace webrtc {
+
+// An observer for PeerConnectionInterface::SetRemoteDescription(). The
+// callback is invoked such that the state of the peer connection can be
+// examined to accurately reflect the effects of the SetRemoteDescription
+// operation.
+class SetRemoteDescriptionObserverInterface : public rtc::RefCountInterface {
+ public:
+ // On success, `error.ok()` is true.
+ virtual void OnSetRemoteDescriptionComplete(RTCError error) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_SET_REMOTE_DESCRIPTION_OBSERVER_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/simulated_network_api_gn/moz.build b/third_party/libwebrtc/api/simulated_network_api_gn/moz.build
new file mode 100644
index 0000000000..0867200479
--- /dev/null
+++ b/third_party/libwebrtc/api/simulated_network_api_gn/moz.build
@@ -0,0 +1,205 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("simulated_network_api_gn")
diff --git a/third_party/libwebrtc/api/stats/OWNERS b/third_party/libwebrtc/api/stats/OWNERS
new file mode 100644
index 0000000000..7e98070d5d
--- /dev/null
+++ b/third_party/libwebrtc/api/stats/OWNERS
@@ -0,0 +1,2 @@
+hbos@webrtc.org
+hta@webrtc.org
diff --git a/third_party/libwebrtc/api/stats/rtc_stats.h b/third_party/libwebrtc/api/stats/rtc_stats.h
new file mode 100644
index 0000000000..72775243c7
--- /dev/null
+++ b/third_party/libwebrtc/api/stats/rtc_stats.h
@@ -0,0 +1,580 @@
+/*
+ * Copyright 2016 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_STATS_RTC_STATS_H_
+#define API_STATS_RTC_STATS_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/units/timestamp.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/system/rtc_export.h"
+#include "rtc_base/system/rtc_export_template.h"
+
+namespace webrtc {
+
+class RTCStatsMemberInterface;
+
+// Abstract base class for RTCStats-derived dictionaries, see
+// https://w3c.github.io/webrtc-stats/.
+//
+// All derived classes must have the following static variable defined:
+// static const char kType[];
+// It is used as a unique class identifier and a string representation of the
+// class type, see https://w3c.github.io/webrtc-stats/#rtcstatstype-str*.
+// Use the `WEBRTC_RTCSTATS_IMPL` macro when implementing subclasses, see macro
+// for details.
+//
+// Derived classes list their dictionary members, RTCStatsMember<T>, as public
+// fields, allowing the following:
+//
+// RTCFooStats foo("fooId", Timestamp::Micros(GetCurrentTime()));
+// foo.bar = 42;
+// foo.baz = std::vector<std::string>();
+// foo.baz->push_back("hello world");
+// uint32_t x = *foo.bar;
+//
+// Pointers to all the members are available with `Members`, allowing iteration:
+//
+// for (const RTCStatsMemberInterface* member : foo.Members()) {
+// printf("%s = %s\n", member->name(), member->ValueToString().c_str());
+// }
+class RTC_EXPORT RTCStats {
+ public:
+ RTCStats(const std::string& id, Timestamp timestamp)
+ : id_(id), timestamp_(timestamp) {}
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCStats(std::string id, int64_t timestamp_us)
+ : RTCStats(std::move(id), Timestamp::Micros(timestamp_us)) {}
+
+ virtual ~RTCStats() {}
+
+ virtual std::unique_ptr<RTCStats> copy() const = 0;
+
+ const std::string& id() const { return id_; }
+ // Time relative to the UNIX epoch (Jan 1, 1970, UTC), in microseconds.
+ ABSL_DEPRECATED("Use .timestamp().us() instead")
+ int64_t timestamp_us() const { return timestamp_.us(); }
+ Timestamp timestamp() const { return timestamp_; }
+
+ // Returns the static member variable `kType` of the implementing class.
+ virtual const char* type() const = 0;
+ // Returns a vector of pointers to all the `RTCStatsMemberInterface` members
+ // of this class. This allows for iteration of members. For a given class,
+ // `Members` always returns the same members in the same order.
+ std::vector<const RTCStatsMemberInterface*> Members() const;
+ // Checks if the two stats objects are of the same type and have the same
+ // member values. Timestamps are not compared. These operators are exposed for
+ // testing.
+ bool operator==(const RTCStats& other) const;
+ bool operator!=(const RTCStats& other) const;
+
+ // Creates a JSON readable string representation of the stats
+ // object, listing all of its members (names and values).
+ std::string ToJson() const;
+
+ // Downcasts the stats object to an `RTCStats` subclass `T`. DCHECKs that the
+ // object is of type `T`.
+ template <typename T>
+ const T& cast_to() const {
+ RTC_DCHECK_EQ(type(), T::kType);
+ return static_cast<const T&>(*this);
+ }
+
+ protected:
+ // Gets a vector of all members of this `RTCStats` object, including members
+ // derived from parent classes. `additional_capacity` is how many more members
+ // shall be reserved in the vector (so that subclasses can allocate a vector
+ // with room for both parent and child members without it having to resize).
+ virtual std::vector<const RTCStatsMemberInterface*>
+ MembersOfThisObjectAndAncestors(size_t additional_capacity) const;
+
+ std::string const id_;
+ Timestamp timestamp_;
+};
+
+// All `RTCStats` classes should use these macros.
+// `WEBRTC_RTCSTATS_DECL` is placed in a public section of the class definition.
+// `WEBRTC_RTCSTATS_IMPL` is placed outside the class definition (in a .cc).
+//
+// These macros declare (in _DECL) and define (in _IMPL) the static `kType` and
+// overrides methods as required by subclasses of `RTCStats`: `copy`, `type` and
+// `MembersOfThisObjectAndAncestors`. The |...| argument is a list of addresses
+// to each member defined in the implementing class. The list must have at least
+// one member.
+//
+// (Since class names need to be known to implement these methods this cannot be
+// part of the base `RTCStats`. While these methods could be implemented using
+// templates, that would only work for immediate subclasses. Subclasses of
+// subclasses also have to override these methods, resulting in boilerplate
+// code. Using a macro avoids this and works for any `RTCStats` class, including
+// grandchildren.)
+//
+// Sample usage:
+//
+// rtcfoostats.h:
+// class RTCFooStats : public RTCStats {
+// public:
+// WEBRTC_RTCSTATS_DECL();
+//
+// RTCFooStats(const std::string& id, int64_t timestamp_us);
+//
+// RTCStatsMember<int32_t> foo;
+// RTCStatsMember<int32_t> bar;
+// };
+//
+// rtcfoostats.cc:
+// WEBRTC_RTCSTATS_IMPL(RTCFooStats, RTCStats, "foo-stats"
+// &foo,
+// &bar);
+//
+// RTCFooStats::RTCFooStats(const std::string& id, int64_t timestamp_us)
+// : RTCStats(id, timestamp_us),
+// foo("foo"),
+// bar("bar") {
+// }
+//
+#define WEBRTC_RTCSTATS_DECL() \
+ protected: \
+ std::vector<const webrtc::RTCStatsMemberInterface*> \
+ MembersOfThisObjectAndAncestors(size_t local_var_additional_capacity) \
+ const override; \
+ \
+ public: \
+ static const char kType[]; \
+ \
+ std::unique_ptr<webrtc::RTCStats> copy() const override; \
+ const char* type() const override
+
+#define WEBRTC_RTCSTATS_IMPL(this_class, parent_class, type_str, ...) \
+ const char this_class::kType[] = type_str; \
+ \
+ std::unique_ptr<webrtc::RTCStats> this_class::copy() const { \
+ return std::make_unique<this_class>(*this); \
+ } \
+ \
+ const char* this_class::type() const { return this_class::kType; } \
+ \
+ std::vector<const webrtc::RTCStatsMemberInterface*> \
+ this_class::MembersOfThisObjectAndAncestors( \
+ size_t local_var_additional_capacity) const { \
+ const webrtc::RTCStatsMemberInterface* local_var_members[] = { \
+ __VA_ARGS__}; \
+ size_t local_var_members_count = \
+ sizeof(local_var_members) / sizeof(local_var_members[0]); \
+ std::vector<const webrtc::RTCStatsMemberInterface*> \
+ local_var_members_vec = parent_class::MembersOfThisObjectAndAncestors( \
+ local_var_members_count + local_var_additional_capacity); \
+ RTC_DCHECK_GE( \
+ local_var_members_vec.capacity() - local_var_members_vec.size(), \
+ local_var_members_count + local_var_additional_capacity); \
+ local_var_members_vec.insert(local_var_members_vec.end(), \
+ &local_var_members[0], \
+ &local_var_members[local_var_members_count]); \
+ return local_var_members_vec; \
+ }
+
+// A version of WEBRTC_RTCSTATS_IMPL() where "..." is omitted, used to avoid a
+// compile error on windows. This is used if the stats dictionary does not
+// declare any members of its own (but perhaps its parent dictionary does).
+#define WEBRTC_RTCSTATS_IMPL_NO_MEMBERS(this_class, parent_class, type_str) \
+ const char this_class::kType[] = type_str; \
+ \
+ std::unique_ptr<webrtc::RTCStats> this_class::copy() const { \
+ return std::make_unique<this_class>(*this); \
+ } \
+ \
+ const char* this_class::type() const { return this_class::kType; } \
+ \
+ std::vector<const webrtc::RTCStatsMemberInterface*> \
+ this_class::MembersOfThisObjectAndAncestors( \
+ size_t local_var_additional_capacity) const { \
+ return parent_class::MembersOfThisObjectAndAncestors(0); \
+ }
+
+// Non-standard stats members can be exposed to the JavaScript API in Chrome
+// e.g. through origin trials. The group ID can be used by the blink layer to
+// determine if a stats member should be exposed or not. Multiple non-standard
+// stats members can share the same group ID so that they are exposed together.
+enum class NonStandardGroupId {
+ // Group ID used for testing purposes only.
+ kGroupIdForTesting,
+ // I2E:
+ // https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/hE2B1iItPDk
+ kRtcAudioJitterBufferMaxPackets,
+ // I2E:
+ // https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/YbhMyqLXXXo
+ kRtcStatsRelativePacketArrivalDelay,
+};
+
+// Certain stat members should only be exposed to the JavaScript API in
+// certain circumstances as to avoid passive fingerprinting.
+enum class StatExposureCriteria : uint8_t {
+ // The stat should always be exposed. This is the default.
+ kAlways,
+ // The stat exposes hardware capabilities and thus should has limited exposure
+ // to JavaScript. The requirements for exposure are written in the spec at
+ // https://w3c.github.io/webrtc-stats/#limiting-exposure-of-hardware-capabilities.
+ kHardwareCapability,
+ // The stat is non-standard so user agents should filter these.
+ kNonStandard,
+};
+
+// Interface for `RTCStats` members, which have a name and a value of a type
+// defined in a subclass. Only the types listed in `Type` are supported, these
+// are implemented by `RTCStatsMember<T>`. The value of a member may be
+// undefined, the value can only be read if `is_defined`.
+class RTCStatsMemberInterface {
+ public:
+ // Member value types.
+ enum Type {
+ kBool, // bool
+ kInt32, // int32_t
+ kUint32, // uint32_t
+ kInt64, // int64_t
+ kUint64, // uint64_t
+ kDouble, // double
+ kString, // std::string
+
+ kSequenceBool, // std::vector<bool>
+ kSequenceInt32, // std::vector<int32_t>
+ kSequenceUint32, // std::vector<uint32_t>
+ kSequenceInt64, // std::vector<int64_t>
+ kSequenceUint64, // std::vector<uint64_t>
+ kSequenceDouble, // std::vector<double>
+ kSequenceString, // std::vector<std::string>
+
+ kMapStringUint64, // std::map<std::string, uint64_t>
+ kMapStringDouble, // std::map<std::string, double>
+ };
+
+ virtual ~RTCStatsMemberInterface() {}
+
+ const char* name() const { return name_; }
+ virtual Type type() const = 0;
+ virtual bool is_sequence() const = 0;
+ virtual bool is_string() const = 0;
+ virtual bool is_defined() const = 0;
+ // Is this part of the stats spec? Used so that chromium can easily filter
+ // out anything unstandardized.
+ bool is_standardized() const {
+ return exposure_criteria() != StatExposureCriteria::kNonStandard;
+ }
+ // Non-standard stats members can have group IDs in order to be exposed in
+ // JavaScript through experiments. Standardized stats have no group IDs.
+ virtual std::vector<NonStandardGroupId> group_ids() const { return {}; }
+ // The conditions for exposing the statistic to JavaScript. Stats with
+ // criteria that is not kAlways has some restriction and should be filtered
+ // in accordance to the spec.
+ virtual StatExposureCriteria exposure_criteria() const {
+ return StatExposureCriteria::kAlways;
+ }
+ // Type and value comparator. The names are not compared. These operators are
+ // exposed for testing.
+ bool operator==(const RTCStatsMemberInterface& other) const {
+ return IsEqual(other);
+ }
+ bool operator!=(const RTCStatsMemberInterface& other) const {
+ return !(*this == other);
+ }
+ virtual std::string ValueToString() const = 0;
+ // This is the same as ValueToString except for kInt64 and kUint64 types,
+ // where the value is represented as a double instead of as an integer.
+ // Since JSON stores numbers as floating point numbers, very large integers
+ // cannot be accurately represented, so we prefer to display them as doubles
+ // instead.
+ virtual std::string ValueToJson() const = 0;
+
+ template <typename T>
+ const T& cast_to() const {
+ RTC_DCHECK_EQ(type(), T::StaticType());
+ return static_cast<const T&>(*this);
+ }
+
+ protected:
+ explicit RTCStatsMemberInterface(const char* name) : name_(name) {}
+
+ virtual bool IsEqual(const RTCStatsMemberInterface& other) const = 0;
+
+ const char* const name_;
+};
+
+// Template implementation of `RTCStatsMemberInterface`.
+// The supported types are the ones described by
+// `RTCStatsMemberInterface::Type`.
+template <typename T>
+class RTCStatsMember : public RTCStatsMemberInterface {
+ public:
+ explicit RTCStatsMember(const char* name)
+ : RTCStatsMemberInterface(name), value_() {}
+ RTCStatsMember(const char* name, const T& value)
+ : RTCStatsMemberInterface(name), value_(value) {}
+ RTCStatsMember(const char* name, T&& value)
+ : RTCStatsMemberInterface(name), value_(std::move(value)) {}
+ explicit RTCStatsMember(const RTCStatsMember<T>& other)
+ : RTCStatsMemberInterface(other.name_), value_(other.value_) {}
+ explicit RTCStatsMember(RTCStatsMember<T>&& other)
+ : RTCStatsMemberInterface(other.name_), value_(std::move(other.value_)) {}
+
+ static Type StaticType();
+ Type type() const override { return StaticType(); }
+ bool is_sequence() const override;
+ bool is_string() const override;
+ bool is_defined() const override { return value_.has_value(); }
+ std::string ValueToString() const override;
+ std::string ValueToJson() const override;
+
+ template <typename U>
+ inline T ValueOrDefault(U default_value) const {
+ return value_.value_or(default_value);
+ }
+
+ // Assignment operators.
+ T& operator=(const T& value) {
+ value_ = value;
+ return value_.value();
+ }
+ T& operator=(const T&& value) {
+ value_ = std::move(value);
+ return value_.value();
+ }
+
+ // Value getters.
+ T& operator*() {
+ RTC_DCHECK(value_);
+ return *value_;
+ }
+ const T& operator*() const {
+ RTC_DCHECK(value_);
+ return *value_;
+ }
+
+ // Value getters, arrow operator.
+ T* operator->() {
+ RTC_DCHECK(value_);
+ return &(*value_);
+ }
+ const T* operator->() const {
+ RTC_DCHECK(value_);
+ return &(*value_);
+ }
+
+ protected:
+ bool IsEqual(const RTCStatsMemberInterface& other) const override {
+ if (type() != other.type() ||
+ is_standardized() != other.is_standardized() ||
+ exposure_criteria() != other.exposure_criteria())
+ return false;
+ const RTCStatsMember<T>& other_t =
+ static_cast<const RTCStatsMember<T>&>(other);
+ return value_ == other_t.value_;
+ }
+
+ private:
+ absl::optional<T> value_;
+};
+
+namespace rtc_stats_internal {
+
+typedef std::map<std::string, uint64_t> MapStringUint64;
+typedef std::map<std::string, double> MapStringDouble;
+
+} // namespace rtc_stats_internal
+
+#define WEBRTC_DECLARE_RTCSTATSMEMBER(T) \
+ template <> \
+ RTC_EXPORT RTCStatsMemberInterface::Type RTCStatsMember<T>::StaticType(); \
+ template <> \
+ RTC_EXPORT bool RTCStatsMember<T>::is_sequence() const; \
+ template <> \
+ RTC_EXPORT bool RTCStatsMember<T>::is_string() const; \
+ template <> \
+ RTC_EXPORT std::string RTCStatsMember<T>::ValueToString() const; \
+ template <> \
+ RTC_EXPORT std::string RTCStatsMember<T>::ValueToJson() const; \
+ extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT) \
+ RTCStatsMember<T>
+
+WEBRTC_DECLARE_RTCSTATSMEMBER(bool);
+WEBRTC_DECLARE_RTCSTATSMEMBER(int32_t);
+WEBRTC_DECLARE_RTCSTATSMEMBER(uint32_t);
+WEBRTC_DECLARE_RTCSTATSMEMBER(int64_t);
+WEBRTC_DECLARE_RTCSTATSMEMBER(uint64_t);
+WEBRTC_DECLARE_RTCSTATSMEMBER(double);
+WEBRTC_DECLARE_RTCSTATSMEMBER(std::string);
+WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<bool>);
+WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<int32_t>);
+WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<uint32_t>);
+WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<int64_t>);
+WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<uint64_t>);
+WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<double>);
+WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector<std::string>);
+WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringUint64);
+WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringDouble);
+
+// For stats with restricted exposure.
+template <typename T, StatExposureCriteria E>
+class RTCRestrictedStatsMember : public RTCStatsMember<T> {
+ public:
+ explicit RTCRestrictedStatsMember(const char* name)
+ : RTCStatsMember<T>(name) {}
+ RTCRestrictedStatsMember(const char* name, const T& value)
+ : RTCStatsMember<T>(name, value) {}
+ RTCRestrictedStatsMember(const char* name, T&& value)
+ : RTCStatsMember<T>(name, std::move(value)) {}
+ RTCRestrictedStatsMember(const RTCRestrictedStatsMember<T, E>& other)
+ : RTCStatsMember<T>(other) {}
+ RTCRestrictedStatsMember(RTCRestrictedStatsMember<T, E>&& other)
+ : RTCStatsMember<T>(std::move(other)) {}
+
+ StatExposureCriteria exposure_criteria() const override { return E; }
+
+ T& operator=(const T& value) { return RTCStatsMember<T>::operator=(value); }
+ T& operator=(const T&& value) {
+ return RTCStatsMember<T>::operator=(std::move(value));
+ }
+
+ private:
+ static_assert(E != StatExposureCriteria::kAlways,
+ "kAlways is the default exposure criteria. Use "
+ "RTCStatMember<T> instead.");
+};
+
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCRestrictedStatsMember<bool, StatExposureCriteria::kHardwareCapability>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCRestrictedStatsMember<int32_t,
+ StatExposureCriteria::kHardwareCapability>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCRestrictedStatsMember<uint32_t,
+ StatExposureCriteria::kHardwareCapability>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCRestrictedStatsMember<int64_t,
+ StatExposureCriteria::kHardwareCapability>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCRestrictedStatsMember<uint64_t,
+ StatExposureCriteria::kHardwareCapability>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCRestrictedStatsMember<double, StatExposureCriteria::kHardwareCapability>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCRestrictedStatsMember<std::string,
+ StatExposureCriteria::kHardwareCapability>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCRestrictedStatsMember<std::vector<bool>,
+ StatExposureCriteria::kHardwareCapability>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCRestrictedStatsMember<std::vector<int32_t>,
+ StatExposureCriteria::kHardwareCapability>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCRestrictedStatsMember<std::vector<uint32_t>,
+ StatExposureCriteria::kHardwareCapability>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCRestrictedStatsMember<std::vector<int64_t>,
+ StatExposureCriteria::kHardwareCapability>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCRestrictedStatsMember<std::vector<uint64_t>,
+ StatExposureCriteria::kHardwareCapability>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCRestrictedStatsMember<std::vector<double>,
+ StatExposureCriteria::kHardwareCapability>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCRestrictedStatsMember<std::vector<std::string>,
+ StatExposureCriteria::kHardwareCapability>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCRestrictedStatsMember<std::map<std::string, uint64_t>,
+ StatExposureCriteria::kHardwareCapability>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCRestrictedStatsMember<std::map<std::string, double>,
+ StatExposureCriteria::kHardwareCapability>;
+
+// Using inheritance just so that it's obvious from the member's declaration
+// whether it's standardized or not.
+template <typename T>
+class RTCNonStandardStatsMember
+ : public RTCRestrictedStatsMember<T, StatExposureCriteria::kNonStandard> {
+ public:
+ explicit RTCNonStandardStatsMember(const char* name)
+ : RTCRestrictedStatsBase(name) {}
+ RTCNonStandardStatsMember(const char* name,
+ std::initializer_list<NonStandardGroupId> group_ids)
+ : RTCRestrictedStatsBase(name), group_ids_(group_ids) {}
+ RTCNonStandardStatsMember(const char* name, const T& value)
+ : RTCRestrictedStatsBase(name, value) {}
+ RTCNonStandardStatsMember(const char* name, T&& value)
+ : RTCRestrictedStatsBase(name, std::move(value)) {}
+ RTCNonStandardStatsMember(const RTCNonStandardStatsMember<T>& other)
+ : RTCRestrictedStatsBase(other), group_ids_(other.group_ids_) {}
+ RTCNonStandardStatsMember(RTCNonStandardStatsMember<T>&& other)
+ : RTCRestrictedStatsBase(std::move(other)),
+ group_ids_(std::move(other.group_ids_)) {}
+
+ std::vector<NonStandardGroupId> group_ids() const override {
+ return group_ids_;
+ }
+
+ T& operator=(const T& value) {
+ return RTCRestrictedStatsMember<
+ T, StatExposureCriteria::kNonStandard>::operator=(value);
+ }
+ T& operator=(const T&& value) {
+ return RTCRestrictedStatsMember<
+ T, StatExposureCriteria::kNonStandard>::operator=(std::move(value));
+ }
+
+ private:
+ using RTCRestrictedStatsBase =
+ RTCRestrictedStatsMember<T, StatExposureCriteria::kNonStandard>;
+ std::vector<NonStandardGroupId> group_ids_;
+};
+
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCNonStandardStatsMember<bool>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCNonStandardStatsMember<int32_t>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCNonStandardStatsMember<uint32_t>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCNonStandardStatsMember<int64_t>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCNonStandardStatsMember<uint64_t>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCNonStandardStatsMember<double>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCNonStandardStatsMember<std::string>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCNonStandardStatsMember<std::vector<bool>>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCNonStandardStatsMember<std::vector<int32_t>>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCNonStandardStatsMember<std::vector<uint32_t>>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCNonStandardStatsMember<std::vector<int64_t>>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCNonStandardStatsMember<std::vector<uint64_t>>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCNonStandardStatsMember<std::vector<double>>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCNonStandardStatsMember<std::vector<std::string>>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCNonStandardStatsMember<std::map<std::string, uint64_t>>;
+extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT)
+ RTCNonStandardStatsMember<std::map<std::string, double>>;
+
+} // namespace webrtc
+
+#endif // API_STATS_RTC_STATS_H_
diff --git a/third_party/libwebrtc/api/stats/rtc_stats_collector_callback.h b/third_party/libwebrtc/api/stats/rtc_stats_collector_callback.h
new file mode 100644
index 0000000000..506cc63e6f
--- /dev/null
+++ b/third_party/libwebrtc/api/stats/rtc_stats_collector_callback.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2016 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_STATS_RTC_STATS_COLLECTOR_CALLBACK_H_
+#define API_STATS_RTC_STATS_COLLECTOR_CALLBACK_H_
+
+#include "api/scoped_refptr.h"
+#include "api/stats/rtc_stats_report.h"
+#include "rtc_base/ref_count.h"
+
+namespace webrtc {
+
+class RTCStatsCollectorCallback : public rtc::RefCountInterface {
+ public:
+ ~RTCStatsCollectorCallback() override = default;
+
+ virtual void OnStatsDelivered(
+ const rtc::scoped_refptr<const RTCStatsReport>& report) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_STATS_RTC_STATS_COLLECTOR_CALLBACK_H_
diff --git a/third_party/libwebrtc/api/stats/rtc_stats_report.h b/third_party/libwebrtc/api/stats/rtc_stats_report.h
new file mode 100644
index 0000000000..1cc6293fec
--- /dev/null
+++ b/third_party/libwebrtc/api/stats/rtc_stats_report.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2016 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_STATS_RTC_STATS_REPORT_H_
+#define API_STATS_RTC_STATS_REPORT_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "api/ref_counted_base.h"
+#include "api/scoped_refptr.h"
+#include "api/stats/rtc_stats.h"
+#include "api/units/timestamp.h"
+// TODO(tommi): Remove this include after fixing iwyu issue in chromium.
+// See: third_party/blink/renderer/platform/peerconnection/rtc_stats.cc
+#include "rtc_base/ref_counted_object.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// A collection of stats.
+// This is accessible as a map from `RTCStats::id` to `RTCStats`.
+class RTC_EXPORT RTCStatsReport final
+ : public rtc::RefCountedNonVirtual<RTCStatsReport> {
+ public:
+ typedef std::map<std::string, std::unique_ptr<const RTCStats>> StatsMap;
+
+ class RTC_EXPORT ConstIterator {
+ public:
+ ConstIterator(ConstIterator&& other);
+ ~ConstIterator();
+
+ ConstIterator& operator++();
+ ConstIterator& operator++(int);
+ const RTCStats& operator*() const;
+ const RTCStats* operator->() const;
+ bool operator==(const ConstIterator& other) const;
+ bool operator!=(const ConstIterator& other) const;
+
+ private:
+ friend class RTCStatsReport;
+ ConstIterator(const rtc::scoped_refptr<const RTCStatsReport>& report,
+ StatsMap::const_iterator it);
+
+ // Reference report to make sure it is kept alive.
+ rtc::scoped_refptr<const RTCStatsReport> report_;
+ StatsMap::const_iterator it_;
+ };
+
+ // TODO(bugs.webrtc.org/13756): deprecate this in favor of Timestamp.
+ // TODO(hbos): Remove "= 0" once downstream has been updated to call with a
+ // parameter.
+ static rtc::scoped_refptr<RTCStatsReport> Create(int64_t timestamp_us = 0);
+ static rtc::scoped_refptr<RTCStatsReport> Create(Timestamp timestamp);
+
+ // TODO(bugs.webrtc.org/13756): deprecate this in favor of Timestamp.
+ explicit RTCStatsReport(int64_t timestamp_us);
+ explicit RTCStatsReport(Timestamp timestamp);
+
+ RTCStatsReport(const RTCStatsReport& other) = delete;
+ rtc::scoped_refptr<RTCStatsReport> Copy() const;
+
+ int64_t timestamp_us() const { return timestamp_.us_or(-1); }
+ Timestamp timestamp() const { return timestamp_; }
+ void AddStats(std::unique_ptr<const RTCStats> stats);
+ // On success, returns a non-owning pointer to `stats`. If the stats ID is not
+ // unique, `stats` is not inserted and nullptr is returned.
+ template <typename T>
+ T* TryAddStats(std::unique_ptr<T> stats) {
+ T* stats_ptr = stats.get();
+ if (!stats_
+ .insert(std::make_pair(std::string(stats->id()), std::move(stats)))
+ .second) {
+ return nullptr;
+ }
+ return stats_ptr;
+ }
+ const RTCStats* Get(const std::string& id) const;
+ size_t size() const { return stats_.size(); }
+
+ // Gets the stat object of type `T` by ID, where `T` is any class descending
+ // from `RTCStats`.
+ // Returns null if there is no stats object for the given ID or it is the
+ // wrong type.
+ template <typename T>
+ const T* GetAs(const std::string& id) const {
+ const RTCStats* stats = Get(id);
+ if (!stats || stats->type() != T::kType) {
+ return nullptr;
+ }
+ return &stats->cast_to<const T>();
+ }
+
+ // Removes the stats object from the report, returning ownership of it or null
+ // if there is no object with `id`.
+ std::unique_ptr<const RTCStats> Take(const std::string& id);
+ // Takes ownership of all the stats in `other`, leaving it empty.
+ void TakeMembersFrom(rtc::scoped_refptr<RTCStatsReport> other);
+
+ // Stats iterators. Stats are ordered lexicographically on `RTCStats::id`.
+ ConstIterator begin() const;
+ ConstIterator end() const;
+
+ // Gets the subset of stats that are of type `T`, where `T` is any class
+ // descending from `RTCStats`.
+ template <typename T>
+ std::vector<const T*> GetStatsOfType() const {
+ std::vector<const T*> stats_of_type;
+ for (const RTCStats& stats : *this) {
+ if (stats.type() == T::kType)
+ stats_of_type.push_back(&stats.cast_to<const T>());
+ }
+ return stats_of_type;
+ }
+
+ // Creates a JSON readable string representation of the report,
+ // listing all of its stats objects.
+ std::string ToJson() const;
+
+ protected:
+ friend class rtc::RefCountedNonVirtual<RTCStatsReport>;
+ ~RTCStatsReport() = default;
+
+ private:
+ Timestamp timestamp_;
+ StatsMap stats_;
+};
+
+} // namespace webrtc
+
+#endif // API_STATS_RTC_STATS_REPORT_H_
diff --git a/third_party/libwebrtc/api/stats/rtcstats_objects.h b/third_party/libwebrtc/api/stats/rtcstats_objects.h
new file mode 100644
index 0000000000..e5de2100bb
--- /dev/null
+++ b/third_party/libwebrtc/api/stats/rtcstats_objects.h
@@ -0,0 +1,722 @@
+/*
+ * Copyright 2016 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_STATS_RTCSTATS_OBJECTS_H_
+#define API_STATS_RTCSTATS_OBJECTS_H_
+
+#include <stdint.h>
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "api/stats/rtc_stats.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// https://w3c.github.io/webrtc-pc/#idl-def-rtcdatachannelstate
+struct RTCDataChannelState {
+ static const char* const kConnecting;
+ static const char* const kOpen;
+ static const char* const kClosing;
+ static const char* const kClosed;
+};
+
+// https://w3c.github.io/webrtc-stats/#dom-rtcstatsicecandidatepairstate
+struct RTCStatsIceCandidatePairState {
+ static const char* const kFrozen;
+ static const char* const kWaiting;
+ static const char* const kInProgress;
+ static const char* const kFailed;
+ static const char* const kSucceeded;
+};
+
+// https://w3c.github.io/webrtc-pc/#rtcicecandidatetype-enum
+struct RTCIceCandidateType {
+ static const char* const kHost;
+ static const char* const kSrflx;
+ static const char* const kPrflx;
+ static const char* const kRelay;
+};
+
+// https://w3c.github.io/webrtc-pc/#idl-def-rtcdtlstransportstate
+struct RTCDtlsTransportState {
+ static const char* const kNew;
+ static const char* const kConnecting;
+ static const char* const kConnected;
+ static const char* const kClosed;
+ static const char* const kFailed;
+};
+
+// `RTCMediaStreamTrackStats::kind` is not an enum in the spec but the only
+// valid values are "audio" and "video".
+// https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamtrackstats-kind
+struct RTCMediaStreamTrackKind {
+ static const char* const kAudio;
+ static const char* const kVideo;
+};
+
+// https://w3c.github.io/webrtc-stats/#dom-rtcnetworktype
+struct RTCNetworkType {
+ static const char* const kBluetooth;
+ static const char* const kCellular;
+ static const char* const kEthernet;
+ static const char* const kWifi;
+ static const char* const kWimax;
+ static const char* const kVpn;
+ static const char* const kUnknown;
+};
+
+// https://w3c.github.io/webrtc-stats/#dom-rtcqualitylimitationreason
+struct RTCQualityLimitationReason {
+ static const char* const kNone;
+ static const char* const kCpu;
+ static const char* const kBandwidth;
+ static const char* const kOther;
+};
+
+// https://webrtc.org/experiments/rtp-hdrext/video-content-type/
+struct RTCContentType {
+ static const char* const kUnspecified;
+ static const char* const kScreenshare;
+};
+
+// https://w3c.github.io/webrtc-stats/#dom-rtcdtlsrole
+struct RTCDtlsRole {
+ static const char* const kUnknown;
+ static const char* const kClient;
+ static const char* const kServer;
+};
+
+// https://www.w3.org/TR/webrtc/#rtcicerole
+struct RTCIceRole {
+ static const char* const kUnknown;
+ static const char* const kControlled;
+ static const char* const kControlling;
+};
+
+// https://www.w3.org/TR/webrtc/#dom-rtcicetransportstate
+struct RTCIceTransportState {
+ static const char* const kNew;
+ static const char* const kChecking;
+ static const char* const kConnected;
+ static const char* const kCompleted;
+ static const char* const kDisconnected;
+ static const char* const kFailed;
+ static const char* const kClosed;
+};
+
+// https://w3c.github.io/webrtc-stats/#certificatestats-dict*
+class RTC_EXPORT RTCCertificateStats final : public RTCStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ RTCCertificateStats(std::string id, Timestamp timestamp);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCCertificateStats(std::string id, int64_t timestamp_us);
+ RTCCertificateStats(const RTCCertificateStats& other);
+ ~RTCCertificateStats() override;
+
+ RTCStatsMember<std::string> fingerprint;
+ RTCStatsMember<std::string> fingerprint_algorithm;
+ RTCStatsMember<std::string> base64_certificate;
+ RTCStatsMember<std::string> issuer_certificate_id;
+};
+
+// Non standard extension mapping to rtc::AdapterType
+struct RTCNetworkAdapterType {
+ static constexpr char kUnknown[] = "unknown";
+ static constexpr char kEthernet[] = "ethernet";
+ static constexpr char kWifi[] = "wifi";
+ static constexpr char kCellular[] = "cellular";
+ static constexpr char kLoopback[] = "loopback";
+ static constexpr char kAny[] = "any";
+ static constexpr char kCellular2g[] = "cellular2g";
+ static constexpr char kCellular3g[] = "cellular3g";
+ static constexpr char kCellular4g[] = "cellular4g";
+ static constexpr char kCellular5g[] = "cellular5g";
+};
+
+// https://w3c.github.io/webrtc-stats/#codec-dict*
+class RTC_EXPORT RTCCodecStats final : public RTCStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ RTCCodecStats(std::string id, Timestamp timestamp);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCCodecStats(std::string id, int64_t timestamp_us);
+ RTCCodecStats(const RTCCodecStats& other);
+ ~RTCCodecStats() override;
+
+ RTCStatsMember<std::string> transport_id;
+ RTCStatsMember<uint32_t> payload_type;
+ RTCStatsMember<std::string> mime_type;
+ RTCStatsMember<uint32_t> clock_rate;
+ RTCStatsMember<uint32_t> channels;
+ RTCStatsMember<std::string> sdp_fmtp_line;
+};
+
+// https://w3c.github.io/webrtc-stats/#dcstats-dict*
+class RTC_EXPORT RTCDataChannelStats final : public RTCStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ RTCDataChannelStats(std::string id, Timestamp timestamp);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCDataChannelStats(std::string id, int64_t timestamp_us);
+ RTCDataChannelStats(const RTCDataChannelStats& other);
+ ~RTCDataChannelStats() override;
+
+ RTCStatsMember<std::string> label;
+ RTCStatsMember<std::string> protocol;
+ RTCStatsMember<int32_t> data_channel_identifier;
+ // Enum type RTCDataChannelState.
+ RTCStatsMember<std::string> state;
+ RTCStatsMember<uint32_t> messages_sent;
+ RTCStatsMember<uint64_t> bytes_sent;
+ RTCStatsMember<uint32_t> messages_received;
+ RTCStatsMember<uint64_t> bytes_received;
+};
+
+// https://w3c.github.io/webrtc-stats/#candidatepair-dict*
+class RTC_EXPORT RTCIceCandidatePairStats final : public RTCStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ RTCIceCandidatePairStats(std::string id, Timestamp timestamp);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCIceCandidatePairStats(std::string id, int64_t timestamp_us);
+ RTCIceCandidatePairStats(const RTCIceCandidatePairStats& other);
+ ~RTCIceCandidatePairStats() override;
+
+ RTCStatsMember<std::string> transport_id;
+ RTCStatsMember<std::string> local_candidate_id;
+ RTCStatsMember<std::string> remote_candidate_id;
+ // Enum type RTCStatsIceCandidatePairState.
+ RTCStatsMember<std::string> state;
+ // Obsolete: priority
+ RTCStatsMember<uint64_t> priority;
+ RTCStatsMember<bool> nominated;
+ // `writable` does not exist in the spec and old comments suggest it used to
+ // exist but was incorrectly implemented.
+ // TODO(https://crbug.com/webrtc/14171): Standardize and/or modify
+ // implementation.
+ RTCStatsMember<bool> writable;
+ RTCStatsMember<uint64_t> packets_sent;
+ RTCStatsMember<uint64_t> packets_received;
+ RTCStatsMember<uint64_t> bytes_sent;
+ RTCStatsMember<uint64_t> bytes_received;
+ RTCStatsMember<double> total_round_trip_time;
+ RTCStatsMember<double> current_round_trip_time;
+ RTCStatsMember<double> available_outgoing_bitrate;
+ RTCStatsMember<double> available_incoming_bitrate;
+ RTCStatsMember<uint64_t> requests_received;
+ RTCStatsMember<uint64_t> requests_sent;
+ RTCStatsMember<uint64_t> responses_received;
+ RTCStatsMember<uint64_t> responses_sent;
+ RTCStatsMember<uint64_t> consent_requests_sent;
+ RTCStatsMember<uint64_t> packets_discarded_on_send;
+ RTCStatsMember<uint64_t> bytes_discarded_on_send;
+ RTCStatsMember<double> last_packet_received_timestamp;
+ RTCStatsMember<double> last_packet_sent_timestamp;
+};
+
+// https://w3c.github.io/webrtc-stats/#icecandidate-dict*
+class RTC_EXPORT RTCIceCandidateStats : public RTCStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ RTCIceCandidateStats(const RTCIceCandidateStats& other);
+ ~RTCIceCandidateStats() override;
+
+ RTCStatsMember<std::string> transport_id;
+ // Obsolete: is_remote
+ RTCStatsMember<bool> is_remote;
+ RTCStatsMember<std::string> network_type;
+ RTCStatsMember<std::string> ip;
+ RTCStatsMember<std::string> address;
+ RTCStatsMember<int32_t> port;
+ RTCStatsMember<std::string> protocol;
+ RTCStatsMember<std::string> relay_protocol;
+ // Enum type RTCIceCandidateType.
+ RTCStatsMember<std::string> candidate_type;
+ RTCStatsMember<int32_t> priority;
+ RTCStatsMember<std::string> url;
+ RTCStatsMember<std::string> foundation;
+ RTCStatsMember<std::string> related_address;
+ RTCStatsMember<int32_t> related_port;
+ RTCStatsMember<std::string> username_fragment;
+ // Enum type RTCIceTcpCandidateType.
+ RTCStatsMember<std::string> tcp_type;
+
+ RTCNonStandardStatsMember<bool> vpn;
+ RTCNonStandardStatsMember<std::string> network_adapter_type;
+
+ protected:
+ RTCIceCandidateStats(std::string id, Timestamp timestamp, bool is_remote);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCIceCandidateStats(std::string id, int64_t timestamp_us, bool is_remote);
+};
+
+// In the spec both local and remote varieties are of type RTCIceCandidateStats.
+// But here we define them as subclasses of `RTCIceCandidateStats` because the
+// `kType` need to be different ("RTCStatsType type") in the local/remote case.
+// https://w3c.github.io/webrtc-stats/#rtcstatstype-str*
+// This forces us to have to override copy() and type().
+class RTC_EXPORT RTCLocalIceCandidateStats final : public RTCIceCandidateStats {
+ public:
+ static const char kType[];
+ RTCLocalIceCandidateStats(std::string id, Timestamp timestamp);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCLocalIceCandidateStats(std::string id, int64_t timestamp_us);
+ std::unique_ptr<RTCStats> copy() const override;
+ const char* type() const override;
+};
+
+class RTC_EXPORT RTCRemoteIceCandidateStats final
+ : public RTCIceCandidateStats {
+ public:
+ static const char kType[];
+ RTCRemoteIceCandidateStats(std::string id, Timestamp timestamp);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCRemoteIceCandidateStats(std::string id, int64_t timestamp_us);
+ std::unique_ptr<RTCStats> copy() const override;
+ const char* type() const override;
+};
+
+// TODO(https://crbug.com/webrtc/14419): Delete this class, it's deprecated.
+class RTC_EXPORT DEPRECATED_RTCMediaStreamStats final : public RTCStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ DEPRECATED_RTCMediaStreamStats(std::string id, Timestamp timestamp);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ DEPRECATED_RTCMediaStreamStats(std::string id, int64_t timestamp_us);
+ DEPRECATED_RTCMediaStreamStats(const DEPRECATED_RTCMediaStreamStats& other);
+ ~DEPRECATED_RTCMediaStreamStats() override;
+
+ RTCStatsMember<std::string> stream_identifier;
+ RTCStatsMember<std::vector<std::string>> track_ids;
+};
+using RTCMediaStreamStats [[deprecated("bugs.webrtc.org/14419")]] =
+ DEPRECATED_RTCMediaStreamStats;
+
+// TODO(https://crbug.com/webrtc/14175): Delete this class, it's deprecated.
+class RTC_EXPORT DEPRECATED_RTCMediaStreamTrackStats final : public RTCStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ DEPRECATED_RTCMediaStreamTrackStats(std::string id,
+ Timestamp timestamp,
+ const char* kind);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ DEPRECATED_RTCMediaStreamTrackStats(std::string id,
+ int64_t timestamp_us,
+ const char* kind);
+ DEPRECATED_RTCMediaStreamTrackStats(
+ const DEPRECATED_RTCMediaStreamTrackStats& other);
+ ~DEPRECATED_RTCMediaStreamTrackStats() override;
+
+ RTCStatsMember<std::string> track_identifier;
+ RTCStatsMember<std::string> media_source_id;
+ RTCStatsMember<bool> remote_source;
+ RTCStatsMember<bool> ended;
+ // TODO(https://crbug.com/webrtc/14173): Remove this obsolete metric.
+ RTCStatsMember<bool> detached;
+ // Enum type RTCMediaStreamTrackKind.
+ RTCStatsMember<std::string> kind;
+ RTCStatsMember<double> jitter_buffer_delay;
+ RTCStatsMember<uint64_t> jitter_buffer_emitted_count;
+ // Video-only members
+ RTCStatsMember<uint32_t> frame_width;
+ RTCStatsMember<uint32_t> frame_height;
+ RTCStatsMember<uint32_t> frames_sent;
+ RTCStatsMember<uint32_t> huge_frames_sent;
+ RTCStatsMember<uint32_t> frames_received;
+ RTCStatsMember<uint32_t> frames_decoded;
+ RTCStatsMember<uint32_t> frames_dropped;
+ // Audio-only members
+ RTCStatsMember<double> audio_level; // Receive-only
+ RTCStatsMember<double> total_audio_energy; // Receive-only
+ RTCStatsMember<double> echo_return_loss;
+ RTCStatsMember<double> echo_return_loss_enhancement;
+ RTCStatsMember<uint64_t> total_samples_received;
+ RTCStatsMember<double> total_samples_duration; // Receive-only
+ RTCStatsMember<uint64_t> concealed_samples;
+ RTCStatsMember<uint64_t> silent_concealed_samples;
+ RTCStatsMember<uint64_t> concealment_events;
+ RTCStatsMember<uint64_t> inserted_samples_for_deceleration;
+ RTCStatsMember<uint64_t> removed_samples_for_acceleration;
+};
+using RTCMediaStreamTrackStats [[deprecated("bugs.webrtc.org/14175")]] =
+ DEPRECATED_RTCMediaStreamTrackStats;
+
+// https://w3c.github.io/webrtc-stats/#pcstats-dict*
+class RTC_EXPORT RTCPeerConnectionStats final : public RTCStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ RTCPeerConnectionStats(std::string id, Timestamp timestamp);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCPeerConnectionStats(std::string id, int64_t timestamp_us);
+ RTCPeerConnectionStats(const RTCPeerConnectionStats& other);
+ ~RTCPeerConnectionStats() override;
+
+ RTCStatsMember<uint32_t> data_channels_opened;
+ RTCStatsMember<uint32_t> data_channels_closed;
+};
+
+// https://w3c.github.io/webrtc-stats/#streamstats-dict*
+class RTC_EXPORT RTCRTPStreamStats : public RTCStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ RTCRTPStreamStats(const RTCRTPStreamStats& other);
+ ~RTCRTPStreamStats() override;
+
+ RTCStatsMember<uint32_t> ssrc;
+ RTCStatsMember<std::string> kind;
+ // Obsolete: track_id
+ RTCStatsMember<std::string> track_id;
+ RTCStatsMember<std::string> transport_id;
+ RTCStatsMember<std::string> codec_id;
+
+ // Obsolete
+ RTCStatsMember<std::string> media_type; // renamed to kind.
+
+ protected:
+ RTCRTPStreamStats(std::string id, Timestamp timestamp);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCRTPStreamStats(std::string id, int64_t timestamp_us);
+};
+
+// https://www.w3.org/TR/webrtc-stats/#receivedrtpstats-dict*
+class RTC_EXPORT RTCReceivedRtpStreamStats : public RTCRTPStreamStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ RTCReceivedRtpStreamStats(const RTCReceivedRtpStreamStats& other);
+ ~RTCReceivedRtpStreamStats() override;
+
+ RTCStatsMember<double> jitter;
+ RTCStatsMember<int32_t> packets_lost; // Signed per RFC 3550
+
+ protected:
+ RTCReceivedRtpStreamStats(std::string id, Timestamp timestamp);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCReceivedRtpStreamStats(std::string id, int64_t timestamp_us);
+};
+
+// https://www.w3.org/TR/webrtc-stats/#sentrtpstats-dict*
+class RTC_EXPORT RTCSentRtpStreamStats : public RTCRTPStreamStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ RTCSentRtpStreamStats(const RTCSentRtpStreamStats& other);
+ ~RTCSentRtpStreamStats() override;
+
+ RTCStatsMember<uint32_t> packets_sent;
+ RTCStatsMember<uint64_t> bytes_sent;
+
+ protected:
+ RTCSentRtpStreamStats(std::string id, Timestamp timestamp);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCSentRtpStreamStats(std::string id, int64_t timestamp_us);
+};
+
+// https://w3c.github.io/webrtc-stats/#inboundrtpstats-dict*
+class RTC_EXPORT RTCInboundRTPStreamStats final
+ : public RTCReceivedRtpStreamStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ RTCInboundRTPStreamStats(std::string id, Timestamp timestamp);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCInboundRTPStreamStats(std::string id, int64_t timestamp_us);
+ RTCInboundRTPStreamStats(const RTCInboundRTPStreamStats& other);
+ ~RTCInboundRTPStreamStats() override;
+
+ // TODO(https://crbug.com/webrtc/14174): Implement trackIdentifier and kind.
+
+ RTCStatsMember<std::string> playout_id;
+ RTCStatsMember<std::string> track_identifier;
+ RTCStatsMember<std::string> mid;
+ RTCStatsMember<std::string> remote_id;
+ RTCStatsMember<uint32_t> packets_received;
+ RTCStatsMember<uint64_t> packets_discarded;
+ RTCStatsMember<uint64_t> fec_packets_received;
+ RTCStatsMember<uint64_t> fec_packets_discarded;
+ RTCStatsMember<uint64_t> bytes_received;
+ RTCStatsMember<uint64_t> header_bytes_received;
+ RTCStatsMember<double> last_packet_received_timestamp;
+ RTCStatsMember<double> jitter_buffer_delay;
+ RTCStatsMember<double> jitter_buffer_target_delay;
+ RTCStatsMember<double> jitter_buffer_minimum_delay;
+ RTCStatsMember<uint64_t> jitter_buffer_emitted_count;
+ RTCStatsMember<uint64_t> total_samples_received;
+ RTCStatsMember<uint64_t> concealed_samples;
+ RTCStatsMember<uint64_t> silent_concealed_samples;
+ RTCStatsMember<uint64_t> concealment_events;
+ RTCStatsMember<uint64_t> inserted_samples_for_deceleration;
+ RTCStatsMember<uint64_t> removed_samples_for_acceleration;
+ RTCStatsMember<double> audio_level;
+ RTCStatsMember<double> total_audio_energy;
+ RTCStatsMember<double> total_samples_duration;
+ // Stats below are only implemented or defined for video.
+ RTCStatsMember<int32_t> frames_received;
+ RTCStatsMember<uint32_t> frame_width;
+ RTCStatsMember<uint32_t> frame_height;
+ RTCStatsMember<double> frames_per_second;
+ RTCStatsMember<uint32_t> frames_decoded;
+ RTCStatsMember<uint32_t> key_frames_decoded;
+ RTCStatsMember<uint32_t> frames_dropped;
+ RTCStatsMember<double> total_decode_time;
+ RTCStatsMember<double> total_processing_delay;
+ RTCStatsMember<double> total_assembly_time;
+ RTCStatsMember<uint32_t> frames_assembled_from_multiple_packets;
+ RTCStatsMember<double> total_inter_frame_delay;
+ RTCStatsMember<double> total_squared_inter_frame_delay;
+ RTCStatsMember<uint32_t> pause_count;
+ RTCStatsMember<double> total_pauses_duration;
+ RTCStatsMember<uint32_t> freeze_count;
+ RTCStatsMember<double> total_freezes_duration;
+ // https://w3c.github.io/webrtc-provisional-stats/#dom-rtcinboundrtpstreamstats-contenttype
+ RTCStatsMember<std::string> content_type;
+ // Only populated if audio/video sync is enabled.
+ // TODO(https://crbug.com/webrtc/14177): Expose even if A/V sync is off?
+ RTCStatsMember<double> estimated_playout_timestamp;
+ // Only implemented for video.
+ // TODO(https://crbug.com/webrtc/14178): Also implement for audio.
+ RTCRestrictedStatsMember<std::string,
+ StatExposureCriteria::kHardwareCapability>
+ decoder_implementation;
+ // FIR and PLI counts are only defined for |kind == "video"|.
+ RTCStatsMember<uint32_t> fir_count;
+ RTCStatsMember<uint32_t> pli_count;
+ RTCStatsMember<uint32_t> nack_count;
+ RTCStatsMember<uint64_t> qp_sum;
+ // This is a remnant of the legacy getStats() API. When the "video-timing"
+ // header extension is used,
+ // https://webrtc.github.io/webrtc-org/experiments/rtp-hdrext/video-timing/,
+ // `googTimingFrameInfo` is exposed with the value of
+ // TimingFrameInfo::ToString().
+ // TODO(https://crbug.com/webrtc/14586): Unship or standardize this metric.
+ RTCStatsMember<std::string> goog_timing_frame_info;
+ RTCRestrictedStatsMember<bool, StatExposureCriteria::kHardwareCapability>
+ power_efficient_decoder;
+ // Non-standard audio metrics.
+ RTCNonStandardStatsMember<uint64_t> jitter_buffer_flushes;
+ RTCNonStandardStatsMember<uint64_t> delayed_packet_outage_samples;
+ RTCNonStandardStatsMember<double> relative_packet_arrival_delay;
+ RTCNonStandardStatsMember<uint32_t> interruption_count;
+ RTCNonStandardStatsMember<double> total_interruption_duration;
+
+ // The former googMinPlayoutDelayMs (in seconds).
+ RTCNonStandardStatsMember<double> min_playout_delay;
+};
+
+// https://w3c.github.io/webrtc-stats/#outboundrtpstats-dict*
+class RTC_EXPORT RTCOutboundRTPStreamStats final : public RTCRTPStreamStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ RTCOutboundRTPStreamStats(std::string id, Timestamp timestamp);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCOutboundRTPStreamStats(std::string id, int64_t timestamp_us);
+ RTCOutboundRTPStreamStats(const RTCOutboundRTPStreamStats& other);
+ ~RTCOutboundRTPStreamStats() override;
+
+ RTCStatsMember<std::string> media_source_id;
+ RTCStatsMember<std::string> remote_id;
+ RTCStatsMember<std::string> mid;
+ RTCStatsMember<std::string> rid;
+ RTCStatsMember<uint32_t> packets_sent;
+ RTCStatsMember<uint64_t> retransmitted_packets_sent;
+ RTCStatsMember<uint64_t> bytes_sent;
+ RTCStatsMember<uint64_t> header_bytes_sent;
+ RTCStatsMember<uint64_t> retransmitted_bytes_sent;
+ RTCStatsMember<double> target_bitrate;
+ RTCStatsMember<uint32_t> frames_encoded;
+ RTCStatsMember<uint32_t> key_frames_encoded;
+ RTCStatsMember<double> total_encode_time;
+ RTCStatsMember<uint64_t> total_encoded_bytes_target;
+ RTCStatsMember<uint32_t> frame_width;
+ RTCStatsMember<uint32_t> frame_height;
+ RTCStatsMember<double> frames_per_second;
+ RTCStatsMember<uint32_t> frames_sent;
+ RTCStatsMember<uint32_t> huge_frames_sent;
+ RTCStatsMember<double> total_packet_send_delay;
+ // Enum type RTCQualityLimitationReason
+ RTCStatsMember<std::string> quality_limitation_reason;
+ RTCStatsMember<std::map<std::string, double>> quality_limitation_durations;
+ // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-qualitylimitationresolutionchanges
+ RTCStatsMember<uint32_t> quality_limitation_resolution_changes;
+ // https://w3c.github.io/webrtc-provisional-stats/#dom-rtcoutboundrtpstreamstats-contenttype
+ RTCStatsMember<std::string> content_type;
+ // Only implemented for video.
+ // TODO(https://crbug.com/webrtc/14178): Implement for audio as well.
+ RTCRestrictedStatsMember<std::string,
+ StatExposureCriteria::kHardwareCapability>
+ encoder_implementation;
+ // FIR and PLI counts are only defined for |kind == "video"|.
+ RTCStatsMember<uint32_t> fir_count;
+ RTCStatsMember<uint32_t> pli_count;
+ RTCStatsMember<uint32_t> nack_count;
+ RTCStatsMember<uint64_t> qp_sum;
+ RTCStatsMember<bool> active;
+ RTCRestrictedStatsMember<bool, StatExposureCriteria::kHardwareCapability>
+ power_efficient_encoder;
+ RTCStatsMember<std::string> scalability_mode;
+};
+
+// https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
+class RTC_EXPORT RTCRemoteInboundRtpStreamStats final
+ : public RTCReceivedRtpStreamStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ RTCRemoteInboundRtpStreamStats(std::string id, Timestamp timestamp);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCRemoteInboundRtpStreamStats(std::string id, int64_t timestamp_us);
+ RTCRemoteInboundRtpStreamStats(const RTCRemoteInboundRtpStreamStats& other);
+ ~RTCRemoteInboundRtpStreamStats() override;
+
+ RTCStatsMember<std::string> local_id;
+ RTCStatsMember<double> round_trip_time;
+ RTCStatsMember<double> fraction_lost;
+ RTCStatsMember<double> total_round_trip_time;
+ RTCStatsMember<int32_t> round_trip_time_measurements;
+};
+
+// https://w3c.github.io/webrtc-stats/#remoteoutboundrtpstats-dict*
+class RTC_EXPORT RTCRemoteOutboundRtpStreamStats final
+ : public RTCSentRtpStreamStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ RTCRemoteOutboundRtpStreamStats(std::string id, Timestamp timestamp);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCRemoteOutboundRtpStreamStats(std::string id, int64_t timestamp_us);
+ RTCRemoteOutboundRtpStreamStats(const RTCRemoteOutboundRtpStreamStats& other);
+ ~RTCRemoteOutboundRtpStreamStats() override;
+
+ RTCStatsMember<std::string> local_id;
+ RTCStatsMember<double> remote_timestamp;
+ RTCStatsMember<uint64_t> reports_sent;
+ RTCStatsMember<double> round_trip_time;
+ RTCStatsMember<uint64_t> round_trip_time_measurements;
+ RTCStatsMember<double> total_round_trip_time;
+};
+
+// https://w3c.github.io/webrtc-stats/#dom-rtcmediasourcestats
+class RTC_EXPORT RTCMediaSourceStats : public RTCStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ RTCMediaSourceStats(const RTCMediaSourceStats& other);
+ ~RTCMediaSourceStats() override;
+
+ RTCStatsMember<std::string> track_identifier;
+ RTCStatsMember<std::string> kind;
+
+ protected:
+ RTCMediaSourceStats(std::string id, Timestamp timestamp);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCMediaSourceStats(std::string id, int64_t timestamp_us);
+};
+
+// https://w3c.github.io/webrtc-stats/#dom-rtcaudiosourcestats
+class RTC_EXPORT RTCAudioSourceStats final : public RTCMediaSourceStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ RTCAudioSourceStats(std::string id, Timestamp timestamp);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCAudioSourceStats(std::string id, int64_t timestamp_us);
+ RTCAudioSourceStats(const RTCAudioSourceStats& other);
+ ~RTCAudioSourceStats() override;
+
+ RTCStatsMember<double> audio_level;
+ RTCStatsMember<double> total_audio_energy;
+ RTCStatsMember<double> total_samples_duration;
+ RTCStatsMember<double> echo_return_loss;
+ RTCStatsMember<double> echo_return_loss_enhancement;
+};
+
+// https://w3c.github.io/webrtc-stats/#dom-rtcvideosourcestats
+class RTC_EXPORT RTCVideoSourceStats final : public RTCMediaSourceStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ RTCVideoSourceStats(std::string id, Timestamp timestamp);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCVideoSourceStats(std::string id, int64_t timestamp_us);
+ RTCVideoSourceStats(const RTCVideoSourceStats& other);
+ ~RTCVideoSourceStats() override;
+
+ RTCStatsMember<uint32_t> width;
+ RTCStatsMember<uint32_t> height;
+ RTCStatsMember<uint32_t> frames;
+ RTCStatsMember<double> frames_per_second;
+};
+
+// https://w3c.github.io/webrtc-stats/#transportstats-dict*
+class RTC_EXPORT RTCTransportStats final : public RTCStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ RTCTransportStats(std::string id, Timestamp timestamp);
+ ABSL_DEPRECATED("Use constructor with Timestamp instead")
+ RTCTransportStats(std::string id, int64_t timestamp_us);
+ RTCTransportStats(const RTCTransportStats& other);
+ ~RTCTransportStats() override;
+
+ RTCStatsMember<uint64_t> bytes_sent;
+ RTCStatsMember<uint64_t> packets_sent;
+ RTCStatsMember<uint64_t> bytes_received;
+ RTCStatsMember<uint64_t> packets_received;
+ RTCStatsMember<std::string> rtcp_transport_stats_id;
+ // Enum type RTCDtlsTransportState.
+ RTCStatsMember<std::string> dtls_state;
+ RTCStatsMember<std::string> selected_candidate_pair_id;
+ RTCStatsMember<std::string> local_certificate_id;
+ RTCStatsMember<std::string> remote_certificate_id;
+ RTCStatsMember<std::string> tls_version;
+ RTCStatsMember<std::string> dtls_cipher;
+ RTCStatsMember<std::string> dtls_role;
+ RTCStatsMember<std::string> srtp_cipher;
+ RTCStatsMember<uint32_t> selected_candidate_pair_changes;
+ RTCStatsMember<std::string> ice_role;
+ RTCStatsMember<std::string> ice_local_username_fragment;
+ RTCStatsMember<std::string> ice_state;
+};
+
+// https://w3c.github.io/webrtc-stats/#playoutstats-dict*
+class RTC_EXPORT RTCAudioPlayoutStats final : public RTCStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ RTCAudioPlayoutStats(const std::string& id, Timestamp timestamp);
+ RTCAudioPlayoutStats(const RTCAudioPlayoutStats& other);
+ ~RTCAudioPlayoutStats() override;
+
+ RTCStatsMember<std::string> kind;
+ RTCStatsMember<double> synthesized_samples_duration;
+ RTCStatsMember<uint64_t> synthesized_samples_events;
+ RTCStatsMember<double> total_samples_duration;
+ RTCStatsMember<double> total_playout_delay;
+ RTCStatsMember<uint64_t> total_samples_count;
+};
+
+} // namespace webrtc
+
+#endif // API_STATS_RTCSTATS_OBJECTS_H_
diff --git a/third_party/libwebrtc/api/task_queue/BUILD.gn b/third_party/libwebrtc/api/task_queue/BUILD.gn
new file mode 100644
index 0000000000..1c342cb57e
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/BUILD.gn
@@ -0,0 +1,166 @@
+# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../webrtc.gni")
+
+rtc_library("task_queue") {
+ visibility = [ "*" ]
+ public = [
+ "task_queue_base.h",
+ "task_queue_factory.h",
+ ]
+ sources = [ "task_queue_base.cc" ]
+
+ deps = [
+ "../../rtc_base:checks",
+ "../../rtc_base:macromagic",
+ "../../rtc_base/system:rtc_export",
+ "../units:time_delta",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/base:config",
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ "//third_party/abseil-cpp/absl/functional:any_invocable",
+ "//third_party/abseil-cpp/absl/strings",
+ ]
+}
+
+# Mozilla - we want to ensure that rtc_include_tests is set to false
+# to guarantee that default_task_queue_factory is not used so we
+# know that remaining win32k code in task_queue_win.cc is not built.
+# See Bug 1797161 for more info.
+assert(!rtc_include_tests, "Mozilla - verify rtc_include_tests is off")
+if (rtc_include_tests) {
+rtc_library("task_queue_test") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "task_queue_test.cc",
+ "task_queue_test.h",
+ ]
+
+ check_includes = false # no-presubmit-check TODO(bugs.webrtc.org/9419)
+ if (build_with_chromium) {
+ visibility = []
+ visibility = webrtc_default_visibility
+ visibility += [
+ # This is the only Chromium targets that can depend on this. The reason
+ # behind this is the fact that these are 'testonly' targets and as such
+ # it cannot be part of the WebRTC component.
+ "//components/webrtc:unit_tests",
+ "//third_party/blink/renderer/platform:blink_platform_unittests_sources",
+ ]
+
+ # Don't depend on WebRTC code outside of webrtc_overrides:webrtc_component
+ # because this will break the WebRTC component build in Chromium.
+ deps = [
+ "../../../webrtc_overrides:webrtc_component",
+ "../../test:test_support",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/cleanup",
+ "//third_party/abseil-cpp/absl/strings",
+ ]
+ } else {
+ deps = [
+ ":default_task_queue_factory",
+ ":task_queue",
+ "../../api:field_trials_view",
+ "../../api:make_ref_counted",
+ "../../api/units:time_delta",
+ "../../rtc_base:refcount",
+ "../../rtc_base:rtc_event",
+ "../../rtc_base:timeutils",
+ "../../test:test_support",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/cleanup",
+ "//third_party/abseil-cpp/absl/strings",
+ ]
+ }
+}
+}
+
+rtc_library("default_task_queue_factory") {
+ visibility = [ "*" ]
+ if (!is_ios && !is_android) {
+ poisonous = [ "default_task_queue" ]
+ }
+ sources = [ "default_task_queue_factory.h" ]
+ deps = [
+ ":task_queue",
+ "../../api:field_trials_view",
+ "../../rtc_base/memory:always_valid_pointer",
+ ]
+
+ if (rtc_enable_libevent) {
+ if (is_android) {
+ sources +=
+ [ "default_task_queue_factory_stdlib_or_libevent_experiment.cc" ]
+ deps += [
+ "../../api/transport:field_trial_based_config",
+ "../../rtc_base:logging",
+ "../../rtc_base:rtc_task_queue_libevent",
+ "../../rtc_base:rtc_task_queue_stdlib",
+ ]
+ } else {
+ sources += [ "default_task_queue_factory_libevent.cc" ]
+ deps += [ "../../rtc_base:rtc_task_queue_libevent" ]
+ }
+ } else if (is_mac || is_ios) {
+ sources += [ "default_task_queue_factory_gcd.cc" ]
+ deps += [ "../../rtc_base:rtc_task_queue_gcd" ]
+ } else if (is_win && current_os != "winuwp") {
+ sources += [ "default_task_queue_factory_win.cc" ]
+ deps += [ "../../rtc_base:rtc_task_queue_win" ]
+ } else {
+ sources += [ "default_task_queue_factory_stdlib.cc" ]
+ deps += [ "../../rtc_base:rtc_task_queue_stdlib" ]
+ }
+}
+
+rtc_library("pending_task_safety_flag") {
+ visibility = [ "*" ]
+ sources = [
+ "pending_task_safety_flag.cc",
+ "pending_task_safety_flag.h",
+ ]
+ deps = [
+ "../../api:refcountedbase",
+ "../../api:scoped_refptr",
+ "../../api:sequence_checker",
+ "../../rtc_base:checks",
+ "../../rtc_base/system:no_unique_address",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/functional:any_invocable" ]
+}
+
+if (rtc_include_tests) {
+ rtc_library("task_queue_default_factory_unittests") {
+ testonly = true
+ sources = [ "default_task_queue_factory_unittest.cc" ]
+ deps = [
+ ":default_task_queue_factory",
+ ":task_queue_test",
+ "../../test:test_support",
+ ]
+ }
+
+ rtc_library("pending_task_safety_flag_unittests") {
+ testonly = true
+ sources = [ "pending_task_safety_flag_unittest.cc" ]
+ deps = [
+ ":pending_task_safety_flag",
+ "../../rtc_base:logging",
+ "../../rtc_base:rtc_event",
+ "../../rtc_base:rtc_task_queue",
+ "../../rtc_base:task_queue_for_test",
+ "../../test:test_support",
+ ]
+ }
+}
diff --git a/third_party/libwebrtc/api/task_queue/DEPS b/third_party/libwebrtc/api/task_queue/DEPS
new file mode 100644
index 0000000000..1365edb504
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/DEPS
@@ -0,0 +1,14 @@
+specific_include_rules = {
+ "task_queue_base\.h": [
+ # Make TaskQueueBase RTC_LOCKABALE to allow annotate variables are only
+ # accessed on specific task queue.
+ "+rtc_base/thread_annotations.h",
+ ],
+ "task_queue_test\.h": [
+ "+test/gtest.h",
+ ],
+ "pending_task_safety_flag.h": [
+ "+rtc_base/checks.h",
+ "+rtc_base/system/no_unique_address.h",
+ ],
+}
diff --git a/third_party/libwebrtc/api/task_queue/default_task_queue_factory.h b/third_party/libwebrtc/api/task_queue/default_task_queue_factory.h
new file mode 100644
index 0000000000..1d2dbd7ec2
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/default_task_queue_factory.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_TASK_QUEUE_DEFAULT_TASK_QUEUE_FACTORY_H_
+#define API_TASK_QUEUE_DEFAULT_TASK_QUEUE_FACTORY_H_
+
+#include <memory>
+
+#include "api/field_trials_view.h"
+#include "api/task_queue/task_queue_factory.h"
+
+namespace webrtc {
+
+std::unique_ptr<TaskQueueFactory> CreateDefaultTaskQueueFactory(
+ const FieldTrialsView* field_trials = nullptr);
+
+} // namespace webrtc
+
+#endif // API_TASK_QUEUE_DEFAULT_TASK_QUEUE_FACTORY_H_
diff --git a/third_party/libwebrtc/api/task_queue/default_task_queue_factory_gcd.cc b/third_party/libwebrtc/api/task_queue/default_task_queue_factory_gcd.cc
new file mode 100644
index 0000000000..391f09b393
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/default_task_queue_factory_gcd.cc
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include <memory>
+
+#include "api/field_trials_view.h"
+#include "api/task_queue/task_queue_factory.h"
+#include "rtc_base/task_queue_gcd.h"
+
+namespace webrtc {
+
+std::unique_ptr<TaskQueueFactory> CreateDefaultTaskQueueFactory(
+ const FieldTrialsView* field_trials) {
+ return CreateTaskQueueGcdFactory();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/task_queue/default_task_queue_factory_libevent.cc b/third_party/libwebrtc/api/task_queue/default_task_queue_factory_libevent.cc
new file mode 100644
index 0000000000..89079f51ca
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/default_task_queue_factory_libevent.cc
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include <memory>
+
+#include "api/field_trials_view.h"
+#include "api/task_queue/task_queue_factory.h"
+#include "rtc_base/task_queue_libevent.h"
+
+namespace webrtc {
+
+std::unique_ptr<TaskQueueFactory> CreateDefaultTaskQueueFactory(
+ const FieldTrialsView* field_trials) {
+ return CreateTaskQueueLibeventFactory();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/task_queue/default_task_queue_factory_stdlib.cc b/third_party/libwebrtc/api/task_queue/default_task_queue_factory_stdlib.cc
new file mode 100644
index 0000000000..10cda7c5ec
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/default_task_queue_factory_stdlib.cc
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include <memory>
+
+#include "api/field_trials_view.h"
+#include "api/task_queue/task_queue_factory.h"
+#include "rtc_base/task_queue_stdlib.h"
+
+namespace webrtc {
+
+std::unique_ptr<TaskQueueFactory> CreateDefaultTaskQueueFactory(
+ const FieldTrialsView* field_trials) {
+ return CreateTaskQueueStdlibFactory();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/task_queue/default_task_queue_factory_stdlib_or_libevent_experiment.cc b/third_party/libwebrtc/api/task_queue/default_task_queue_factory_stdlib_or_libevent_experiment.cc
new file mode 100644
index 0000000000..dc6e835907
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/default_task_queue_factory_stdlib_or_libevent_experiment.cc
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <memory>
+
+#include "api/field_trials_view.h"
+#include "api/task_queue/task_queue_factory.h"
+#include "api/transport/field_trial_based_config.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/memory/always_valid_pointer.h"
+#include "rtc_base/task_queue_libevent.h"
+#include "rtc_base/task_queue_stdlib.h"
+
+namespace webrtc {
+
+std::unique_ptr<TaskQueueFactory> CreateDefaultTaskQueueFactory(
+ const FieldTrialsView* field_trials_view) {
+ AlwaysValidPointer<const FieldTrialsView, FieldTrialBasedConfig> field_trials(
+ field_trials_view);
+ if (field_trials->IsEnabled("WebRTC-TaskQueue-ReplaceLibeventWithStdlib")) {
+ RTC_LOG(LS_INFO) << "WebRTC-TaskQueue-ReplaceLibeventWithStdlib: "
+ << "using TaskQueueStdlibFactory.";
+ return CreateTaskQueueStdlibFactory();
+ }
+
+ RTC_LOG(LS_INFO) << "WebRTC-TaskQueue-ReplaceLibeventWithStdlib: "
+ << "using TaskQueueLibeventFactory.";
+ return CreateTaskQueueLibeventFactory();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/task_queue/default_task_queue_factory_unittest.cc b/third_party/libwebrtc/api/task_queue/default_task_queue_factory_unittest.cc
new file mode 100644
index 0000000000..92c17d8444
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/default_task_queue_factory_unittest.cc
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/task_queue/default_task_queue_factory.h"
+
+#include "api/task_queue/task_queue_test.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace {
+
+INSTANTIATE_TEST_SUITE_P(Default,
+ TaskQueueTest,
+ ::testing::Values(CreateDefaultTaskQueueFactory));
+
+} // namespace
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/task_queue/default_task_queue_factory_win.cc b/third_party/libwebrtc/api/task_queue/default_task_queue_factory_win.cc
new file mode 100644
index 0000000000..e3adc07327
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/default_task_queue_factory_win.cc
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include <memory>
+
+#include "api/field_trials_view.h"
+#include "api/task_queue/task_queue_factory.h"
+#include "rtc_base/task_queue_win.h"
+
+namespace webrtc {
+
+std::unique_ptr<TaskQueueFactory> CreateDefaultTaskQueueFactory(
+ const FieldTrialsView* field_trials) {
+ return CreateTaskQueueWinFactory();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/task_queue/pending_task_safety_flag.cc b/third_party/libwebrtc/api/task_queue/pending_task_safety_flag.cc
new file mode 100644
index 0000000000..437ce0755d
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/pending_task_safety_flag.cc
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2020 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/task_queue/pending_task_safety_flag.h"
+
+namespace webrtc {
+
+// static
+rtc::scoped_refptr<PendingTaskSafetyFlag> PendingTaskSafetyFlag::CreateInternal(
+ bool alive) {
+ // Explicit new, to access private constructor.
+ return rtc::scoped_refptr<PendingTaskSafetyFlag>(
+ new PendingTaskSafetyFlag(alive));
+}
+
+// static
+rtc::scoped_refptr<PendingTaskSafetyFlag> PendingTaskSafetyFlag::Create() {
+ return CreateInternal(true);
+}
+
+rtc::scoped_refptr<PendingTaskSafetyFlag>
+PendingTaskSafetyFlag::CreateDetached() {
+ rtc::scoped_refptr<PendingTaskSafetyFlag> safety_flag = CreateInternal(true);
+ safety_flag->main_sequence_.Detach();
+ return safety_flag;
+}
+
+rtc::scoped_refptr<PendingTaskSafetyFlag>
+PendingTaskSafetyFlag::CreateDetachedInactive() {
+ rtc::scoped_refptr<PendingTaskSafetyFlag> safety_flag = CreateInternal(false);
+ safety_flag->main_sequence_.Detach();
+ return safety_flag;
+}
+
+void PendingTaskSafetyFlag::SetNotAlive() {
+ RTC_DCHECK_RUN_ON(&main_sequence_);
+ alive_ = false;
+}
+
+void PendingTaskSafetyFlag::SetAlive() {
+ RTC_DCHECK_RUN_ON(&main_sequence_);
+ alive_ = true;
+}
+
+bool PendingTaskSafetyFlag::alive() const {
+ RTC_DCHECK_RUN_ON(&main_sequence_);
+ return alive_;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/task_queue/pending_task_safety_flag.h b/third_party/libwebrtc/api/task_queue/pending_task_safety_flag.h
new file mode 100644
index 0000000000..3b948ca8f1
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/pending_task_safety_flag.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2020 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TASK_QUEUE_PENDING_TASK_SAFETY_FLAG_H_
+#define API_TASK_QUEUE_PENDING_TASK_SAFETY_FLAG_H_
+
+#include <utility>
+
+#include "absl/functional/any_invocable.h"
+#include "api/ref_counted_base.h"
+#include "api/scoped_refptr.h"
+#include "api/sequence_checker.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/system/no_unique_address.h"
+
+namespace webrtc {
+
+// The PendingTaskSafetyFlag and the ScopedTaskSafety are designed to address
+// the issue where you have a task to be executed later that has references,
+// but cannot guarantee that the referenced object is alive when the task is
+// executed.
+
+// This mechanism can be used with tasks that are created and destroyed
+// on a single thread / task queue, and with tasks posted to the same
+// thread/task queue, but tasks can be posted from any thread/TQ.
+
+// Typical usage:
+// When posting a task, post a copy (capture by-value in a lambda) of the flag
+// reference and before performing the work, check the `alive()` state. Abort if
+// alive() returns `false`:
+//
+// class ExampleClass {
+// ....
+// rtc::scoped_refptr<PendingTaskSafetyFlag> flag = safety_flag_;
+// my_task_queue_->PostTask(
+// [flag = std::move(flag), this] {
+// // Now running on the main thread.
+// if (!flag->alive())
+// return;
+// MyMethod();
+// });
+// ....
+// ~ExampleClass() {
+// safety_flag_->SetNotAlive();
+// }
+// scoped_refptr<PendingTaskSafetyFlag> safety_flag_
+// = PendingTaskSafetyFlag::Create();
+// }
+//
+// SafeTask makes this check automatic:
+//
+// my_task_queue_->PostTask(SafeTask(safety_flag_, [this] { MyMethod(); }));
+//
+class PendingTaskSafetyFlag final
+ : public rtc::RefCountedNonVirtual<PendingTaskSafetyFlag> {
+ public:
+ static rtc::scoped_refptr<PendingTaskSafetyFlag> Create();
+
+ // Creates a flag, but with its SequenceChecker initially detached. Hence, it
+ // may be created on a different thread than the flag will be used on.
+ static rtc::scoped_refptr<PendingTaskSafetyFlag> CreateDetached();
+
+ // Same as `CreateDetached()` except the initial state of the returned flag
+ // will be `!alive()`.
+ static rtc::scoped_refptr<PendingTaskSafetyFlag> CreateDetachedInactive();
+
+ ~PendingTaskSafetyFlag() = default;
+
+ void SetNotAlive();
+ // The SetAlive method is intended to support Start/Stop/Restart usecases.
+ // When a class has called SetNotAlive on a flag used for posted tasks, and
+ // decides it wants to post new tasks and have them run, there are two
+ // reasonable ways to do that:
+ //
+ // (i) Use the below SetAlive method. One subtlety is that any task posted
+ // prior to SetNotAlive, and still in the queue, is resurrected and will
+ // run.
+ //
+ // (ii) Create a fresh flag, and just drop the reference to the old one. This
+ // avoids the above problem, and ensures that tasks poster prior to
+ // SetNotAlive stay cancelled. Instead, there's a potential data race on
+ // the flag pointer itself. Some synchronization is required between the
+ // thread overwriting the flag pointer, and the threads that want to post
+ // tasks and therefore read that same pointer.
+ void SetAlive();
+ bool alive() const;
+
+ protected:
+ explicit PendingTaskSafetyFlag(bool alive) : alive_(alive) {}
+
+ private:
+ static rtc::scoped_refptr<PendingTaskSafetyFlag> CreateInternal(bool alive);
+
+ bool alive_ = true;
+ RTC_NO_UNIQUE_ADDRESS SequenceChecker main_sequence_;
+};
+
+// The ScopedTaskSafety makes using PendingTaskSafetyFlag very simple.
+// It does automatic PTSF creation and signalling of destruction when the
+// ScopedTaskSafety instance goes out of scope.
+//
+// Example usage:
+//
+// my_task_queue->PostTask(SafeTask(scoped_task_safety.flag(),
+// [this] {
+// // task goes here
+// }
+//
+// This should be used by the class that wants tasks dropped after destruction.
+// The requirement is that the instance has to be constructed and destructed on
+// the same thread as the potentially dropped tasks would be running on.
+class ScopedTaskSafety final {
+ public:
+ ScopedTaskSafety() = default;
+ explicit ScopedTaskSafety(rtc::scoped_refptr<PendingTaskSafetyFlag> flag)
+ : flag_(std::move(flag)) {}
+ ~ScopedTaskSafety() { flag_->SetNotAlive(); }
+
+ // Returns a new reference to the safety flag.
+ rtc::scoped_refptr<PendingTaskSafetyFlag> flag() const { return flag_; }
+
+ // Marks the current flag as not-alive and attaches to a new one.
+ void reset(rtc::scoped_refptr<PendingTaskSafetyFlag> new_flag =
+ PendingTaskSafetyFlag::Create()) {
+ flag_->SetNotAlive();
+ flag_ = std::move(new_flag);
+ }
+
+ private:
+ rtc::scoped_refptr<PendingTaskSafetyFlag> flag_ =
+ PendingTaskSafetyFlag::Create();
+};
+
+// Like ScopedTaskSafety, but allows construction on a different thread than
+// where the flag will be used.
+class ScopedTaskSafetyDetached final {
+ public:
+ ScopedTaskSafetyDetached() = default;
+ ~ScopedTaskSafetyDetached() { flag_->SetNotAlive(); }
+
+ // Returns a new reference to the safety flag.
+ rtc::scoped_refptr<PendingTaskSafetyFlag> flag() const { return flag_; }
+
+ private:
+ rtc::scoped_refptr<PendingTaskSafetyFlag> flag_ =
+ PendingTaskSafetyFlag::CreateDetached();
+};
+
+inline absl::AnyInvocable<void() &&> SafeTask(
+ rtc::scoped_refptr<PendingTaskSafetyFlag> flag,
+ absl::AnyInvocable<void() &&> task) {
+ return [flag = std::move(flag), task = std::move(task)]() mutable {
+ if (flag->alive()) {
+ std::move(task)();
+ }
+ };
+}
+
+} // namespace webrtc
+
+#endif // API_TASK_QUEUE_PENDING_TASK_SAFETY_FLAG_H_
diff --git a/third_party/libwebrtc/api/task_queue/pending_task_safety_flag_gn/moz.build b/third_party/libwebrtc/api/task_queue/pending_task_safety_flag_gn/moz.build
new file mode 100644
index 0000000000..d7e6a087fa
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/pending_task_safety_flag_gn/moz.build
@@ -0,0 +1,221 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/task_queue/pending_task_safety_flag.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("pending_task_safety_flag_gn")
diff --git a/third_party/libwebrtc/api/task_queue/pending_task_safety_flag_unittest.cc b/third_party/libwebrtc/api/task_queue/pending_task_safety_flag_unittest.cc
new file mode 100644
index 0000000000..cedf0eb8df
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/pending_task_safety_flag_unittest.cc
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/task_queue/pending_task_safety_flag.h"
+
+#include <memory>
+
+#include "rtc_base/event.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/task_queue_for_test.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+TEST(PendingTaskSafetyFlagTest, Basic) {
+ rtc::scoped_refptr<PendingTaskSafetyFlag> safety_flag;
+ {
+ // Scope for the `owner` instance.
+ class Owner {
+ public:
+ Owner() = default;
+ ~Owner() { flag_->SetNotAlive(); }
+
+ rtc::scoped_refptr<PendingTaskSafetyFlag> flag_ =
+ PendingTaskSafetyFlag::Create();
+ } owner;
+ EXPECT_TRUE(owner.flag_->alive());
+ safety_flag = owner.flag_;
+ EXPECT_TRUE(safety_flag->alive());
+ }
+ // `owner` now out of scope.
+ EXPECT_FALSE(safety_flag->alive());
+}
+
+TEST(PendingTaskSafetyFlagTest, BasicScoped) {
+ rtc::scoped_refptr<PendingTaskSafetyFlag> safety_flag;
+ {
+ struct Owner {
+ ScopedTaskSafety safety;
+ } owner;
+ safety_flag = owner.safety.flag();
+ EXPECT_TRUE(safety_flag->alive());
+ }
+ // `owner` now out of scope.
+ EXPECT_FALSE(safety_flag->alive());
+}
+
+TEST(PendingTaskSafetyFlagTest, PendingTaskSuccess) {
+ TaskQueueForTest tq1("OwnerHere");
+ TaskQueueForTest tq2("OwnerNotHere");
+
+ class Owner {
+ public:
+ Owner() : tq_main_(TaskQueueBase::Current()) { RTC_DCHECK(tq_main_); }
+ ~Owner() {
+ RTC_DCHECK(tq_main_->IsCurrent());
+ flag_->SetNotAlive();
+ }
+
+ void DoStuff() {
+ RTC_DCHECK(!tq_main_->IsCurrent());
+ rtc::scoped_refptr<PendingTaskSafetyFlag> safe = flag_;
+ tq_main_->PostTask([safe = std::move(safe), this]() {
+ if (!safe->alive())
+ return;
+ stuff_done_ = true;
+ });
+ }
+
+ bool stuff_done() const { return stuff_done_; }
+
+ private:
+ TaskQueueBase* const tq_main_;
+ bool stuff_done_ = false;
+ rtc::scoped_refptr<PendingTaskSafetyFlag> flag_ =
+ PendingTaskSafetyFlag::Create();
+ };
+
+ std::unique_ptr<Owner> owner;
+ tq1.SendTask([&owner]() {
+ owner = std::make_unique<Owner>();
+ EXPECT_FALSE(owner->stuff_done());
+ });
+ ASSERT_TRUE(owner);
+ tq2.SendTask([&owner]() { owner->DoStuff(); });
+ tq1.SendTask([&owner]() {
+ EXPECT_TRUE(owner->stuff_done());
+ owner.reset();
+ });
+ ASSERT_FALSE(owner);
+}
+
+TEST(PendingTaskSafetyFlagTest, PendingTaskDropped) {
+ TaskQueueForTest tq1("OwnerHere");
+ TaskQueueForTest tq2("OwnerNotHere");
+
+ class Owner {
+ public:
+ explicit Owner(bool* stuff_done)
+ : tq_main_(TaskQueueBase::Current()), stuff_done_(stuff_done) {
+ RTC_DCHECK(tq_main_);
+ *stuff_done_ = false;
+ }
+ ~Owner() { RTC_DCHECK(tq_main_->IsCurrent()); }
+
+ void DoStuff() {
+ RTC_DCHECK(!tq_main_->IsCurrent());
+ tq_main_->PostTask(
+ SafeTask(safety_.flag(), [this]() { *stuff_done_ = true; }));
+ }
+
+ private:
+ TaskQueueBase* const tq_main_;
+ bool* const stuff_done_;
+ ScopedTaskSafety safety_;
+ };
+
+ std::unique_ptr<Owner> owner;
+ bool stuff_done = false;
+ tq1.SendTask([&owner, &stuff_done]() {
+ owner = std::make_unique<Owner>(&stuff_done);
+ });
+ ASSERT_TRUE(owner);
+ // Queue up a task on tq1 that will execute before the 'DoStuff' task
+ // can, and delete the `owner` before the 'stuff' task can execute.
+ rtc::Event blocker;
+ tq1.PostTask([&blocker, &owner]() {
+ blocker.Wait(rtc::Event::kForever);
+ owner.reset();
+ });
+
+ // Queue up a DoStuff...
+ tq2.SendTask([&owner]() { owner->DoStuff(); });
+
+ ASSERT_TRUE(owner);
+ blocker.Set();
+
+ // Run an empty task on tq1 to flush all the queued tasks.
+ tq1.WaitForPreviouslyPostedTasks();
+ ASSERT_FALSE(owner);
+ EXPECT_FALSE(stuff_done);
+}
+
+TEST(PendingTaskSafetyFlagTest, PendingTaskNotAliveInitialized) {
+ TaskQueueForTest tq("PendingTaskNotAliveInitialized");
+
+ // Create a new flag that initially not `alive`.
+ auto flag = PendingTaskSafetyFlag::CreateDetachedInactive();
+ tq.SendTask([&flag]() { EXPECT_FALSE(flag->alive()); });
+
+ bool task_1_ran = false;
+ bool task_2_ran = false;
+ tq.PostTask(SafeTask(flag, [&task_1_ran]() { task_1_ran = true; }));
+ tq.PostTask([&flag]() { flag->SetAlive(); });
+ tq.PostTask(SafeTask(flag, [&task_2_ran]() { task_2_ran = true; }));
+
+ tq.WaitForPreviouslyPostedTasks();
+ EXPECT_FALSE(task_1_ran);
+ EXPECT_TRUE(task_2_ran);
+}
+
+TEST(PendingTaskSafetyFlagTest, SafeTask) {
+ rtc::scoped_refptr<PendingTaskSafetyFlag> flag =
+ PendingTaskSafetyFlag::Create();
+
+ int count = 0;
+ // Create two identical tasks that increment the `count`.
+ auto task1 = SafeTask(flag, [&count] { ++count; });
+ auto task2 = SafeTask(flag, [&count] { ++count; });
+
+ EXPECT_EQ(count, 0);
+ std::move(task1)();
+ EXPECT_EQ(count, 1);
+ flag->SetNotAlive();
+ // Now task2 should actually not run.
+ std::move(task2)();
+ EXPECT_EQ(count, 1);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/task_queue/task_queue_base.cc b/third_party/libwebrtc/api/task_queue/task_queue_base.cc
new file mode 100644
index 0000000000..ecdc7f7691
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/task_queue_base.cc
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/task_queue/task_queue_base.h"
+
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/functional/any_invocable.h"
+#include "api/units/time_delta.h"
+#include "rtc_base/checks.h"
+
+#if defined(ABSL_HAVE_THREAD_LOCAL)
+
+namespace webrtc {
+namespace {
+
+ABSL_CONST_INIT thread_local TaskQueueBase* current = nullptr;
+
+} // namespace
+
+TaskQueueBase* TaskQueueBase::Current() {
+ return current;
+}
+
+TaskQueueBase::CurrentTaskQueueSetter::CurrentTaskQueueSetter(
+ TaskQueueBase* task_queue)
+ : previous_(current) {
+ current = task_queue;
+}
+
+TaskQueueBase::CurrentTaskQueueSetter::~CurrentTaskQueueSetter() {
+ current = previous_;
+}
+} // namespace webrtc
+
+#elif defined(WEBRTC_POSIX)
+
+#include <pthread.h>
+
+namespace webrtc {
+namespace {
+
+ABSL_CONST_INIT pthread_key_t g_queue_ptr_tls = 0;
+
+void InitializeTls() {
+ RTC_CHECK(pthread_key_create(&g_queue_ptr_tls, nullptr) == 0);
+}
+
+pthread_key_t GetQueuePtrTls() {
+ static pthread_once_t init_once = PTHREAD_ONCE_INIT;
+ RTC_CHECK(pthread_once(&init_once, &InitializeTls) == 0);
+ return g_queue_ptr_tls;
+}
+
+} // namespace
+
+TaskQueueBase* TaskQueueBase::Current() {
+ return static_cast<TaskQueueBase*>(pthread_getspecific(GetQueuePtrTls()));
+}
+
+TaskQueueBase::CurrentTaskQueueSetter::CurrentTaskQueueSetter(
+ TaskQueueBase* task_queue)
+ : previous_(TaskQueueBase::Current()) {
+ pthread_setspecific(GetQueuePtrTls(), task_queue);
+}
+
+TaskQueueBase::CurrentTaskQueueSetter::~CurrentTaskQueueSetter() {
+ pthread_setspecific(GetQueuePtrTls(), previous_);
+}
+
+} // namespace webrtc
+
+#else
+#error Unsupported platform
+#endif
diff --git a/third_party/libwebrtc/api/task_queue/task_queue_base.h b/third_party/libwebrtc/api/task_queue/task_queue_base.h
new file mode 100644
index 0000000000..f78600de60
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/task_queue_base.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_TASK_QUEUE_TASK_QUEUE_BASE_H_
+#define API_TASK_QUEUE_TASK_QUEUE_BASE_H_
+
+#include <memory>
+#include <utility>
+
+#include "absl/functional/any_invocable.h"
+#include "api/units/time_delta.h"
+#include "rtc_base/system/rtc_export.h"
+#include "rtc_base/thread_annotations.h"
+
+namespace webrtc {
+
+// Asynchronously executes tasks in a way that guarantees that they're executed
+// in FIFO order and that tasks never overlap. Tasks may always execute on the
+// same worker thread and they may not. To DCHECK that tasks are executing on a
+// known task queue, use IsCurrent().
+class RTC_LOCKABLE RTC_EXPORT TaskQueueBase {
+ public:
+ enum class DelayPrecision {
+ // This may include up to a 17 ms leeway in addition to OS timer precision.
+ // See PostDelayedTask() for more information.
+ kLow,
+ // This does not have the additional delay that kLow has, but it is still
+ // limited by OS timer precision. See PostDelayedHighPrecisionTask() for
+ // more information.
+ kHigh,
+ };
+
+ // Starts destruction of the task queue.
+ // On return ensures no task are running and no new tasks are able to start
+ // on the task queue.
+ // Responsible for deallocation. Deallocation may happen synchronously during
+ // Delete or asynchronously after Delete returns.
+ // Code not running on the TaskQueue should not make any assumption when
+ // TaskQueue is deallocated and thus should not call any methods after Delete.
+ // Code running on the TaskQueue should not call Delete, but can assume
+ // TaskQueue still exists and may call other methods, e.g. PostTask.
+ // Should be called on the same task queue or thread that this task queue
+ // was created on.
+ virtual void Delete() = 0;
+
+ // Schedules a `task` to execute. Tasks are executed in FIFO order.
+ // When a TaskQueue is deleted, pending tasks will not be executed but they
+ // will be deleted.
+ //
+ // As long as tasks are not posted from task destruction, posted tasks are
+ // guaranteed to be destroyed with Current() pointing to the task queue they
+ // were posted to, whether they're executed or not. That means SequenceChecker
+ // works during task destruction, a fact that can be used to guarantee
+ // thread-compatible object deletion happening on a particular task queue
+ // which can simplify class design.
+ // Note that this guarantee does not apply to delayed tasks.
+ //
+ // May be called on any thread or task queue, including this task queue.
+ virtual void PostTask(absl::AnyInvocable<void() &&> task) = 0;
+
+ // Prefer PostDelayedTask() over PostDelayedHighPrecisionTask() whenever
+ // possible.
+ //
+ // Schedules a `task` to execute a specified `delay` from when the call is
+ // made, using "low" precision. All scheduling is affected by OS-specific
+ // leeway and current workloads which means that in terms of precision there
+ // are no hard guarantees, but in addition to the OS induced leeway, "low"
+ // precision adds up to a 17 ms additional leeway. The purpose of this leeway
+ // is to achieve more efficient CPU scheduling and reduce Idle Wake Up
+ // frequency.
+ //
+ // The task may execute with [-1, 17 + OS induced leeway) ms additional delay.
+ //
+ // Avoid making assumptions about the precision of the OS scheduler. On macOS,
+ // the OS induced leeway may be 10% of sleep interval. On Windows, 1 ms
+ // precision timers may be used but there are cases, such as when running on
+ // battery, when the timer precision can be as poor as 15 ms.
+ //
+ // "Low" precision is not implemented everywhere yet. Where not yet
+ // implemented, PostDelayedTask() has "high" precision. See
+ // https://crbug.com/webrtc/13583 for more information.
+ //
+ // May be called on any thread or task queue, including this task queue.
+ virtual void PostDelayedTask(absl::AnyInvocable<void() &&> task,
+ TimeDelta delay) = 0;
+
+ // Prefer PostDelayedTask() over PostDelayedHighPrecisionTask() whenever
+ // possible.
+ //
+ // Schedules a `task` to execute a specified `delay` from when the call is
+ // made, using "high" precision. All scheduling is affected by OS-specific
+ // leeway and current workloads which means that in terms of precision there
+ // are no hard guarantees.
+ //
+ // The task may execute with [-1, OS induced leeway] ms additional delay.
+ //
+ // Avoid making assumptions about the precision of the OS scheduler. On macOS,
+ // the OS induced leeway may be 10% of sleep interval. On Windows, 1 ms
+ // precision timers may be used but there are cases, such as when running on
+ // battery, when the timer precision can be as poor as 15 ms.
+ //
+ // May be called on any thread or task queue, including this task queue.
+ virtual void PostDelayedHighPrecisionTask(absl::AnyInvocable<void() &&> task,
+ TimeDelta delay) = 0;
+
+ // As specified by `precision`, calls either PostDelayedTask() or
+ // PostDelayedHighPrecisionTask().
+ void PostDelayedTaskWithPrecision(DelayPrecision precision,
+ absl::AnyInvocable<void() &&> task,
+ TimeDelta delay) {
+ switch (precision) {
+ case DelayPrecision::kLow:
+ PostDelayedTask(std::move(task), delay);
+ break;
+ case DelayPrecision::kHigh:
+ PostDelayedHighPrecisionTask(std::move(task), delay);
+ break;
+ }
+ }
+
+ // Returns the task queue that is running the current thread.
+ // Returns nullptr if this thread is not associated with any task queue.
+ // May be called on any thread or task queue, including this task queue.
+ static TaskQueueBase* Current();
+ bool IsCurrent() const { return Current() == this; }
+
+ protected:
+ class RTC_EXPORT CurrentTaskQueueSetter {
+ public:
+ explicit CurrentTaskQueueSetter(TaskQueueBase* task_queue);
+ CurrentTaskQueueSetter(const CurrentTaskQueueSetter&) = delete;
+ CurrentTaskQueueSetter& operator=(const CurrentTaskQueueSetter&) = delete;
+ ~CurrentTaskQueueSetter();
+
+ private:
+ TaskQueueBase* const previous_;
+ };
+
+ // Users of the TaskQueue should call Delete instead of directly deleting
+ // this object.
+ virtual ~TaskQueueBase() = default;
+};
+
+struct TaskQueueDeleter {
+ void operator()(TaskQueueBase* task_queue) const { task_queue->Delete(); }
+};
+
+} // namespace webrtc
+
+#endif // API_TASK_QUEUE_TASK_QUEUE_BASE_H_
diff --git a/third_party/libwebrtc/api/task_queue/task_queue_factory.h b/third_party/libwebrtc/api/task_queue/task_queue_factory.h
new file mode 100644
index 0000000000..b68ab33f69
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/task_queue_factory.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_TASK_QUEUE_TASK_QUEUE_FACTORY_H_
+#define API_TASK_QUEUE_TASK_QUEUE_FACTORY_H_
+
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "api/task_queue/task_queue_base.h"
+
+namespace webrtc {
+
+// The implementation of this interface must be thread-safe.
+class TaskQueueFactory {
+ public:
+ // TaskQueue priority levels. On some platforms these will map to thread
+ // priorities, on others such as Mac and iOS, GCD queue priorities.
+ enum class Priority { NORMAL = 0, HIGH, LOW };
+
+ virtual ~TaskQueueFactory() = default;
+ virtual std::unique_ptr<TaskQueueBase, TaskQueueDeleter> CreateTaskQueue(
+ absl::string_view name,
+ Priority priority) const = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_TASK_QUEUE_TASK_QUEUE_FACTORY_H_
diff --git a/third_party/libwebrtc/api/task_queue/task_queue_gn/moz.build b/third_party/libwebrtc/api/task_queue/task_queue_gn/moz.build
new file mode 100644
index 0000000000..c4d9c9d67d
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/task_queue_gn/moz.build
@@ -0,0 +1,221 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/task_queue/task_queue_base.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("task_queue_gn")
diff --git a/third_party/libwebrtc/api/task_queue/task_queue_test.cc b/third_party/libwebrtc/api/task_queue/task_queue_test.cc
new file mode 100644
index 0000000000..7849f4273d
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/task_queue_test.cc
@@ -0,0 +1,333 @@
+/*
+ * Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/task_queue/task_queue_test.h"
+
+#include <memory>
+
+#include "absl/cleanup/cleanup.h"
+#include "absl/strings/string_view.h"
+#include "api/task_queue/task_queue_base.h"
+#include "api/units/time_delta.h"
+#include "rtc_base/event.h"
+#include "rtc_base/ref_counter.h"
+#include "rtc_base/time_utils.h"
+
+namespace webrtc {
+namespace {
+
+// Avoids a dependency to system_wrappers.
+void SleepFor(TimeDelta duration) {
+ rtc::ScopedAllowBaseSyncPrimitivesForTesting allow;
+ rtc::Event event;
+ event.Wait(duration);
+}
+
+std::unique_ptr<TaskQueueBase, TaskQueueDeleter> CreateTaskQueue(
+ const std::unique_ptr<webrtc::TaskQueueFactory>& factory,
+ absl::string_view task_queue_name,
+ TaskQueueFactory::Priority priority = TaskQueueFactory::Priority::NORMAL) {
+ return factory->CreateTaskQueue(task_queue_name, priority);
+}
+
+TEST_P(TaskQueueTest, Construct) {
+ std::unique_ptr<webrtc::TaskQueueFactory> factory = GetParam()(nullptr);
+ auto queue = CreateTaskQueue(factory, "Construct");
+ EXPECT_FALSE(queue->IsCurrent());
+}
+
+TEST_P(TaskQueueTest, PostAndCheckCurrent) {
+ std::unique_ptr<webrtc::TaskQueueFactory> factory = GetParam()(nullptr);
+ rtc::Event event;
+ auto queue = CreateTaskQueue(factory, "PostAndCheckCurrent");
+
+ // We're not running a task, so `queue` shouldn't be current.
+ // Note that because rtc::Thread also supports the TQ interface and
+ // TestMainImpl::Init wraps the main test thread (bugs.webrtc.org/9714), that
+ // means that TaskQueueBase::Current() will still return a valid value.
+ EXPECT_FALSE(queue->IsCurrent());
+
+ queue->PostTask([&event, &queue] {
+ EXPECT_TRUE(queue->IsCurrent());
+ event.Set();
+ });
+ EXPECT_TRUE(event.Wait(TimeDelta::Seconds(1)));
+}
+
+TEST_P(TaskQueueTest, PostCustomTask) {
+ std::unique_ptr<webrtc::TaskQueueFactory> factory = GetParam()(nullptr);
+ rtc::Event ran;
+ auto queue = CreateTaskQueue(factory, "PostCustomImplementation");
+
+ class CustomTask {
+ public:
+ explicit CustomTask(rtc::Event* ran) : ran_(ran) {}
+
+ void operator()() { ran_->Set(); }
+
+ private:
+ rtc::Event* const ran_;
+ } my_task(&ran);
+
+ queue->PostTask(my_task);
+ EXPECT_TRUE(ran.Wait(TimeDelta::Seconds(1)));
+}
+
+TEST_P(TaskQueueTest, PostDelayedZero) {
+ std::unique_ptr<webrtc::TaskQueueFactory> factory = GetParam()(nullptr);
+ rtc::Event event;
+ auto queue = CreateTaskQueue(factory, "PostDelayedZero");
+
+ queue->PostDelayedTask([&event] { event.Set(); }, TimeDelta::Zero());
+ EXPECT_TRUE(event.Wait(TimeDelta::Seconds(1)));
+}
+
+TEST_P(TaskQueueTest, PostFromQueue) {
+ std::unique_ptr<webrtc::TaskQueueFactory> factory = GetParam()(nullptr);
+ rtc::Event event;
+ auto queue = CreateTaskQueue(factory, "PostFromQueue");
+
+ queue->PostTask(
+ [&event, &queue] { queue->PostTask([&event] { event.Set(); }); });
+ EXPECT_TRUE(event.Wait(TimeDelta::Seconds(1)));
+}
+
+TEST_P(TaskQueueTest, PostDelayed) {
+ std::unique_ptr<webrtc::TaskQueueFactory> factory = GetParam()(nullptr);
+ rtc::Event event;
+ auto queue =
+ CreateTaskQueue(factory, "PostDelayed", TaskQueueFactory::Priority::HIGH);
+
+ int64_t start = rtc::TimeMillis();
+ queue->PostDelayedTask(
+ [&event, &queue] {
+ EXPECT_TRUE(queue->IsCurrent());
+ event.Set();
+ },
+ TimeDelta::Millis(100));
+ EXPECT_TRUE(event.Wait(TimeDelta::Seconds(1)));
+ int64_t end = rtc::TimeMillis();
+ // These tests are a little relaxed due to how "powerful" our test bots can
+ // be. Most recently we've seen windows bots fire the callback after 94-99ms,
+ // which is why we have a little bit of leeway backwards as well.
+ EXPECT_GE(end - start, 90u);
+ EXPECT_NEAR(end - start, 190u, 100u); // Accept 90-290.
+}
+
+TEST_P(TaskQueueTest, PostMultipleDelayed) {
+ std::unique_ptr<webrtc::TaskQueueFactory> factory = GetParam()(nullptr);
+ auto queue = CreateTaskQueue(factory, "PostMultipleDelayed");
+
+ std::vector<rtc::Event> events(100);
+ for (int i = 0; i < 100; ++i) {
+ rtc::Event* event = &events[i];
+ queue->PostDelayedTask(
+ [event, &queue] {
+ EXPECT_TRUE(queue->IsCurrent());
+ event->Set();
+ },
+ TimeDelta::Millis(i));
+ }
+
+ for (rtc::Event& e : events)
+ EXPECT_TRUE(e.Wait(TimeDelta::Seconds(1)));
+}
+
+TEST_P(TaskQueueTest, PostDelayedAfterDestruct) {
+ std::unique_ptr<webrtc::TaskQueueFactory> factory = GetParam()(nullptr);
+ rtc::Event run;
+ rtc::Event deleted;
+ auto queue = CreateTaskQueue(factory, "PostDelayedAfterDestruct");
+ absl::Cleanup cleanup = [&deleted] { deleted.Set(); };
+ queue->PostDelayedTask([&run, cleanup = std::move(cleanup)] { run.Set(); },
+ TimeDelta::Millis(100));
+ // Destroy the queue.
+ queue = nullptr;
+ // Task might outlive the TaskQueue, but still should be deleted.
+ EXPECT_TRUE(deleted.Wait(TimeDelta::Seconds(1)));
+ EXPECT_FALSE(run.Wait(TimeDelta::Zero())); // and should not run.
+}
+
+TEST_P(TaskQueueTest, PostDelayedHighPrecisionAfterDestruct) {
+ std::unique_ptr<webrtc::TaskQueueFactory> factory = GetParam()(nullptr);
+ rtc::Event run;
+ rtc::Event deleted;
+ auto queue =
+ CreateTaskQueue(factory, "PostDelayedHighPrecisionAfterDestruct");
+ absl::Cleanup cleanup = [&deleted] { deleted.Set(); };
+ queue->PostDelayedHighPrecisionTask(
+ [&run, cleanup = std::move(cleanup)] { run.Set(); },
+ TimeDelta::Millis(100));
+ // Destroy the queue.
+ queue = nullptr;
+ // Task might outlive the TaskQueue, but still should be deleted.
+ EXPECT_TRUE(deleted.Wait(TimeDelta::Seconds(1)));
+ EXPECT_FALSE(run.Wait(TimeDelta::Zero())); // and should not run.
+}
+
+TEST_P(TaskQueueTest, PostedUnexecutedClosureDestroyedOnTaskQueue) {
+ std::unique_ptr<webrtc::TaskQueueFactory> factory = GetParam()(nullptr);
+ auto queue =
+ CreateTaskQueue(factory, "PostedUnexecutedClosureDestroyedOnTaskQueue");
+ TaskQueueBase* queue_ptr = queue.get();
+ queue->PostTask([] { SleepFor(TimeDelta::Millis(100)); });
+ // Give the task queue a chance to start executing the first lambda.
+ SleepFor(TimeDelta::Millis(10));
+ // Then ensure the next lambda (which is likely not executing yet) is
+ // destroyed in the task queue context when the queue is deleted.
+ auto cleanup = absl::Cleanup(
+ [queue_ptr] { EXPECT_EQ(queue_ptr, TaskQueueBase::Current()); });
+ queue->PostTask([cleanup = std::move(cleanup)] {});
+ queue = nullptr;
+}
+
+TEST_P(TaskQueueTest, PostedExecutedClosureDestroyedOnTaskQueue) {
+ std::unique_ptr<webrtc::TaskQueueFactory> factory = GetParam()(nullptr);
+ auto queue =
+ CreateTaskQueue(factory, "PostedExecutedClosureDestroyedOnTaskQueue");
+ TaskQueueBase* queue_ptr = queue.get();
+ // Ensure an executed lambda is destroyed on the task queue.
+ rtc::Event finished;
+ queue->PostTask([cleanup = absl::Cleanup([queue_ptr, &finished] {
+ EXPECT_EQ(queue_ptr, TaskQueueBase::Current());
+ finished.Set();
+ })] {});
+ finished.Wait(rtc::Event::kForever);
+}
+
+TEST_P(TaskQueueTest, PostAndReuse) {
+ std::unique_ptr<webrtc::TaskQueueFactory> factory = GetParam()(nullptr);
+ rtc::Event event;
+ auto post_queue = CreateTaskQueue(factory, "PostQueue");
+ auto reply_queue = CreateTaskQueue(factory, "ReplyQueue");
+
+ int call_count = 0;
+
+ class ReusedTask {
+ public:
+ ReusedTask(int* counter, TaskQueueBase* reply_queue, rtc::Event* event)
+ : counter_(*counter), reply_queue_(reply_queue), event_(*event) {
+ EXPECT_EQ(counter_, 0);
+ }
+ ReusedTask(ReusedTask&&) = default;
+ ReusedTask& operator=(ReusedTask&&) = delete;
+
+ void operator()() && {
+ if (++counter_ == 1) {
+ reply_queue_->PostTask(std::move(*this));
+ // At this point, the object is in the moved-from state.
+ } else {
+ EXPECT_EQ(counter_, 2);
+ EXPECT_TRUE(reply_queue_->IsCurrent());
+ event_.Set();
+ }
+ }
+
+ private:
+ int& counter_;
+ TaskQueueBase* const reply_queue_;
+ rtc::Event& event_;
+ };
+
+ ReusedTask task(&call_count, reply_queue.get(), &event);
+ post_queue->PostTask(std::move(task));
+ EXPECT_TRUE(event.Wait(TimeDelta::Seconds(1)));
+}
+
+TEST_P(TaskQueueTest, PostALot) {
+ // Waits until DecrementCount called `count` times. Thread safe.
+ class BlockingCounter {
+ public:
+ explicit BlockingCounter(int initial_count) : count_(initial_count) {}
+
+ void DecrementCount() {
+ if (count_.DecRef() == rtc::RefCountReleaseStatus::kDroppedLastRef) {
+ event_.Set();
+ }
+ }
+ bool Wait(TimeDelta give_up_after) { return event_.Wait(give_up_after); }
+
+ private:
+ webrtc_impl::RefCounter count_;
+ rtc::Event event_;
+ };
+
+ std::unique_ptr<webrtc::TaskQueueFactory> factory = GetParam()(nullptr);
+ static constexpr int kTaskCount = 0xffff;
+ rtc::Event posting_done;
+ BlockingCounter all_destroyed(kTaskCount);
+
+ int tasks_executed = 0;
+ auto task_queue = CreateTaskQueue(factory, "PostALot");
+
+ task_queue->PostTask([&] {
+ // Post tasks from the queue to guarantee that the 1st task won't be
+ // executed before the last one is posted.
+ for (int i = 0; i < kTaskCount; ++i) {
+ absl::Cleanup cleanup = [&] { all_destroyed.DecrementCount(); };
+ task_queue->PostTask([&tasks_executed, cleanup = std::move(cleanup)] {
+ ++tasks_executed;
+ });
+ }
+
+ posting_done.Set();
+ });
+
+ // Before destroying the task queue wait until all child tasks are posted.
+ posting_done.Wait(rtc::Event::kForever);
+ // Destroy the task queue.
+ task_queue = nullptr;
+
+ // Expect all tasks are destroyed eventually. In some task queue
+ // implementations that might happen on a different thread after task queue is
+ // destroyed.
+ EXPECT_TRUE(all_destroyed.Wait(TimeDelta::Minutes(1)));
+ EXPECT_LE(tasks_executed, kTaskCount);
+}
+
+// Test posting two tasks that have shared state not protected by a
+// lock. The TaskQueue should guarantee memory read-write order and
+// FIFO task execution order, so the second task should always see the
+// changes that were made by the first task.
+//
+// If the TaskQueue doesn't properly synchronize the execution of
+// tasks, there will be a data race, which is undefined behavior. The
+// EXPECT calls may randomly catch this, but to make the most of this
+// unit test, run it under TSan or some other tool that is able to
+// directly detect data races.
+TEST_P(TaskQueueTest, PostTwoWithSharedUnprotectedState) {
+ std::unique_ptr<webrtc::TaskQueueFactory> factory = GetParam()(nullptr);
+ struct SharedState {
+ // First task will set this value to 1 and second will assert it.
+ int state = 0;
+ } state;
+
+ auto queue = CreateTaskQueue(factory, "PostTwoWithSharedUnprotectedState");
+ rtc::Event done;
+ queue->PostTask([&state, &queue, &done] {
+ // Post tasks from queue to guarantee, that 1st task won't be
+ // executed before the second one will be posted.
+ queue->PostTask([&state] { state.state = 1; });
+ queue->PostTask([&state, &done] {
+ EXPECT_EQ(state.state, 1);
+ done.Set();
+ });
+ // Check, that state changing tasks didn't start yet.
+ EXPECT_EQ(state.state, 0);
+ });
+ EXPECT_TRUE(done.Wait(TimeDelta::Seconds(1)));
+}
+
+// TaskQueueTest is a set of tests for any implementation of the TaskQueueBase.
+// Tests are instantiated next to the concrete implementation(s).
+// https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#creating-value-parameterized-abstract-tests
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TaskQueueTest);
+
+} // namespace
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/task_queue/task_queue_test.h b/third_party/libwebrtc/api/task_queue/task_queue_test.h
new file mode 100644
index 0000000000..214f95008f
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/task_queue_test.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_TASK_QUEUE_TASK_QUEUE_TEST_H_
+#define API_TASK_QUEUE_TASK_QUEUE_TEST_H_
+
+#include <functional>
+#include <memory>
+
+#include "api/field_trials_view.h"
+#include "api/task_queue/task_queue_factory.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+// Suite of tests to verify TaskQueue implementation with.
+// Example usage:
+//
+// namespace {
+//
+// using ::testing::Values;
+// using ::webrtc::TaskQueueTest;
+//
+// std::unique_ptr<webrtc::TaskQueueFactory> CreateMyFactory();
+//
+// INSTANTIATE_TEST_SUITE_P(My, TaskQueueTest, Values(CreateMyFactory));
+//
+// } // namespace
+class TaskQueueTest
+ : public ::testing::TestWithParam<std::function<
+ std::unique_ptr<TaskQueueFactory>(const FieldTrialsView*)>> {};
+
+} // namespace webrtc
+
+#endif // API_TASK_QUEUE_TASK_QUEUE_TEST_H_
diff --git a/third_party/libwebrtc/api/task_queue/test/BUILD.gn b/third_party/libwebrtc/api/task_queue/test/BUILD.gn
new file mode 100644
index 0000000000..25f7ed0c7f
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/test/BUILD.gn
@@ -0,0 +1,20 @@
+# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+
+rtc_library("mock_task_queue_base") {
+ testonly = true
+ sources = [ "mock_task_queue_base.h" ]
+ deps = [
+ "../../../api/task_queue:task_queue",
+ "../../../api/units:time_delta",
+ "../../../test:test_support",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/functional:any_invocable" ]
+}
diff --git a/third_party/libwebrtc/api/task_queue/test/mock_task_queue_base.h b/third_party/libwebrtc/api/task_queue/test/mock_task_queue_base.h
new file mode 100644
index 0000000000..2e99be7e82
--- /dev/null
+++ b/third_party/libwebrtc/api/task_queue/test/mock_task_queue_base.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2022 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TASK_QUEUE_TEST_MOCK_TASK_QUEUE_BASE_H_
+#define API_TASK_QUEUE_TEST_MOCK_TASK_QUEUE_BASE_H_
+
+#include "absl/functional/any_invocable.h"
+#include "api/task_queue/task_queue_base.h"
+#include "api/units/time_delta.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockTaskQueueBase : public TaskQueueBase {
+ public:
+ MOCK_METHOD(void, Delete, (), (override));
+ MOCK_METHOD(void, PostTask, (absl::AnyInvocable<void() &&>), (override));
+ MOCK_METHOD(void,
+ PostDelayedTask,
+ (absl::AnyInvocable<void() &&>, TimeDelta),
+ (override));
+ MOCK_METHOD(void,
+ PostDelayedHighPrecisionTask,
+ (absl::AnyInvocable<void() &&>, TimeDelta),
+ (override));
+};
+
+} // namespace webrtc
+
+#endif // API_TASK_QUEUE_TEST_MOCK_TASK_QUEUE_BASE_H_
diff --git a/third_party/libwebrtc/api/test/DEPS b/third_party/libwebrtc/api/test/DEPS
new file mode 100644
index 0000000000..270b274c5f
--- /dev/null
+++ b/third_party/libwebrtc/api/test/DEPS
@@ -0,0 +1,39 @@
+specific_include_rules = {
+ ".*": [
+ "+modules/video_coding",
+ ],
+ ".*": [
+ "+video"
+ ],
+ "dummy_peer_connection\.h": [
+ "+rtc_base/ref_counted_object.h",
+ ],
+ "neteq_factory_with_codecs\.h": [
+ "+system_wrappers/include/clock.h",
+ ],
+ "network_emulation_manager\.h": [
+ "+rtc_base/thread.h",
+ "+rtc_base/network.h",
+ "+rtc_base/network_constants.h",
+ ],
+ "peer_network_dependencies\.h": [
+ "+rtc_base/network.h",
+ "+rtc_base/thread.h",
+ ],
+ "peerconnection_quality_test_fixture\.h": [
+ "+logging/rtc_event_log/rtc_event_log_factory_interface.h",
+ "+rtc_base/network.h",
+ "+rtc_base/rtc_certificate_generator.h",
+ "+rtc_base/ssl_certificate.h",
+ "+rtc_base/thread.h",
+ "+media/base/media_constants.h",
+ "+modules/audio_processing/include/audio_processing.h",
+ ],
+ "time_controller\.h": [
+ "+rtc_base/synchronization/yield_policy.h",
+ "+system_wrappers/include/clock.h",
+ ],
+ "create_frame_generator\.h": [
+ "+system_wrappers/include/clock.h",
+ ],
+}
diff --git a/third_party/libwebrtc/api/test/OWNERS b/third_party/libwebrtc/api/test/OWNERS
new file mode 100644
index 0000000000..a7392abe31
--- /dev/null
+++ b/third_party/libwebrtc/api/test/OWNERS
@@ -0,0 +1,5 @@
+mbonadei@webrtc.org
+sprang@webrtc.org
+srte@webrtc.org
+titovartem@webrtc.org
+
diff --git a/third_party/libwebrtc/api/test/audio_quality_analyzer_interface.h b/third_party/libwebrtc/api/test/audio_quality_analyzer_interface.h
new file mode 100644
index 0000000000..2eb7817445
--- /dev/null
+++ b/third_party/libwebrtc/api/test/audio_quality_analyzer_interface.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_AUDIO_QUALITY_ANALYZER_INTERFACE_H_
+#define API_TEST_AUDIO_QUALITY_ANALYZER_INTERFACE_H_
+
+#include <string>
+
+#include "api/test/stats_observer_interface.h"
+#include "api/test/track_id_stream_info_map.h"
+
+namespace webrtc {
+namespace webrtc_pc_e2e {
+
+// API is in development. Can be changed/removed without notice.
+class AudioQualityAnalyzerInterface : public StatsObserverInterface {
+ public:
+ ~AudioQualityAnalyzerInterface() override = default;
+
+ // Will be called by the framework before the test.
+ // `test_case_name` is name of test case, that should be used to report all
+ // audio metrics.
+ // `analyzer_helper` is a pointer to a class that will allow track_id to
+ // stream_id matching. The caller is responsible for ensuring the
+ // AnalyzerHelper outlives the instance of the AudioQualityAnalyzerInterface.
+ virtual void Start(std::string test_case_name,
+ TrackIdStreamInfoMap* analyzer_helper) = 0;
+
+ // Will be called by the framework at the end of the test. The analyzer
+ // has to finalize all its stats and it should report them.
+ virtual void Stop() = 0;
+};
+
+} // namespace webrtc_pc_e2e
+} // namespace webrtc
+
+#endif // API_TEST_AUDIO_QUALITY_ANALYZER_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/test/audioproc_float.cc b/third_party/libwebrtc/api/test/audioproc_float.cc
new file mode 100644
index 0000000000..c8d7ff7193
--- /dev/null
+++ b/third_party/libwebrtc/api/test/audioproc_float.cc
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/audioproc_float.h"
+
+#include <utility>
+
+#include "modules/audio_processing/test/audioproc_float_impl.h"
+
+namespace webrtc {
+namespace test {
+
+int AudioprocFloat(rtc::scoped_refptr<AudioProcessing> audio_processing,
+ int argc,
+ char* argv[]) {
+ return AudioprocFloatImpl(std::move(audio_processing), argc, argv);
+}
+
+int AudioprocFloat(std::unique_ptr<AudioProcessingBuilder> ap_builder,
+ int argc,
+ char* argv[]) {
+ return AudioprocFloatImpl(std::move(ap_builder), argc, argv,
+ /*input_aecdump=*/"",
+ /*processed_capture_samples=*/nullptr);
+}
+
+int AudioprocFloat(std::unique_ptr<AudioProcessingBuilder> ap_builder,
+ int argc,
+ char* argv[],
+ absl::string_view input_aecdump,
+ std::vector<float>* processed_capture_samples) {
+ return AudioprocFloatImpl(std::move(ap_builder), argc, argv, input_aecdump,
+ processed_capture_samples);
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/audioproc_float.h b/third_party/libwebrtc/api/test/audioproc_float.h
new file mode 100644
index 0000000000..1ef1c9828f
--- /dev/null
+++ b/third_party/libwebrtc/api/test/audioproc_float.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_AUDIOPROC_FLOAT_H_
+#define API_TEST_AUDIOPROC_FLOAT_H_
+
+#include <memory>
+#include <vector>
+
+#include "modules/audio_processing/include/audio_processing.h"
+
+namespace webrtc {
+namespace test {
+
+// This is an interface for the audio processing simulation utility. This
+// utility can be used to simulate the audioprocessing module using a recording
+// (either an AEC dump or wav files), and generate the output as a wav file.
+// Any audio_processing object specified in the input is used for the
+// simulation. The optional `audio_processing` object provides the
+// AudioProcessing instance that is used during the simulation. Note that when
+// the audio_processing object is specified all functionality that relies on
+// using the AudioProcessingBuilder is deactivated, since the AudioProcessing
+// object is already created and the builder is not used in the simulation. It
+// is needed to pass the command line flags as `argc` and `argv`, so these can
+// be interpreted properly by the utility. To see a list of all supported
+// command line flags, run the executable with the '--help' flag.
+int AudioprocFloat(rtc::scoped_refptr<AudioProcessing> audio_processing,
+ int argc,
+ char* argv[]);
+
+// This is an interface for the audio processing simulation utility. This
+// utility can be used to simulate the audioprocessing module using a recording
+// (either an AEC dump or wav files), and generate the output as a wav file.
+// The `ap_builder` object will be used to create the AudioProcessing instance
+// that is used during the simulation. The `ap_builder` supports setting of
+// injectable components, which will be passed on to the created AudioProcessing
+// instance. It is needed to pass the command line flags as `argc` and `argv`,
+// so these can be interpreted properly by the utility.
+// To get a fully-working audioproc_f utility, all that is needed is to write a
+// main function, create an AudioProcessingBuilder, optionally set custom
+// processing components on it, and pass the builder together with the command
+// line arguments into this function.
+// To see a list of all supported command line flags, run the executable with
+// the '--help' flag.
+int AudioprocFloat(std::unique_ptr<AudioProcessingBuilder> ap_builder,
+ int argc,
+ char* argv[]);
+
+// Interface for the audio processing simulation utility, which is similar to
+// the one above, but which adds the option of receiving the input as a string
+// and returning the output as an array. The first three arguments fulfill the
+// same purpose as above. Pass the `input_aecdump` to provide the content of an
+// AEC dump file as a string. After the simulation is completed,
+// `processed_capture_samples` will contain the the samples processed on the
+// capture side.
+int AudioprocFloat(std::unique_ptr<AudioProcessingBuilder> ap_builder,
+ int argc,
+ char* argv[],
+ absl::string_view input_aecdump,
+ std::vector<float>* processed_capture_samples);
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_AUDIOPROC_FLOAT_H_
diff --git a/third_party/libwebrtc/api/test/compile_all_headers.cc b/third_party/libwebrtc/api/test/compile_all_headers.cc
new file mode 100644
index 0000000000..1fcf63e97b
--- /dev/null
+++ b/third_party/libwebrtc/api/test/compile_all_headers.cc
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This file verifies that all include files in this directory can be
+// compiled without errors or other required includes.
+
+// Note: The following header files are not not tested here, as their
+// associated targets are not included in all configurations.
+// "api/test/audioproc_float.h"
+// "api/test/create_video_quality_test_fixture.h"
+// "api/test/neteq_simulator_factory.h"
+// "api/test/video_quality_test_fixture.h"
+// The following header files are also not tested:
+// "api/test/create_simulcast_test_fixture.h"
+// "api/test/create_videocodec_test_fixture.h"
+// "api/test/neteq_simulator.h"
+// "api/test/simulated_network.h"
+// "api/test/simulcast_test_fixture.h"
+// "api/test/test_dependency_factory.h"
+// "api/test/videocodec_test_fixture.h"
+// "api/test/videocodec_test_stats.h"
+
+#include "api/test/fake_frame_decryptor.h"
+#include "api/test/fake_frame_encryptor.h"
+#include "api/test/mock_async_dns_resolver.h"
+#include "api/test/mock_audio_mixer.h"
+#include "api/test/mock_audio_sink.h"
+#include "api/test/mock_data_channel.h"
+#include "api/test/mock_dtmf_sender.h"
+#include "api/test/mock_frame_decryptor.h"
+#include "api/test/mock_frame_encryptor.h"
+#include "api/test/mock_media_stream_interface.h"
+#include "api/test/mock_peer_connection_factory_interface.h"
+#include "api/test/mock_peerconnectioninterface.h"
+#include "api/test/mock_rtp_transceiver.h"
+#include "api/test/mock_rtpreceiver.h"
+#include "api/test/mock_rtpsender.h"
+#include "api/test/mock_session_description_interface.h"
+#include "api/test/mock_transformable_video_frame.h"
+#include "api/test/mock_video_bitrate_allocator.h"
+#include "api/test/mock_video_bitrate_allocator_factory.h"
+#include "api/test/mock_video_decoder.h"
+#include "api/test/mock_video_decoder_factory.h"
+#include "api/test/mock_video_encoder.h"
+#include "api/test/mock_video_encoder_factory.h"
+#include "api/test/mock_video_track.h"
diff --git a/third_party/libwebrtc/api/test/create_frame_generator.cc b/third_party/libwebrtc/api/test/create_frame_generator.cc
new file mode 100644
index 0000000000..5e6fb3228b
--- /dev/null
+++ b/third_party/libwebrtc/api/test/create_frame_generator.cc
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/create_frame_generator.h"
+
+#include <cstdio>
+#include <utility>
+
+#include "rtc_base/checks.h"
+#include "test/frame_generator.h"
+#include "test/testsupport/ivf_video_frame_generator.h"
+
+namespace webrtc {
+namespace test {
+
+std::unique_ptr<FrameGeneratorInterface> CreateSquareFrameGenerator(
+ int width,
+ int height,
+ absl::optional<FrameGeneratorInterface::OutputType> type,
+ absl::optional<int> num_squares) {
+ return std::make_unique<SquareGenerator>(
+ width, height, type.value_or(FrameGeneratorInterface::OutputType::kI420),
+ num_squares.value_or(10));
+}
+
+std::unique_ptr<FrameGeneratorInterface> CreateFromYuvFileFrameGenerator(
+ std::vector<std::string> filenames,
+ size_t width,
+ size_t height,
+ int frame_repeat_count) {
+ RTC_DCHECK(!filenames.empty());
+ std::vector<FILE*> files;
+ for (const std::string& filename : filenames) {
+ FILE* file = fopen(filename.c_str(), "rb");
+ RTC_DCHECK(file != nullptr) << "Failed to open: '" << filename << "'\n";
+ files.push_back(file);
+ }
+
+ return std::make_unique<YuvFileGenerator>(files, width, height,
+ frame_repeat_count);
+}
+
+std::unique_ptr<FrameGeneratorInterface> CreateFromNV12FileFrameGenerator(
+ std::vector<std::string> filenames,
+ size_t width,
+ size_t height,
+ int frame_repeat_count) {
+ RTC_DCHECK(!filenames.empty());
+ std::vector<FILE*> files;
+ for (const std::string& filename : filenames) {
+ FILE* file = fopen(filename.c_str(), "rb");
+ RTC_DCHECK(file != nullptr) << "Failed to open: '" << filename << "'\n";
+ files.push_back(file);
+ }
+
+ return std::make_unique<NV12FileGenerator>(files, width, height,
+ frame_repeat_count);
+}
+
+std::unique_ptr<FrameGeneratorInterface> CreateFromIvfFileFrameGenerator(
+ std::string filename) {
+ return std::make_unique<IvfVideoFrameGenerator>(std::move(filename));
+}
+
+std::unique_ptr<FrameGeneratorInterface>
+CreateScrollingInputFromYuvFilesFrameGenerator(
+ Clock* clock,
+ std::vector<std::string> filenames,
+ size_t source_width,
+ size_t source_height,
+ size_t target_width,
+ size_t target_height,
+ int64_t scroll_time_ms,
+ int64_t pause_time_ms) {
+ RTC_DCHECK(!filenames.empty());
+ std::vector<FILE*> files;
+ for (const std::string& filename : filenames) {
+ FILE* file = fopen(filename.c_str(), "rb");
+ RTC_DCHECK(file != nullptr);
+ files.push_back(file);
+ }
+
+ return std::make_unique<ScrollingImageFrameGenerator>(
+ clock, files, source_width, source_height, target_width, target_height,
+ scroll_time_ms, pause_time_ms);
+}
+
+std::unique_ptr<FrameGeneratorInterface>
+CreateSlideFrameGenerator(int width, int height, int frame_repeat_count) {
+ return std::make_unique<SlideGenerator>(width, height, frame_repeat_count);
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/create_frame_generator.h b/third_party/libwebrtc/api/test/create_frame_generator.h
new file mode 100644
index 0000000000..70be0c4e8e
--- /dev/null
+++ b/third_party/libwebrtc/api/test/create_frame_generator.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_CREATE_FRAME_GENERATOR_H_
+#define API_TEST_CREATE_FRAME_GENERATOR_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/test/frame_generator_interface.h"
+#include "system_wrappers/include/clock.h"
+
+namespace webrtc {
+namespace test {
+
+// Creates a frame generator that produces frames with small squares that
+// move randomly towards the lower right corner.
+// `type` has the default value FrameGeneratorInterface::OutputType::I420.
+// `num_squares` has the default value 10.
+std::unique_ptr<FrameGeneratorInterface> CreateSquareFrameGenerator(
+ int width,
+ int height,
+ absl::optional<FrameGeneratorInterface::OutputType> type,
+ absl::optional<int> num_squares);
+
+// Creates a frame generator that repeatedly plays a set of yuv files.
+// The frame_repeat_count determines how many times each frame is shown,
+// with 1 = show each frame once, etc.
+std::unique_ptr<FrameGeneratorInterface> CreateFromYuvFileFrameGenerator(
+ std::vector<std::string> filenames,
+ size_t width,
+ size_t height,
+ int frame_repeat_count);
+
+// Creates a frame generator that repeatedly plays a set of nv12 files.
+// The frame_repeat_count determines how many times each frame is shown,
+// with 1 = show each frame once, etc.
+std::unique_ptr<FrameGeneratorInterface> CreateFromNV12FileFrameGenerator(
+ std::vector<std::string> filenames,
+ size_t width,
+ size_t height,
+ int frame_repeat_count = 1);
+
+// Creates a frame generator that repeatedly plays an ivf file.
+std::unique_ptr<FrameGeneratorInterface> CreateFromIvfFileFrameGenerator(
+ std::string filename);
+
+// Creates a frame generator which takes a set of yuv files (wrapping a
+// frame generator created by CreateFromYuvFile() above), but outputs frames
+// that have been cropped to specified resolution: source_width/source_height
+// is the size of the source images, target_width/target_height is the size of
+// the cropped output. For each source image read, the cropped viewport will
+// be scrolled top to bottom/left to right for scroll_tim_ms milliseconds.
+// After that the image will stay in place for pause_time_ms milliseconds,
+// and then this will be repeated with the next file from the input set.
+std::unique_ptr<FrameGeneratorInterface>
+CreateScrollingInputFromYuvFilesFrameGenerator(
+ Clock* clock,
+ std::vector<std::string> filenames,
+ size_t source_width,
+ size_t source_height,
+ size_t target_width,
+ size_t target_height,
+ int64_t scroll_time_ms,
+ int64_t pause_time_ms);
+
+// Creates a frame generator that produces randomly generated slides. It fills
+// the frames with randomly sized and colored squares.
+// `frame_repeat_count` determines how many times each slide is shown.
+std::unique_ptr<FrameGeneratorInterface>
+CreateSlideFrameGenerator(int width, int height, int frame_repeat_count);
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_CREATE_FRAME_GENERATOR_H_
diff --git a/third_party/libwebrtc/api/test/create_network_emulation_manager.cc b/third_party/libwebrtc/api/test/create_network_emulation_manager.cc
new file mode 100644
index 0000000000..f5d5a1bc88
--- /dev/null
+++ b/third_party/libwebrtc/api/test/create_network_emulation_manager.cc
@@ -0,0 +1,27 @@
+
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/create_network_emulation_manager.h"
+
+#include <memory>
+
+#include "test/network/network_emulation_manager.h"
+
+namespace webrtc {
+
+std::unique_ptr<NetworkEmulationManager> CreateNetworkEmulationManager(
+ TimeMode time_mode,
+ EmulatedNetworkStatsGatheringMode stats_gathering_mode) {
+ return std::make_unique<test::NetworkEmulationManagerImpl>(
+ time_mode, stats_gathering_mode);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/create_network_emulation_manager.h b/third_party/libwebrtc/api/test/create_network_emulation_manager.h
new file mode 100644
index 0000000000..941b2b1c52
--- /dev/null
+++ b/third_party/libwebrtc/api/test/create_network_emulation_manager.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_CREATE_NETWORK_EMULATION_MANAGER_H_
+#define API_TEST_CREATE_NETWORK_EMULATION_MANAGER_H_
+
+#include <memory>
+
+#include "api/test/network_emulation_manager.h"
+
+namespace webrtc {
+
+// Returns a non-null NetworkEmulationManager instance.
+std::unique_ptr<NetworkEmulationManager> CreateNetworkEmulationManager(
+ TimeMode time_mode = TimeMode::kRealTime,
+ EmulatedNetworkStatsGatheringMode stats_gathering_mode =
+ EmulatedNetworkStatsGatheringMode::kDefault);
+
+} // namespace webrtc
+
+#endif // API_TEST_CREATE_NETWORK_EMULATION_MANAGER_H_
diff --git a/third_party/libwebrtc/api/test/create_peer_connection_quality_test_frame_generator.cc b/third_party/libwebrtc/api/test/create_peer_connection_quality_test_frame_generator.cc
new file mode 100644
index 0000000000..a1c53635f9
--- /dev/null
+++ b/third_party/libwebrtc/api/test/create_peer_connection_quality_test_frame_generator.cc
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/create_peer_connection_quality_test_frame_generator.h"
+
+#include <utility>
+#include <vector>
+
+#include "api/test/create_frame_generator.h"
+#include "api/test/pclf/media_configuration.h"
+#include "rtc_base/checks.h"
+#include "test/testsupport/file_utils.h"
+
+namespace webrtc {
+namespace webrtc_pc_e2e {
+
+void ValidateScreenShareConfig(const VideoConfig& video_config,
+ const ScreenShareConfig& screen_share_config) {
+ if (screen_share_config.slides_yuv_file_names.empty()) {
+ if (screen_share_config.scrolling_params) {
+ // If we have scrolling params, then its `source_width` and `source_heigh`
+ // will be used as width and height of video input, so we have to validate
+ // it against width and height of default input.
+ RTC_CHECK_EQ(screen_share_config.scrolling_params->source_width,
+ kDefaultSlidesWidth);
+ RTC_CHECK_EQ(screen_share_config.scrolling_params->source_height,
+ kDefaultSlidesHeight);
+ } else {
+ RTC_CHECK_EQ(video_config.width, kDefaultSlidesWidth);
+ RTC_CHECK_EQ(video_config.height, kDefaultSlidesHeight);
+ }
+ }
+ if (screen_share_config.scrolling_params) {
+ RTC_CHECK_LE(screen_share_config.scrolling_params->duration,
+ screen_share_config.slide_change_interval);
+ RTC_CHECK_GE(screen_share_config.scrolling_params->source_width,
+ video_config.width);
+ RTC_CHECK_GE(screen_share_config.scrolling_params->source_height,
+ video_config.height);
+ }
+}
+
+std::unique_ptr<test::FrameGeneratorInterface> CreateSquareFrameGenerator(
+ const VideoConfig& video_config,
+ absl::optional<test::FrameGeneratorInterface::OutputType> type) {
+ return test::CreateSquareFrameGenerator(
+ video_config.width, video_config.height, std::move(type), absl::nullopt);
+}
+
+std::unique_ptr<test::FrameGeneratorInterface> CreateFromYuvFileFrameGenerator(
+ const VideoConfig& video_config,
+ std::string filename) {
+ return test::CreateFromYuvFileFrameGenerator(
+ {std::move(filename)}, video_config.width, video_config.height,
+ /*frame_repeat_count=*/1);
+}
+
+std::unique_ptr<test::FrameGeneratorInterface> CreateScreenShareFrameGenerator(
+ const VideoConfig& video_config,
+ const ScreenShareConfig& screen_share_config) {
+ ValidateScreenShareConfig(video_config, screen_share_config);
+ if (screen_share_config.generate_slides) {
+ return test::CreateSlideFrameGenerator(
+ video_config.width, video_config.height,
+ screen_share_config.slide_change_interval.seconds() * video_config.fps);
+ }
+ std::vector<std::string> slides = screen_share_config.slides_yuv_file_names;
+ if (slides.empty()) {
+ // If slides is empty we need to add default slides as source. In such case
+ // video width and height is validated to be equal to kDefaultSlidesWidth
+ // and kDefaultSlidesHeight.
+ slides.push_back(test::ResourcePath("web_screenshot_1850_1110", "yuv"));
+ slides.push_back(test::ResourcePath("presentation_1850_1110", "yuv"));
+ slides.push_back(test::ResourcePath("photo_1850_1110", "yuv"));
+ slides.push_back(test::ResourcePath("difficult_photo_1850_1110", "yuv"));
+ }
+ if (!screen_share_config.scrolling_params) {
+ // Cycle image every slide_change_interval seconds.
+ return test::CreateFromYuvFileFrameGenerator(
+ slides, video_config.width, video_config.height,
+ screen_share_config.slide_change_interval.seconds() * video_config.fps);
+ }
+
+ TimeDelta pause_duration = screen_share_config.slide_change_interval -
+ screen_share_config.scrolling_params->duration;
+ RTC_DCHECK(pause_duration >= TimeDelta::Zero());
+ return test::CreateScrollingInputFromYuvFilesFrameGenerator(
+ Clock::GetRealTimeClock(), slides,
+ screen_share_config.scrolling_params->source_width,
+ screen_share_config.scrolling_params->source_height, video_config.width,
+ video_config.height, screen_share_config.scrolling_params->duration.ms(),
+ pause_duration.ms());
+}
+
+} // namespace webrtc_pc_e2e
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/create_peer_connection_quality_test_frame_generator.h b/third_party/libwebrtc/api/test/create_peer_connection_quality_test_frame_generator.h
new file mode 100644
index 0000000000..62043d140a
--- /dev/null
+++ b/third_party/libwebrtc/api/test/create_peer_connection_quality_test_frame_generator.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_TEST_CREATE_PEER_CONNECTION_QUALITY_TEST_FRAME_GENERATOR_H_
+#define API_TEST_CREATE_PEER_CONNECTION_QUALITY_TEST_FRAME_GENERATOR_H_
+
+#include <memory>
+#include <string>
+
+#include "absl/types/optional.h"
+#include "api/test/frame_generator_interface.h"
+#include "api/test/pclf/media_configuration.h"
+
+namespace webrtc {
+namespace webrtc_pc_e2e {
+
+// Creates a frame generator that produces frames with small squares that move
+// randomly towards the lower right corner. `type` has the default value
+// FrameGeneratorInterface::OutputType::I420. video_config specifies frame
+// weight and height.
+std::unique_ptr<test::FrameGeneratorInterface> CreateSquareFrameGenerator(
+ const VideoConfig& video_config,
+ absl::optional<test::FrameGeneratorInterface::OutputType> type);
+
+// Creates a frame generator that plays frames from the yuv file.
+std::unique_ptr<test::FrameGeneratorInterface> CreateFromYuvFileFrameGenerator(
+ const VideoConfig& video_config,
+ std::string filename);
+
+// Creates a proper frame generator for testing screen sharing.
+std::unique_ptr<test::FrameGeneratorInterface> CreateScreenShareFrameGenerator(
+ const VideoConfig& video_config,
+ const ScreenShareConfig& screen_share_config);
+
+} // namespace webrtc_pc_e2e
+} // namespace webrtc
+
+#endif // API_TEST_CREATE_PEER_CONNECTION_QUALITY_TEST_FRAME_GENERATOR_H_
diff --git a/third_party/libwebrtc/api/test/create_peerconnection_quality_test_fixture.cc b/third_party/libwebrtc/api/test/create_peerconnection_quality_test_fixture.cc
new file mode 100644
index 0000000000..e156991ed4
--- /dev/null
+++ b/third_party/libwebrtc/api/test/create_peerconnection_quality_test_fixture.cc
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/create_peerconnection_quality_test_fixture.h"
+
+#include <memory>
+#include <utility>
+
+#include "api/test/metrics/global_metrics_logger_and_exporter.h"
+#include "api/test/time_controller.h"
+#include "test/pc/e2e/peer_connection_quality_test.h"
+
+namespace webrtc {
+namespace webrtc_pc_e2e {
+
+std::unique_ptr<PeerConnectionE2EQualityTestFixture>
+CreatePeerConnectionE2EQualityTestFixture(
+ std::string test_case_name,
+ TimeController& time_controller,
+ std::unique_ptr<AudioQualityAnalyzerInterface> audio_quality_analyzer,
+ std::unique_ptr<VideoQualityAnalyzerInterface> video_quality_analyzer) {
+ return std::make_unique<PeerConnectionE2EQualityTest>(
+ std::move(test_case_name), time_controller,
+ std::move(audio_quality_analyzer), std::move(video_quality_analyzer),
+ test::GetGlobalMetricsLogger());
+}
+
+} // namespace webrtc_pc_e2e
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/create_peerconnection_quality_test_fixture.h b/third_party/libwebrtc/api/test/create_peerconnection_quality_test_fixture.h
new file mode 100644
index 0000000000..a0b0d08dd4
--- /dev/null
+++ b/third_party/libwebrtc/api/test/create_peerconnection_quality_test_fixture.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_TEST_CREATE_PEERCONNECTION_QUALITY_TEST_FIXTURE_H_
+#define API_TEST_CREATE_PEERCONNECTION_QUALITY_TEST_FIXTURE_H_
+
+#include <memory>
+#include <string>
+
+#include "api/test/audio_quality_analyzer_interface.h"
+#include "api/test/peerconnection_quality_test_fixture.h"
+#include "api/test/time_controller.h"
+#include "api/test/video_quality_analyzer_interface.h"
+
+namespace webrtc {
+namespace webrtc_pc_e2e {
+
+// API is in development. Can be changed/removed without notice.
+
+// Create test fixture to establish test call between Alice and Bob.
+// During the test Alice will be caller and Bob will answer the call.
+// `test_case_name` is a name of test case, that will be used for all metrics
+// reporting.
+// `time_controller` is used to manage all rtc::Thread's and TaskQueue
+// instances. Instance of `time_controller` have to outlive created fixture.
+// Returns a non-null PeerConnectionE2EQualityTestFixture instance.
+std::unique_ptr<PeerConnectionE2EQualityTestFixture>
+CreatePeerConnectionE2EQualityTestFixture(
+ std::string test_case_name,
+ TimeController& time_controller,
+ std::unique_ptr<AudioQualityAnalyzerInterface> audio_quality_analyzer,
+ std::unique_ptr<VideoQualityAnalyzerInterface> video_quality_analyzer);
+
+} // namespace webrtc_pc_e2e
+} // namespace webrtc
+
+#endif // API_TEST_CREATE_PEERCONNECTION_QUALITY_TEST_FIXTURE_H_
diff --git a/third_party/libwebrtc/api/test/create_simulcast_test_fixture.cc b/third_party/libwebrtc/api/test/create_simulcast_test_fixture.cc
new file mode 100644
index 0000000000..024145dff0
--- /dev/null
+++ b/third_party/libwebrtc/api/test/create_simulcast_test_fixture.cc
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/create_simulcast_test_fixture.h"
+
+#include <memory>
+#include <utility>
+
+#include "api/test/simulcast_test_fixture.h"
+#include "modules/video_coding/utility/simulcast_test_fixture_impl.h"
+
+namespace webrtc {
+namespace test {
+
+std::unique_ptr<SimulcastTestFixture> CreateSimulcastTestFixture(
+ std::unique_ptr<VideoEncoderFactory> encoder_factory,
+ std::unique_ptr<VideoDecoderFactory> decoder_factory,
+ SdpVideoFormat video_format) {
+ return std::make_unique<SimulcastTestFixtureImpl>(
+ std::move(encoder_factory), std::move(decoder_factory), video_format);
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/create_simulcast_test_fixture.h b/third_party/libwebrtc/api/test/create_simulcast_test_fixture.h
new file mode 100644
index 0000000000..87f229c009
--- /dev/null
+++ b/third_party/libwebrtc/api/test/create_simulcast_test_fixture.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_CREATE_SIMULCAST_TEST_FIXTURE_H_
+#define API_TEST_CREATE_SIMULCAST_TEST_FIXTURE_H_
+
+#include <memory>
+
+#include "api/test/simulcast_test_fixture.h"
+#include "api/video_codecs/sdp_video_format.h"
+#include "api/video_codecs/video_decoder_factory.h"
+#include "api/video_codecs/video_encoder_factory.h"
+
+namespace webrtc {
+namespace test {
+
+std::unique_ptr<SimulcastTestFixture> CreateSimulcastTestFixture(
+ std::unique_ptr<VideoEncoderFactory> encoder_factory,
+ std::unique_ptr<VideoDecoderFactory> decoder_factory,
+ SdpVideoFormat video_format);
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_CREATE_SIMULCAST_TEST_FIXTURE_H_
diff --git a/third_party/libwebrtc/api/test/create_time_controller.cc b/third_party/libwebrtc/api/test/create_time_controller.cc
new file mode 100644
index 0000000000..d198f2b0fe
--- /dev/null
+++ b/third_party/libwebrtc/api/test/create_time_controller.cc
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/create_time_controller.h"
+
+#include <memory>
+
+#include "call/call.h"
+#include "call/rtp_transport_config.h"
+#include "call/rtp_transport_controller_send_factory_interface.h"
+#include "test/time_controller/external_time_controller.h"
+#include "test/time_controller/simulated_time_controller.h"
+
+namespace webrtc {
+
+std::unique_ptr<TimeController> CreateTimeController(
+ ControlledAlarmClock* alarm) {
+ return std::make_unique<ExternalTimeController>(alarm);
+}
+
+std::unique_ptr<TimeController> CreateSimulatedTimeController() {
+ return std::make_unique<GlobalSimulatedTimeController>(
+ Timestamp::Seconds(10000));
+}
+
+std::unique_ptr<CallFactoryInterface> CreateTimeControllerBasedCallFactory(
+ TimeController* time_controller) {
+ class TimeControllerBasedCallFactory : public CallFactoryInterface {
+ public:
+ explicit TimeControllerBasedCallFactory(TimeController* time_controller)
+ : time_controller_(time_controller) {}
+ Call* CreateCall(const Call::Config& config) override {
+ RtpTransportConfig transportConfig = config.ExtractTransportConfig();
+
+ return Call::Create(config, time_controller_->GetClock(),
+ config.rtp_transport_controller_send_factory->Create(
+ transportConfig, time_controller_->GetClock()));
+ }
+
+ private:
+ TimeController* time_controller_;
+ };
+ return std::make_unique<TimeControllerBasedCallFactory>(time_controller);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/create_time_controller.h b/third_party/libwebrtc/api/test/create_time_controller.h
new file mode 100644
index 0000000000..e7bc9cb465
--- /dev/null
+++ b/third_party/libwebrtc/api/test/create_time_controller.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_TEST_CREATE_TIME_CONTROLLER_H_
+#define API_TEST_CREATE_TIME_CONTROLLER_H_
+
+#include <memory>
+
+#include "api/call/call_factory_interface.h"
+#include "api/test/time_controller.h"
+
+namespace webrtc {
+
+// Creates a time coltroller that wraps `alarm`.
+std::unique_ptr<TimeController> CreateTimeController(
+ ControlledAlarmClock* alarm);
+
+// Creates a time controller that runs in simulated time.
+std::unique_ptr<TimeController> CreateSimulatedTimeController();
+
+// This is creates a call factory that creates Call instances that are backed by
+// a time controller.
+std::unique_ptr<CallFactoryInterface> CreateTimeControllerBasedCallFactory(
+ TimeController* time_controller);
+
+} // namespace webrtc
+
+#endif // API_TEST_CREATE_TIME_CONTROLLER_H_
diff --git a/third_party/libwebrtc/api/test/create_time_controller_unittest.cc b/third_party/libwebrtc/api/test/create_time_controller_unittest.cc
new file mode 100644
index 0000000000..0ea868c5cc
--- /dev/null
+++ b/third_party/libwebrtc/api/test/create_time_controller_unittest.cc
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/create_time_controller.h"
+
+#include "api/test/time_controller.h"
+#include "api/units/time_delta.h"
+#include "api/units/timestamp.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace {
+
+class FakeAlarm : public ControlledAlarmClock {
+ public:
+ explicit FakeAlarm(Timestamp start_time);
+
+ Clock* GetClock() override;
+ bool ScheduleAlarmAt(Timestamp deadline) override;
+ void SetCallback(std::function<void()> callback) override;
+ void Sleep(TimeDelta duration) override;
+
+ private:
+ SimulatedClock clock_;
+ Timestamp deadline_;
+ std::function<void()> callback_;
+};
+
+FakeAlarm::FakeAlarm(Timestamp start_time)
+ : clock_(start_time),
+ deadline_(Timestamp::PlusInfinity()),
+ callback_([] {}) {}
+
+Clock* FakeAlarm::GetClock() {
+ return &clock_;
+}
+
+bool FakeAlarm::ScheduleAlarmAt(Timestamp deadline) {
+ if (deadline < deadline_) {
+ deadline_ = deadline;
+ return true;
+ }
+ return false;
+}
+
+void FakeAlarm::SetCallback(std::function<void()> callback) {
+ callback_ = callback;
+}
+
+void FakeAlarm::Sleep(TimeDelta duration) {
+ Timestamp end_time = clock_.CurrentTime() + duration;
+
+ while (deadline_ <= end_time) {
+ clock_.AdvanceTime(deadline_ - clock_.CurrentTime());
+ deadline_ = Timestamp::PlusInfinity();
+ callback_();
+ }
+
+ clock_.AdvanceTime(end_time - clock_.CurrentTime());
+}
+
+TEST(CreateTimeControllerTest, CreatesNonNullController) {
+ FakeAlarm alarm(Timestamp::Millis(100));
+ EXPECT_NE(CreateTimeController(&alarm), nullptr);
+}
+
+} // namespace
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/create_video_codec_tester.cc b/third_party/libwebrtc/api/test/create_video_codec_tester.cc
new file mode 100644
index 0000000000..a1efefdb48
--- /dev/null
+++ b/third_party/libwebrtc/api/test/create_video_codec_tester.cc
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/create_video_codec_tester.h"
+
+#include <memory>
+#include <utility>
+
+#include "api/test/video_codec_tester.h"
+#include "modules/video_coding/codecs/test/video_codec_tester_impl.h"
+
+namespace webrtc {
+namespace test {
+
+std::unique_ptr<VideoCodecTester> CreateVideoCodecTester() {
+ return std::make_unique<VideoCodecTesterImpl>();
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/create_video_codec_tester.h b/third_party/libwebrtc/api/test/create_video_codec_tester.h
new file mode 100644
index 0000000000..c68864ce85
--- /dev/null
+++ b/third_party/libwebrtc/api/test/create_video_codec_tester.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_CREATE_VIDEO_CODEC_TESTER_H_
+#define API_TEST_CREATE_VIDEO_CODEC_TESTER_H_
+
+#include <memory>
+
+#include "api/test/video_codec_tester.h"
+
+namespace webrtc {
+namespace test {
+
+std::unique_ptr<VideoCodecTester> CreateVideoCodecTester();
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_CREATE_VIDEO_CODEC_TESTER_H_
diff --git a/third_party/libwebrtc/api/test/create_video_quality_test_fixture.cc b/third_party/libwebrtc/api/test/create_video_quality_test_fixture.cc
new file mode 100644
index 0000000000..1fa7d243cc
--- /dev/null
+++ b/third_party/libwebrtc/api/test/create_video_quality_test_fixture.cc
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/create_video_quality_test_fixture.h"
+
+#include <memory>
+#include <utility>
+
+#include "video/video_quality_test.h"
+
+namespace webrtc {
+
+std::unique_ptr<VideoQualityTestFixtureInterface>
+CreateVideoQualityTestFixture() {
+ // By default, we don't override the FEC module, so pass an empty factory.
+ return std::make_unique<VideoQualityTest>(nullptr);
+}
+
+std::unique_ptr<VideoQualityTestFixtureInterface> CreateVideoQualityTestFixture(
+ std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory) {
+ auto components =
+ std::make_unique<VideoQualityTestFixtureInterface::InjectionComponents>();
+ components->fec_controller_factory = std::move(fec_controller_factory);
+ return std::make_unique<VideoQualityTest>(std::move(components));
+}
+
+std::unique_ptr<VideoQualityTestFixtureInterface> CreateVideoQualityTestFixture(
+ std::unique_ptr<VideoQualityTestFixtureInterface::InjectionComponents>
+ components) {
+ return std::make_unique<VideoQualityTest>(std::move(components));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/create_video_quality_test_fixture.h b/third_party/libwebrtc/api/test/create_video_quality_test_fixture.h
new file mode 100644
index 0000000000..ed618fefc8
--- /dev/null
+++ b/third_party/libwebrtc/api/test/create_video_quality_test_fixture.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_TEST_CREATE_VIDEO_QUALITY_TEST_FIXTURE_H_
+#define API_TEST_CREATE_VIDEO_QUALITY_TEST_FIXTURE_H_
+
+#include <memory>
+
+#include "api/fec_controller.h"
+#include "api/test/video_quality_test_fixture.h"
+
+namespace webrtc {
+
+std::unique_ptr<VideoQualityTestFixtureInterface>
+CreateVideoQualityTestFixture();
+
+std::unique_ptr<VideoQualityTestFixtureInterface> CreateVideoQualityTestFixture(
+ std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory);
+
+std::unique_ptr<VideoQualityTestFixtureInterface> CreateVideoQualityTestFixture(
+ std::unique_ptr<VideoQualityTestFixtureInterface::InjectionComponents>
+ components);
+} // namespace webrtc
+
+#endif // API_TEST_CREATE_VIDEO_QUALITY_TEST_FIXTURE_H_
diff --git a/third_party/libwebrtc/api/test/create_videocodec_test_fixture.cc b/third_party/libwebrtc/api/test/create_videocodec_test_fixture.cc
new file mode 100644
index 0000000000..1f618e5db8
--- /dev/null
+++ b/third_party/libwebrtc/api/test/create_videocodec_test_fixture.cc
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/create_videocodec_test_fixture.h"
+
+#include <memory>
+#include <utility>
+
+#include "api/test/videocodec_test_fixture.h"
+#include "modules/video_coding/codecs/test/videocodec_test_fixture_impl.h"
+
+namespace webrtc {
+namespace test {
+
+using Config = VideoCodecTestFixture::Config;
+
+std::unique_ptr<VideoCodecTestFixture> CreateVideoCodecTestFixture(
+ const Config& config) {
+ return std::make_unique<VideoCodecTestFixtureImpl>(config);
+}
+
+std::unique_ptr<VideoCodecTestFixture> CreateVideoCodecTestFixture(
+ const Config& config,
+ std::unique_ptr<VideoDecoderFactory> decoder_factory,
+ std::unique_ptr<VideoEncoderFactory> encoder_factory) {
+ return std::make_unique<VideoCodecTestFixtureImpl>(
+ config, std::move(decoder_factory), std::move(encoder_factory));
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/create_videocodec_test_fixture.h b/third_party/libwebrtc/api/test/create_videocodec_test_fixture.h
new file mode 100644
index 0000000000..7a44f6b058
--- /dev/null
+++ b/third_party/libwebrtc/api/test/create_videocodec_test_fixture.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_CREATE_VIDEOCODEC_TEST_FIXTURE_H_
+#define API_TEST_CREATE_VIDEOCODEC_TEST_FIXTURE_H_
+
+#include <memory>
+
+#include "api/test/videocodec_test_fixture.h"
+#include "api/video_codecs/video_decoder_factory.h"
+#include "api/video_codecs/video_encoder_factory.h"
+
+namespace webrtc {
+namespace test {
+
+std::unique_ptr<VideoCodecTestFixture> CreateVideoCodecTestFixture(
+ const VideoCodecTestFixture::Config& config);
+
+std::unique_ptr<VideoCodecTestFixture> CreateVideoCodecTestFixture(
+ const VideoCodecTestFixture::Config& config,
+ std::unique_ptr<VideoDecoderFactory> decoder_factory,
+ std::unique_ptr<VideoEncoderFactory> encoder_factory);
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_CREATE_VIDEOCODEC_TEST_FIXTURE_H_
diff --git a/third_party/libwebrtc/api/test/fake_frame_decryptor.cc b/third_party/libwebrtc/api/test/fake_frame_decryptor.cc
new file mode 100644
index 0000000000..16cb1bd3b6
--- /dev/null
+++ b/third_party/libwebrtc/api/test/fake_frame_decryptor.cc
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/fake_frame_decryptor.h"
+
+#include <vector>
+
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+FakeFrameDecryptor::FakeFrameDecryptor(uint8_t fake_key,
+ uint8_t expected_postfix_byte)
+ : fake_key_(fake_key), expected_postfix_byte_(expected_postfix_byte) {}
+
+FakeFrameDecryptor::Result FakeFrameDecryptor::Decrypt(
+ cricket::MediaType media_type,
+ const std::vector<uint32_t>& csrcs,
+ rtc::ArrayView<const uint8_t> additional_data,
+ rtc::ArrayView<const uint8_t> encrypted_frame,
+ rtc::ArrayView<uint8_t> frame) {
+ if (fail_decryption_) {
+ return Result(Status::kFailedToDecrypt, 0);
+ }
+
+ RTC_CHECK_EQ(frame.size() + 1, encrypted_frame.size());
+ for (size_t i = 0; i < frame.size(); i++) {
+ frame[i] = encrypted_frame[i] ^ fake_key_;
+ }
+
+ if (encrypted_frame[frame.size()] != expected_postfix_byte_) {
+ return Result(Status::kFailedToDecrypt, 0);
+ }
+
+ return Result(Status::kOk, frame.size());
+}
+
+size_t FakeFrameDecryptor::GetMaxPlaintextByteSize(
+ cricket::MediaType media_type,
+ size_t encrypted_frame_size) {
+ return encrypted_frame_size - 1;
+}
+
+void FakeFrameDecryptor::SetFakeKey(uint8_t fake_key) {
+ fake_key_ = fake_key;
+}
+
+uint8_t FakeFrameDecryptor::GetFakeKey() const {
+ return fake_key_;
+}
+
+void FakeFrameDecryptor::SetExpectedPostfixByte(uint8_t expected_postfix_byte) {
+ expected_postfix_byte_ = expected_postfix_byte;
+}
+
+uint8_t FakeFrameDecryptor::GetExpectedPostfixByte() const {
+ return expected_postfix_byte_;
+}
+
+void FakeFrameDecryptor::SetFailDecryption(bool fail_decryption) {
+ fail_decryption_ = fail_decryption;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/fake_frame_decryptor.h b/third_party/libwebrtc/api/test/fake_frame_decryptor.h
new file mode 100644
index 0000000000..783bc805c4
--- /dev/null
+++ b/third_party/libwebrtc/api/test/fake_frame_decryptor.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_FAKE_FRAME_DECRYPTOR_H_
+#define API_TEST_FAKE_FRAME_DECRYPTOR_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <vector>
+
+#include "api/array_view.h"
+#include "api/crypto/frame_decryptor_interface.h"
+#include "api/media_types.h"
+
+namespace webrtc {
+
+// The FakeFrameDecryptor is a TEST ONLY fake implementation of the
+// FrameDecryptorInterface. It is constructed with a simple single digit key and
+// a fixed postfix byte. This is just to validate that the core code works
+// as expected.
+class FakeFrameDecryptor : public FrameDecryptorInterface {
+ public:
+ // Provide a key (0,255) and some postfix byte (0,255) this should match the
+ // byte you expect from the FakeFrameEncryptor.
+ explicit FakeFrameDecryptor(uint8_t fake_key = 0xAA,
+ uint8_t expected_postfix_byte = 255);
+ // Fake decryption that just xors the payload with the 1 byte key and checks
+ // the postfix byte. This will always fail if fail_decryption_ is set to true.
+ Result Decrypt(cricket::MediaType media_type,
+ const std::vector<uint32_t>& csrcs,
+ rtc::ArrayView<const uint8_t> additional_data,
+ rtc::ArrayView<const uint8_t> encrypted_frame,
+ rtc::ArrayView<uint8_t> frame) override;
+ // Always returns 1 less than the size of the encrypted frame.
+ size_t GetMaxPlaintextByteSize(cricket::MediaType media_type,
+ size_t encrypted_frame_size) override;
+ // Sets the fake key to use for encryption.
+ void SetFakeKey(uint8_t fake_key);
+ // Returns the fake key used for encryption.
+ uint8_t GetFakeKey() const;
+ // Set the Postfix byte that is expected in the encrypted payload.
+ void SetExpectedPostfixByte(uint8_t expected_postfix_byte);
+ // Returns the postfix byte that will be checked for in the encrypted payload.
+ uint8_t GetExpectedPostfixByte() const;
+ // If set to true will force all encryption to fail.
+ void SetFailDecryption(bool fail_decryption);
+ // Simple error codes for tests to validate against.
+ enum class FakeDecryptStatus : int {
+ OK = 0,
+ FORCED_FAILURE = 1,
+ INVALID_POSTFIX = 2
+ };
+
+ private:
+ uint8_t fake_key_ = 0;
+ uint8_t expected_postfix_byte_ = 0;
+ bool fail_decryption_ = false;
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_FAKE_FRAME_DECRYPTOR_H_
diff --git a/third_party/libwebrtc/api/test/fake_frame_encryptor.cc b/third_party/libwebrtc/api/test/fake_frame_encryptor.cc
new file mode 100644
index 0000000000..89d14aab88
--- /dev/null
+++ b/third_party/libwebrtc/api/test/fake_frame_encryptor.cc
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/fake_frame_encryptor.h"
+
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+FakeFrameEncryptor::FakeFrameEncryptor(uint8_t fake_key, uint8_t postfix_byte)
+ : fake_key_(fake_key), postfix_byte_(postfix_byte) {}
+
+// FrameEncryptorInterface implementation
+int FakeFrameEncryptor::Encrypt(cricket::MediaType media_type,
+ uint32_t ssrc,
+ rtc::ArrayView<const uint8_t> additional_data,
+ rtc::ArrayView<const uint8_t> frame,
+ rtc::ArrayView<uint8_t> encrypted_frame,
+ size_t* bytes_written) {
+ if (fail_encryption_) {
+ return static_cast<int>(FakeEncryptionStatus::FORCED_FAILURE);
+ }
+
+ RTC_CHECK_EQ(frame.size() + 1, encrypted_frame.size());
+ for (size_t i = 0; i < frame.size(); i++) {
+ encrypted_frame[i] = frame[i] ^ fake_key_;
+ }
+
+ encrypted_frame[frame.size()] = postfix_byte_;
+ *bytes_written = encrypted_frame.size();
+ return static_cast<int>(FakeEncryptionStatus::OK);
+}
+
+size_t FakeFrameEncryptor::GetMaxCiphertextByteSize(
+ cricket::MediaType media_type,
+ size_t frame_size) {
+ return frame_size + 1;
+}
+
+void FakeFrameEncryptor::SetFakeKey(uint8_t fake_key) {
+ fake_key_ = fake_key;
+}
+
+uint8_t FakeFrameEncryptor::GetFakeKey() const {
+ return fake_key_;
+}
+
+void FakeFrameEncryptor::SetPostfixByte(uint8_t postfix_byte) {
+ postfix_byte_ = postfix_byte;
+}
+
+uint8_t FakeFrameEncryptor::GetPostfixByte() const {
+ return postfix_byte_;
+}
+
+void FakeFrameEncryptor::SetFailEncryption(bool fail_encryption) {
+ fail_encryption_ = fail_encryption;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/fake_frame_encryptor.h b/third_party/libwebrtc/api/test/fake_frame_encryptor.h
new file mode 100644
index 0000000000..074981b183
--- /dev/null
+++ b/third_party/libwebrtc/api/test/fake_frame_encryptor.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_FAKE_FRAME_ENCRYPTOR_H_
+#define API_TEST_FAKE_FRAME_ENCRYPTOR_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "api/array_view.h"
+#include "api/crypto/frame_encryptor_interface.h"
+#include "api/media_types.h"
+#include "rtc_base/ref_counted_object.h"
+
+namespace webrtc {
+
+// The FakeFrameEncryptor is a TEST ONLY fake implementation of the
+// FrameEncryptorInterface. It is constructed with a simple single digit key and
+// a fixed postfix byte. This is just to validate that the core code works
+// as expected.
+class FakeFrameEncryptor
+ : public rtc::RefCountedObject<FrameEncryptorInterface> {
+ public:
+ // Provide a key (0,255) and some postfix byte (0,255).
+ explicit FakeFrameEncryptor(uint8_t fake_key = 0xAA,
+ uint8_t postfix_byte = 255);
+ // Simply xors each payload with the provided fake key and adds the postfix
+ // bit to the end. This will always fail if fail_encryption_ is set to true.
+ int Encrypt(cricket::MediaType media_type,
+ uint32_t ssrc,
+ rtc::ArrayView<const uint8_t> additional_data,
+ rtc::ArrayView<const uint8_t> frame,
+ rtc::ArrayView<uint8_t> encrypted_frame,
+ size_t* bytes_written) override;
+ // Always returns 1 more than the size of the frame.
+ size_t GetMaxCiphertextByteSize(cricket::MediaType media_type,
+ size_t frame_size) override;
+ // Sets the fake key to use during encryption.
+ void SetFakeKey(uint8_t fake_key);
+ // Returns the fake key used during encryption.
+ uint8_t GetFakeKey() const;
+ // Set the postfix byte to use.
+ void SetPostfixByte(uint8_t expected_postfix_byte);
+ // Return a postfix byte added to each outgoing payload.
+ uint8_t GetPostfixByte() const;
+ // Force all encryptions to fail.
+ void SetFailEncryption(bool fail_encryption);
+
+ enum class FakeEncryptionStatus : int {
+ OK = 0,
+ FORCED_FAILURE = 1,
+ };
+
+ private:
+ uint8_t fake_key_ = 0;
+ uint8_t postfix_byte_ = 0;
+ bool fail_encryption_ = false;
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_FAKE_FRAME_ENCRYPTOR_H_
diff --git a/third_party/libwebrtc/api/test/frame_generator_interface.cc b/third_party/libwebrtc/api/test/frame_generator_interface.cc
new file mode 100644
index 0000000000..fe7b1e883d
--- /dev/null
+++ b/third_party/libwebrtc/api/test/frame_generator_interface.cc
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/frame_generator_interface.h"
+
+namespace webrtc {
+namespace test {
+
+// static
+const char* FrameGeneratorInterface::OutputTypeToString(
+ FrameGeneratorInterface::OutputType type) {
+ switch (type) {
+ case OutputType::kI420:
+ return "I420";
+ case OutputType::kI420A:
+ return "I420A";
+ case OutputType::kI010:
+ return "I010";
+ case OutputType::kNV12:
+ return "NV12";
+ default:
+ RTC_DCHECK_NOTREACHED();
+ }
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/frame_generator_interface.h b/third_party/libwebrtc/api/test/frame_generator_interface.h
new file mode 100644
index 0000000000..90e60debac
--- /dev/null
+++ b/third_party/libwebrtc/api/test/frame_generator_interface.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_FRAME_GENERATOR_INTERFACE_H_
+#define API_TEST_FRAME_GENERATOR_INTERFACE_H_
+
+#include <utility>
+
+#include "absl/types/optional.h"
+#include "api/scoped_refptr.h"
+#include "api/video/video_frame.h"
+#include "api/video/video_frame_buffer.h"
+
+namespace webrtc {
+namespace test {
+
+class FrameGeneratorInterface {
+ public:
+ struct VideoFrameData {
+ VideoFrameData(rtc::scoped_refptr<VideoFrameBuffer> buffer,
+ absl::optional<VideoFrame::UpdateRect> update_rect)
+ : buffer(std::move(buffer)), update_rect(update_rect) {}
+
+ rtc::scoped_refptr<VideoFrameBuffer> buffer;
+ absl::optional<VideoFrame::UpdateRect> update_rect;
+ };
+
+ enum class OutputType { kI420, kI420A, kI010, kNV12 };
+ static const char* OutputTypeToString(OutputType type);
+
+ virtual ~FrameGeneratorInterface() = default;
+
+ // Returns VideoFrameBuffer and area where most of update was done to set them
+ // on the VideoFrame object.
+ virtual VideoFrameData NextFrame() = 0;
+
+ // Change the capture resolution.
+ virtual void ChangeResolution(size_t width, size_t height) = 0;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_FRAME_GENERATOR_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/test/metrics/BUILD.gn b/third_party/libwebrtc/api/test/metrics/BUILD.gn
new file mode 100644
index 0000000000..309b699329
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/BUILD.gn
@@ -0,0 +1,281 @@
+# Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+if (rtc_enable_protobuf) {
+ import("//third_party/protobuf/proto_library.gni")
+}
+
+group("metrics") {
+ deps = [
+ ":global_metrics_logger_and_exporter",
+ ":metric",
+ ":metrics_accumulator",
+ ":metrics_exporter",
+ ":metrics_logger",
+ ":stdout_metrics_exporter",
+ ]
+}
+
+if (rtc_include_tests) {
+ group("metrics_unittests") {
+ testonly = true
+
+ deps = [
+ ":global_metrics_logger_and_exporter_test",
+ ":metrics_accumulator_test",
+ ":metrics_logger_test",
+ ":print_result_proxy_metrics_exporter_test",
+ ":stdout_metrics_exporter_test",
+ ]
+
+ if (rtc_enable_protobuf) {
+ deps += [
+ ":chrome_perf_dashboard_metrics_exporter_test",
+ ":metrics_set_proto_file_exporter_test",
+ ]
+ }
+ }
+}
+
+rtc_library("metric") {
+ visibility = [ "*" ]
+ sources = [
+ "metric.cc",
+ "metric.h",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+ deps = [ "../../../api/units:timestamp" ]
+}
+
+rtc_library("metrics_logger") {
+ visibility = [ "*" ]
+ sources = [
+ "metrics_logger.cc",
+ "metrics_logger.h",
+ ]
+ deps = [
+ ":metric",
+ ":metrics_accumulator",
+ "../..:array_view",
+ "../../../rtc_base/synchronization:mutex",
+ "../../../system_wrappers",
+ "../../numerics",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
+}
+
+rtc_library("metrics_accumulator") {
+ visibility = [ "*" ]
+ sources = [
+ "metrics_accumulator.cc",
+ "metrics_accumulator.h",
+ ]
+ deps = [
+ ":metric",
+ "../../../rtc_base:macromagic",
+ "../../../rtc_base/synchronization:mutex",
+ "../../numerics",
+ "../../units:timestamp",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
+}
+
+rtc_library("metrics_exporter") {
+ visibility = [ "*" ]
+ sources = [ "metrics_exporter.h" ]
+ deps = [
+ ":metric",
+ "../..:array_view",
+ ]
+}
+
+rtc_library("stdout_metrics_exporter") {
+ visibility = [ "*" ]
+ sources = [
+ "stdout_metrics_exporter.cc",
+ "stdout_metrics_exporter.h",
+ ]
+ deps = [
+ ":metric",
+ ":metrics_exporter",
+ "../..:array_view",
+ "../../../rtc_base:stringutils",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_library("chrome_perf_dashboard_metrics_exporter") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "chrome_perf_dashboard_metrics_exporter.cc",
+ "chrome_perf_dashboard_metrics_exporter.h",
+ ]
+ deps = [
+ ":metric",
+ ":metrics_exporter",
+ "../../../api:array_view",
+ "../../../test:fileutils",
+ "../../../test:perf_test",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/memory",
+ "//third_party/abseil-cpp/absl/strings",
+ ]
+}
+
+if (rtc_enable_protobuf) {
+ proto_library("metric_proto") {
+ visibility = [ "*" ]
+ sources = [ "proto/metric.proto" ]
+ proto_out_dir = "api/test/metrics/proto"
+ cc_generator_options = "lite"
+ }
+}
+
+rtc_library("metrics_set_proto_file_exporter") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "metrics_set_proto_file_exporter.cc",
+ "metrics_set_proto_file_exporter.h",
+ ]
+ deps = [
+ ":metric",
+ ":metrics_exporter",
+ "../..:array_view",
+ "../../../rtc_base:logging",
+ "../../../test:fileutils",
+ ]
+
+ if (rtc_enable_protobuf) {
+ deps += [ ":metric_proto" ]
+ }
+}
+
+rtc_library("print_result_proxy_metrics_exporter") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "print_result_proxy_metrics_exporter.cc",
+ "print_result_proxy_metrics_exporter.h",
+ ]
+ deps = [
+ ":metric",
+ ":metrics_exporter",
+ "../..:array_view",
+ "../../../test:perf_test",
+ ]
+}
+
+rtc_library("global_metrics_logger_and_exporter") {
+ visibility = [ "*" ]
+ sources = [
+ "global_metrics_logger_and_exporter.cc",
+ "global_metrics_logger_and_exporter.h",
+ ]
+ deps = [
+ ":metrics_exporter",
+ ":metrics_logger",
+ "../../../rtc_base:checks",
+ "../../../system_wrappers",
+ ]
+}
+
+if (rtc_include_tests) {
+ rtc_library("metrics_logger_test") {
+ testonly = true
+ sources = [ "metrics_logger_test.cc" ]
+ deps = [
+ ":metric",
+ ":metrics_logger",
+ "../../../system_wrappers",
+ "../../../test:test_support",
+ "../../numerics",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+ }
+
+ rtc_library("metrics_accumulator_test") {
+ testonly = true
+ sources = [ "metrics_accumulator_test.cc" ]
+ deps = [
+ ":metric",
+ ":metrics_accumulator",
+ "../../../test:test_support",
+ "../../units:timestamp",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+ }
+
+ rtc_library("stdout_metrics_exporter_test") {
+ testonly = true
+ sources = [ "stdout_metrics_exporter_test.cc" ]
+ deps = [
+ ":metric",
+ ":stdout_metrics_exporter",
+ "../../../test:test_support",
+ "../../units:timestamp",
+ ]
+ }
+
+ rtc_library("print_result_proxy_metrics_exporter_test") {
+ testonly = true
+ sources = [ "print_result_proxy_metrics_exporter_test.cc" ]
+ deps = [
+ ":metric",
+ ":print_result_proxy_metrics_exporter",
+ "../../../test:test_support",
+ "../../units:timestamp",
+ ]
+ }
+
+ rtc_library("global_metrics_logger_and_exporter_test") {
+ testonly = true
+ sources = [ "global_metrics_logger_and_exporter_test.cc" ]
+ deps = [
+ ":global_metrics_logger_and_exporter",
+ ":metric",
+ ":metrics_exporter",
+ ":metrics_logger",
+ "../../../system_wrappers",
+ "../../../test:test_support",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+ }
+
+ if (rtc_enable_protobuf) {
+ rtc_library("metrics_set_proto_file_exporter_test") {
+ testonly = true
+ sources = [ "metrics_set_proto_file_exporter_test.cc" ]
+ deps = [
+ ":metric",
+ ":metric_proto",
+ ":metrics_set_proto_file_exporter",
+ "../../../rtc_base:protobuf_utils",
+ "../../../test:fileutils",
+ "../../../test:test_support",
+ "../../units:timestamp",
+ ]
+ }
+
+ rtc_library("chrome_perf_dashboard_metrics_exporter_test") {
+ testonly = true
+ sources = [ "chrome_perf_dashboard_metrics_exporter_test.cc" ]
+ deps = [
+ ":chrome_perf_dashboard_metrics_exporter",
+ ":metric",
+ "../../../api/units:timestamp",
+ "../../../test:fileutils",
+ "../../../test:test_support",
+ "//third_party/catapult/tracing/tracing:histogram",
+ ]
+ }
+ }
+}
diff --git a/third_party/libwebrtc/api/test/metrics/DEPS b/third_party/libwebrtc/api/test/metrics/DEPS
new file mode 100644
index 0000000000..74889c61c7
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/DEPS
@@ -0,0 +1,14 @@
+specific_include_rules = {
+ "metrics_logger_and_exporter\.h": [
+ "+rtc_base/synchronization/mutex.h",
+ "+system_wrappers/include/clock.h",
+ ],
+ "metrics_logger\.h": [
+ "+rtc_base/synchronization/mutex.h",
+ "+system_wrappers/include/clock.h",
+ ],
+ "metrics_accumulator\.h": [
+ "+rtc_base/synchronization/mutex.h",
+ "+rtc_base/thread_annotations.h",
+ ],
+}
diff --git a/third_party/libwebrtc/api/test/metrics/chrome_perf_dashboard_metrics_exporter.cc b/third_party/libwebrtc/api/test/metrics/chrome_perf_dashboard_metrics_exporter.cc
new file mode 100644
index 0000000000..018d110b12
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/chrome_perf_dashboard_metrics_exporter.cc
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/metrics/chrome_perf_dashboard_metrics_exporter.h"
+
+#include <stdio.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/string_view.h"
+#include "api/array_view.h"
+#include "api/test/metrics/metric.h"
+#include "test/testsupport/file_utils.h"
+#include "test/testsupport/perf_test_histogram_writer.h"
+#include "test/testsupport/perf_test_result_writer.h"
+
+namespace webrtc {
+namespace test {
+namespace {
+
+std::string ToChromePerfDashboardUnit(Unit unit) {
+ switch (unit) {
+ case Unit::kMilliseconds:
+ return "msBestFitFormat";
+ case Unit::kPercent:
+ return "n%";
+ case Unit::kBytes:
+ return "sizeInBytes";
+ case Unit::kKilobitsPerSecond:
+ // Chrome Perf Dashboard doesn't have kpbs units, so we change the unit
+ // and value accordingly.
+ return "bytesPerSecond";
+ case Unit::kHertz:
+ return "Hz";
+ case Unit::kUnitless:
+ return "unitless";
+ case Unit::kCount:
+ return "count";
+ }
+}
+
+double ToChromePerfDashboardValue(double value, Unit unit) {
+ switch (unit) {
+ case Unit::kKilobitsPerSecond:
+ // Chrome Perf Dashboard doesn't have kpbs units, so we change the unit
+ // and value accordingly.
+ return value * 1000 / 8;
+ default:
+ return value;
+ }
+}
+
+ImproveDirection ToChromePerfDashboardImproveDirection(
+ ImprovementDirection direction) {
+ switch (direction) {
+ case ImprovementDirection::kBiggerIsBetter:
+ return ImproveDirection::kBiggerIsBetter;
+ case ImprovementDirection::kNeitherIsBetter:
+ return ImproveDirection::kNone;
+ case ImprovementDirection::kSmallerIsBetter:
+ return ImproveDirection::kSmallerIsBetter;
+ }
+}
+
+bool WriteMetricsToFile(const std::string& path, const std::string& data) {
+ CreateDir(DirName(path));
+ FILE* output = fopen(path.c_str(), "wb");
+ if (output == NULL) {
+ printf("Failed to write to %s.\n", path.c_str());
+ return false;
+ }
+ size_t written = fwrite(data.c_str(), sizeof(char), data.size(), output);
+ fclose(output);
+
+ if (written != data.size()) {
+ size_t expected = data.size();
+ printf("Wrote %zu, tried to write %zu\n", written, expected);
+ return false;
+ }
+ return true;
+}
+
+bool IsEmpty(const Metric::Stats& stats) {
+ return !stats.mean.has_value() && !stats.stddev.has_value() &&
+ !stats.min.has_value() && !stats.max.has_value();
+}
+
+} // namespace
+
+ChromePerfDashboardMetricsExporter::ChromePerfDashboardMetricsExporter(
+ absl::string_view export_file_path)
+ : export_file_path_(export_file_path) {}
+
+bool ChromePerfDashboardMetricsExporter::Export(
+ rtc::ArrayView<const Metric> metrics) {
+ std::unique_ptr<PerfTestResultWriter> writer =
+ absl::WrapUnique<PerfTestResultWriter>(CreateHistogramWriter());
+ for (const Metric& metric : metrics) {
+ if (metric.time_series.samples.empty() && IsEmpty(metric.stats)) {
+ // If there were no data collected for the metric it is expected that 0
+ // will be exported, so add 0 to the samples.
+ writer->LogResult(
+ metric.name, metric.test_case,
+ ToChromePerfDashboardValue(0, metric.unit),
+ ToChromePerfDashboardUnit(metric.unit),
+ /*important=*/false,
+ ToChromePerfDashboardImproveDirection(metric.improvement_direction));
+ continue;
+ }
+
+ if (metric.time_series.samples.empty()) {
+ writer->LogResultMeanAndError(
+ metric.name, metric.test_case,
+ ToChromePerfDashboardValue(*metric.stats.mean, metric.unit),
+ ToChromePerfDashboardValue(*metric.stats.stddev, metric.unit),
+ ToChromePerfDashboardUnit(metric.unit),
+ /*important=*/false,
+ ToChromePerfDashboardImproveDirection(metric.improvement_direction));
+ continue;
+ }
+
+ std::vector<double> samples(metric.time_series.samples.size());
+ for (size_t i = 0; i < metric.time_series.samples.size(); ++i) {
+ samples[i] = ToChromePerfDashboardValue(
+ metric.time_series.samples[i].value, metric.unit);
+ }
+ writer->LogResultList(
+ metric.name, metric.test_case, samples,
+ ToChromePerfDashboardUnit(metric.unit),
+ /*important=*/false,
+ ToChromePerfDashboardImproveDirection(metric.improvement_direction));
+ }
+ return WriteMetricsToFile(export_file_path_, writer->Serialize());
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/metrics/chrome_perf_dashboard_metrics_exporter.h b/third_party/libwebrtc/api/test/metrics/chrome_perf_dashboard_metrics_exporter.h
new file mode 100644
index 0000000000..dda17a08c6
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/chrome_perf_dashboard_metrics_exporter.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_METRICS_CHROME_PERF_DASHBOARD_METRICS_EXPORTER_H_
+#define API_TEST_METRICS_CHROME_PERF_DASHBOARD_METRICS_EXPORTER_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "api/array_view.h"
+#include "api/test/metrics/metric.h"
+#include "api/test/metrics/metrics_exporter.h"
+
+namespace webrtc {
+namespace test {
+
+// Exports all collected metrics in the Chrome Perf Dashboard proto format.
+class ChromePerfDashboardMetricsExporter : public MetricsExporter {
+ public:
+ // `export_file_path` - path where the proto file will be written.
+ explicit ChromePerfDashboardMetricsExporter(
+ absl::string_view export_file_path);
+ ~ChromePerfDashboardMetricsExporter() override = default;
+
+ bool Export(rtc::ArrayView<const Metric> metrics) override;
+
+ private:
+ const std::string export_file_path_;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_METRICS_CHROME_PERF_DASHBOARD_METRICS_EXPORTER_H_
diff --git a/third_party/libwebrtc/api/test/metrics/chrome_perf_dashboard_metrics_exporter_test.cc b/third_party/libwebrtc/api/test/metrics/chrome_perf_dashboard_metrics_exporter_test.cc
new file mode 100644
index 0000000000..5d3136f49a
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/chrome_perf_dashboard_metrics_exporter_test.cc
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/metrics/chrome_perf_dashboard_metrics_exporter.h"
+
+#include <fstream>
+#include <map>
+#include <vector>
+
+#include "api/test/metrics/metric.h"
+#include "api/units/timestamp.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+#include "test/testsupport/file_utils.h"
+#include "third_party/catapult/tracing/tracing/value/histogram.h"
+
+namespace webrtc {
+namespace test {
+namespace {
+
+using ::testing::DoubleNear;
+using ::testing::Eq;
+using ::testing::Test;
+
+namespace proto = ::catapult::tracing::tracing::proto;
+
+std::map<std::string, std::string> DefaultMetadata() {
+ return std::map<std::string, std::string>{{"key", "value"}};
+}
+
+Metric::TimeSeries::Sample Sample(double value) {
+ return Metric::TimeSeries::Sample{.timestamp = Timestamp::Seconds(1),
+ .value = value,
+ .sample_metadata = DefaultMetadata()};
+}
+
+std::string ReadFileAsString(const std::string& filename) {
+ std::ifstream infile(filename, std::ios_base::binary);
+ auto buffer = std::vector<char>(std::istreambuf_iterator<char>(infile),
+ std::istreambuf_iterator<char>());
+ return std::string(buffer.begin(), buffer.end());
+}
+
+class ChromePerfDashboardMetricsExporterTest : public Test {
+ protected:
+ ~ChromePerfDashboardMetricsExporterTest() override = default;
+
+ void SetUp() override {
+ temp_filename_ = webrtc::test::TempFilename(
+ webrtc::test::OutputPath(),
+ "chrome_perf_dashboard_metrics_exporter_test");
+ }
+
+ void TearDown() override {
+ ASSERT_TRUE(webrtc::test::RemoveFile(temp_filename_));
+ }
+
+ std::string temp_filename_;
+};
+
+TEST_F(ChromePerfDashboardMetricsExporterTest, ExportMetricFormatCorrect) {
+ Metric metric1{
+ .name = "test_metric1",
+ .unit = Unit::kMilliseconds,
+ .improvement_direction = ImprovementDirection::kBiggerIsBetter,
+ .test_case = "test_case_name1",
+ .metric_metadata = DefaultMetadata(),
+ .time_series =
+ Metric::TimeSeries{.samples = std::vector{Sample(10), Sample(20)}},
+ .stats =
+ Metric::Stats{.mean = 15.0, .stddev = 5.0, .min = 10.0, .max = 20.0}};
+ Metric metric2{
+ .name = "test_metric2",
+ .unit = Unit::kKilobitsPerSecond,
+ .improvement_direction = ImprovementDirection::kSmallerIsBetter,
+ .test_case = "test_case_name2",
+ .metric_metadata = DefaultMetadata(),
+ .time_series =
+ Metric::TimeSeries{.samples = std::vector{Sample(20), Sample(40)}},
+ .stats = Metric::Stats{
+ .mean = 30.0, .stddev = 10.0, .min = 20.0, .max = 40.0}};
+
+ ChromePerfDashboardMetricsExporter exporter(temp_filename_);
+
+ ASSERT_TRUE(exporter.Export(std::vector<Metric>{metric1, metric2}));
+ proto::HistogramSet actual_histogram_set;
+ actual_histogram_set.ParseFromString(ReadFileAsString(temp_filename_));
+ EXPECT_THAT(actual_histogram_set.histograms().size(), Eq(2));
+
+ // Validate output for `metric1`
+ EXPECT_THAT(actual_histogram_set.histograms(0).name(), Eq("test_metric1"));
+ EXPECT_THAT(actual_histogram_set.histograms(0).unit().unit(),
+ Eq(proto::Unit::MS_BEST_FIT_FORMAT));
+ EXPECT_THAT(actual_histogram_set.histograms(0).unit().improvement_direction(),
+ Eq(proto::ImprovementDirection::BIGGER_IS_BETTER));
+ EXPECT_THAT(
+ actual_histogram_set.histograms(0).diagnostics().diagnostic_map().size(),
+ Eq(1lu));
+ EXPECT_THAT(actual_histogram_set.histograms(0)
+ .diagnostics()
+ .diagnostic_map()
+ .at("stories")
+ .generic_set()
+ .values(0),
+ Eq("\"test_case_name1\""));
+ EXPECT_THAT(actual_histogram_set.histograms(0).sample_values().size(), Eq(2));
+ EXPECT_THAT(actual_histogram_set.histograms(0).sample_values(0), Eq(10.0));
+ EXPECT_THAT(actual_histogram_set.histograms(0).sample_values(1), Eq(20.0));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().count(), Eq(2));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().max(), Eq(20));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().meanlogs(),
+ DoubleNear(2.64916, 0.1));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().mean(), Eq(15));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().min(), Eq(10));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().sum(), Eq(30));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().variance(), Eq(50));
+
+ // Validate output for `metric2`
+ EXPECT_THAT(actual_histogram_set.histograms(1).name(), Eq("test_metric2"));
+ EXPECT_THAT(actual_histogram_set.histograms(1).unit().unit(),
+ Eq(proto::Unit::BYTES_PER_SECOND));
+ EXPECT_THAT(actual_histogram_set.histograms(1).unit().improvement_direction(),
+ Eq(proto::ImprovementDirection::SMALLER_IS_BETTER));
+ EXPECT_THAT(
+ actual_histogram_set.histograms(1).diagnostics().diagnostic_map().size(),
+ Eq(1lu));
+ EXPECT_THAT(actual_histogram_set.histograms(1)
+ .diagnostics()
+ .diagnostic_map()
+ .at("stories")
+ .generic_set()
+ .values(0),
+ Eq("\"test_case_name2\""));
+ EXPECT_THAT(actual_histogram_set.histograms(1).sample_values().size(), Eq(2));
+ EXPECT_THAT(actual_histogram_set.histograms(1).sample_values(0), Eq(2500.0));
+ EXPECT_THAT(actual_histogram_set.histograms(1).sample_values(1), Eq(5000.0));
+ EXPECT_THAT(actual_histogram_set.histograms(1).running().count(), Eq(2));
+ EXPECT_THAT(actual_histogram_set.histograms(1).running().max(), Eq(5000));
+ EXPECT_THAT(actual_histogram_set.histograms(1).running().meanlogs(),
+ DoubleNear(8.17062, 0.1));
+ EXPECT_THAT(actual_histogram_set.histograms(1).running().mean(), Eq(3750));
+ EXPECT_THAT(actual_histogram_set.histograms(1).running().min(), Eq(2500));
+ EXPECT_THAT(actual_histogram_set.histograms(1).running().sum(), Eq(7500));
+ EXPECT_THAT(actual_histogram_set.histograms(1).running().variance(),
+ Eq(3125000));
+}
+
+TEST_F(ChromePerfDashboardMetricsExporterTest,
+ ExportEmptyMetricExportsZeroValue) {
+ Metric metric{.name = "test_metric",
+ .unit = Unit::kMilliseconds,
+ .improvement_direction = ImprovementDirection::kBiggerIsBetter,
+ .test_case = "test_case_name",
+ .metric_metadata = DefaultMetadata(),
+ .time_series = Metric::TimeSeries{.samples = {}},
+ .stats = Metric::Stats{}};
+
+ ChromePerfDashboardMetricsExporter exporter(temp_filename_);
+
+ ASSERT_TRUE(exporter.Export(std::vector<Metric>{metric}));
+ proto::HistogramSet actual_histogram_set;
+ actual_histogram_set.ParseFromString(ReadFileAsString(temp_filename_));
+ EXPECT_THAT(actual_histogram_set.histograms().size(), Eq(1));
+
+ // Validate values for `metric`
+ EXPECT_THAT(actual_histogram_set.histograms(0).sample_values().size(), Eq(1));
+ EXPECT_THAT(actual_histogram_set.histograms(0).sample_values(0), Eq(0.0));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().count(), Eq(1));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().max(),
+ DoubleNear(0, 1e-6));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().meanlogs(), Eq(0));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().mean(), Eq(0));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().min(), Eq(0));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().sum(), Eq(0));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().variance(), Eq(0));
+}
+
+TEST_F(ChromePerfDashboardMetricsExporterTest,
+ ExportMetricWithOnlyStatsExportsMeanValues) {
+ Metric metric{.name = "test_metric",
+ .unit = Unit::kMilliseconds,
+ .improvement_direction = ImprovementDirection::kBiggerIsBetter,
+ .test_case = "test_case_name",
+ .metric_metadata = DefaultMetadata(),
+ .time_series = Metric::TimeSeries{.samples = {}},
+ .stats = Metric::Stats{
+ .mean = 15.0, .stddev = 5.0, .min = 10.0, .max = 20.0}};
+
+ ChromePerfDashboardMetricsExporter exporter(temp_filename_);
+
+ ASSERT_TRUE(exporter.Export(std::vector<Metric>{metric}));
+ proto::HistogramSet actual_histogram_set;
+ actual_histogram_set.ParseFromString(ReadFileAsString(temp_filename_));
+ EXPECT_THAT(actual_histogram_set.histograms().size(), Eq(1));
+
+ // Validate values for `metric`
+ EXPECT_THAT(actual_histogram_set.histograms(0).sample_values().size(), Eq(1));
+ EXPECT_THAT(actual_histogram_set.histograms(0).sample_values(0), Eq(15.0));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().count(), Eq(1));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().max(), Eq(15));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().meanlogs(),
+ DoubleNear(2.70805, 0.1));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().mean(), Eq(15));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().min(), Eq(15));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().sum(), Eq(15));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().variance(), Eq(0));
+}
+
+TEST_F(ChromePerfDashboardMetricsExporterTest,
+ ExportMetricWithOnlyStatsConvertsMeanValuesWhenRequired) {
+ Metric metric{.name = "test_metric",
+ .unit = Unit::kKilobitsPerSecond,
+ .improvement_direction = ImprovementDirection::kBiggerIsBetter,
+ .test_case = "test_case_name",
+ .metric_metadata = DefaultMetadata(),
+ .time_series = Metric::TimeSeries{.samples = {}},
+ .stats = Metric::Stats{
+ .mean = 15.0, .stddev = 5.0, .min = 10.0, .max = 20.0}};
+
+ ChromePerfDashboardMetricsExporter exporter(temp_filename_);
+
+ ASSERT_TRUE(exporter.Export(std::vector<Metric>{metric}));
+ proto::HistogramSet actual_histogram_set;
+ actual_histogram_set.ParseFromString(ReadFileAsString(temp_filename_));
+ EXPECT_THAT(actual_histogram_set.histograms().size(), Eq(1));
+
+ // Validate values for `metric`
+ EXPECT_THAT(actual_histogram_set.histograms(0).sample_values().size(), Eq(1));
+ EXPECT_THAT(actual_histogram_set.histograms(0).sample_values(0), Eq(1875.0));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().count(), Eq(1));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().max(), Eq(1875));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().meanlogs(),
+ DoubleNear(7.53636, 0.1));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().mean(), Eq(1875));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().min(), Eq(1875));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().sum(), Eq(1875));
+ EXPECT_THAT(actual_histogram_set.histograms(0).running().variance(), Eq(0));
+}
+
+} // namespace
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/metrics/global_metrics_logger_and_exporter.cc b/third_party/libwebrtc/api/test/metrics/global_metrics_logger_and_exporter.cc
new file mode 100644
index 0000000000..2d42a976aa
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/global_metrics_logger_and_exporter.cc
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/metrics/global_metrics_logger_and_exporter.h"
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "api/test/metrics/metrics_exporter.h"
+#include "api/test/metrics/metrics_logger.h"
+#include "rtc_base/checks.h"
+#include "system_wrappers/include/clock.h"
+
+namespace webrtc {
+namespace test {
+
+DefaultMetricsLogger* GetGlobalMetricsLogger() {
+ static DefaultMetricsLogger* logger_ =
+ new DefaultMetricsLogger(Clock::GetRealTimeClock());
+ return logger_;
+}
+
+bool ExportPerfMetric(MetricsLogger& logger,
+ std::vector<std::unique_ptr<MetricsExporter>> exporters) {
+ std::vector<Metric> metrics = logger.GetCollectedMetrics();
+ bool success = true;
+ for (auto& exporter : exporters) {
+ bool export_result = exporter->Export(metrics);
+ success = success && export_result;
+ }
+ return success;
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/metrics/global_metrics_logger_and_exporter.h b/third_party/libwebrtc/api/test/metrics/global_metrics_logger_and_exporter.h
new file mode 100644
index 0000000000..f77ff1c737
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/global_metrics_logger_and_exporter.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_METRICS_GLOBAL_METRICS_LOGGER_AND_EXPORTER_H_
+#define API_TEST_METRICS_GLOBAL_METRICS_LOGGER_AND_EXPORTER_H_
+
+#include <memory>
+#include <vector>
+
+#include "api/test/metrics/metrics_exporter.h"
+#include "api/test/metrics/metrics_logger.h"
+
+namespace webrtc {
+namespace test {
+
+// Returns non-null global `MetricsLogger` to log metrics.
+DefaultMetricsLogger* GetGlobalMetricsLogger();
+
+bool ExportPerfMetric(MetricsLogger& logger,
+ std::vector<std::unique_ptr<MetricsExporter>> exporters);
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_METRICS_GLOBAL_METRICS_LOGGER_AND_EXPORTER_H_
diff --git a/third_party/libwebrtc/api/test/metrics/global_metrics_logger_and_exporter_test.cc b/third_party/libwebrtc/api/test/metrics/global_metrics_logger_and_exporter_test.cc
new file mode 100644
index 0000000000..567b3da9e3
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/global_metrics_logger_and_exporter_test.cc
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/metrics/global_metrics_logger_and_exporter.h"
+
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/test/metrics/metric.h"
+#include "api/test/metrics/metrics_exporter.h"
+#include "api/test/metrics/metrics_logger.h"
+#include "system_wrappers/include/clock.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace test {
+namespace {
+
+using ::testing::Eq;
+using ::testing::IsEmpty;
+
+std::map<std::string, std::string> DefaultMetadata() {
+ return std::map<std::string, std::string>{{"key", "value"}};
+}
+
+struct TestMetricsExporterFactory {
+ public:
+ std::unique_ptr<MetricsExporter> CreateExporter() {
+ return std::make_unique<TestMetricsExporter>(this, /*export_result=*/true);
+ }
+
+ std::unique_ptr<MetricsExporter> CreateFailureExporter() {
+ return std::make_unique<TestMetricsExporter>(this, /*export_result=*/false);
+ }
+
+ std::vector<Metric> exported_metrics;
+
+ private:
+ class TestMetricsExporter : public MetricsExporter {
+ public:
+ TestMetricsExporter(TestMetricsExporterFactory* factory, bool export_result)
+ : factory_(factory), export_result_(export_result) {}
+ ~TestMetricsExporter() override = default;
+
+ bool Export(rtc::ArrayView<const Metric> metrics) override {
+ factory_->exported_metrics =
+ std::vector<Metric>(metrics.begin(), metrics.end());
+ return export_result_;
+ }
+
+ TestMetricsExporterFactory* factory_;
+ bool export_result_;
+ };
+};
+
+TEST(ExportPerfMetricTest, CollectedMetricsAreExporter) {
+ TestMetricsExporterFactory exporter_factory;
+
+ DefaultMetricsLogger logger(Clock::GetRealTimeClock());
+ logger.LogSingleValueMetric(
+ "metric_name", "test_case_name",
+ /*value=*/10, Unit::kMilliseconds, ImprovementDirection::kBiggerIsBetter,
+ std::map<std::string, std::string>{{"key", "value"}});
+
+ std::vector<std::unique_ptr<MetricsExporter>> exporters;
+ exporters.push_back(exporter_factory.CreateExporter());
+ ASSERT_TRUE(ExportPerfMetric(logger, std::move(exporters)));
+
+ std::vector<Metric> metrics = exporter_factory.exported_metrics;
+ ASSERT_THAT(metrics.size(), Eq(1lu));
+ const Metric& metric = metrics[0];
+ EXPECT_THAT(metric.name, Eq("metric_name"));
+ EXPECT_THAT(metric.test_case, Eq("test_case_name"));
+ EXPECT_THAT(metric.unit, Eq(Unit::kMilliseconds));
+ EXPECT_THAT(metric.improvement_direction,
+ Eq(ImprovementDirection::kBiggerIsBetter));
+ EXPECT_THAT(metric.metric_metadata,
+ Eq(std::map<std::string, std::string>{{"key", "value"}}));
+ ASSERT_THAT(metric.time_series.samples.size(), Eq(1lu));
+ EXPECT_THAT(metric.time_series.samples[0].value, Eq(10.0));
+ EXPECT_THAT(metric.time_series.samples[0].sample_metadata,
+ Eq(std::map<std::string, std::string>{}));
+ ASSERT_THAT(metric.stats.mean, absl::optional<double>(10.0));
+ ASSERT_THAT(metric.stats.stddev, absl::nullopt);
+ ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
+ ASSERT_THAT(metric.stats.max, absl::optional<double>(10.0));
+}
+
+TEST(ExportPerfMetricTest, OneFailedExporterDoesNotPreventExportToOthers) {
+ TestMetricsExporterFactory exporter_factory1;
+ TestMetricsExporterFactory exporter_factory2;
+ TestMetricsExporterFactory exporter_factory3;
+
+ DefaultMetricsLogger logger(Clock::GetRealTimeClock());
+ logger.LogSingleValueMetric("metric_name", "test_case_name",
+ /*value=*/10, Unit::kMilliseconds,
+ ImprovementDirection::kBiggerIsBetter,
+ DefaultMetadata());
+
+ std::vector<std::unique_ptr<MetricsExporter>> exporters;
+ exporters.push_back(exporter_factory1.CreateExporter());
+ exporters.push_back(exporter_factory2.CreateFailureExporter());
+ exporters.push_back(exporter_factory3.CreateExporter());
+ ASSERT_FALSE(ExportPerfMetric(logger, std::move(exporters)));
+
+ std::vector<Metric> metrics1 = exporter_factory1.exported_metrics;
+ std::vector<Metric> metrics2 = exporter_factory2.exported_metrics;
+ std::vector<Metric> metrics3 = exporter_factory3.exported_metrics;
+ ASSERT_THAT(metrics1.size(), Eq(1lu))
+ << metrics1[0].name << "; " << metrics1[1].name;
+ EXPECT_THAT(metrics1[0].name, Eq("metric_name"));
+ ASSERT_THAT(metrics2.size(), Eq(1lu));
+ EXPECT_THAT(metrics2[0].name, Eq("metric_name"));
+ ASSERT_THAT(metrics3.size(), Eq(1lu));
+ EXPECT_THAT(metrics3[0].name, Eq("metric_name"));
+}
+
+} // namespace
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/metrics/metric.cc b/third_party/libwebrtc/api/test/metrics/metric.cc
new file mode 100644
index 0000000000..3c30f36f49
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/metric.cc
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/metrics/metric.h"
+
+#include <string>
+
+namespace webrtc {
+namespace test {
+
+absl::string_view ToString(Unit unit) {
+ switch (unit) {
+ case Unit::kMilliseconds:
+ return "Milliseconds";
+ case Unit::kPercent:
+ return "Percent";
+ case Unit::kBytes:
+ return "Bytes";
+ case Unit::kKilobitsPerSecond:
+ return "KilobitsPerSecond";
+ case Unit::kHertz:
+ return "Hertz";
+ case Unit::kUnitless:
+ return "Unitless";
+ case Unit::kCount:
+ return "Count";
+ }
+}
+
+absl::string_view ToString(ImprovementDirection direction) {
+ switch (direction) {
+ case ImprovementDirection::kBiggerIsBetter:
+ return "BiggerIsBetter";
+ case ImprovementDirection::kNeitherIsBetter:
+ return "NeitherIsBetter";
+ case ImprovementDirection::kSmallerIsBetter:
+ return "SmallerIsBetter";
+ }
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/metrics/metric.h b/third_party/libwebrtc/api/test/metrics/metric.h
new file mode 100644
index 0000000000..17c1755f95
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/metric.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_METRICS_METRIC_H_
+#define API_TEST_METRICS_METRIC_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/units/timestamp.h"
+
+namespace webrtc {
+namespace test {
+
+enum class Unit {
+ kMilliseconds,
+ kPercent,
+ kBytes,
+ kKilobitsPerSecond,
+ kHertz,
+ // General unitless value. Can be used either for dimensionless quantities
+ // (ex ratio) or for units not presented in this enum and too specific to add
+ // to this enum.
+ kUnitless,
+ kCount
+};
+
+absl::string_view ToString(Unit unit);
+
+enum class ImprovementDirection {
+ kBiggerIsBetter,
+ kNeitherIsBetter,
+ kSmallerIsBetter
+};
+
+absl::string_view ToString(ImprovementDirection direction);
+
+struct Metric {
+ struct TimeSeries {
+ struct Sample {
+ // Timestamp in microseconds associated with a sample. For example,
+ // the timestamp when the sample was collected.
+ webrtc::Timestamp timestamp;
+ double value;
+ // Metadata associated with this particular sample.
+ std::map<std::string, std::string> sample_metadata;
+ };
+
+ // All samples collected for this metric. It can be empty if the Metric
+ // object only contains `stats`.
+ std::vector<Sample> samples;
+ };
+
+ // Contains metric's precomputed statistics based on the `time_series` or if
+ // `time_series` is omitted (has 0 samples) contains precomputed statistics
+ // provided by the metric's calculator.
+ struct Stats {
+ // Sample mean of the metric
+ // (https://en.wikipedia.org/wiki/Sample_mean_and_covariance).
+ absl::optional<double> mean;
+ // Standard deviation (https://en.wikipedia.org/wiki/Standard_deviation).
+ // Is undefined if `time_series` contains only a single value.
+ absl::optional<double> stddev;
+ absl::optional<double> min;
+ absl::optional<double> max;
+ };
+
+ // Metric name, for example PSNR, SSIM, decode_time, etc.
+ std::string name;
+ Unit unit;
+ ImprovementDirection improvement_direction;
+ // If the metric is generated by a test, this field can be used to specify
+ // this information.
+ std::string test_case;
+ // Metadata associated with the whole metric.
+ std::map<std::string, std::string> metric_metadata;
+ // Contains all samples of the metric collected during test execution.
+ // It can be empty if the user only stores precomputed statistics into
+ // `stats`.
+ TimeSeries time_series;
+ Stats stats;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_METRICS_METRIC_H_
diff --git a/third_party/libwebrtc/api/test/metrics/metrics_accumulator.cc b/third_party/libwebrtc/api/test/metrics/metrics_accumulator.cc
new file mode 100644
index 0000000000..c34396be97
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/metrics_accumulator.cc
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/metrics/metrics_accumulator.h"
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/numerics/samples_stats_counter.h"
+#include "api/test/metrics/metric.h"
+#include "api/units/timestamp.h"
+#include "rtc_base/synchronization/mutex.h"
+
+namespace webrtc {
+namespace test {
+namespace {
+
+Metric::Stats ToStats(const SamplesStatsCounter& values) {
+ if (values.IsEmpty()) {
+ return Metric::Stats();
+ }
+ return Metric::Stats{.mean = values.GetAverage(),
+ .stddev = values.GetStandardDeviation(),
+ .min = values.GetMin(),
+ .max = values.GetMax()};
+}
+
+Metric SetTimeseries(const Metric& prototype,
+ const SamplesStatsCounter& counter) {
+ Metric output(prototype);
+ Metric::TimeSeries time_series;
+ for (const SamplesStatsCounter::StatsSample& sample :
+ counter.GetTimedSamples()) {
+ time_series.samples.push_back(
+ Metric::TimeSeries::Sample{.timestamp = sample.time,
+ .value = sample.value,
+ .sample_metadata = sample.metadata});
+ }
+ output.time_series = std::move(time_series);
+ output.stats = ToStats(counter);
+ return output;
+}
+
+} // namespace
+
+bool operator<(const MetricsAccumulator::MetricKey& a,
+ const MetricsAccumulator::MetricKey& b) {
+ if (a.test_case_name < b.test_case_name) {
+ return true;
+ } else if (a.test_case_name > b.test_case_name) {
+ return false;
+ } else {
+ return a.metric_name < b.metric_name;
+ }
+}
+
+bool MetricsAccumulator::AddSample(
+ absl::string_view metric_name,
+ absl::string_view test_case_name,
+ double value,
+ Timestamp timestamp,
+ std::map<std::string, std::string> point_metadata) {
+ MutexLock lock(&mutex_);
+ bool created;
+ MetricValue* metric_value =
+ GetOrCreateMetric(metric_name, test_case_name, &created);
+ metric_value->counter.AddSample(
+ SamplesStatsCounter::StatsSample{.value = value,
+ .time = timestamp,
+ .metadata = std::move(point_metadata)});
+ return created;
+}
+
+bool MetricsAccumulator::AddMetricMetadata(
+ absl::string_view metric_name,
+ absl::string_view test_case_name,
+ Unit unit,
+ ImprovementDirection improvement_direction,
+ std::map<std::string, std::string> metric_metadata) {
+ MutexLock lock(&mutex_);
+ bool created;
+ MetricValue* metric_value =
+ GetOrCreateMetric(metric_name, test_case_name, &created);
+ metric_value->metric.unit = unit;
+ metric_value->metric.improvement_direction = improvement_direction;
+ metric_value->metric.metric_metadata = std::move(metric_metadata);
+ return created;
+}
+
+std::vector<Metric> MetricsAccumulator::GetCollectedMetrics() const {
+ MutexLock lock(&mutex_);
+ std::vector<Metric> out;
+ out.reserve(metrics_.size());
+ for (const auto& [unused_key, metric_value] : metrics_) {
+ out.push_back(SetTimeseries(metric_value.metric, metric_value.counter));
+ }
+ return out;
+}
+
+MetricsAccumulator::MetricValue* MetricsAccumulator::GetOrCreateMetric(
+ absl::string_view metric_name,
+ absl::string_view test_case_name,
+ bool* created) {
+ MetricKey key(metric_name, test_case_name);
+ auto it = metrics_.find(key);
+ if (it != metrics_.end()) {
+ *created = false;
+ return &it->second;
+ }
+ *created = true;
+
+ Metric metric{
+ .name = key.metric_name,
+ .unit = Unit::kUnitless,
+ .improvement_direction = ImprovementDirection::kNeitherIsBetter,
+ .test_case = key.test_case_name,
+ };
+ return &metrics_.emplace(key, MetricValue{.metric = std::move(metric)})
+ .first->second;
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/metrics/metrics_accumulator.h b/third_party/libwebrtc/api/test/metrics/metrics_accumulator.h
new file mode 100644
index 0000000000..c75bd9429c
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/metrics_accumulator.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_METRICS_METRICS_ACCUMULATOR_H_
+#define API_TEST_METRICS_METRICS_ACCUMULATOR_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/numerics/samples_stats_counter.h"
+#include "api/test/metrics/metric.h"
+#include "api/units/timestamp.h"
+#include "rtc_base/synchronization/mutex.h"
+#include "rtc_base/thread_annotations.h"
+
+namespace webrtc {
+namespace test {
+
+// Accumulates metrics' samples internally and provides API to get collected
+// ones.
+//
+// This object is thread safe.
+class MetricsAccumulator {
+ public:
+ MetricsAccumulator() = default;
+
+ // Adds sample for the specified `metric_name` within specified
+ // `test_case_name`. If it is the first time when this combination of
+ // `metric_name` and `test_case_name` is used, creates a new Metric to collect
+ // samples, otherwise adds a sample to the previously created Metric.
+ //
+ // By default metric will use `Unit::kUnitless` and
+ // `ImprovementDirection::kNeitherIsBetter`.
+ //
+ // `point_metadata` - the metadata to be added to the single data point that
+ // this method adds to the Metric (it is not a metric global metadata).
+ //
+ // Returns true if a new metric was created and false otherwise.
+ bool AddSample(absl::string_view metric_name,
+ absl::string_view test_case_name,
+ double value,
+ Timestamp timestamp,
+ std::map<std::string, std::string> point_metadata = {});
+
+ // Adds metadata to the metric specified by `metric_name` within specified
+ // `test_case_name`. If such a metric doesn't exist, creates a new one,
+ // otherwise overrides previously recorded values.
+ //
+ // Returns true if a new metric was created and false otherwise.
+ bool AddMetricMetadata(
+ absl::string_view metric_name,
+ absl::string_view test_case_name,
+ Unit unit,
+ ImprovementDirection improvement_direction,
+ std::map<std::string, std::string> metric_metadata = {});
+
+ // Returns all metrics collected by this accumulator. No order guarantees
+ // provided.
+ std::vector<Metric> GetCollectedMetrics() const;
+
+ private:
+ struct MetricKey {
+ MetricKey(absl::string_view metric_name, absl::string_view test_case_name)
+ : metric_name(metric_name), test_case_name(test_case_name) {}
+
+ std::string metric_name;
+ std::string test_case_name;
+ };
+ friend bool operator<(const MetricKey& a, const MetricKey& b);
+
+ struct MetricValue {
+ SamplesStatsCounter counter;
+ Metric metric;
+ };
+
+ // Gets existing metrics or creates a new one. If metric was created `created`
+ // will be set to true.
+ MetricValue* GetOrCreateMetric(absl::string_view metric_name,
+ absl::string_view test_case_name,
+ bool* created)
+ RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
+
+ mutable Mutex mutex_;
+ std::map<MetricKey, MetricValue> metrics_ RTC_GUARDED_BY(mutex_);
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_METRICS_METRICS_ACCUMULATOR_H_
diff --git a/third_party/libwebrtc/api/test/metrics/metrics_accumulator_test.cc b/third_party/libwebrtc/api/test/metrics/metrics_accumulator_test.cc
new file mode 100644
index 0000000000..677f523339
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/metrics_accumulator_test.cc
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/metrics/metrics_accumulator.h"
+
+#include <map>
+#include <vector>
+
+#include "api/test/metrics/metric.h"
+#include "api/units/timestamp.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace test {
+namespace {
+
+using ::testing::Eq;
+using ::testing::IsEmpty;
+using ::testing::SizeIs;
+
+TEST(MetricsAccumulatorTest, AddSampleToTheNewMetricWillCreateOne) {
+ MetricsAccumulator accumulator;
+ ASSERT_TRUE(accumulator.AddSample(
+ "metric_name", "test_case_name",
+ /*value=*/10, Timestamp::Seconds(1),
+ /*point_metadata=*/std::map<std::string, std::string>{{"key", "value"}}));
+
+ std::vector<Metric> metrics = accumulator.GetCollectedMetrics();
+ ASSERT_THAT(metrics, SizeIs(1));
+ const Metric& metric = metrics[0];
+ EXPECT_THAT(metric.name, Eq("metric_name"));
+ EXPECT_THAT(metric.test_case, Eq("test_case_name"));
+ EXPECT_THAT(metric.unit, Eq(Unit::kUnitless));
+ EXPECT_THAT(metric.improvement_direction,
+ Eq(ImprovementDirection::kNeitherIsBetter));
+ EXPECT_THAT(metric.metric_metadata, IsEmpty());
+ ASSERT_THAT(metric.time_series.samples, SizeIs(1));
+ EXPECT_THAT(metric.time_series.samples[0].value, Eq(10.0));
+ EXPECT_THAT(metric.time_series.samples[0].timestamp,
+ Eq(Timestamp::Seconds(1)));
+ EXPECT_THAT(metric.time_series.samples[0].sample_metadata,
+ Eq(std::map<std::string, std::string>{{"key", "value"}}));
+ ASSERT_THAT(metric.stats.mean, absl::optional<double>(10.0));
+ ASSERT_THAT(metric.stats.stddev, absl::optional<double>(0.0));
+ ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
+ ASSERT_THAT(metric.stats.max, absl::optional<double>(10.0));
+}
+
+TEST(MetricsAccumulatorTest, AddSamplesToExistingMetricWontCreateNewOne) {
+ MetricsAccumulator accumulator;
+ ASSERT_TRUE(accumulator.AddSample(
+ "metric_name", "test_case_name",
+ /*value=*/10, Timestamp::Seconds(1),
+ /*point_metadata=*/
+ std::map<std::string, std::string>{{"key1", "value1"}}));
+ ASSERT_FALSE(accumulator.AddSample(
+ "metric_name", "test_case_name",
+ /*value=*/20, Timestamp::Seconds(2),
+ /*point_metadata=*/
+ std::map<std::string, std::string>{{"key2", "value2"}}));
+
+ std::vector<Metric> metrics = accumulator.GetCollectedMetrics();
+ ASSERT_THAT(metrics, SizeIs(1));
+ const Metric& metric = metrics[0];
+ EXPECT_THAT(metric.name, Eq("metric_name"));
+ EXPECT_THAT(metric.test_case, Eq("test_case_name"));
+ EXPECT_THAT(metric.unit, Eq(Unit::kUnitless));
+ EXPECT_THAT(metric.improvement_direction,
+ Eq(ImprovementDirection::kNeitherIsBetter));
+ EXPECT_THAT(metric.metric_metadata, IsEmpty());
+ ASSERT_THAT(metric.time_series.samples, SizeIs(2));
+ EXPECT_THAT(metric.time_series.samples[0].value, Eq(10.0));
+ EXPECT_THAT(metric.time_series.samples[0].timestamp,
+ Eq(Timestamp::Seconds(1)));
+ EXPECT_THAT(metric.time_series.samples[0].sample_metadata,
+ Eq(std::map<std::string, std::string>{{"key1", "value1"}}));
+ EXPECT_THAT(metric.time_series.samples[1].value, Eq(20.0));
+ EXPECT_THAT(metric.time_series.samples[1].timestamp,
+ Eq(Timestamp::Seconds(2)));
+ EXPECT_THAT(metric.time_series.samples[1].sample_metadata,
+ Eq(std::map<std::string, std::string>{{"key2", "value2"}}));
+ ASSERT_THAT(metric.stats.mean, absl::optional<double>(15.0));
+ ASSERT_THAT(metric.stats.stddev, absl::optional<double>(5.0));
+ ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
+ ASSERT_THAT(metric.stats.max, absl::optional<double>(20.0));
+}
+
+TEST(MetricsAccumulatorTest, AddSampleToDifferentMetricsWillCreateBoth) {
+ MetricsAccumulator accumulator;
+ ASSERT_TRUE(accumulator.AddSample(
+ "metric_name1", "test_case_name1",
+ /*value=*/10, Timestamp::Seconds(1),
+ /*point_metadata=*/
+ std::map<std::string, std::string>{{"key1", "value1"}}));
+ ASSERT_TRUE(accumulator.AddSample(
+ "metric_name2", "test_case_name2",
+ /*value=*/20, Timestamp::Seconds(2),
+ /*point_metadata=*/
+ std::map<std::string, std::string>{{"key2", "value2"}}));
+
+ std::vector<Metric> metrics = accumulator.GetCollectedMetrics();
+ ASSERT_THAT(metrics, SizeIs(2));
+ EXPECT_THAT(metrics[0].name, Eq("metric_name1"));
+ EXPECT_THAT(metrics[0].test_case, Eq("test_case_name1"));
+ EXPECT_THAT(metrics[0].unit, Eq(Unit::kUnitless));
+ EXPECT_THAT(metrics[0].improvement_direction,
+ Eq(ImprovementDirection::kNeitherIsBetter));
+ EXPECT_THAT(metrics[0].metric_metadata, IsEmpty());
+ ASSERT_THAT(metrics[0].time_series.samples, SizeIs(1));
+ EXPECT_THAT(metrics[0].time_series.samples[0].value, Eq(10.0));
+ EXPECT_THAT(metrics[0].time_series.samples[0].timestamp,
+ Eq(Timestamp::Seconds(1)));
+ EXPECT_THAT(metrics[0].time_series.samples[0].sample_metadata,
+ Eq(std::map<std::string, std::string>{{"key1", "value1"}}));
+ ASSERT_THAT(metrics[0].stats.mean, absl::optional<double>(10.0));
+ ASSERT_THAT(metrics[0].stats.stddev, absl::optional<double>(0.0));
+ ASSERT_THAT(metrics[0].stats.min, absl::optional<double>(10.0));
+ ASSERT_THAT(metrics[0].stats.max, absl::optional<double>(10.0));
+ EXPECT_THAT(metrics[1].name, Eq("metric_name2"));
+ EXPECT_THAT(metrics[1].test_case, Eq("test_case_name2"));
+ EXPECT_THAT(metrics[1].unit, Eq(Unit::kUnitless));
+ EXPECT_THAT(metrics[1].improvement_direction,
+ Eq(ImprovementDirection::kNeitherIsBetter));
+ EXPECT_THAT(metrics[1].metric_metadata, IsEmpty());
+ ASSERT_THAT(metrics[1].time_series.samples, SizeIs(1));
+ EXPECT_THAT(metrics[1].time_series.samples[0].value, Eq(20.0));
+ EXPECT_THAT(metrics[1].time_series.samples[0].timestamp,
+ Eq(Timestamp::Seconds(2)));
+ EXPECT_THAT(metrics[1].time_series.samples[0].sample_metadata,
+ Eq(std::map<std::string, std::string>{{"key2", "value2"}}));
+ ASSERT_THAT(metrics[1].stats.mean, absl::optional<double>(20.0));
+ ASSERT_THAT(metrics[1].stats.stddev, absl::optional<double>(0.0));
+ ASSERT_THAT(metrics[1].stats.min, absl::optional<double>(20.0));
+ ASSERT_THAT(metrics[1].stats.max, absl::optional<double>(20.0));
+}
+
+TEST(MetricsAccumulatorTest, AddMetadataToTheNewMetricWillCreateOne) {
+ MetricsAccumulator accumulator;
+ ASSERT_TRUE(accumulator.AddMetricMetadata(
+ "metric_name", "test_case_name", Unit::kMilliseconds,
+ ImprovementDirection::kBiggerIsBetter,
+ /*metric_metadata=*/
+ std::map<std::string, std::string>{{"key", "value"}}));
+
+ std::vector<Metric> metrics = accumulator.GetCollectedMetrics();
+ ASSERT_THAT(metrics, SizeIs(1));
+ const Metric& metric = metrics[0];
+ EXPECT_THAT(metric.name, Eq("metric_name"));
+ EXPECT_THAT(metric.test_case, Eq("test_case_name"));
+ EXPECT_THAT(metric.unit, Eq(Unit::kMilliseconds));
+ EXPECT_THAT(metric.improvement_direction,
+ Eq(ImprovementDirection::kBiggerIsBetter));
+ EXPECT_THAT(metric.metric_metadata,
+ Eq(std::map<std::string, std::string>{{"key", "value"}}));
+ ASSERT_THAT(metric.time_series.samples, IsEmpty());
+ ASSERT_THAT(metric.stats.mean, absl::nullopt);
+ ASSERT_THAT(metric.stats.stddev, absl::nullopt);
+ ASSERT_THAT(metric.stats.min, absl::nullopt);
+ ASSERT_THAT(metric.stats.max, absl::nullopt);
+}
+
+TEST(MetricsAccumulatorTest,
+ AddMetadataToTheExistingMetricWillOverwriteValues) {
+ MetricsAccumulator accumulator;
+ ASSERT_TRUE(accumulator.AddMetricMetadata(
+ "metric_name", "test_case_name", Unit::kMilliseconds,
+ ImprovementDirection::kBiggerIsBetter,
+ /*metric_metadata=*/
+ std::map<std::string, std::string>{{"key1", "value1"}}));
+
+ ASSERT_FALSE(accumulator.AddMetricMetadata(
+ "metric_name", "test_case_name", Unit::kBytes,
+ ImprovementDirection::kSmallerIsBetter,
+ /*metric_metadata=*/
+ std::map<std::string, std::string>{{"key2", "value2"}}));
+
+ std::vector<Metric> metrics = accumulator.GetCollectedMetrics();
+ ASSERT_THAT(metrics, SizeIs(1));
+ const Metric& metric = metrics[0];
+ EXPECT_THAT(metric.name, Eq("metric_name"));
+ EXPECT_THAT(metric.test_case, Eq("test_case_name"));
+ EXPECT_THAT(metric.unit, Eq(Unit::kBytes));
+ EXPECT_THAT(metric.improvement_direction,
+ Eq(ImprovementDirection::kSmallerIsBetter));
+ EXPECT_THAT(metric.metric_metadata,
+ Eq(std::map<std::string, std::string>{{"key2", "value2"}}));
+ ASSERT_THAT(metric.time_series.samples, IsEmpty());
+ ASSERT_THAT(metric.stats.mean, absl::nullopt);
+ ASSERT_THAT(metric.stats.stddev, absl::nullopt);
+ ASSERT_THAT(metric.stats.min, absl::nullopt);
+ ASSERT_THAT(metric.stats.max, absl::nullopt);
+}
+
+TEST(MetricsAccumulatorTest, AddMetadataToDifferentMetricsWillCreateBoth) {
+ MetricsAccumulator accumulator;
+ ASSERT_TRUE(accumulator.AddMetricMetadata(
+ "metric_name1", "test_case_name1", Unit::kMilliseconds,
+ ImprovementDirection::kBiggerIsBetter,
+ /*metric_metadata=*/
+ std::map<std::string, std::string>{{"key1", "value1"}}));
+
+ ASSERT_TRUE(accumulator.AddMetricMetadata(
+ "metric_name2", "test_case_name2", Unit::kBytes,
+ ImprovementDirection::kSmallerIsBetter,
+ /*metric_metadata=*/
+ std::map<std::string, std::string>{{"key2", "value2"}}));
+
+ std::vector<Metric> metrics = accumulator.GetCollectedMetrics();
+ ASSERT_THAT(metrics, SizeIs(2));
+ EXPECT_THAT(metrics[0].name, Eq("metric_name1"));
+ EXPECT_THAT(metrics[0].test_case, Eq("test_case_name1"));
+ EXPECT_THAT(metrics[0].unit, Eq(Unit::kMilliseconds));
+ EXPECT_THAT(metrics[0].improvement_direction,
+ Eq(ImprovementDirection::kBiggerIsBetter));
+ EXPECT_THAT(metrics[0].metric_metadata,
+ Eq(std::map<std::string, std::string>{{"key1", "value1"}}));
+ ASSERT_THAT(metrics[0].time_series.samples, IsEmpty());
+ ASSERT_THAT(metrics[0].stats.mean, absl::nullopt);
+ ASSERT_THAT(metrics[0].stats.stddev, absl::nullopt);
+ ASSERT_THAT(metrics[0].stats.min, absl::nullopt);
+ ASSERT_THAT(metrics[0].stats.max, absl::nullopt);
+ EXPECT_THAT(metrics[1].name, Eq("metric_name2"));
+ EXPECT_THAT(metrics[1].test_case, Eq("test_case_name2"));
+ EXPECT_THAT(metrics[1].unit, Eq(Unit::kBytes));
+ EXPECT_THAT(metrics[1].improvement_direction,
+ Eq(ImprovementDirection::kSmallerIsBetter));
+ EXPECT_THAT(metrics[1].metric_metadata,
+ Eq(std::map<std::string, std::string>{{"key2", "value2"}}));
+ ASSERT_THAT(metrics[1].time_series.samples, IsEmpty());
+ ASSERT_THAT(metrics[1].stats.mean, absl::nullopt);
+ ASSERT_THAT(metrics[1].stats.stddev, absl::nullopt);
+ ASSERT_THAT(metrics[1].stats.min, absl::nullopt);
+ ASSERT_THAT(metrics[1].stats.max, absl::nullopt);
+}
+
+TEST(MetricsAccumulatorTest, AddMetadataAfterAddingSampleWontCreateNewMetric) {
+ MetricsAccumulator accumulator;
+ ASSERT_TRUE(accumulator.AddSample(
+ "metric_name", "test_case_name",
+ /*value=*/10, Timestamp::Seconds(1),
+ /*point_metadata=*/
+ std::map<std::string, std::string>{{"key_s", "value_s"}}));
+ ASSERT_FALSE(accumulator.AddMetricMetadata(
+ "metric_name", "test_case_name", Unit::kMilliseconds,
+ ImprovementDirection::kBiggerIsBetter,
+ /*metric_metadata=*/
+ std::map<std::string, std::string>{{"key_m", "value_m"}}));
+
+ std::vector<Metric> metrics = accumulator.GetCollectedMetrics();
+ ASSERT_THAT(metrics, SizeIs(1));
+ const Metric& metric = metrics[0];
+ EXPECT_THAT(metric.name, Eq("metric_name"));
+ EXPECT_THAT(metric.test_case, Eq("test_case_name"));
+ EXPECT_THAT(metric.unit, Eq(Unit::kMilliseconds));
+ EXPECT_THAT(metric.improvement_direction,
+ Eq(ImprovementDirection::kBiggerIsBetter));
+ EXPECT_THAT(metric.metric_metadata,
+ Eq(std::map<std::string, std::string>{{"key_m", "value_m"}}));
+ ASSERT_THAT(metric.time_series.samples, SizeIs(1));
+ EXPECT_THAT(metric.time_series.samples[0].value, Eq(10.0));
+ EXPECT_THAT(metric.time_series.samples[0].timestamp,
+ Eq(Timestamp::Seconds(1)));
+ EXPECT_THAT(metric.time_series.samples[0].sample_metadata,
+ Eq(std::map<std::string, std::string>{{"key_s", "value_s"}}));
+ ASSERT_THAT(metric.stats.mean, absl::optional<double>(10.0));
+ ASSERT_THAT(metric.stats.stddev, absl::optional<double>(0.0));
+ ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
+ ASSERT_THAT(metric.stats.max, absl::optional<double>(10.0));
+}
+
+TEST(MetricsAccumulatorTest, AddSampleAfterAddingMetadataWontCreateNewMetric) {
+ MetricsAccumulator accumulator;
+ ASSERT_TRUE(accumulator.AddMetricMetadata(
+ "metric_name", "test_case_name", Unit::kMilliseconds,
+ ImprovementDirection::kBiggerIsBetter,
+ /*metric_metadata=*/
+ std::map<std::string, std::string>{{"key_m", "value_m"}}));
+ ASSERT_FALSE(accumulator.AddSample(
+ "metric_name", "test_case_name",
+ /*value=*/10, Timestamp::Seconds(1),
+ /*point_metadata=*/
+ std::map<std::string, std::string>{{"key_s", "value_s"}}));
+
+ std::vector<Metric> metrics = accumulator.GetCollectedMetrics();
+ ASSERT_THAT(metrics, SizeIs(1));
+ const Metric& metric = metrics[0];
+ EXPECT_THAT(metric.name, Eq("metric_name"));
+ EXPECT_THAT(metric.test_case, Eq("test_case_name"));
+ EXPECT_THAT(metric.unit, Eq(Unit::kMilliseconds));
+ EXPECT_THAT(metric.improvement_direction,
+ Eq(ImprovementDirection::kBiggerIsBetter));
+ EXPECT_THAT(metric.metric_metadata,
+ Eq(std::map<std::string, std::string>{{"key_m", "value_m"}}));
+ ASSERT_THAT(metric.time_series.samples, SizeIs(1));
+ EXPECT_THAT(metric.time_series.samples[0].value, Eq(10.0));
+ EXPECT_THAT(metric.time_series.samples[0].timestamp,
+ Eq(Timestamp::Seconds(1)));
+ EXPECT_THAT(metric.time_series.samples[0].sample_metadata,
+ Eq(std::map<std::string, std::string>{{"key_s", "value_s"}}));
+ ASSERT_THAT(metric.stats.mean, absl::optional<double>(10.0));
+ ASSERT_THAT(metric.stats.stddev, absl::optional<double>(0.0));
+ ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
+ ASSERT_THAT(metric.stats.max, absl::optional<double>(10.0));
+}
+
+} // namespace
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/metrics/metrics_exporter.h b/third_party/libwebrtc/api/test/metrics/metrics_exporter.h
new file mode 100644
index 0000000000..23954b6b1f
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/metrics_exporter.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_METRICS_METRICS_EXPORTER_H_
+#define API_TEST_METRICS_METRICS_EXPORTER_H_
+
+#include "api/array_view.h"
+#include "api/test/metrics/metric.h"
+
+namespace webrtc {
+namespace test {
+
+// Exports metrics in the requested format.
+class MetricsExporter {
+ public:
+ virtual ~MetricsExporter() = default;
+
+ // Exports specified metrics in a format that depends on the implementation.
+ // Returns true if export succeeded, false otherwise.
+ virtual bool Export(rtc::ArrayView<const Metric> metrics) = 0;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_METRICS_METRICS_EXPORTER_H_
diff --git a/third_party/libwebrtc/api/test/metrics/metrics_logger.cc b/third_party/libwebrtc/api/test/metrics/metrics_logger.cc
new file mode 100644
index 0000000000..1e24400367
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/metrics_logger.cc
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/metrics/metrics_logger.h"
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/numerics/samples_stats_counter.h"
+#include "api/test/metrics/metric.h"
+#include "rtc_base/synchronization/mutex.h"
+
+namespace webrtc {
+namespace test {
+namespace {
+
+Metric::Stats ToStats(const SamplesStatsCounter& values) {
+ if (values.IsEmpty()) {
+ return Metric::Stats();
+ }
+ return Metric::Stats{.mean = values.GetAverage(),
+ .stddev = values.GetStandardDeviation(),
+ .min = values.GetMin(),
+ .max = values.GetMax()};
+}
+
+} // namespace
+
+void DefaultMetricsLogger::LogSingleValueMetric(
+ absl::string_view name,
+ absl::string_view test_case_name,
+ double value,
+ Unit unit,
+ ImprovementDirection improvement_direction,
+ std::map<std::string, std::string> metadata) {
+ MutexLock lock(&mutex_);
+ metrics_.push_back(Metric{
+ .name = std::string(name),
+ .unit = unit,
+ .improvement_direction = improvement_direction,
+ .test_case = std::string(test_case_name),
+ .metric_metadata = std::move(metadata),
+ .time_series =
+ Metric::TimeSeries{.samples = std::vector{Metric::TimeSeries::Sample{
+ .timestamp = Now(), .value = value}}},
+ .stats = Metric::Stats{
+ .mean = value, .stddev = absl::nullopt, .min = value, .max = value}});
+}
+
+void DefaultMetricsLogger::LogMetric(
+ absl::string_view name,
+ absl::string_view test_case_name,
+ const SamplesStatsCounter& values,
+ Unit unit,
+ ImprovementDirection improvement_direction,
+ std::map<std::string, std::string> metadata) {
+ MutexLock lock(&mutex_);
+ Metric::TimeSeries time_series;
+ for (const SamplesStatsCounter::StatsSample& sample :
+ values.GetTimedSamples()) {
+ time_series.samples.push_back(
+ Metric::TimeSeries::Sample{.timestamp = sample.time,
+ .value = sample.value,
+ .sample_metadata = sample.metadata});
+ }
+
+ metrics_.push_back(Metric{.name = std::string(name),
+ .unit = unit,
+ .improvement_direction = improvement_direction,
+ .test_case = std::string(test_case_name),
+ .metric_metadata = std::move(metadata),
+ .time_series = std::move(time_series),
+ .stats = ToStats(values)});
+}
+
+void DefaultMetricsLogger::LogMetric(
+ absl::string_view name,
+ absl::string_view test_case_name,
+ const Metric::Stats& metric_stats,
+ Unit unit,
+ ImprovementDirection improvement_direction,
+ std::map<std::string, std::string> metadata) {
+ MutexLock lock(&mutex_);
+ metrics_.push_back(Metric{.name = std::string(name),
+ .unit = unit,
+ .improvement_direction = improvement_direction,
+ .test_case = std::string(test_case_name),
+ .metric_metadata = std::move(metadata),
+ .time_series = Metric::TimeSeries{.samples = {}},
+ .stats = std::move(metric_stats)});
+}
+
+std::vector<Metric> DefaultMetricsLogger::GetCollectedMetrics() const {
+ std::vector<Metric> out = metrics_accumulator_.GetCollectedMetrics();
+ MutexLock lock(&mutex_);
+ out.insert(out.end(), metrics_.begin(), metrics_.end());
+ return out;
+}
+
+Timestamp DefaultMetricsLogger::Now() {
+ return clock_->CurrentTime();
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/metrics/metrics_logger.h b/third_party/libwebrtc/api/test/metrics/metrics_logger.h
new file mode 100644
index 0000000000..66f9e55b95
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/metrics_logger.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_METRICS_METRICS_LOGGER_H_
+#define API_TEST_METRICS_METRICS_LOGGER_H_
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/numerics/samples_stats_counter.h"
+#include "api/test/metrics/metric.h"
+#include "api/test/metrics/metrics_accumulator.h"
+#include "rtc_base/synchronization/mutex.h"
+#include "system_wrappers/include/clock.h"
+
+namespace webrtc {
+namespace test {
+
+// Provides API to log and collect performance metrics.
+class MetricsLogger {
+ public:
+ virtual ~MetricsLogger() = default;
+
+ // Adds a metric with a single value.
+ // `metadata` - metric's level metadata to add.
+ virtual void LogSingleValueMetric(
+ absl::string_view name,
+ absl::string_view test_case_name,
+ double value,
+ Unit unit,
+ ImprovementDirection improvement_direction,
+ std::map<std::string, std::string> metadata = {}) = 0;
+
+ // Adds metrics with a time series created based on the provided `values`.
+ // `metadata` - metric's level metadata to add.
+ virtual void LogMetric(absl::string_view name,
+ absl::string_view test_case_name,
+ const SamplesStatsCounter& values,
+ Unit unit,
+ ImprovementDirection improvement_direction,
+ std::map<std::string, std::string> metadata = {}) = 0;
+
+ // Adds metric with a time series with only stats object and without actual
+ // collected values.
+ // `metadata` - metric's level metadata to add.
+ virtual void LogMetric(absl::string_view name,
+ absl::string_view test_case_name,
+ const Metric::Stats& metric_stats,
+ Unit unit,
+ ImprovementDirection improvement_direction,
+ std::map<std::string, std::string> metadata = {}) = 0;
+
+ // Returns all metrics collected by this logger.
+ virtual std::vector<Metric> GetCollectedMetrics() const = 0;
+};
+
+class DefaultMetricsLogger : public MetricsLogger {
+ public:
+ explicit DefaultMetricsLogger(webrtc::Clock* clock) : clock_(clock) {}
+ ~DefaultMetricsLogger() override = default;
+
+ void LogSingleValueMetric(
+ absl::string_view name,
+ absl::string_view test_case_name,
+ double value,
+ Unit unit,
+ ImprovementDirection improvement_direction,
+ std::map<std::string, std::string> metadata = {}) override;
+
+ void LogMetric(absl::string_view name,
+ absl::string_view test_case_name,
+ const SamplesStatsCounter& values,
+ Unit unit,
+ ImprovementDirection improvement_direction,
+ std::map<std::string, std::string> metadata = {}) override;
+
+ void LogMetric(absl::string_view name,
+ absl::string_view test_case_name,
+ const Metric::Stats& metric_stats,
+ Unit unit,
+ ImprovementDirection improvement_direction,
+ std::map<std::string, std::string> metadata = {}) override;
+
+ // Returns all metrics collected by this logger and its `MetricsAccumulator`.
+ std::vector<Metric> GetCollectedMetrics() const override;
+
+ MetricsAccumulator* GetMetricsAccumulator() { return &metrics_accumulator_; }
+
+ private:
+ webrtc::Timestamp Now();
+
+ webrtc::Clock* const clock_;
+ MetricsAccumulator metrics_accumulator_;
+
+ mutable Mutex mutex_;
+ std::vector<Metric> metrics_ RTC_GUARDED_BY(mutex_);
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_METRICS_METRICS_LOGGER_H_
diff --git a/third_party/libwebrtc/api/test/metrics/metrics_logger_test.cc b/third_party/libwebrtc/api/test/metrics/metrics_logger_test.cc
new file mode 100644
index 0000000000..de4501ca36
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/metrics_logger_test.cc
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/metrics/metrics_logger.h"
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/numerics/samples_stats_counter.h"
+#include "api/test/metrics/metric.h"
+#include "system_wrappers/include/clock.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace test {
+namespace {
+
+using ::testing::Eq;
+using ::testing::IsEmpty;
+using ::testing::SizeIs;
+
+std::map<std::string, std::string> DefaultMetadata() {
+ return std::map<std::string, std::string>{{"key", "value"}};
+}
+
+TEST(DefaultMetricsLoggerTest, LogSingleValueMetricRecordsMetric) {
+ DefaultMetricsLogger logger(Clock::GetRealTimeClock());
+ logger.LogSingleValueMetric(
+ "metric_name", "test_case_name",
+ /*value=*/10, Unit::kMilliseconds, ImprovementDirection::kBiggerIsBetter,
+ std::map<std::string, std::string>{{"key", "value"}});
+
+ std::vector<Metric> metrics = logger.GetCollectedMetrics();
+ ASSERT_THAT(metrics, SizeIs(1));
+ const Metric& metric = metrics[0];
+ EXPECT_THAT(metric.name, Eq("metric_name"));
+ EXPECT_THAT(metric.test_case, Eq("test_case_name"));
+ EXPECT_THAT(metric.unit, Eq(Unit::kMilliseconds));
+ EXPECT_THAT(metric.improvement_direction,
+ Eq(ImprovementDirection::kBiggerIsBetter));
+ EXPECT_THAT(metric.metric_metadata,
+ Eq(std::map<std::string, std::string>{{"key", "value"}}));
+ ASSERT_THAT(metric.time_series.samples, SizeIs(1));
+ EXPECT_THAT(metric.time_series.samples[0].value, Eq(10.0));
+ EXPECT_THAT(metric.time_series.samples[0].sample_metadata,
+ Eq(std::map<std::string, std::string>{}));
+ ASSERT_THAT(metric.stats.mean, absl::optional<double>(10.0));
+ ASSERT_THAT(metric.stats.stddev, absl::nullopt);
+ ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
+ ASSERT_THAT(metric.stats.max, absl::optional<double>(10.0));
+}
+
+TEST(DefaultMetricsLoggerTest, LogMetricWithSamplesStatsCounterRecordsMetric) {
+ DefaultMetricsLogger logger(Clock::GetRealTimeClock());
+
+ SamplesStatsCounter values;
+ values.AddSample(SamplesStatsCounter::StatsSample{
+ .value = 10,
+ .time = Clock::GetRealTimeClock()->CurrentTime(),
+ .metadata =
+ std::map<std::string, std::string>{{"point_key1", "value1"}}});
+ values.AddSample(SamplesStatsCounter::StatsSample{
+ .value = 20,
+ .time = Clock::GetRealTimeClock()->CurrentTime(),
+ .metadata =
+ std::map<std::string, std::string>{{"point_key2", "value2"}}});
+ logger.LogMetric("metric_name", "test_case_name", values, Unit::kMilliseconds,
+ ImprovementDirection::kBiggerIsBetter,
+ std::map<std::string, std::string>{{"key", "value"}});
+
+ std::vector<Metric> metrics = logger.GetCollectedMetrics();
+ ASSERT_THAT(metrics, SizeIs(1));
+ const Metric& metric = metrics[0];
+ EXPECT_THAT(metric.name, Eq("metric_name"));
+ EXPECT_THAT(metric.test_case, Eq("test_case_name"));
+ EXPECT_THAT(metric.unit, Eq(Unit::kMilliseconds));
+ EXPECT_THAT(metric.improvement_direction,
+ Eq(ImprovementDirection::kBiggerIsBetter));
+ EXPECT_THAT(metric.metric_metadata,
+ Eq(std::map<std::string, std::string>{{"key", "value"}}));
+ ASSERT_THAT(metric.time_series.samples, SizeIs(2));
+ EXPECT_THAT(metric.time_series.samples[0].value, Eq(10.0));
+ EXPECT_THAT(metric.time_series.samples[0].sample_metadata,
+ Eq(std::map<std::string, std::string>{{"point_key1", "value1"}}));
+ EXPECT_THAT(metric.time_series.samples[1].value, Eq(20.0));
+ EXPECT_THAT(metric.time_series.samples[1].sample_metadata,
+ Eq(std::map<std::string, std::string>{{"point_key2", "value2"}}));
+ ASSERT_THAT(metric.stats.mean, absl::optional<double>(15.0));
+ ASSERT_THAT(metric.stats.stddev, absl::optional<double>(5.0));
+ ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
+ ASSERT_THAT(metric.stats.max, absl::optional<double>(20.0));
+}
+
+TEST(DefaultMetricsLoggerTest,
+ LogMetricWithEmptySamplesStatsCounterRecordsEmptyMetric) {
+ DefaultMetricsLogger logger(Clock::GetRealTimeClock());
+ SamplesStatsCounter values;
+ logger.LogMetric("metric_name", "test_case_name", values, Unit::kUnitless,
+ ImprovementDirection::kBiggerIsBetter, DefaultMetadata());
+
+ std::vector<Metric> metrics = logger.GetCollectedMetrics();
+ ASSERT_THAT(metrics, SizeIs(1));
+ EXPECT_THAT(metrics[0].name, Eq("metric_name"));
+ EXPECT_THAT(metrics[0].test_case, Eq("test_case_name"));
+ EXPECT_THAT(metrics[0].time_series.samples, IsEmpty());
+ ASSERT_THAT(metrics[0].stats.mean, Eq(absl::nullopt));
+ ASSERT_THAT(metrics[0].stats.stddev, Eq(absl::nullopt));
+ ASSERT_THAT(metrics[0].stats.min, Eq(absl::nullopt));
+ ASSERT_THAT(metrics[0].stats.max, Eq(absl::nullopt));
+}
+
+TEST(DefaultMetricsLoggerTest, LogMetricWithStatsRecordsMetric) {
+ DefaultMetricsLogger logger(Clock::GetRealTimeClock());
+ Metric::Stats metric_stats{.mean = 15, .stddev = 5, .min = 10, .max = 20};
+ logger.LogMetric("metric_name", "test_case_name", metric_stats,
+ Unit::kMilliseconds, ImprovementDirection::kBiggerIsBetter,
+ std::map<std::string, std::string>{{"key", "value"}});
+
+ std::vector<Metric> metrics = logger.GetCollectedMetrics();
+ ASSERT_THAT(metrics, SizeIs(1));
+ const Metric& metric = metrics[0];
+ EXPECT_THAT(metric.name, Eq("metric_name"));
+ EXPECT_THAT(metric.test_case, Eq("test_case_name"));
+ EXPECT_THAT(metric.unit, Eq(Unit::kMilliseconds));
+ EXPECT_THAT(metric.improvement_direction,
+ Eq(ImprovementDirection::kBiggerIsBetter));
+ EXPECT_THAT(metric.metric_metadata,
+ Eq(std::map<std::string, std::string>{{"key", "value"}}));
+ ASSERT_THAT(metric.time_series.samples, IsEmpty());
+ ASSERT_THAT(metric.stats.mean, absl::optional<double>(15.0));
+ ASSERT_THAT(metric.stats.stddev, absl::optional<double>(5.0));
+ ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
+ ASSERT_THAT(metric.stats.max, absl::optional<double>(20.0));
+}
+
+TEST(DefaultMetricsLoggerTest, LogSingleValueMetricRecordsMultipleMetrics) {
+ DefaultMetricsLogger logger(Clock::GetRealTimeClock());
+
+ logger.LogSingleValueMetric("metric_name1", "test_case_name1",
+ /*value=*/10, Unit::kMilliseconds,
+ ImprovementDirection::kBiggerIsBetter,
+ DefaultMetadata());
+ logger.LogSingleValueMetric("metric_name2", "test_case_name2",
+ /*value=*/10, Unit::kMilliseconds,
+ ImprovementDirection::kBiggerIsBetter,
+ DefaultMetadata());
+
+ std::vector<Metric> metrics = logger.GetCollectedMetrics();
+ ASSERT_THAT(metrics, SizeIs(2));
+ EXPECT_THAT(metrics[0].name, Eq("metric_name1"));
+ EXPECT_THAT(metrics[0].test_case, Eq("test_case_name1"));
+ EXPECT_THAT(metrics[1].name, Eq("metric_name2"));
+ EXPECT_THAT(metrics[1].test_case, Eq("test_case_name2"));
+}
+
+TEST(DefaultMetricsLoggerTest,
+ LogMetricWithSamplesStatsCounterRecordsMultipleMetrics) {
+ DefaultMetricsLogger logger(Clock::GetRealTimeClock());
+ SamplesStatsCounter values;
+ values.AddSample(SamplesStatsCounter::StatsSample{
+ .value = 10,
+ .time = Clock::GetRealTimeClock()->CurrentTime(),
+ .metadata = DefaultMetadata()});
+ values.AddSample(SamplesStatsCounter::StatsSample{
+ .value = 20,
+ .time = Clock::GetRealTimeClock()->CurrentTime(),
+ .metadata = DefaultMetadata()});
+
+ logger.LogMetric("metric_name1", "test_case_name1", values,
+ Unit::kMilliseconds, ImprovementDirection::kBiggerIsBetter,
+ DefaultMetadata());
+ logger.LogMetric("metric_name2", "test_case_name2", values,
+ Unit::kMilliseconds, ImprovementDirection::kBiggerIsBetter,
+ DefaultMetadata());
+
+ std::vector<Metric> metrics = logger.GetCollectedMetrics();
+ ASSERT_THAT(metrics, SizeIs(2));
+ EXPECT_THAT(metrics[0].name, Eq("metric_name1"));
+ EXPECT_THAT(metrics[0].test_case, Eq("test_case_name1"));
+ EXPECT_THAT(metrics[1].name, Eq("metric_name2"));
+ EXPECT_THAT(metrics[1].test_case, Eq("test_case_name2"));
+}
+
+TEST(DefaultMetricsLoggerTest, LogMetricWithStatsRecordsMultipleMetrics) {
+ DefaultMetricsLogger logger(Clock::GetRealTimeClock());
+ Metric::Stats metric_stats{.mean = 15, .stddev = 5, .min = 10, .max = 20};
+
+ logger.LogMetric("metric_name1", "test_case_name1", metric_stats,
+ Unit::kMilliseconds, ImprovementDirection::kBiggerIsBetter,
+ DefaultMetadata());
+ logger.LogMetric("metric_name2", "test_case_name2", metric_stats,
+ Unit::kMilliseconds, ImprovementDirection::kBiggerIsBetter,
+ DefaultMetadata());
+
+ std::vector<Metric> metrics = logger.GetCollectedMetrics();
+ ASSERT_THAT(metrics, SizeIs(2));
+ EXPECT_THAT(metrics[0].name, Eq("metric_name1"));
+ EXPECT_THAT(metrics[0].test_case, Eq("test_case_name1"));
+ EXPECT_THAT(metrics[1].name, Eq("metric_name2"));
+ EXPECT_THAT(metrics[1].test_case, Eq("test_case_name2"));
+}
+
+TEST(DefaultMetricsLoggerTest,
+ LogMetricThroughtAllMethodsAccumulateAllMetrics) {
+ DefaultMetricsLogger logger(Clock::GetRealTimeClock());
+ SamplesStatsCounter values;
+ values.AddSample(SamplesStatsCounter::StatsSample{
+ .value = 10,
+ .time = Clock::GetRealTimeClock()->CurrentTime(),
+ .metadata = DefaultMetadata()});
+ values.AddSample(SamplesStatsCounter::StatsSample{
+ .value = 20,
+ .time = Clock::GetRealTimeClock()->CurrentTime(),
+ .metadata = DefaultMetadata()});
+ Metric::Stats metric_stats{.mean = 15, .stddev = 5, .min = 10, .max = 20};
+
+ logger.LogSingleValueMetric("metric_name1", "test_case_name1",
+ /*value=*/10, Unit::kMilliseconds,
+ ImprovementDirection::kBiggerIsBetter,
+ DefaultMetadata());
+ logger.LogMetric("metric_name2", "test_case_name2", values,
+ Unit::kMilliseconds, ImprovementDirection::kBiggerIsBetter,
+ DefaultMetadata());
+ logger.LogMetric("metric_name3", "test_case_name3", metric_stats,
+ Unit::kMilliseconds, ImprovementDirection::kBiggerIsBetter,
+ DefaultMetadata());
+
+ std::vector<Metric> metrics = logger.GetCollectedMetrics();
+ ASSERT_THAT(metrics.size(), Eq(3lu));
+ EXPECT_THAT(metrics[0].name, Eq("metric_name1"));
+ EXPECT_THAT(metrics[0].test_case, Eq("test_case_name1"));
+ EXPECT_THAT(metrics[1].name, Eq("metric_name2"));
+ EXPECT_THAT(metrics[1].test_case, Eq("test_case_name2"));
+ EXPECT_THAT(metrics[2].name, Eq("metric_name3"));
+ EXPECT_THAT(metrics[2].test_case, Eq("test_case_name3"));
+}
+
+TEST(DefaultMetricsLoggerTest, AccumulatedMetricsReturnedInCollectedMetrics) {
+ DefaultMetricsLogger logger(Clock::GetRealTimeClock());
+ logger.GetMetricsAccumulator()->AddSample(
+ "metric_name", "test_case_name",
+ /*value=*/10, Timestamp::Seconds(1),
+ /*point_metadata=*/std::map<std::string, std::string>{{"key", "value"}});
+
+ std::vector<Metric> metrics = logger.GetCollectedMetrics();
+ ASSERT_THAT(metrics, SizeIs(1));
+ const Metric& metric = metrics[0];
+ EXPECT_THAT(metric.name, Eq("metric_name"));
+ EXPECT_THAT(metric.test_case, Eq("test_case_name"));
+ EXPECT_THAT(metric.unit, Eq(Unit::kUnitless));
+ EXPECT_THAT(metric.improvement_direction,
+ Eq(ImprovementDirection::kNeitherIsBetter));
+ EXPECT_THAT(metric.metric_metadata, IsEmpty());
+ ASSERT_THAT(metric.time_series.samples, SizeIs(1));
+ EXPECT_THAT(metric.time_series.samples[0].value, Eq(10.0));
+ EXPECT_THAT(metric.time_series.samples[0].timestamp,
+ Eq(Timestamp::Seconds(1)));
+ EXPECT_THAT(metric.time_series.samples[0].sample_metadata,
+ Eq(std::map<std::string, std::string>{{"key", "value"}}));
+ ASSERT_THAT(metric.stats.mean, absl::optional<double>(10.0));
+ ASSERT_THAT(metric.stats.stddev, absl::optional<double>(0.0));
+ ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
+ ASSERT_THAT(metric.stats.max, absl::optional<double>(10.0));
+}
+
+TEST(DefaultMetricsLoggerTest,
+ AccumulatedMetricsReturnedTogetherWithLoggedMetrics) {
+ DefaultMetricsLogger logger(Clock::GetRealTimeClock());
+ logger.LogSingleValueMetric(
+ "metric_name1", "test_case_name1",
+ /*value=*/10, Unit::kMilliseconds, ImprovementDirection::kBiggerIsBetter,
+ std::map<std::string, std::string>{{"key_m", "value_m"}});
+ logger.GetMetricsAccumulator()->AddSample(
+ "metric_name2", "test_case_name2",
+ /*value=*/10, Timestamp::Seconds(1),
+ /*point_metadata=*/
+ std::map<std::string, std::string>{{"key_s", "value_s"}});
+
+ std::vector<Metric> metrics = logger.GetCollectedMetrics();
+ ASSERT_THAT(metrics, SizeIs(2));
+ EXPECT_THAT(metrics[0].name, Eq("metric_name2"));
+ EXPECT_THAT(metrics[0].test_case, Eq("test_case_name2"));
+ EXPECT_THAT(metrics[0].unit, Eq(Unit::kUnitless));
+ EXPECT_THAT(metrics[0].improvement_direction,
+ Eq(ImprovementDirection::kNeitherIsBetter));
+ EXPECT_THAT(metrics[0].metric_metadata, IsEmpty());
+ ASSERT_THAT(metrics[0].time_series.samples, SizeIs(1));
+ EXPECT_THAT(metrics[0].time_series.samples[0].value, Eq(10.0));
+ EXPECT_THAT(metrics[0].time_series.samples[0].timestamp,
+ Eq(Timestamp::Seconds(1)));
+ EXPECT_THAT(metrics[0].time_series.samples[0].sample_metadata,
+ Eq(std::map<std::string, std::string>{{"key_s", "value_s"}}));
+ ASSERT_THAT(metrics[0].stats.mean, absl::optional<double>(10.0));
+ ASSERT_THAT(metrics[0].stats.stddev, absl::optional<double>(0.0));
+ ASSERT_THAT(metrics[0].stats.min, absl::optional<double>(10.0));
+ ASSERT_THAT(metrics[0].stats.max, absl::optional<double>(10.0));
+ EXPECT_THAT(metrics[1].name, Eq("metric_name1"));
+ EXPECT_THAT(metrics[1].test_case, Eq("test_case_name1"));
+ EXPECT_THAT(metrics[1].unit, Eq(Unit::kMilliseconds));
+ EXPECT_THAT(metrics[1].improvement_direction,
+ Eq(ImprovementDirection::kBiggerIsBetter));
+ EXPECT_THAT(metrics[1].metric_metadata,
+ Eq(std::map<std::string, std::string>{{"key_m", "value_m"}}));
+ ASSERT_THAT(metrics[1].time_series.samples, SizeIs(1));
+ EXPECT_THAT(metrics[1].time_series.samples[0].value, Eq(10.0));
+ EXPECT_THAT(metrics[1].time_series.samples[0].sample_metadata,
+ Eq(std::map<std::string, std::string>{}));
+ ASSERT_THAT(metrics[1].stats.mean, absl::optional<double>(10.0));
+ ASSERT_THAT(metrics[1].stats.stddev, absl::nullopt);
+ ASSERT_THAT(metrics[1].stats.min, absl::optional<double>(10.0));
+ ASSERT_THAT(metrics[1].stats.max, absl::optional<double>(10.0));
+}
+
+} // namespace
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/metrics/metrics_set_proto_file_exporter.cc b/third_party/libwebrtc/api/test/metrics/metrics_set_proto_file_exporter.cc
new file mode 100644
index 0000000000..86e6f2e136
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/metrics_set_proto_file_exporter.cc
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/metrics/metrics_set_proto_file_exporter.h"
+
+#include <stdio.h>
+
+#include <string>
+
+#include "api/test/metrics/metric.h"
+#include "rtc_base/logging.h"
+#include "test/testsupport/file_utils.h"
+
+#if WEBRTC_ENABLE_PROTOBUF
+#include "api/test/metrics/proto/metric.pb.h"
+#endif
+
+namespace webrtc {
+namespace test {
+namespace {
+
+#if WEBRTC_ENABLE_PROTOBUF
+webrtc::test_metrics::Unit ToProtoUnit(Unit unit) {
+ switch (unit) {
+ case Unit::kMilliseconds:
+ return webrtc::test_metrics::Unit::MILLISECONDS;
+ case Unit::kPercent:
+ return webrtc::test_metrics::Unit::PERCENT;
+ case Unit::kBytes:
+ return webrtc::test_metrics::Unit::BYTES;
+ case Unit::kKilobitsPerSecond:
+ return webrtc::test_metrics::Unit::KILOBITS_PER_SECOND;
+ case Unit::kHertz:
+ return webrtc::test_metrics::Unit::HERTZ;
+ case Unit::kUnitless:
+ return webrtc::test_metrics::Unit::UNITLESS;
+ case Unit::kCount:
+ return webrtc::test_metrics::Unit::COUNT;
+ }
+}
+
+webrtc::test_metrics::ImprovementDirection ToProtoImprovementDirection(
+ ImprovementDirection direction) {
+ switch (direction) {
+ case ImprovementDirection::kBiggerIsBetter:
+ return webrtc::test_metrics::ImprovementDirection::BIGGER_IS_BETTER;
+ case ImprovementDirection::kNeitherIsBetter:
+ return webrtc::test_metrics::ImprovementDirection::NEITHER_IS_BETTER;
+ case ImprovementDirection::kSmallerIsBetter:
+ return webrtc::test_metrics::ImprovementDirection::SMALLER_IS_BETTER;
+ }
+}
+
+void SetTimeSeries(
+ const Metric::TimeSeries& time_series,
+ webrtc::test_metrics::Metric::TimeSeries* proto_time_series) {
+ for (const Metric::TimeSeries::Sample& sample : time_series.samples) {
+ webrtc::test_metrics::Metric::TimeSeries::Sample* proto_sample =
+ proto_time_series->add_samples();
+ proto_sample->set_value(sample.value);
+ proto_sample->set_timestamp_us(sample.timestamp.us());
+ for (const auto& [key, value] : sample.sample_metadata) {
+ proto_sample->mutable_sample_metadata()->insert({key, value});
+ }
+ }
+}
+
+void SetStats(const Metric::Stats& stats,
+ webrtc::test_metrics::Metric::Stats* proto_stats) {
+ if (stats.mean.has_value()) {
+ proto_stats->set_mean(*stats.mean);
+ }
+ if (stats.stddev.has_value()) {
+ proto_stats->set_stddev(*stats.stddev);
+ }
+ if (stats.min.has_value()) {
+ proto_stats->set_min(*stats.min);
+ }
+ if (stats.max.has_value()) {
+ proto_stats->set_max(*stats.max);
+ }
+}
+
+bool WriteMetricsToFile(const std::string& path,
+ const webrtc::test_metrics::MetricsSet& metrics_set) {
+ std::string data;
+ bool ok = metrics_set.SerializeToString(&data);
+ if (!ok) {
+ RTC_LOG(LS_ERROR) << "Failed to serialize histogram set to string";
+ return false;
+ }
+
+ CreateDir(DirName(path));
+ FILE* output = fopen(path.c_str(), "wb");
+ if (output == NULL) {
+ RTC_LOG(LS_ERROR) << "Failed to write to " << path;
+ return false;
+ }
+ size_t written = fwrite(data.c_str(), sizeof(char), data.size(), output);
+ fclose(output);
+
+ if (written != data.size()) {
+ size_t expected = data.size();
+ RTC_LOG(LS_ERROR) << "Wrote " << written << ", tried to write " << expected;
+ return false;
+ }
+ return true;
+}
+#endif // WEBRTC_ENABLE_PROTOBUF
+
+} // namespace
+
+MetricsSetProtoFileExporter::Options::Options(
+ absl::string_view export_file_path)
+ : export_file_path(export_file_path) {}
+MetricsSetProtoFileExporter::Options::Options(
+ absl::string_view export_file_path,
+ bool export_whole_time_series)
+ : export_file_path(export_file_path),
+ export_whole_time_series(export_whole_time_series) {}
+
+bool MetricsSetProtoFileExporter::Export(rtc::ArrayView<const Metric> metrics) {
+#if WEBRTC_ENABLE_PROTOBUF
+ webrtc::test_metrics::MetricsSet metrics_set;
+ for (const Metric& metric : metrics) {
+ webrtc::test_metrics::Metric* metric_proto = metrics_set.add_metrics();
+ metric_proto->set_name(metric.name);
+ metric_proto->set_unit(ToProtoUnit(metric.unit));
+ metric_proto->set_improvement_direction(
+ ToProtoImprovementDirection(metric.improvement_direction));
+ metric_proto->set_test_case(metric.test_case);
+ for (const auto& [key, value] : metric.metric_metadata) {
+ metric_proto->mutable_metric_metadata()->insert({key, value});
+ }
+
+ if (options_.export_whole_time_series) {
+ SetTimeSeries(metric.time_series, metric_proto->mutable_time_series());
+ }
+ SetStats(metric.stats, metric_proto->mutable_stats());
+ }
+
+ return WriteMetricsToFile(options_.export_file_path, metrics_set);
+#else
+ RTC_LOG(LS_ERROR)
+ << "Compile with protobuf support to properly use this class";
+ return false;
+#endif
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/metrics/metrics_set_proto_file_exporter.h b/third_party/libwebrtc/api/test/metrics/metrics_set_proto_file_exporter.h
new file mode 100644
index 0000000000..f996e9e7b0
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/metrics_set_proto_file_exporter.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_METRICS_METRICS_SET_PROTO_FILE_EXPORTER_H_
+#define API_TEST_METRICS_METRICS_SET_PROTO_FILE_EXPORTER_H_
+
+#include <string>
+
+#include "api/array_view.h"
+#include "api/test/metrics/metric.h"
+#include "api/test/metrics/metrics_exporter.h"
+
+namespace webrtc {
+namespace test {
+
+// Exports all collected metrics to the proto file using
+// `webrtc::test_metrics::MetricsSet` format.
+class MetricsSetProtoFileExporter : public MetricsExporter {
+ public:
+ struct Options {
+ explicit Options(absl::string_view export_file_path);
+ Options(absl::string_view export_file_path, bool export_whole_time_series);
+
+ // File to export proto.
+ std::string export_file_path;
+ // If true will write all time series values to the output proto file,
+ // otherwise will write stats only.
+ bool export_whole_time_series = true;
+ };
+
+ explicit MetricsSetProtoFileExporter(const Options& options)
+ : options_(options) {}
+
+ MetricsSetProtoFileExporter(const MetricsSetProtoFileExporter&) = delete;
+ MetricsSetProtoFileExporter& operator=(const MetricsSetProtoFileExporter&) =
+ delete;
+
+ bool Export(rtc::ArrayView<const Metric> metrics) override;
+
+ private:
+ const Options options_;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_METRICS_METRICS_SET_PROTO_FILE_EXPORTER_H_
diff --git a/third_party/libwebrtc/api/test/metrics/metrics_set_proto_file_exporter_test.cc b/third_party/libwebrtc/api/test/metrics/metrics_set_proto_file_exporter_test.cc
new file mode 100644
index 0000000000..eb4d483068
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/metrics_set_proto_file_exporter_test.cc
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/metrics/metrics_set_proto_file_exporter.h"
+
+#include <fstream>
+#include <map>
+#include <string>
+#include <vector>
+
+#include "api/test/metrics/metric.h"
+#include "api/test/metrics/proto/metric.pb.h"
+#include "api/units/timestamp.h"
+#include "rtc_base/protobuf_utils.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+#include "test/testsupport/file_utils.h"
+
+namespace webrtc {
+namespace test {
+namespace {
+
+using ::testing::Eq;
+using ::testing::Test;
+
+namespace proto = ::webrtc::test_metrics;
+
+std::string ReadFileAsString(const std::string& filename) {
+ std::ifstream infile(filename, std::ios_base::binary);
+ auto buffer = std::vector<char>(std::istreambuf_iterator<char>(infile),
+ std::istreambuf_iterator<char>());
+ return std::string(buffer.begin(), buffer.end());
+}
+
+std::map<std::string, std::string> DefaultMetadata() {
+ return std::map<std::string, std::string>{{"key", "value"}};
+}
+
+Metric::TimeSeries::Sample Sample(double value) {
+ return Metric::TimeSeries::Sample{.timestamp = Timestamp::Seconds(1),
+ .value = value,
+ .sample_metadata = DefaultMetadata()};
+}
+
+void AssertSamplesEqual(const proto::Metric::TimeSeries::Sample& actual_sample,
+ const Metric::TimeSeries::Sample& expected_sample) {
+ EXPECT_THAT(actual_sample.value(), Eq(expected_sample.value));
+ EXPECT_THAT(actual_sample.timestamp_us(), Eq(expected_sample.timestamp.us()));
+ EXPECT_THAT(actual_sample.sample_metadata().size(),
+ Eq(expected_sample.sample_metadata.size()));
+ for (const auto& [key, value] : expected_sample.sample_metadata) {
+ EXPECT_THAT(actual_sample.sample_metadata().at(key), Eq(value));
+ }
+}
+
+class MetricsSetProtoFileExporterTest : public Test {
+ protected:
+ ~MetricsSetProtoFileExporterTest() override = default;
+
+ void SetUp() override {
+ temp_filename_ = webrtc::test::TempFilename(
+ webrtc::test::OutputPath(), "metrics_set_proto_file_exporter_test");
+ }
+
+ void TearDown() override {
+ ASSERT_TRUE(webrtc::test::RemoveFile(temp_filename_));
+ }
+
+ std::string temp_filename_;
+};
+
+TEST_F(MetricsSetProtoFileExporterTest, MetricsAreExportedCorrectly) {
+ MetricsSetProtoFileExporter::Options options(temp_filename_);
+ MetricsSetProtoFileExporter exporter(options);
+
+ Metric metric1{
+ .name = "test_metric1",
+ .unit = Unit::kMilliseconds,
+ .improvement_direction = ImprovementDirection::kBiggerIsBetter,
+ .test_case = "test_case_name1",
+ .metric_metadata = DefaultMetadata(),
+ .time_series =
+ Metric::TimeSeries{.samples = std::vector{Sample(10), Sample(20)}},
+ .stats =
+ Metric::Stats{.mean = 15.0, .stddev = 5.0, .min = 10.0, .max = 20.0}};
+ Metric metric2{
+ .name = "test_metric2",
+ .unit = Unit::kKilobitsPerSecond,
+ .improvement_direction = ImprovementDirection::kSmallerIsBetter,
+ .test_case = "test_case_name2",
+ .metric_metadata = DefaultMetadata(),
+ .time_series =
+ Metric::TimeSeries{.samples = std::vector{Sample(20), Sample(40)}},
+ .stats = Metric::Stats{
+ .mean = 30.0, .stddev = 10.0, .min = 20.0, .max = 40.0}};
+
+ ASSERT_TRUE(exporter.Export(std::vector<Metric>{metric1, metric2}));
+ webrtc::test_metrics::MetricsSet actual_metrics_set;
+ actual_metrics_set.ParseFromString(ReadFileAsString(temp_filename_));
+ EXPECT_THAT(actual_metrics_set.metrics().size(), Eq(2));
+
+ EXPECT_THAT(actual_metrics_set.metrics(0).name(), Eq("test_metric1"));
+ EXPECT_THAT(actual_metrics_set.metrics(0).test_case(), Eq("test_case_name1"));
+ EXPECT_THAT(actual_metrics_set.metrics(0).unit(),
+ Eq(proto::Unit::MILLISECONDS));
+ EXPECT_THAT(actual_metrics_set.metrics(0).improvement_direction(),
+ Eq(proto::ImprovementDirection::BIGGER_IS_BETTER));
+ EXPECT_THAT(actual_metrics_set.metrics(0).metric_metadata().size(), Eq(1lu));
+ EXPECT_THAT(actual_metrics_set.metrics(0).metric_metadata().at("key"),
+ Eq("value"));
+ EXPECT_THAT(actual_metrics_set.metrics(0).time_series().samples().size(),
+ Eq(2));
+ AssertSamplesEqual(actual_metrics_set.metrics(0).time_series().samples(0),
+ Sample(10.0));
+ AssertSamplesEqual(actual_metrics_set.metrics(0).time_series().samples(1),
+ Sample(20.0));
+ EXPECT_THAT(actual_metrics_set.metrics(0).stats().mean(), Eq(15.0));
+ EXPECT_THAT(actual_metrics_set.metrics(0).stats().stddev(), Eq(5.0));
+ EXPECT_THAT(actual_metrics_set.metrics(0).stats().min(), Eq(10.0));
+ EXPECT_THAT(actual_metrics_set.metrics(0).stats().max(), Eq(20.0));
+
+ EXPECT_THAT(actual_metrics_set.metrics(1).name(), Eq("test_metric2"));
+ EXPECT_THAT(actual_metrics_set.metrics(1).test_case(), Eq("test_case_name2"));
+ EXPECT_THAT(actual_metrics_set.metrics(1).unit(),
+ Eq(proto::Unit::KILOBITS_PER_SECOND));
+ EXPECT_THAT(actual_metrics_set.metrics(1).improvement_direction(),
+ Eq(proto::ImprovementDirection::SMALLER_IS_BETTER));
+ EXPECT_THAT(actual_metrics_set.metrics(1).metric_metadata().size(), Eq(1lu));
+ EXPECT_THAT(actual_metrics_set.metrics(1).metric_metadata().at("key"),
+ Eq("value"));
+ EXPECT_THAT(actual_metrics_set.metrics(1).time_series().samples().size(),
+ Eq(2));
+ AssertSamplesEqual(actual_metrics_set.metrics(1).time_series().samples(0),
+ Sample(20.0));
+ AssertSamplesEqual(actual_metrics_set.metrics(1).time_series().samples(1),
+ Sample(40.0));
+ EXPECT_THAT(actual_metrics_set.metrics(1).stats().mean(), Eq(30.0));
+ EXPECT_THAT(actual_metrics_set.metrics(1).stats().stddev(), Eq(10.0));
+ EXPECT_THAT(actual_metrics_set.metrics(1).stats().min(), Eq(20.0));
+ EXPECT_THAT(actual_metrics_set.metrics(1).stats().max(), Eq(40.0));
+}
+
+} // namespace
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/metrics/print_result_proxy_metrics_exporter.cc b/third_party/libwebrtc/api/test/metrics/print_result_proxy_metrics_exporter.cc
new file mode 100644
index 0000000000..1ce1e63892
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/print_result_proxy_metrics_exporter.cc
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/metrics/print_result_proxy_metrics_exporter.h"
+
+#include <string>
+#include <unordered_set>
+
+#include "api/array_view.h"
+#include "api/test/metrics/metric.h"
+#include "test/testsupport/perf_test.h"
+
+namespace webrtc {
+namespace test {
+namespace {
+
+std::string ToPrintResultUnit(Unit unit) {
+ switch (unit) {
+ case Unit::kMilliseconds:
+ return "msBestFitFormat";
+ case Unit::kPercent:
+ return "n%";
+ case Unit::kBytes:
+ return "sizeInBytes";
+ case Unit::kKilobitsPerSecond:
+ // PrintResults prefer Chrome Perf Dashboard units, which doesn't have
+ // kpbs units, so we change the unit and value accordingly.
+ return "bytesPerSecond";
+ case Unit::kHertz:
+ return "Hz";
+ case Unit::kUnitless:
+ return "unitless";
+ case Unit::kCount:
+ return "count";
+ }
+}
+
+double ToPrintResultValue(double value, Unit unit) {
+ switch (unit) {
+ case Unit::kKilobitsPerSecond:
+ // PrintResults prefer Chrome Perf Dashboard units, which doesn't have
+ // kpbs units, so we change the unit and value accordingly.
+ return value * 1000 / 8;
+ default:
+ return value;
+ }
+}
+
+ImproveDirection ToPrintResultImproveDirection(ImprovementDirection direction) {
+ switch (direction) {
+ case ImprovementDirection::kBiggerIsBetter:
+ return ImproveDirection::kBiggerIsBetter;
+ case ImprovementDirection::kNeitherIsBetter:
+ return ImproveDirection::kNone;
+ case ImprovementDirection::kSmallerIsBetter:
+ return ImproveDirection::kSmallerIsBetter;
+ }
+}
+
+bool IsEmpty(const Metric::Stats& stats) {
+ return !stats.mean.has_value() && !stats.stddev.has_value() &&
+ !stats.min.has_value() && !stats.max.has_value();
+}
+
+bool NameEndsWithConnected(const std::string& name) {
+ static const std::string suffix = "_connected";
+ return name.size() >= suffix.size() &&
+ 0 == name.compare(name.size() - suffix.size(), suffix.size(), suffix);
+}
+
+} // namespace
+
+bool PrintResultProxyMetricsExporter::Export(
+ rtc::ArrayView<const Metric> metrics) {
+ static const std::unordered_set<std::string> per_call_metrics{
+ "actual_encode_bitrate",
+ "encode_frame_rate",
+ "harmonic_framerate",
+ "max_skipped",
+ "min_psnr_dB",
+ "retransmission_bitrate",
+ "sent_packets_loss",
+ "transmission_bitrate",
+ "dropped_frames",
+ "frames_in_flight",
+ "rendered_frames",
+ "average_receive_rate",
+ "average_send_rate",
+ "bytes_discarded_no_receiver",
+ "bytes_received",
+ "bytes_sent",
+ "packets_discarded_no_receiver",
+ "packets_received",
+ "packets_sent",
+ "payload_bytes_received",
+ "payload_bytes_sent",
+ "cpu_usage"};
+
+ for (const Metric& metric : metrics) {
+ if (metric.time_series.samples.empty() && IsEmpty(metric.stats)) {
+ // If there were no data collected for the metric it is expected that 0
+ // will be exported, so add 0 to the samples.
+ PrintResult(metric.name, /*modifier=*/"", metric.test_case,
+ ToPrintResultValue(0, metric.unit),
+ ToPrintResultUnit(metric.unit), /*important=*/false,
+ ToPrintResultImproveDirection(metric.improvement_direction));
+ continue;
+ }
+
+ if (metric.time_series.samples.empty()) {
+ PrintResultMeanAndError(
+ metric.name, /*modifier=*/"", metric.test_case,
+ ToPrintResultValue(*metric.stats.mean, metric.unit),
+ ToPrintResultValue(*metric.stats.stddev, metric.unit),
+ ToPrintResultUnit(metric.unit),
+ /*important=*/false,
+ ToPrintResultImproveDirection(metric.improvement_direction));
+ continue;
+ }
+
+ if (metric.time_series.samples.size() == 1lu &&
+ (per_call_metrics.count(metric.name) > 0 ||
+ NameEndsWithConnected(metric.name))) {
+ // Increase backwards compatibility for 1 value use case.
+ PrintResult(
+ metric.name, /*modifier=*/"", metric.test_case,
+ ToPrintResultValue(metric.time_series.samples[0].value, metric.unit),
+ ToPrintResultUnit(metric.unit), /*important=*/false,
+ ToPrintResultImproveDirection(metric.improvement_direction));
+ continue;
+ }
+
+ SamplesStatsCounter counter;
+ for (size_t i = 0; i < metric.time_series.samples.size(); ++i) {
+ counter.AddSample(SamplesStatsCounter::StatsSample{
+ .value = ToPrintResultValue(metric.time_series.samples[i].value,
+ metric.unit),
+ .time = metric.time_series.samples[i].timestamp,
+ .metadata = metric.time_series.samples[i].sample_metadata});
+ }
+
+ PrintResult(metric.name, /*modifier=*/"", metric.test_case, counter,
+ ToPrintResultUnit(metric.unit),
+ /*important=*/false,
+ ToPrintResultImproveDirection(metric.improvement_direction));
+ }
+ return true;
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/metrics/print_result_proxy_metrics_exporter.h b/third_party/libwebrtc/api/test/metrics/print_result_proxy_metrics_exporter.h
new file mode 100644
index 0000000000..bad0594972
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/print_result_proxy_metrics_exporter.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_METRICS_PRINT_RESULT_PROXY_METRICS_EXPORTER_H_
+#define API_TEST_METRICS_PRINT_RESULT_PROXY_METRICS_EXPORTER_H_
+
+#include "api/array_view.h"
+#include "api/test/metrics/metric.h"
+#include "api/test/metrics/metrics_exporter.h"
+
+namespace webrtc {
+namespace test {
+
+// Proxies all exported metrics to the `webrtc::test::PrintResult` API.
+class PrintResultProxyMetricsExporter : public MetricsExporter {
+ public:
+ ~PrintResultProxyMetricsExporter() override = default;
+
+ bool Export(rtc::ArrayView<const Metric> metrics) override;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_METRICS_PRINT_RESULT_PROXY_METRICS_EXPORTER_H_
diff --git a/third_party/libwebrtc/api/test/metrics/print_result_proxy_metrics_exporter_test.cc b/third_party/libwebrtc/api/test/metrics/print_result_proxy_metrics_exporter_test.cc
new file mode 100644
index 0000000000..768c794b40
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/print_result_proxy_metrics_exporter_test.cc
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/metrics/print_result_proxy_metrics_exporter.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "api/test/metrics/metric.h"
+#include "api/units/timestamp.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace test {
+namespace {
+
+using ::testing::TestWithParam;
+
+std::map<std::string, std::string> DefaultMetadata() {
+ return std::map<std::string, std::string>{{"key", "value"}};
+}
+
+Metric::TimeSeries::Sample Sample(double value) {
+ return Metric::TimeSeries::Sample{.timestamp = Timestamp::Seconds(1),
+ .value = value,
+ .sample_metadata = DefaultMetadata()};
+}
+
+TEST(PrintResultProxyMetricsExporterTest,
+ ExportMetricsWithTimeSeriesFormatCorrect) {
+ Metric metric1{
+ .name = "test_metric1",
+ .unit = Unit::kMilliseconds,
+ .improvement_direction = ImprovementDirection::kBiggerIsBetter,
+ .test_case = "test_case_name1",
+ .metric_metadata = DefaultMetadata(),
+ .time_series =
+ Metric::TimeSeries{.samples = std::vector{Sample(10), Sample(20)}},
+ .stats =
+ Metric::Stats{.mean = 15.0, .stddev = 5.0, .min = 10.0, .max = 20.0}};
+ Metric metric2{
+ .name = "test_metric2",
+ .unit = Unit::kKilobitsPerSecond,
+ .improvement_direction = ImprovementDirection::kSmallerIsBetter,
+ .test_case = "test_case_name2",
+ .metric_metadata = DefaultMetadata(),
+ .time_series =
+ Metric::TimeSeries{.samples = std::vector{Sample(20), Sample(40)}},
+ .stats = Metric::Stats{
+ .mean = 30.0, .stddev = 10.0, .min = 20.0, .max = 40.0}};
+
+ testing::internal::CaptureStdout();
+ PrintResultProxyMetricsExporter exporter;
+
+ std::string expected =
+ "RESULT test_metric1: test_case_name1= {15,5} "
+ "msBestFitFormat_biggerIsBetter\n"
+ "RESULT test_metric2: test_case_name2= {3750,1250} "
+ "bytesPerSecond_smallerIsBetter\n";
+
+ EXPECT_TRUE(exporter.Export(std::vector<Metric>{metric1, metric2}));
+ EXPECT_EQ(expected, testing::internal::GetCapturedStdout());
+}
+
+TEST(PrintResultProxyMetricsExporterTest,
+ ExportMetricsTimeSeriesOfSingleValueBackwardCompatibleFormat) {
+ // This should be printed as {mean, stddev} despite only being a single data
+ // point.
+ Metric metric1{
+ .name = "available_send_bandwidth",
+ .unit = Unit::kKilobitsPerSecond,
+ .improvement_direction = ImprovementDirection::kBiggerIsBetter,
+ .test_case = "test_case/alice",
+ .metric_metadata = DefaultMetadata(),
+ .time_series = Metric::TimeSeries{.samples = std::vector{Sample(1000)}},
+ .stats = Metric::Stats{
+ .mean = 1000.0, .stddev = 0.0, .min = 1000.0, .max = 1000.0}};
+ // This is a per-call metric that shouldn't have a stddev estimate.
+ Metric metric2{
+ .name = "min_psnr_dB",
+ .unit = Unit::kUnitless,
+ .improvement_direction = ImprovementDirection::kBiggerIsBetter,
+ .test_case = "test_case/alice-video",
+ .metric_metadata = DefaultMetadata(),
+ .time_series = Metric::TimeSeries{.samples = std::vector{Sample(10)}},
+ .stats =
+ Metric::Stats{.mean = 10.0, .stddev = 0.0, .min = 10.0, .max = 10.0}};
+ // This is a per-call metric that shouldn't have a stddev estimate.
+ Metric metric3{
+ .name = "alice_connected",
+ .unit = Unit::kUnitless,
+ .improvement_direction = ImprovementDirection::kBiggerIsBetter,
+ .test_case = "test_case",
+ .metric_metadata = DefaultMetadata(),
+ .time_series = Metric::TimeSeries{.samples = std::vector{Sample(1)}},
+ .stats =
+ Metric::Stats{.mean = 1.0, .stddev = 0.0, .min = 1.0, .max = 1.0}};
+
+ testing::internal::CaptureStdout();
+ PrintResultProxyMetricsExporter exporter;
+
+ std::string expected =
+ "RESULT available_send_bandwidth: test_case/alice= {125000,0} "
+ "bytesPerSecond_biggerIsBetter\n"
+ "RESULT min_psnr_dB: test_case/alice-video= 10 "
+ "unitless_biggerIsBetter\n"
+ "RESULT alice_connected: test_case= 1 "
+ "unitless_biggerIsBetter\n";
+
+ EXPECT_TRUE(exporter.Export(std::vector<Metric>{metric1, metric2, metric3}));
+ EXPECT_EQ(expected, testing::internal::GetCapturedStdout());
+}
+
+TEST(PrintResultProxyMetricsExporterTest,
+ ExportMetricsWithStatsOnlyFormatCorrect) {
+ Metric metric1{.name = "test_metric1",
+ .unit = Unit::kMilliseconds,
+ .improvement_direction = ImprovementDirection::kBiggerIsBetter,
+ .test_case = "test_case_name1",
+ .metric_metadata = DefaultMetadata(),
+ .time_series = Metric::TimeSeries{.samples = {}},
+ .stats = Metric::Stats{
+ .mean = 15.0, .stddev = 5.0, .min = 10.0, .max = 20.0}};
+ Metric metric2{
+ .name = "test_metric2",
+ .unit = Unit::kKilobitsPerSecond,
+ .improvement_direction = ImprovementDirection::kSmallerIsBetter,
+ .test_case = "test_case_name2",
+ .metric_metadata = DefaultMetadata(),
+ .time_series = Metric::TimeSeries{.samples = {}},
+ .stats = Metric::Stats{
+ .mean = 30.0, .stddev = 10.0, .min = 20.0, .max = 40.0}};
+
+ testing::internal::CaptureStdout();
+ PrintResultProxyMetricsExporter exporter;
+
+ std::string expected =
+ "RESULT test_metric1: test_case_name1= {15,5} "
+ "msBestFitFormat_biggerIsBetter\n"
+ "RESULT test_metric2: test_case_name2= {3750,1250} "
+ "bytesPerSecond_smallerIsBetter\n";
+
+ EXPECT_TRUE(exporter.Export(std::vector<Metric>{metric1, metric2}));
+ EXPECT_EQ(expected, testing::internal::GetCapturedStdout());
+}
+
+TEST(PrintResultProxyMetricsExporterTest, ExportEmptyMetricOnlyFormatCorrect) {
+ Metric metric{.name = "test_metric",
+ .unit = Unit::kMilliseconds,
+ .improvement_direction = ImprovementDirection::kBiggerIsBetter,
+ .test_case = "test_case_name",
+ .metric_metadata = DefaultMetadata(),
+ .time_series = Metric::TimeSeries{.samples = {}},
+ .stats = Metric::Stats{}};
+
+ testing::internal::CaptureStdout();
+ PrintResultProxyMetricsExporter exporter;
+
+ std::string expected =
+ "RESULT test_metric: test_case_name= 0 "
+ "msBestFitFormat_biggerIsBetter\n";
+
+ EXPECT_TRUE(exporter.Export(std::vector<Metric>{metric}));
+ EXPECT_EQ(expected, testing::internal::GetCapturedStdout());
+}
+
+} // namespace
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/metrics/proto/metric.proto b/third_party/libwebrtc/api/test/metrics/proto/metric.proto
new file mode 100644
index 0000000000..cdd312589d
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/proto/metric.proto
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+syntax = "proto3";
+
+package webrtc.test_metrics;
+
+// Root message of the proto file. Contains collection of all the metrics.
+message MetricsSet {
+ repeated Metric metrics = 1;
+}
+
+enum Unit {
+ // Default value that has to be defined.
+ UNDEFINED_UNIT = 0;
+ // General unitless value. Can be used either for dimensionless quantities
+ // (ex ratio) or for units not presented in this enum and too specific to add
+ // to this enum.
+ UNITLESS = 1;
+ MILLISECONDS = 2;
+ PERCENT = 3;
+ BYTES = 4;
+ KILOBITS_PER_SECOND = 5;
+ HERTZ = 6;
+ COUNT = 7;
+}
+
+enum ImprovementDirection {
+ // Default value that has to be defined.
+ UNDEFINED_IMPROVEMENT_DIRECTION = 0;
+ BIGGER_IS_BETTER = 1;
+ NEITHER_IS_BETTER = 2;
+ SMALLER_IS_BETTER = 3;
+}
+
+// Single performance metric with all related metadata.
+message Metric {
+ // Metric name, for example PSNR, SSIM, decode_time, etc.
+ string name = 1;
+ Unit unit = 2;
+ ImprovementDirection improvement_direction = 3;
+ // If the metric is generated by a test, this field can be used to specify
+ // this information.
+ string test_case = 4;
+ // Metadata associated with the whole metric.
+ map<string, string> metric_metadata = 5;
+
+ message TimeSeries {
+ message Sample {
+ // Timestamp in microseconds associated with a sample. For example,
+ // the timestamp when the sample was collected.
+ int64 timestamp_us = 1;
+ double value = 2;
+ // Metadata associated with this particular sample.
+ map<string, string> sample_metadata = 3;
+ }
+ // All samples collected for this metric. It can be empty if the Metric
+ // object only contains `stats`.
+ repeated Sample samples = 1;
+ }
+ // Contains all samples of the metric collected during test execution.
+ // It can be empty if the user only stores precomputed statistics into
+ // `stats`.
+ TimeSeries time_series = 6;
+
+ // Contains metric's precomputed statistics based on the `time_series` or if
+ // `time_series` is omitted (has 0 samples) contains precomputed statistics
+ // provided by the metric's calculator.
+ message Stats {
+ // Sample mean of the metric
+ // (https://en.wikipedia.org/wiki/Sample_mean_and_covariance).
+ optional double mean = 1;
+ // Standard deviation (https://en.wikipedia.org/wiki/Standard_deviation).
+ // Is undefined if `time_series` contains only a single sample.
+ optional double stddev = 2;
+ optional double min = 3;
+ optional double max = 4;
+ }
+ Stats stats = 7;
+}
diff --git a/third_party/libwebrtc/api/test/metrics/stdout_metrics_exporter.cc b/third_party/libwebrtc/api/test/metrics/stdout_metrics_exporter.cc
new file mode 100644
index 0000000000..22243e73e8
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/stdout_metrics_exporter.cc
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/metrics/stdout_metrics_exporter.h"
+
+#include <stdio.h>
+
+#include <cmath>
+#include <string>
+
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/test/metrics/metric.h"
+#include "rtc_base/strings/string_builder.h"
+
+namespace webrtc {
+namespace test {
+namespace {
+
+// Returns positive integral part of the number.
+int64_t IntegralPart(double value) {
+ return std::lround(std::floor(std::abs(value)));
+}
+
+void AppendWithPrecision(double value,
+ int digits_after_comma,
+ rtc::StringBuilder& out) {
+ int64_t multiplier = std::lround(std::pow(10, digits_after_comma));
+ int64_t integral_part = IntegralPart(value);
+ double decimal_part = std::abs(value) - integral_part;
+
+ // If decimal part has leading zeros then when it will be multiplied on
+ // `multiplier`, leading zeros will be lost. To preserve them we add "1"
+ // so then leading digit will be greater than 0 and won't be removed.
+ //
+ // During conversion to the string leading digit has to be stripped.
+ //
+ // Also due to rounding it may happen that leading digit may be incremented,
+ // like with `digits_after_comma` 3 number 1.9995 will be rounded to 2. In
+ // such case this increment has to be propagated to the `integral_part`.
+ int64_t decimal_holder = std::lround((1 + decimal_part) * multiplier);
+ if (decimal_holder >= 2 * multiplier) {
+ // Rounding incremented added leading digit, so we need to transfer 1 to
+ // integral part.
+ integral_part++;
+ decimal_holder -= multiplier;
+ }
+ // Remove trailing zeros.
+ while (decimal_holder % 10 == 0) {
+ decimal_holder /= 10;
+ }
+
+ // Print serialized number to output.
+ if (value < 0) {
+ out << "-";
+ }
+ out << integral_part;
+ if (decimal_holder != 1) {
+ out << "." << std::to_string(decimal_holder).substr(1, digits_after_comma);
+ }
+}
+
+} // namespace
+
+StdoutMetricsExporter::StdoutMetricsExporter() : output_(stdout) {}
+
+bool StdoutMetricsExporter::Export(rtc::ArrayView<const Metric> metrics) {
+ for (const Metric& metric : metrics) {
+ PrintMetric(metric);
+ }
+ return true;
+}
+
+void StdoutMetricsExporter::PrintMetric(const Metric& metric) {
+ rtc::StringBuilder value_stream;
+ value_stream << metric.test_case << " / " << metric.name << "= {mean=";
+ if (metric.stats.mean.has_value()) {
+ AppendWithPrecision(*metric.stats.mean, 8, value_stream);
+ } else {
+ value_stream << "-";
+ }
+ value_stream << ", stddev=";
+ if (metric.stats.stddev.has_value()) {
+ AppendWithPrecision(*metric.stats.stddev, 8, value_stream);
+ } else {
+ value_stream << "-";
+ }
+ value_stream << "} " << ToString(metric.unit) << " ("
+ << ToString(metric.improvement_direction) << ")";
+
+ fprintf(output_, "RESULT: %s\n", value_stream.str().c_str());
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/metrics/stdout_metrics_exporter.h b/third_party/libwebrtc/api/test/metrics/stdout_metrics_exporter.h
new file mode 100644
index 0000000000..2c572cb2ea
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/stdout_metrics_exporter.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_METRICS_STDOUT_METRICS_EXPORTER_H_
+#define API_TEST_METRICS_STDOUT_METRICS_EXPORTER_H_
+
+#include "api/array_view.h"
+#include "api/test/metrics/metric.h"
+#include "api/test/metrics/metrics_exporter.h"
+
+namespace webrtc {
+namespace test {
+
+// Exports all collected metrics to stdout.
+class StdoutMetricsExporter : public MetricsExporter {
+ public:
+ StdoutMetricsExporter();
+ ~StdoutMetricsExporter() override = default;
+
+ StdoutMetricsExporter(const StdoutMetricsExporter&) = delete;
+ StdoutMetricsExporter& operator=(const StdoutMetricsExporter&) = delete;
+
+ bool Export(rtc::ArrayView<const Metric> metrics) override;
+
+ private:
+ void PrintMetric(const Metric& metric);
+
+ FILE* const output_;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_METRICS_STDOUT_METRICS_EXPORTER_H_
diff --git a/third_party/libwebrtc/api/test/metrics/stdout_metrics_exporter_test.cc b/third_party/libwebrtc/api/test/metrics/stdout_metrics_exporter_test.cc
new file mode 100644
index 0000000000..91c06fac5b
--- /dev/null
+++ b/third_party/libwebrtc/api/test/metrics/stdout_metrics_exporter_test.cc
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/metrics/stdout_metrics_exporter.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "api/test/metrics/metric.h"
+#include "api/units/timestamp.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace test {
+namespace {
+
+using ::testing::TestWithParam;
+
+std::map<std::string, std::string> DefaultMetadata() {
+ return std::map<std::string, std::string>{{"key", "value"}};
+}
+
+Metric::TimeSeries::Sample Sample(double value) {
+ return Metric::TimeSeries::Sample{.timestamp = Timestamp::Seconds(1),
+ .value = value,
+ .sample_metadata = DefaultMetadata()};
+}
+
+Metric PsnrForTestFoo(double mean, double stddev) {
+ return Metric{.name = "psnr",
+ .unit = Unit::kUnitless,
+ .improvement_direction = ImprovementDirection::kBiggerIsBetter,
+ .test_case = "foo",
+ .time_series = Metric::TimeSeries{},
+ .stats = Metric::Stats{.mean = mean, .stddev = stddev}};
+}
+
+TEST(StdoutMetricsExporterTest, ExportMetricFormatCorrect) {
+ Metric metric1{
+ .name = "test_metric1",
+ .unit = Unit::kMilliseconds,
+ .improvement_direction = ImprovementDirection::kBiggerIsBetter,
+ .test_case = "test_case_name1",
+ .metric_metadata = DefaultMetadata(),
+ .time_series =
+ Metric::TimeSeries{.samples = std::vector{Sample(10), Sample(20)}},
+ .stats =
+ Metric::Stats{.mean = 15.0, .stddev = 5.0, .min = 10.0, .max = 20.0}};
+ Metric metric2{
+ .name = "test_metric2",
+ .unit = Unit::kKilobitsPerSecond,
+ .improvement_direction = ImprovementDirection::kSmallerIsBetter,
+ .test_case = "test_case_name2",
+ .metric_metadata = DefaultMetadata(),
+ .time_series =
+ Metric::TimeSeries{.samples = std::vector{Sample(20), Sample(40)}},
+ .stats = Metric::Stats{
+ .mean = 30.0, .stddev = 10.0, .min = 20.0, .max = 40.0}};
+
+ testing::internal::CaptureStdout();
+ StdoutMetricsExporter exporter;
+
+ std::string expected =
+ "RESULT: test_case_name1 / test_metric1= "
+ "{mean=15, stddev=5} Milliseconds (BiggerIsBetter)\n"
+ "RESULT: test_case_name2 / test_metric2= "
+ "{mean=30, stddev=10} KilobitsPerSecond (SmallerIsBetter)\n";
+
+ EXPECT_TRUE(exporter.Export(std::vector<Metric>{metric1, metric2}));
+ EXPECT_EQ(expected, testing::internal::GetCapturedStdout());
+}
+
+TEST(StdoutMetricsExporterNumberFormatTest, PositiveNumberMaxPrecision) {
+ testing::internal::CaptureStdout();
+ StdoutMetricsExporter exporter;
+
+ Metric metric = PsnrForTestFoo(15.00000001, 0.00000001);
+ std::string expected =
+ "RESULT: foo / psnr= "
+ "{mean=15.00000001, stddev=0.00000001} Unitless (BiggerIsBetter)\n";
+ EXPECT_TRUE(exporter.Export(std::vector<Metric>{metric}));
+ EXPECT_EQ(expected, testing::internal::GetCapturedStdout());
+}
+
+TEST(StdoutMetricsExporterNumberFormatTest,
+ PositiveNumberTrailingZeroNotAdded) {
+ testing::internal::CaptureStdout();
+ StdoutMetricsExporter exporter;
+
+ Metric metric = PsnrForTestFoo(15.12345, 0.12);
+ std::string expected =
+ "RESULT: foo / psnr= "
+ "{mean=15.12345, stddev=0.12} Unitless (BiggerIsBetter)\n";
+ EXPECT_TRUE(exporter.Export(std::vector<Metric>{metric}));
+ EXPECT_EQ(expected, testing::internal::GetCapturedStdout());
+}
+
+TEST(StdoutMetricsExporterNumberFormatTest,
+ PositiveNumberTrailingZeroAreRemoved) {
+ testing::internal::CaptureStdout();
+ StdoutMetricsExporter exporter;
+
+ Metric metric = PsnrForTestFoo(15.123450000, 0.120000000);
+ std::string expected =
+ "RESULT: foo / psnr= "
+ "{mean=15.12345, stddev=0.12} Unitless (BiggerIsBetter)\n";
+ EXPECT_TRUE(exporter.Export(std::vector<Metric>{metric}));
+ EXPECT_EQ(expected, testing::internal::GetCapturedStdout());
+}
+
+TEST(StdoutMetricsExporterNumberFormatTest,
+ PositiveNumberRoundsUpOnPrecisionCorrectly) {
+ testing::internal::CaptureStdout();
+ StdoutMetricsExporter exporter;
+
+ Metric metric = PsnrForTestFoo(15.000000009, 0.999999999);
+ std::string expected =
+ "RESULT: foo / psnr= "
+ "{mean=15.00000001, stddev=1} Unitless (BiggerIsBetter)\n";
+ EXPECT_TRUE(exporter.Export(std::vector<Metric>{metric}));
+ EXPECT_EQ(expected, testing::internal::GetCapturedStdout());
+}
+
+TEST(StdoutMetricsExporterNumberFormatTest,
+ PositiveNumberRoundsDownOnPrecisionCorrectly) {
+ testing::internal::CaptureStdout();
+ StdoutMetricsExporter exporter;
+
+ Metric metric = PsnrForTestFoo(15.0000000049, 0.9999999949);
+ std::string expected =
+ "RESULT: foo / psnr= "
+ "{mean=15, stddev=0.99999999} Unitless (BiggerIsBetter)\n";
+ EXPECT_TRUE(exporter.Export(std::vector<Metric>{metric}));
+ EXPECT_EQ(expected, testing::internal::GetCapturedStdout());
+}
+
+TEST(StdoutMetricsExporterNumberFormatTest, NegativeNumberMaxPrecision) {
+ testing::internal::CaptureStdout();
+ StdoutMetricsExporter exporter;
+
+ Metric metric = PsnrForTestFoo(-15.00000001, -0.00000001);
+ std::string expected =
+ "RESULT: foo / psnr= "
+ "{mean=-15.00000001, stddev=-0.00000001} Unitless (BiggerIsBetter)\n";
+ EXPECT_TRUE(exporter.Export(std::vector<Metric>{metric}));
+ EXPECT_EQ(expected, testing::internal::GetCapturedStdout());
+}
+
+TEST(StdoutMetricsExporterNumberFormatTest,
+ NegativeNumberTrailingZeroNotAdded) {
+ testing::internal::CaptureStdout();
+ StdoutMetricsExporter exporter;
+
+ Metric metric = PsnrForTestFoo(-15.12345, -0.12);
+ std::string expected =
+ "RESULT: foo / psnr= "
+ "{mean=-15.12345, stddev=-0.12} Unitless (BiggerIsBetter)\n";
+ EXPECT_TRUE(exporter.Export(std::vector<Metric>{metric}));
+ EXPECT_EQ(expected, testing::internal::GetCapturedStdout());
+}
+
+TEST(StdoutMetricsExporterNumberFormatTest,
+ NegativeNumberTrailingZeroAreRemoved) {
+ testing::internal::CaptureStdout();
+ StdoutMetricsExporter exporter;
+
+ Metric metric = PsnrForTestFoo(-15.123450000, -0.120000000);
+ std::string expected =
+ "RESULT: foo / psnr= "
+ "{mean=-15.12345, stddev=-0.12} Unitless (BiggerIsBetter)\n";
+ EXPECT_TRUE(exporter.Export(std::vector<Metric>{metric}));
+ EXPECT_EQ(expected, testing::internal::GetCapturedStdout());
+}
+
+TEST(StdoutMetricsExporterNumberFormatTest,
+ NegativeNumberRoundsUpOnPrecisionCorrectly) {
+ testing::internal::CaptureStdout();
+ StdoutMetricsExporter exporter;
+
+ Metric metric = PsnrForTestFoo(-15.000000009, -0.999999999);
+ std::string expected =
+ "RESULT: foo / psnr= "
+ "{mean=-15.00000001, stddev=-1} Unitless (BiggerIsBetter)\n";
+ EXPECT_TRUE(exporter.Export(std::vector<Metric>{metric}));
+ EXPECT_EQ(expected, testing::internal::GetCapturedStdout());
+}
+
+TEST(StdoutMetricsExporterNumberFormatTest,
+ NegativeNumberRoundsDownOnPrecisionCorrectly) {
+ testing::internal::CaptureStdout();
+ StdoutMetricsExporter exporter;
+
+ Metric metric = PsnrForTestFoo(-15.0000000049, -0.9999999949);
+ std::string expected =
+ "RESULT: foo / psnr= "
+ "{mean=-15, stddev=-0.99999999} Unitless (BiggerIsBetter)\n";
+ EXPECT_TRUE(exporter.Export(std::vector<Metric>{metric}));
+ EXPECT_EQ(expected, testing::internal::GetCapturedStdout());
+}
+
+} // namespace
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/mock_async_dns_resolver.h b/third_party/libwebrtc/api/test/mock_async_dns_resolver.h
new file mode 100644
index 0000000000..81132c96a5
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_async_dns_resolver.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2021 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_ASYNC_DNS_RESOLVER_H_
+#define API_TEST_MOCK_ASYNC_DNS_RESOLVER_H_
+
+#include <functional>
+#include <memory>
+
+#include "api/async_dns_resolver.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockAsyncDnsResolverResult : public AsyncDnsResolverResult {
+ public:
+ MOCK_METHOD(bool,
+ GetResolvedAddress,
+ (int, rtc::SocketAddress*),
+ (const, override));
+ MOCK_METHOD(int, GetError, (), (const, override));
+};
+
+class MockAsyncDnsResolver : public AsyncDnsResolverInterface {
+ public:
+ MOCK_METHOD(void,
+ Start,
+ (const rtc::SocketAddress&, std::function<void()>),
+ (override));
+ MOCK_METHOD(void,
+ Start,
+ (const rtc::SocketAddress&, int family, std::function<void()>),
+ (override));
+ MOCK_METHOD(AsyncDnsResolverResult&, result, (), (const, override));
+};
+
+class MockAsyncDnsResolverFactory : public AsyncDnsResolverFactoryInterface {
+ public:
+ MOCK_METHOD(std::unique_ptr<webrtc::AsyncDnsResolverInterface>,
+ CreateAndResolve,
+ (const rtc::SocketAddress&, std::function<void()>),
+ (override));
+ MOCK_METHOD(std::unique_ptr<webrtc::AsyncDnsResolverInterface>,
+ CreateAndResolve,
+ (const rtc::SocketAddress&, int, std::function<void()>),
+ (override));
+ MOCK_METHOD(std::unique_ptr<webrtc::AsyncDnsResolverInterface>,
+ Create,
+ (),
+ (override));
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_ASYNC_DNS_RESOLVER_H_
diff --git a/third_party/libwebrtc/api/test/mock_audio_mixer.h b/third_party/libwebrtc/api/test/mock_audio_mixer.h
new file mode 100644
index 0000000000..88dc108ca3
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_audio_mixer.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_AUDIO_MIXER_H_
+#define API_TEST_MOCK_AUDIO_MIXER_H_
+
+#include "api/audio/audio_mixer.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+namespace test {
+
+class MockAudioMixer : public AudioMixer {
+ public:
+ MOCK_METHOD(bool, AddSource, (Source*), (override));
+ MOCK_METHOD(void, RemoveSource, (Source*), (override));
+ MOCK_METHOD(void, Mix, (size_t number_of_channels, AudioFrame*), (override));
+};
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_AUDIO_MIXER_H_
diff --git a/third_party/libwebrtc/api/test/mock_audio_sink.h b/third_party/libwebrtc/api/test/mock_audio_sink.h
new file mode 100644
index 0000000000..88f38a3c57
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_audio_sink.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_AUDIO_SINK_H_
+#define API_TEST_MOCK_AUDIO_SINK_H_
+
+#include "absl/types/optional.h"
+#include "api/media_stream_interface.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockAudioSink : public webrtc::AudioTrackSinkInterface {
+ public:
+ MOCK_METHOD(void,
+ OnData,
+ (const void* audio_data,
+ int bits_per_sample,
+ int sample_rate,
+ size_t number_of_channels,
+ size_t number_of_frames),
+ (override));
+
+ MOCK_METHOD(void,
+ OnData,
+ (const void* audio_data,
+ int bits_per_sample,
+ int sample_rate,
+ size_t number_of_channels,
+ size_t number_of_frames,
+ absl::optional<int64_t> absolute_capture_timestamp_ms),
+ (override));
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_AUDIO_SINK_H_
diff --git a/third_party/libwebrtc/api/test/mock_data_channel.h b/third_party/libwebrtc/api/test/mock_data_channel.h
new file mode 100644
index 0000000000..38730eaa51
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_data_channel.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_DATA_CHANNEL_H_
+#define API_TEST_MOCK_DATA_CHANNEL_H_
+
+#include <string>
+
+#include "api/data_channel_interface.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockDataChannelInterface
+ : public rtc::RefCountedObject<webrtc::DataChannelInterface> {
+ public:
+ static rtc::scoped_refptr<MockDataChannelInterface> Create() {
+ return rtc::scoped_refptr<MockDataChannelInterface>(
+ new MockDataChannelInterface());
+ }
+
+ MOCK_METHOD(void,
+ RegisterObserver,
+ (DataChannelObserver * observer),
+ (override));
+ MOCK_METHOD(void, UnregisterObserver, (), (override));
+ MOCK_METHOD(std::string, label, (), (const, override));
+ MOCK_METHOD(bool, reliable, (), (const, override));
+ MOCK_METHOD(bool, ordered, (), (const, override));
+ MOCK_METHOD(uint16_t, maxRetransmitTime, (), (const, override));
+ MOCK_METHOD(uint16_t, maxRetransmits, (), (const, override));
+ MOCK_METHOD(absl::optional<int>, maxRetransmitsOpt, (), (const, override));
+ MOCK_METHOD(absl::optional<int>, maxPacketLifeTime, (), (const, override));
+ MOCK_METHOD(std::string, protocol, (), (const, override));
+ MOCK_METHOD(bool, negotiated, (), (const, override));
+ MOCK_METHOD(int, id, (), (const, override));
+ MOCK_METHOD(Priority, priority, (), (const, override));
+ MOCK_METHOD(DataState, state, (), (const, override));
+ MOCK_METHOD(RTCError, error, (), (const, override));
+ MOCK_METHOD(uint32_t, messages_sent, (), (const, override));
+ MOCK_METHOD(uint64_t, bytes_sent, (), (const, override));
+ MOCK_METHOD(uint32_t, messages_received, (), (const, override));
+ MOCK_METHOD(uint64_t, bytes_received, (), (const, override));
+ MOCK_METHOD(uint64_t, buffered_amount, (), (const, override));
+ MOCK_METHOD(void, Close, (), (override));
+ MOCK_METHOD(bool, Send, (const DataBuffer& buffer), (override));
+
+ protected:
+ MockDataChannelInterface() = default;
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_DATA_CHANNEL_H_
diff --git a/third_party/libwebrtc/api/test/mock_dtmf_sender.h b/third_party/libwebrtc/api/test/mock_dtmf_sender.h
new file mode 100644
index 0000000000..9029195025
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_dtmf_sender.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_DTMF_SENDER_H_
+#define API_TEST_MOCK_DTMF_SENDER_H_
+
+#include <string>
+
+#include "api/dtmf_sender_interface.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockDtmfSenderObserver : public DtmfSenderObserverInterface {
+ public:
+ MOCK_METHOD(void,
+ OnToneChange,
+ (const std::string&, const std::string&),
+ (override));
+ MOCK_METHOD(void, OnToneChange, (const std::string&), (override));
+};
+
+static_assert(!std::is_abstract_v<MockDtmfSenderObserver>, "");
+
+class MockDtmfSender : public DtmfSenderInterface {
+ public:
+ static rtc::scoped_refptr<MockDtmfSender> Create() {
+ return rtc::make_ref_counted<MockDtmfSender>();
+ }
+
+ MOCK_METHOD(void,
+ RegisterObserver,
+ (DtmfSenderObserverInterface * observer),
+ (override));
+ MOCK_METHOD(void, UnregisterObserver, (), (override));
+ MOCK_METHOD(bool, CanInsertDtmf, (), (override));
+ MOCK_METHOD(std::string, tones, (), (const override));
+ MOCK_METHOD(int, duration, (), (const override));
+ MOCK_METHOD(int, inter_tone_gap, (), (const override));
+
+ protected:
+ MockDtmfSender() = default;
+};
+
+static_assert(!std::is_abstract_v<rtc::RefCountedObject<MockDtmfSender>>, "");
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_DTMF_SENDER_H_
diff --git a/third_party/libwebrtc/api/test/mock_encoder_selector.h b/third_party/libwebrtc/api/test/mock_encoder_selector.h
new file mode 100644
index 0000000000..2e018d57ba
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_encoder_selector.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_ENCODER_SELECTOR_H_
+#define API_TEST_MOCK_ENCODER_SELECTOR_H_
+
+#include "api/video_codecs/video_encoder_factory.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockEncoderSelector
+ : public VideoEncoderFactory::EncoderSelectorInterface {
+ public:
+ MOCK_METHOD(void,
+ OnCurrentEncoder,
+ (const SdpVideoFormat& format),
+ (override));
+
+ MOCK_METHOD(absl::optional<SdpVideoFormat>,
+ OnAvailableBitrate,
+ (const DataRate& rate),
+ (override));
+
+ MOCK_METHOD(absl::optional<SdpVideoFormat>,
+ OnResolutionChange,
+ (const RenderResolution& resolution),
+ (override));
+
+ MOCK_METHOD(absl::optional<SdpVideoFormat>, OnEncoderBroken, (), (override));
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_ENCODER_SELECTOR_H_
diff --git a/third_party/libwebrtc/api/test/mock_fec_controller_override.h b/third_party/libwebrtc/api/test/mock_fec_controller_override.h
new file mode 100644
index 0000000000..8f3accbc03
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_fec_controller_override.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_FEC_CONTROLLER_OVERRIDE_H_
+#define API_TEST_MOCK_FEC_CONTROLLER_OVERRIDE_H_
+
+#include "api/fec_controller_override.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockFecControllerOverride : public FecControllerOverride {
+ public:
+ MOCK_METHOD(void, SetFecAllowed, (bool fec_allowed), (override));
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_FEC_CONTROLLER_OVERRIDE_H_
diff --git a/third_party/libwebrtc/api/test/mock_frame_decryptor.h b/third_party/libwebrtc/api/test/mock_frame_decryptor.h
new file mode 100644
index 0000000000..9604b96cc2
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_frame_decryptor.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_FRAME_DECRYPTOR_H_
+#define API_TEST_MOCK_FRAME_DECRYPTOR_H_
+
+#include <vector>
+
+#include "api/crypto/frame_decryptor_interface.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockFrameDecryptor : public FrameDecryptorInterface {
+ public:
+ MOCK_METHOD(Result,
+ Decrypt,
+ (cricket::MediaType,
+ const std::vector<uint32_t>&,
+ rtc::ArrayView<const uint8_t>,
+ rtc::ArrayView<const uint8_t>,
+ rtc::ArrayView<uint8_t>),
+ (override));
+
+ MOCK_METHOD(size_t,
+ GetMaxPlaintextByteSize,
+ (cricket::MediaType, size_t encrypted_frame_size),
+ (override));
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_FRAME_DECRYPTOR_H_
diff --git a/third_party/libwebrtc/api/test/mock_frame_encryptor.h b/third_party/libwebrtc/api/test/mock_frame_encryptor.h
new file mode 100644
index 0000000000..e47321f801
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_frame_encryptor.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_FRAME_ENCRYPTOR_H_
+#define API_TEST_MOCK_FRAME_ENCRYPTOR_H_
+
+#include "api/crypto/frame_encryptor_interface.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockFrameEncryptor : public FrameEncryptorInterface {
+ public:
+ MOCK_METHOD(int,
+ Encrypt,
+ (cricket::MediaType,
+ uint32_t,
+ rtc::ArrayView<const uint8_t>,
+ rtc::ArrayView<const uint8_t>,
+ rtc::ArrayView<uint8_t>,
+ size_t*),
+ (override));
+
+ MOCK_METHOD(size_t,
+ GetMaxCiphertextByteSize,
+ (cricket::MediaType media_type, size_t frame_size),
+ (override));
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_FRAME_ENCRYPTOR_H_
diff --git a/third_party/libwebrtc/api/test/mock_media_stream_interface.h b/third_party/libwebrtc/api/test/mock_media_stream_interface.h
new file mode 100644
index 0000000000..dfdbab35e9
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_media_stream_interface.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_MEDIA_STREAM_INTERFACE_H_
+#define API_TEST_MOCK_MEDIA_STREAM_INTERFACE_H_
+
+#include <string>
+
+#include "api/media_stream_interface.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockAudioSource : public rtc::RefCountedObject<AudioSourceInterface> {
+ public:
+ static rtc::scoped_refptr<MockAudioSource> Create() {
+ return rtc::scoped_refptr<MockAudioSource>(new MockAudioSource());
+ }
+
+ MOCK_METHOD(void,
+ RegisterObserver,
+ (ObserverInterface * observer),
+ (override));
+ MOCK_METHOD(void,
+ UnregisterObserver,
+ (ObserverInterface * observer),
+ (override));
+ MOCK_METHOD(SourceState, state, (), (const, override));
+ MOCK_METHOD(bool, remote, (), (const, override));
+ MOCK_METHOD(void, SetVolume, (double volume), (override));
+ MOCK_METHOD(void,
+ RegisterAudioObserver,
+ (AudioObserver * observer),
+ (override));
+ MOCK_METHOD(void,
+ UnregisterAudioObserver,
+ (AudioObserver * observer),
+ (override));
+ MOCK_METHOD(void, AddSink, (AudioTrackSinkInterface * sink), (override));
+ MOCK_METHOD(void, RemoveSink, (AudioTrackSinkInterface * sink), (override));
+ MOCK_METHOD(const cricket::AudioOptions, options, (), (const, override));
+
+ private:
+ MockAudioSource() = default;
+};
+
+class MockAudioTrack : public rtc::RefCountedObject<AudioTrackInterface> {
+ public:
+ static rtc::scoped_refptr<MockAudioTrack> Create() {
+ return rtc::scoped_refptr<MockAudioTrack>(new MockAudioTrack());
+ }
+
+ MOCK_METHOD(void,
+ RegisterObserver,
+ (ObserverInterface * observer),
+ (override));
+ MOCK_METHOD(void,
+ UnregisterObserver,
+ (ObserverInterface * observer),
+ (override));
+ MOCK_METHOD(std::string, kind, (), (const, override));
+ MOCK_METHOD(std::string, id, (), (const, override));
+ MOCK_METHOD(bool, enabled, (), (const, override));
+ MOCK_METHOD(bool, set_enabled, (bool enable), (override));
+ MOCK_METHOD(TrackState, state, (), (const, override));
+ MOCK_METHOD(AudioSourceInterface*, GetSource, (), (const, override));
+ MOCK_METHOD(void, AddSink, (AudioTrackSinkInterface * sink), (override));
+ MOCK_METHOD(void, RemoveSink, (AudioTrackSinkInterface * sink), (override));
+ MOCK_METHOD(bool, GetSignalLevel, (int* level), (override));
+ MOCK_METHOD(rtc::scoped_refptr<AudioProcessorInterface>,
+ GetAudioProcessor,
+ (),
+ (override));
+
+ private:
+ MockAudioTrack() = default;
+};
+
+class MockMediaStream : public MediaStreamInterface {
+ public:
+ MOCK_METHOD(std::string, id, (), (const override));
+ MOCK_METHOD(AudioTrackVector, GetAudioTracks, (), (override));
+ MOCK_METHOD(VideoTrackVector, GetVideoTracks, (), (override));
+ MOCK_METHOD(rtc::scoped_refptr<AudioTrackInterface>,
+ FindAudioTrack,
+ (const std::string& track_id),
+ (override));
+ MOCK_METHOD(rtc::scoped_refptr<VideoTrackInterface>,
+ FindVideoTrack,
+ (const std::string& track_id),
+ (override));
+ MOCK_METHOD(bool,
+ AddTrack,
+ (rtc::scoped_refptr<AudioTrackInterface> track),
+ (override));
+ MOCK_METHOD(bool,
+ AddTrack,
+ (rtc::scoped_refptr<VideoTrackInterface> track),
+ (override));
+ MOCK_METHOD(bool,
+ RemoveTrack,
+ (rtc::scoped_refptr<AudioTrackInterface> track),
+ (override));
+ MOCK_METHOD(bool,
+ RemoveTrack,
+ (rtc::scoped_refptr<VideoTrackInterface> track),
+ (override));
+ // Old AddTrack/RemoveTrack methods - slated for removal
+ MOCK_METHOD(bool, AddTrack, (AudioTrackInterface * track), (override));
+ MOCK_METHOD(bool, AddTrack, (VideoTrackInterface * track), (override));
+ MOCK_METHOD(bool, RemoveTrack, (AudioTrackInterface * track), (override));
+ MOCK_METHOD(bool, RemoveTrack, (VideoTrackInterface * track), (override));
+ MOCK_METHOD(void,
+ RegisterObserver,
+ (ObserverInterface * observer),
+ (override));
+ MOCK_METHOD(void,
+ UnregisterObserver,
+ (ObserverInterface * observer),
+ (override));
+};
+
+static_assert(!std::is_abstract_v<rtc::RefCountedObject<MockMediaStream>>, "");
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_MEDIA_STREAM_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/test/mock_packet_socket_factory.h b/third_party/libwebrtc/api/test/mock_packet_socket_factory.h
new file mode 100644
index 0000000000..7e59556385
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_packet_socket_factory.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_PACKET_SOCKET_FACTORY_H_
+#define API_TEST_MOCK_PACKET_SOCKET_FACTORY_H_
+
+#include <memory>
+#include <string>
+
+#include "api/packet_socket_factory.h"
+#include "test/gmock.h"
+
+namespace rtc {
+class MockPacketSocketFactory : public PacketSocketFactory {
+ public:
+ MOCK_METHOD(AsyncPacketSocket*,
+ CreateUdpSocket,
+ (const SocketAddress&, uint16_t, uint16_t),
+ (override));
+ MOCK_METHOD(AsyncListenSocket*,
+ CreateServerTcpSocket,
+ (const SocketAddress&, uint16_t, uint16_t, int opts),
+ (override));
+ MOCK_METHOD(AsyncPacketSocket*,
+ CreateClientTcpSocket,
+ (const SocketAddress& local_address,
+ const SocketAddress&,
+ const ProxyInfo&,
+ const std::string&,
+ const PacketSocketTcpOptions&),
+ (override));
+ MOCK_METHOD(std::unique_ptr<webrtc::AsyncDnsResolverInterface>,
+ CreateAsyncDnsResolver,
+ (),
+ (override));
+};
+
+static_assert(!std::is_abstract_v<MockPacketSocketFactory>, "");
+
+} // namespace rtc
+
+#endif // API_TEST_MOCK_PACKET_SOCKET_FACTORY_H_
diff --git a/third_party/libwebrtc/api/test/mock_peer_connection_factory_interface.h b/third_party/libwebrtc/api/test/mock_peer_connection_factory_interface.h
new file mode 100644
index 0000000000..ae1fbfbbb7
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_peer_connection_factory_interface.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_PEER_CONNECTION_FACTORY_INTERFACE_H_
+#define API_TEST_MOCK_PEER_CONNECTION_FACTORY_INTERFACE_H_
+
+#include <memory>
+#include <string>
+
+#include "api/peer_connection_interface.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockPeerConnectionFactoryInterface
+ : public rtc::RefCountedObject<webrtc::PeerConnectionFactoryInterface> {
+ public:
+ static rtc::scoped_refptr<MockPeerConnectionFactoryInterface> Create() {
+ return rtc::scoped_refptr<MockPeerConnectionFactoryInterface>(
+ new MockPeerConnectionFactoryInterface());
+ }
+
+ MOCK_METHOD(void, SetOptions, (const Options&), (override));
+ MOCK_METHOD(rtc::scoped_refptr<PeerConnectionInterface>,
+ CreatePeerConnection,
+ (const PeerConnectionInterface::RTCConfiguration&,
+ PeerConnectionDependencies),
+ (override));
+ MOCK_METHOD(RTCErrorOr<rtc::scoped_refptr<PeerConnectionInterface>>,
+ CreatePeerConnectionOrError,
+ (const PeerConnectionInterface::RTCConfiguration&,
+ PeerConnectionDependencies),
+ (override));
+ MOCK_METHOD(rtc::scoped_refptr<PeerConnectionInterface>,
+ CreatePeerConnection,
+ (const PeerConnectionInterface::RTCConfiguration&,
+ std::unique_ptr<cricket::PortAllocator>,
+ std::unique_ptr<rtc::RTCCertificateGeneratorInterface>,
+ PeerConnectionObserver*),
+ (override));
+ MOCK_METHOD(RtpCapabilities,
+ GetRtpSenderCapabilities,
+ (cricket::MediaType),
+ (const, override));
+ MOCK_METHOD(RtpCapabilities,
+ GetRtpReceiverCapabilities,
+ (cricket::MediaType),
+ (const, override));
+ MOCK_METHOD(rtc::scoped_refptr<MediaStreamInterface>,
+ CreateLocalMediaStream,
+ (const std::string&),
+ (override));
+ MOCK_METHOD(rtc::scoped_refptr<AudioSourceInterface>,
+ CreateAudioSource,
+ (const cricket::AudioOptions&),
+ (override));
+ MOCK_METHOD(rtc::scoped_refptr<VideoTrackInterface>,
+ CreateVideoTrack,
+ (const std::string&, VideoTrackSourceInterface*),
+ (override));
+ MOCK_METHOD(rtc::scoped_refptr<AudioTrackInterface>,
+ CreateAudioTrack,
+ (const std::string&, AudioSourceInterface*),
+ (override));
+ MOCK_METHOD(bool, StartAecDump, (FILE*, int64_t), (override));
+ MOCK_METHOD(void, StopAecDump, (), (override));
+
+ protected:
+ MockPeerConnectionFactoryInterface() = default;
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_PEER_CONNECTION_FACTORY_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/test/mock_peerconnectioninterface.h b/third_party/libwebrtc/api/test/mock_peerconnectioninterface.h
new file mode 100644
index 0000000000..ccc6ce46b1
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_peerconnectioninterface.h
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_PEERCONNECTIONINTERFACE_H_
+#define API_TEST_MOCK_PEERCONNECTIONINTERFACE_H_
+
+#include <memory>
+#include <string>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "api/peer_connection_interface.h"
+#include "api/scoped_refptr.h"
+#include "api/sctp_transport_interface.h"
+#include "rtc_base/ref_counted_object.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockPeerConnectionInterface : public webrtc::PeerConnectionInterface {
+ public:
+ static rtc::scoped_refptr<MockPeerConnectionInterface> Create() {
+ return rtc::make_ref_counted<MockPeerConnectionInterface>();
+ }
+
+ // PeerConnectionInterface
+ MOCK_METHOD(rtc::scoped_refptr<StreamCollectionInterface>,
+ local_streams,
+ (),
+ (override));
+ MOCK_METHOD(rtc::scoped_refptr<StreamCollectionInterface>,
+ remote_streams,
+ (),
+ (override));
+ MOCK_METHOD(bool, AddStream, (MediaStreamInterface*), (override));
+ MOCK_METHOD(void, RemoveStream, (MediaStreamInterface*), (override));
+ MOCK_METHOD(RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>>,
+ AddTrack,
+ (rtc::scoped_refptr<MediaStreamTrackInterface>,
+ const std::vector<std::string>&),
+ (override));
+ MOCK_METHOD(RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>>,
+ AddTrack,
+ (rtc::scoped_refptr<MediaStreamTrackInterface>,
+ const std::vector<std::string>&,
+ const std::vector<RtpEncodingParameters>&),
+ (override));
+ MOCK_METHOD(RTCError,
+ RemoveTrackOrError,
+ (rtc::scoped_refptr<RtpSenderInterface>),
+ (override));
+ MOCK_METHOD(RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>,
+ AddTransceiver,
+ (rtc::scoped_refptr<MediaStreamTrackInterface>),
+ (override));
+ MOCK_METHOD(RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>,
+ AddTransceiver,
+ (rtc::scoped_refptr<MediaStreamTrackInterface>,
+ const RtpTransceiverInit&),
+ (override));
+ MOCK_METHOD(RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>,
+ AddTransceiver,
+ (cricket::MediaType),
+ (override));
+ MOCK_METHOD(RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>,
+ AddTransceiver,
+ (cricket::MediaType, const RtpTransceiverInit&),
+ (override));
+ MOCK_METHOD(rtc::scoped_refptr<RtpSenderInterface>,
+ CreateSender,
+ (const std::string&, const std::string&),
+ (override));
+ MOCK_METHOD(std::vector<rtc::scoped_refptr<RtpSenderInterface>>,
+ GetSenders,
+ (),
+ (const, override));
+ MOCK_METHOD(std::vector<rtc::scoped_refptr<RtpReceiverInterface>>,
+ GetReceivers,
+ (),
+ (const, override));
+ MOCK_METHOD(std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>,
+ GetTransceivers,
+ (),
+ (const, override));
+ MOCK_METHOD(bool,
+ GetStats,
+ (StatsObserver*, MediaStreamTrackInterface*, StatsOutputLevel),
+ (override));
+ MOCK_METHOD(void, GetStats, (RTCStatsCollectorCallback*), (override));
+ MOCK_METHOD(void,
+ GetStats,
+ (rtc::scoped_refptr<RtpSenderInterface>,
+ rtc::scoped_refptr<RTCStatsCollectorCallback>),
+ (override));
+ MOCK_METHOD(void,
+ GetStats,
+ (rtc::scoped_refptr<RtpReceiverInterface>,
+ rtc::scoped_refptr<RTCStatsCollectorCallback>),
+ (override));
+ MOCK_METHOD(void, ClearStatsCache, (), (override));
+ MOCK_METHOD(rtc::scoped_refptr<SctpTransportInterface>,
+ GetSctpTransport,
+ (),
+ (const, override));
+ MOCK_METHOD(RTCErrorOr<rtc::scoped_refptr<DataChannelInterface>>,
+ CreateDataChannelOrError,
+ (const std::string&, const DataChannelInit*),
+ (override));
+ MOCK_METHOD(const SessionDescriptionInterface*,
+ local_description,
+ (),
+ (const, override));
+ MOCK_METHOD(const SessionDescriptionInterface*,
+ remote_description,
+ (),
+ (const, override));
+ MOCK_METHOD(const SessionDescriptionInterface*,
+ current_local_description,
+ (),
+ (const, override));
+ MOCK_METHOD(const SessionDescriptionInterface*,
+ current_remote_description,
+ (),
+ (const, override));
+ MOCK_METHOD(const SessionDescriptionInterface*,
+ pending_local_description,
+ (),
+ (const, override));
+ MOCK_METHOD(const SessionDescriptionInterface*,
+ pending_remote_description,
+ (),
+ (const, override));
+ MOCK_METHOD(void, RestartIce, (), (override));
+ MOCK_METHOD(void,
+ CreateOffer,
+ (CreateSessionDescriptionObserver*, const RTCOfferAnswerOptions&),
+ (override));
+ MOCK_METHOD(void,
+ CreateAnswer,
+ (CreateSessionDescriptionObserver*, const RTCOfferAnswerOptions&),
+ (override));
+ MOCK_METHOD(void,
+ SetLocalDescription,
+ (SetSessionDescriptionObserver*, SessionDescriptionInterface*),
+ (override));
+ MOCK_METHOD(void,
+ SetRemoteDescription,
+ (SetSessionDescriptionObserver*, SessionDescriptionInterface*),
+ (override));
+ MOCK_METHOD(void,
+ SetRemoteDescription,
+ (std::unique_ptr<SessionDescriptionInterface>,
+ rtc::scoped_refptr<SetRemoteDescriptionObserverInterface>),
+ (override));
+ MOCK_METHOD(PeerConnectionInterface::RTCConfiguration,
+ GetConfiguration,
+ (),
+ (override));
+ MOCK_METHOD(RTCError,
+ SetConfiguration,
+ (const PeerConnectionInterface::RTCConfiguration&),
+ (override));
+ MOCK_METHOD(bool,
+ AddIceCandidate,
+ (const IceCandidateInterface*),
+ (override));
+ MOCK_METHOD(bool,
+ RemoveIceCandidates,
+ (const std::vector<cricket::Candidate>&),
+ (override));
+ MOCK_METHOD(RTCError, SetBitrate, (const BitrateSettings&), (override));
+ MOCK_METHOD(void, SetAudioPlayout, (bool), (override));
+ MOCK_METHOD(void, SetAudioRecording, (bool), (override));
+ MOCK_METHOD(rtc::scoped_refptr<DtlsTransportInterface>,
+ LookupDtlsTransportByMid,
+ (const std::string&),
+ (override));
+ MOCK_METHOD(SignalingState, signaling_state, (), (override));
+ MOCK_METHOD(IceConnectionState, ice_connection_state, (), (override));
+ MOCK_METHOD(IceConnectionState,
+ standardized_ice_connection_state,
+ (),
+ (override));
+ MOCK_METHOD(PeerConnectionState, peer_connection_state, (), (override));
+ MOCK_METHOD(IceGatheringState, ice_gathering_state, (), (override));
+ MOCK_METHOD(absl::optional<bool>, can_trickle_ice_candidates, (), (override));
+ MOCK_METHOD(bool,
+ StartRtcEventLog,
+ (std::unique_ptr<RtcEventLogOutput>, int64_t),
+ (override));
+ MOCK_METHOD(bool,
+ StartRtcEventLog,
+ (std::unique_ptr<RtcEventLogOutput>),
+ (override));
+ MOCK_METHOD(void, StopRtcEventLog, (), (override));
+ MOCK_METHOD(void, Close, (), (override));
+};
+
+static_assert(
+ !std::is_abstract_v<rtc::RefCountedObject<MockPeerConnectionInterface>>,
+ "");
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_PEERCONNECTIONINTERFACE_H_
diff --git a/third_party/libwebrtc/api/test/mock_rtp_transceiver.h b/third_party/libwebrtc/api/test/mock_rtp_transceiver.h
new file mode 100644
index 0000000000..1d21bce5eb
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_rtp_transceiver.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_RTP_TRANSCEIVER_H_
+#define API_TEST_MOCK_RTP_TRANSCEIVER_H_
+
+#include <string>
+#include <vector>
+
+#include "api/rtp_transceiver_interface.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockRtpTransceiver : public RtpTransceiverInterface {
+ public:
+ MockRtpTransceiver() = default;
+
+ static rtc::scoped_refptr<MockRtpTransceiver> Create() {
+ return rtc::make_ref_counted<MockRtpTransceiver>();
+ }
+
+ MOCK_METHOD(cricket::MediaType, media_type, (), (const, override));
+ MOCK_METHOD(absl::optional<std::string>, mid, (), (const, override));
+ MOCK_METHOD(rtc::scoped_refptr<RtpSenderInterface>,
+ sender,
+ (),
+ (const, override));
+ MOCK_METHOD(rtc::scoped_refptr<RtpReceiverInterface>,
+ receiver,
+ (),
+ (const, override));
+ MOCK_METHOD(bool, stopped, (), (const, override));
+ MOCK_METHOD(bool, stopping, (), (const, override));
+ MOCK_METHOD(RtpTransceiverDirection, direction, (), (const, override));
+ MOCK_METHOD(void,
+ SetDirection,
+ (RtpTransceiverDirection new_direction),
+ (override));
+ MOCK_METHOD(RTCError,
+ SetDirectionWithError,
+ (RtpTransceiverDirection new_direction),
+ (override));
+ MOCK_METHOD(absl::optional<RtpTransceiverDirection>,
+ current_direction,
+ (),
+ (const, override));
+ MOCK_METHOD(absl::optional<RtpTransceiverDirection>,
+ fired_direction,
+ (),
+ (const, override));
+ MOCK_METHOD(RTCError, StopStandard, (), (override));
+ MOCK_METHOD(void, StopInternal, (), (override));
+ MOCK_METHOD(void, Stop, (), (override));
+ MOCK_METHOD(RTCError,
+ SetCodecPreferences,
+ (rtc::ArrayView<RtpCodecCapability> codecs),
+ (override));
+ MOCK_METHOD(std::vector<RtpCodecCapability>,
+ codec_preferences,
+ (),
+ (const, override));
+ MOCK_METHOD(std::vector<RtpHeaderExtensionCapability>,
+ HeaderExtensionsToOffer,
+ (),
+ (const, override));
+ MOCK_METHOD(std::vector<RtpHeaderExtensionCapability>,
+ HeaderExtensionsNegotiated,
+ (),
+ (const, override));
+ MOCK_METHOD(webrtc::RTCError,
+ SetOfferedRtpHeaderExtensions,
+ (rtc::ArrayView<const RtpHeaderExtensionCapability>
+ header_extensions_to_offer),
+ (override));
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_RTP_TRANSCEIVER_H_
diff --git a/third_party/libwebrtc/api/test/mock_rtpreceiver.h b/third_party/libwebrtc/api/test/mock_rtpreceiver.h
new file mode 100644
index 0000000000..63318dc32d
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_rtpreceiver.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_RTPRECEIVER_H_
+#define API_TEST_MOCK_RTPRECEIVER_H_
+
+#include <string>
+#include <vector>
+
+#include "api/crypto/frame_decryptor_interface.h"
+#include "api/rtp_receiver_interface.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockRtpReceiver : public rtc::RefCountedObject<RtpReceiverInterface> {
+ public:
+ MOCK_METHOD(rtc::scoped_refptr<MediaStreamTrackInterface>,
+ track,
+ (),
+ (const, override));
+ MOCK_METHOD(std::vector<rtc::scoped_refptr<MediaStreamInterface>>,
+ streams,
+ (),
+ (const, override));
+ MOCK_METHOD(cricket::MediaType, media_type, (), (const, override));
+ MOCK_METHOD(std::string, id, (), (const, override));
+ MOCK_METHOD(RtpParameters, GetParameters, (), (const, override));
+ MOCK_METHOD(bool,
+ SetParameters,
+ (const webrtc::RtpParameters& parameters),
+ (override));
+ MOCK_METHOD(void, SetObserver, (RtpReceiverObserverInterface*), (override));
+ MOCK_METHOD(void,
+ SetJitterBufferMinimumDelay,
+ (absl::optional<double>),
+ (override));
+ MOCK_METHOD(std::vector<RtpSource>, GetSources, (), (const, override));
+ MOCK_METHOD(void,
+ SetFrameDecryptor,
+ (rtc::scoped_refptr<webrtc::FrameDecryptorInterface>),
+ (override));
+ MOCK_METHOD(rtc::scoped_refptr<webrtc::FrameDecryptorInterface>,
+ GetFrameDecryptor,
+ (),
+ (const, override));
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_RTPRECEIVER_H_
diff --git a/third_party/libwebrtc/api/test/mock_rtpsender.h b/third_party/libwebrtc/api/test/mock_rtpsender.h
new file mode 100644
index 0000000000..22113678b9
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_rtpsender.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_RTPSENDER_H_
+#define API_TEST_MOCK_RTPSENDER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "api/rtp_sender_interface.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockRtpSender : public RtpSenderInterface {
+ public:
+ static rtc::scoped_refptr<MockRtpSender> Create() {
+ return rtc::make_ref_counted<MockRtpSender>();
+ }
+
+ MOCK_METHOD(bool, SetTrack, (MediaStreamTrackInterface*), (override));
+ MOCK_METHOD(rtc::scoped_refptr<MediaStreamTrackInterface>,
+ track,
+ (),
+ (const, override));
+ MOCK_METHOD(rtc::scoped_refptr<DtlsTransportInterface>,
+ dtls_transport,
+ (),
+ (const override));
+ MOCK_METHOD(uint32_t, ssrc, (), (const, override));
+ MOCK_METHOD(cricket::MediaType, media_type, (), (const, override));
+ MOCK_METHOD(std::string, id, (), (const, override));
+ MOCK_METHOD(std::vector<std::string>, stream_ids, (), (const, override));
+ MOCK_METHOD(void, SetStreams, (const std::vector<std::string>&), (override));
+ MOCK_METHOD(std::vector<RtpEncodingParameters>,
+ init_send_encodings,
+ (),
+ (const, override));
+ MOCK_METHOD(RtpParameters, GetParameters, (), (const, override));
+ MOCK_METHOD(RTCError, SetParameters, (const RtpParameters&), (override));
+ MOCK_METHOD(void,
+ SetParametersAsync,
+ (const RtpParameters&, SetParametersCallback),
+ (override));
+ MOCK_METHOD(rtc::scoped_refptr<DtmfSenderInterface>,
+ GetDtmfSender,
+ (),
+ (const, override));
+ MOCK_METHOD(void,
+ SetFrameEncryptor,
+ (rtc::scoped_refptr<FrameEncryptorInterface>),
+ (override));
+ MOCK_METHOD(rtc::scoped_refptr<FrameEncryptorInterface>,
+ GetFrameEncryptor,
+ (),
+ (const, override));
+ MOCK_METHOD(void,
+ SetEncoderToPacketizerFrameTransformer,
+ (rtc::scoped_refptr<FrameTransformerInterface>),
+ (override));
+ MOCK_METHOD(void,
+ SetEncoderSelector,
+ (std::unique_ptr<VideoEncoderFactory::EncoderSelectorInterface>),
+ (override));
+};
+
+static_assert(!std::is_abstract_v<rtc::RefCountedObject<MockRtpSender>>, "");
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_RTPSENDER_H_
diff --git a/third_party/libwebrtc/api/test/mock_session_description_interface.h b/third_party/libwebrtc/api/test/mock_session_description_interface.h
new file mode 100644
index 0000000000..f0346ceb11
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_session_description_interface.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_SESSION_DESCRIPTION_INTERFACE_H_
+#define API_TEST_MOCK_SESSION_DESCRIPTION_INTERFACE_H_
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "api/jsep.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockSessionDescriptionInterface : public SessionDescriptionInterface {
+ public:
+ MOCK_METHOD(std::unique_ptr<SessionDescriptionInterface>,
+ Clone,
+ (),
+ (const, override));
+ MOCK_METHOD(cricket::SessionDescription*, description, (), (override));
+ MOCK_METHOD(const cricket::SessionDescription*,
+ description,
+ (),
+ (const, override));
+ MOCK_METHOD(std::string, session_id, (), (const, override));
+ MOCK_METHOD(std::string, session_version, (), (const, override));
+ MOCK_METHOD(SdpType, GetType, (), (const, override));
+ MOCK_METHOD(std::string, type, (), (const, override));
+ MOCK_METHOD(bool, AddCandidate, (const IceCandidateInterface*), (override));
+ MOCK_METHOD(size_t,
+ RemoveCandidates,
+ (const std::vector<cricket::Candidate>&),
+ (override));
+ MOCK_METHOD(size_t, number_of_mediasections, (), (const, override));
+ MOCK_METHOD(const IceCandidateCollection*,
+ candidates,
+ (size_t),
+ (const, override));
+ MOCK_METHOD(bool, ToString, (std::string*), (const, override));
+};
+
+static_assert(!std::is_abstract_v<MockSessionDescriptionInterface>);
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_SESSION_DESCRIPTION_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/test/mock_transformable_video_frame.h b/third_party/libwebrtc/api/test/mock_transformable_video_frame.h
new file mode 100644
index 0000000000..18b3de534e
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_transformable_video_frame.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_TRANSFORMABLE_VIDEO_FRAME_H_
+#define API_TEST_MOCK_TRANSFORMABLE_VIDEO_FRAME_H_
+
+#include <vector>
+
+#include "api/frame_transformer_interface.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockTransformableVideoFrame
+ : public webrtc::TransformableVideoFrameInterface {
+ public:
+ MOCK_METHOD(rtc::ArrayView<const uint8_t>, GetData, (), (const, override));
+ MOCK_METHOD(void, SetData, (rtc::ArrayView<const uint8_t> data), (override));
+ MOCK_METHOD(uint32_t, GetTimestamp, (), (const, override));
+ MOCK_METHOD(uint32_t, GetSsrc, (), (const, override));
+ MOCK_METHOD(bool, IsKeyFrame, (), (const, override));
+ MOCK_METHOD(std::vector<uint8_t>, GetAdditionalData, (), (const, override));
+ MOCK_METHOD(const webrtc::VideoFrameMetadata&,
+ GetMetadata,
+ (),
+ (const, override));
+ MOCK_METHOD(void,
+ SetMetadata,
+ (const webrtc::VideoFrameMetadata&),
+ (override));
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_TRANSFORMABLE_VIDEO_FRAME_H_
diff --git a/third_party/libwebrtc/api/test/mock_video_bitrate_allocator.h b/third_party/libwebrtc/api/test/mock_video_bitrate_allocator.h
new file mode 100644
index 0000000000..76cf49e955
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_video_bitrate_allocator.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_VIDEO_BITRATE_ALLOCATOR_H_
+#define API_TEST_MOCK_VIDEO_BITRATE_ALLOCATOR_H_
+
+#include "api/video/video_bitrate_allocator.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockVideoBitrateAllocator : public webrtc::VideoBitrateAllocator {
+ MOCK_METHOD(VideoBitrateAllocation,
+ Allocate,
+ (VideoBitrateAllocationParameters parameters),
+ (override));
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_VIDEO_BITRATE_ALLOCATOR_H_
diff --git a/third_party/libwebrtc/api/test/mock_video_bitrate_allocator_factory.h b/third_party/libwebrtc/api/test/mock_video_bitrate_allocator_factory.h
new file mode 100644
index 0000000000..16af191970
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_video_bitrate_allocator_factory.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_VIDEO_BITRATE_ALLOCATOR_FACTORY_H_
+#define API_TEST_MOCK_VIDEO_BITRATE_ALLOCATOR_FACTORY_H_
+
+#include <memory>
+
+#include "api/video/video_bitrate_allocator_factory.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockVideoBitrateAllocatorFactory
+ : public webrtc::VideoBitrateAllocatorFactory {
+ public:
+ ~MockVideoBitrateAllocatorFactory() override { Die(); }
+ MOCK_METHOD(std::unique_ptr<VideoBitrateAllocator>,
+ CreateVideoBitrateAllocator,
+ (const VideoCodec&),
+ (override));
+ MOCK_METHOD(void, Die, ());
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_VIDEO_BITRATE_ALLOCATOR_FACTORY_H_
diff --git a/third_party/libwebrtc/api/test/mock_video_decoder.h b/third_party/libwebrtc/api/test/mock_video_decoder.h
new file mode 100644
index 0000000000..34f732ca4d
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_video_decoder.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_VIDEO_DECODER_H_
+#define API_TEST_MOCK_VIDEO_DECODER_H_
+
+#include <utility>
+
+#include "api/video_codecs/video_decoder.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockDecodedImageCallback : public DecodedImageCallback {
+ public:
+ MOCK_METHOD(int32_t,
+ Decoded,
+ (VideoFrame & decoded_image), // NOLINT
+ (override));
+ MOCK_METHOD(int32_t,
+ Decoded,
+ (VideoFrame & decoded_image, // NOLINT
+ int64_t decode_time_ms),
+ (override));
+ MOCK_METHOD(void,
+ Decoded,
+ (VideoFrame & decoded_image, // NOLINT
+ absl::optional<int32_t> decode_time_ms,
+ absl::optional<uint8_t> qp),
+ (override));
+};
+
+class MockVideoDecoder : public VideoDecoder {
+ public:
+ MockVideoDecoder() {
+ // Make `Configure` succeed by default, so that individual tests that
+ // verify other methods wouldn't need to stub `Configure`.
+ ON_CALL(*this, Configure).WillByDefault(testing::Return(true));
+ }
+
+ ~MockVideoDecoder() override { Destruct(); }
+
+ MOCK_METHOD(bool, Configure, (const Settings& settings), (override));
+ MOCK_METHOD(int32_t,
+ Decode,
+ (const EncodedImage& input_image,
+ bool missing_frames,
+ int64_t render_time_ms),
+ (override));
+ MOCK_METHOD(int32_t,
+ RegisterDecodeCompleteCallback,
+ (DecodedImageCallback * callback),
+ (override));
+ MOCK_METHOD(int32_t, Release, (), (override));
+
+ // Special utility method that allows a test to monitor/verify when
+ // destruction of the decoder instance occurs.
+ MOCK_METHOD(void, Destruct, (), ());
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_VIDEO_DECODER_H_
diff --git a/third_party/libwebrtc/api/test/mock_video_decoder_factory.h b/third_party/libwebrtc/api/test/mock_video_decoder_factory.h
new file mode 100644
index 0000000000..6150d9f8b5
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_video_decoder_factory.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_VIDEO_DECODER_FACTORY_H_
+#define API_TEST_MOCK_VIDEO_DECODER_FACTORY_H_
+
+#include <memory>
+#include <vector>
+
+#include "api/video_codecs/sdp_video_format.h"
+#include "api/video_codecs/video_decoder.h"
+#include "api/video_codecs/video_decoder_factory.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockVideoDecoderFactory : public webrtc::VideoDecoderFactory {
+ public:
+ ~MockVideoDecoderFactory() override { Die(); }
+
+ MOCK_METHOD(std::vector<webrtc::SdpVideoFormat>,
+ GetSupportedFormats,
+ (),
+ (const, override));
+ MOCK_METHOD(std::unique_ptr<webrtc::VideoDecoder>,
+ CreateVideoDecoder,
+ (const webrtc::SdpVideoFormat&),
+ (override));
+ MOCK_METHOD(void, Die, ());
+};
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_VIDEO_DECODER_FACTORY_H_
diff --git a/third_party/libwebrtc/api/test/mock_video_encoder.h b/third_party/libwebrtc/api/test/mock_video_encoder.h
new file mode 100644
index 0000000000..11e0f64b3f
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_video_encoder.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_VIDEO_ENCODER_H_
+#define API_TEST_MOCK_VIDEO_ENCODER_H_
+
+#include <vector>
+
+#include "api/video_codecs/video_encoder.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockEncodedImageCallback : public EncodedImageCallback {
+ public:
+ MOCK_METHOD(Result,
+ OnEncodedImage,
+ (const EncodedImage&, const CodecSpecificInfo*),
+ (override));
+ MOCK_METHOD(void, OnDroppedFrame, (DropReason reason), (override));
+};
+
+class MockVideoEncoder : public VideoEncoder {
+ public:
+ MOCK_METHOD(void,
+ SetFecControllerOverride,
+ (FecControllerOverride*),
+ (override));
+ MOCK_METHOD(int32_t,
+ InitEncode,
+ (const VideoCodec*, int32_t numberOfCores, size_t maxPayloadSize),
+ (override));
+ MOCK_METHOD(int32_t,
+ InitEncode,
+ (const VideoCodec*, const VideoEncoder::Settings& settings),
+ (override));
+
+ MOCK_METHOD(int32_t,
+ Encode,
+ (const VideoFrame& inputImage,
+ const std::vector<VideoFrameType>*),
+ (override));
+ MOCK_METHOD(int32_t,
+ RegisterEncodeCompleteCallback,
+ (EncodedImageCallback*),
+ (override));
+ MOCK_METHOD(int32_t, Release, (), (override));
+ MOCK_METHOD(void,
+ SetRates,
+ (const RateControlParameters& parameters),
+ (override));
+ MOCK_METHOD(void,
+ OnPacketLossRateUpdate,
+ (float packet_loss_rate),
+ (override));
+ MOCK_METHOD(void, OnRttUpdate, (int64_t rtt_ms), (override));
+ MOCK_METHOD(void,
+ OnLossNotification,
+ (const LossNotification& loss_notification),
+ (override));
+ MOCK_METHOD(EncoderInfo, GetEncoderInfo, (), (const, override));
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_VIDEO_ENCODER_H_
diff --git a/third_party/libwebrtc/api/test/mock_video_encoder_factory.h b/third_party/libwebrtc/api/test/mock_video_encoder_factory.h
new file mode 100644
index 0000000000..02ee7aa15e
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_video_encoder_factory.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_VIDEO_ENCODER_FACTORY_H_
+#define API_TEST_MOCK_VIDEO_ENCODER_FACTORY_H_
+
+#include <memory>
+#include <vector>
+
+#include "api/video_codecs/sdp_video_format.h"
+#include "api/video_codecs/video_encoder.h"
+#include "api/video_codecs/video_encoder_factory.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockVideoEncoderFactory : public webrtc::VideoEncoderFactory {
+ public:
+ ~MockVideoEncoderFactory() override { Die(); }
+
+ MOCK_METHOD(std::vector<SdpVideoFormat>,
+ GetSupportedFormats,
+ (),
+ (const, override));
+ MOCK_METHOD(std::unique_ptr<VideoEncoder>,
+ CreateVideoEncoder,
+ (const SdpVideoFormat&),
+ (override));
+
+ MOCK_METHOD(void, Die, ());
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_VIDEO_ENCODER_FACTORY_H_
diff --git a/third_party/libwebrtc/api/test/mock_video_track.h b/third_party/libwebrtc/api/test/mock_video_track.h
new file mode 100644
index 0000000000..1212a32527
--- /dev/null
+++ b/third_party/libwebrtc/api/test/mock_video_track.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_MOCK_VIDEO_TRACK_H_
+#define API_TEST_MOCK_VIDEO_TRACK_H_
+
+#include <string>
+
+#include "api/media_stream_interface.h"
+#include "api/scoped_refptr.h"
+#include "rtc_base/ref_counted_object.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockVideoTrack
+ : public rtc::RefCountedObject<webrtc::VideoTrackInterface> {
+ public:
+ static rtc::scoped_refptr<MockVideoTrack> Create() {
+ return rtc::scoped_refptr<MockVideoTrack>(new MockVideoTrack());
+ }
+
+ // NotifierInterface
+ MOCK_METHOD(void,
+ RegisterObserver,
+ (ObserverInterface * observer),
+ (override));
+ MOCK_METHOD(void,
+ UnregisterObserver,
+ (ObserverInterface * observer),
+ (override));
+
+ // MediaStreamTrackInterface
+ MOCK_METHOD(std::string, kind, (), (const, override));
+ MOCK_METHOD(std::string, id, (), (const, override));
+ MOCK_METHOD(bool, enabled, (), (const, override));
+ MOCK_METHOD(bool, set_enabled, (bool enable), (override));
+ MOCK_METHOD(TrackState, state, (), (const, override));
+
+ // VideoSourceInterface
+ MOCK_METHOD(void,
+ AddOrUpdateSink,
+ (rtc::VideoSinkInterface<VideoFrame> * sink,
+ const rtc::VideoSinkWants& wants),
+ (override));
+ // RemoveSink must guarantee that at the time the method returns,
+ // there is no current and no future calls to VideoSinkInterface::OnFrame.
+ MOCK_METHOD(void,
+ RemoveSink,
+ (rtc::VideoSinkInterface<VideoFrame> * sink),
+ (override));
+
+ // VideoTrackInterface
+ MOCK_METHOD(VideoTrackSourceInterface*, GetSource, (), (const, override));
+
+ MOCK_METHOD(ContentHint, content_hint, (), (const, override));
+ MOCK_METHOD(void, set_content_hint, (ContentHint hint), (override));
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_MOCK_VIDEO_TRACK_H_
diff --git a/third_party/libwebrtc/api/test/neteq_simulator.cc b/third_party/libwebrtc/api/test/neteq_simulator.cc
new file mode 100644
index 0000000000..980db96d32
--- /dev/null
+++ b/third_party/libwebrtc/api/test/neteq_simulator.cc
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/neteq_simulator.h"
+
+namespace webrtc {
+namespace test {
+
+NetEqSimulator::SimulationStepResult::SimulationStepResult() = default;
+NetEqSimulator::SimulationStepResult::SimulationStepResult(
+ const NetEqSimulator::SimulationStepResult& other) = default;
+NetEqSimulator::SimulationStepResult::~SimulationStepResult() = default;
+
+NetEqSimulator::NetEqState::NetEqState() = default;
+NetEqSimulator::NetEqState::NetEqState(const NetEqState& other) = default;
+NetEqSimulator::NetEqState::~NetEqState() = default;
+
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/neteq_simulator.h b/third_party/libwebrtc/api/test/neteq_simulator.h
new file mode 100644
index 0000000000..88c7ffa681
--- /dev/null
+++ b/third_party/libwebrtc/api/test/neteq_simulator.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_NETEQ_SIMULATOR_H_
+#define API_TEST_NETEQ_SIMULATOR_H_
+
+#include <stdint.h>
+
+#include <map>
+#include <vector>
+
+namespace webrtc {
+namespace test {
+
+class NetEqSimulator {
+ public:
+ virtual ~NetEqSimulator() = default;
+
+ enum class Action { kNormal, kExpand, kAccelerate, kPreemptiveExpand };
+
+ // The results of one simulation step.
+ struct SimulationStepResult {
+ SimulationStepResult();
+ SimulationStepResult(const SimulationStepResult& other);
+ ~SimulationStepResult();
+
+ bool is_simulation_finished = false;
+ // The amount of audio produced (in ms) with the actions in this time step.
+ std::map<Action, int> action_times_ms;
+ // The amount of wall clock time (in ms) that elapsed since the previous
+ // event. This is not necessarily equal to the sum of the values in
+ // action_times_ms.
+ int64_t simulation_step_ms = 0;
+ };
+
+ struct NetEqState {
+ NetEqState();
+ NetEqState(const NetEqState& other);
+ ~NetEqState();
+ // The sum of the packet buffer and sync buffer delay.
+ int current_delay_ms = 0;
+ // An indicator that packet loss occurred since the last GetAudio event.
+ bool packet_loss_occurred = false;
+ // An indicator that the packet buffer has been flushed since the last
+ // GetAudio event.
+ bool packet_buffer_flushed = false;
+ // Indicates if the next needed packet is available in the buffer.
+ bool next_packet_available = false;
+ // The inter-arrival times in ms of the packets that have arrived since the
+ // last GetAudio event.
+ std::vector<int> packet_iat_ms;
+ // The current packet size in ms.
+ int packet_size_ms = 0;
+ };
+
+ // Runs the simulation until the end. Returns the duration of the produced
+ // audio in ms.
+ virtual int64_t Run() = 0;
+ // Runs the simulation until we hit the next GetAudio event. If the simulation
+ // is finished, is_simulation_finished will be set to true in the returned
+ // SimulationStepResult.
+ virtual SimulationStepResult RunToNextGetAudio() = 0;
+
+ // Set the next action to be taken by NetEq. This will override any action
+ // that NetEq would normally decide to take.
+ virtual void SetNextAction(Action next_operation) = 0;
+
+ // Get the current state of NetEq.
+ virtual NetEqState GetNetEqState() = 0;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_NETEQ_SIMULATOR_H_
diff --git a/third_party/libwebrtc/api/test/neteq_simulator_factory.cc b/third_party/libwebrtc/api/test/neteq_simulator_factory.cc
new file mode 100644
index 0000000000..82b27e546d
--- /dev/null
+++ b/third_party/libwebrtc/api/test/neteq_simulator_factory.cc
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/neteq_simulator_factory.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/flags/flag.h"
+#include "absl/flags/parse.h"
+#include "modules/audio_coding/neteq/tools/neteq_test_factory.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+namespace test {
+namespace {
+NetEqTestFactory::Config convertConfig(
+ const NetEqSimulatorFactory::Config& simulation_config,
+ absl::string_view replacement_audio_filename) {
+ NetEqTestFactory::Config config;
+ config.replacement_audio_file = std::string(replacement_audio_filename);
+ config.max_nr_packets_in_buffer = simulation_config.max_nr_packets_in_buffer;
+ config.initial_dummy_packets = simulation_config.initial_dummy_packets;
+ config.skip_get_audio_events = simulation_config.skip_get_audio_events;
+ config.field_trial_string = simulation_config.field_trial_string;
+ config.output_audio_filename = simulation_config.output_audio_filename;
+ config.pythonplot = simulation_config.python_plot_filename.has_value();
+ config.plot_scripts_basename = simulation_config.python_plot_filename;
+ config.textlog = simulation_config.text_log_filename.has_value();
+ config.textlog_filename = simulation_config.text_log_filename;
+ return config;
+}
+} // namespace
+
+NetEqSimulatorFactory::NetEqSimulatorFactory()
+ : factory_(std::make_unique<NetEqTestFactory>()) {}
+
+NetEqSimulatorFactory::~NetEqSimulatorFactory() = default;
+
+std::unique_ptr<NetEqSimulator> NetEqSimulatorFactory::CreateSimulatorFromFile(
+ absl::string_view event_log_filename,
+ absl::string_view replacement_audio_filename,
+ Config simulation_config) {
+ NetEqTestFactory::Config config =
+ convertConfig(simulation_config, replacement_audio_filename);
+ return factory_->InitializeTestFromFile(
+ std::string(event_log_filename), simulation_config.neteq_factory, config);
+}
+
+std::unique_ptr<NetEqSimulator>
+NetEqSimulatorFactory::CreateSimulatorFromString(
+ absl::string_view event_log_file_contents,
+ absl::string_view replacement_audio_filename,
+ Config simulation_config) {
+ NetEqTestFactory::Config config =
+ convertConfig(simulation_config, replacement_audio_filename);
+ return factory_->InitializeTestFromString(
+ std::string(event_log_file_contents), simulation_config.neteq_factory,
+ config);
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/neteq_simulator_factory.h b/third_party/libwebrtc/api/test/neteq_simulator_factory.h
new file mode 100644
index 0000000000..2a716e665e
--- /dev/null
+++ b/third_party/libwebrtc/api/test/neteq_simulator_factory.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_NETEQ_SIMULATOR_FACTORY_H_
+#define API_TEST_NETEQ_SIMULATOR_FACTORY_H_
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "api/neteq/neteq_factory.h"
+#include "api/test/neteq_simulator.h"
+
+namespace webrtc {
+namespace test {
+
+class NetEqTestFactory;
+
+class NetEqSimulatorFactory {
+ public:
+ NetEqSimulatorFactory();
+ ~NetEqSimulatorFactory();
+ struct Config {
+ // The maximum allowed number of packets in the jitter buffer.
+ int max_nr_packets_in_buffer = 0;
+ // The number of audio packets to insert at the start of the simulation.
+ // Since the simulation is done with a replacement audio file, these
+ // artificial packets will take a small piece of that replacement audio.
+ int initial_dummy_packets = 0;
+ // The number of simulation steps to skip at the start of the simulation.
+ // This removes incoming packets and GetAudio events from the start of the
+ // simulation, until the requested number of GetAudio events has been
+ // removed.
+ int skip_get_audio_events = 0;
+ // A WebRTC field trial string to be used during the simulation.
+ std::string field_trial_string;
+ // A filename for the generated output audio file.
+ absl::optional<std::string> output_audio_filename;
+ // A filename for the python plot.
+ absl::optional<std::string> python_plot_filename;
+ // A filename for the text log.
+ absl::optional<std::string> text_log_filename;
+ // A custom NetEqFactory can be used.
+ NetEqFactory* neteq_factory = nullptr;
+ };
+ std::unique_ptr<NetEqSimulator> CreateSimulatorFromFile(
+ absl::string_view event_log_filename,
+ absl::string_view replacement_audio_filename,
+ Config simulation_config);
+ // The same as above, but pass the file contents as a string.
+ std::unique_ptr<NetEqSimulator> CreateSimulatorFromString(
+ absl::string_view event_log_file_contents,
+ absl::string_view replacement_audio_file,
+ Config simulation_config);
+
+ private:
+ std::unique_ptr<NetEqTestFactory> factory_;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_NETEQ_SIMULATOR_FACTORY_H_
diff --git a/third_party/libwebrtc/api/test/network_emulation/BUILD.gn b/third_party/libwebrtc/api/test/network_emulation/BUILD.gn
new file mode 100644
index 0000000000..d009d39a21
--- /dev/null
+++ b/third_party/libwebrtc/api/test/network_emulation/BUILD.gn
@@ -0,0 +1,52 @@
+# Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+
+rtc_library("network_emulation") {
+ visibility = [ "*" ]
+
+ sources = [
+ "cross_traffic.h",
+ "network_emulation_interfaces.cc",
+ "network_emulation_interfaces.h",
+ ]
+
+ deps = [
+ "../..:array_view",
+ "../../../rtc_base:checks",
+ "../../../rtc_base:copy_on_write_buffer",
+ "../../../rtc_base:ip_address",
+ "../../../rtc_base:net_helper",
+ "../../../rtc_base:socket_address",
+ "../../numerics",
+ "../../task_queue",
+ "../../units:data_rate",
+ "../../units:data_size",
+ "../../units:time_delta",
+ "../../units:timestamp",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_library("create_cross_traffic") {
+ visibility = [ "*" ]
+ testonly = true
+
+ sources = [
+ "create_cross_traffic.cc",
+ "create_cross_traffic.h",
+ ]
+
+ deps = [
+ ":network_emulation",
+ "../..:network_emulation_manager_api",
+ "../../../rtc_base/task_utils:repeating_task",
+ "../../../test/network:emulated_network",
+ ]
+}
diff --git a/third_party/libwebrtc/api/test/network_emulation/DEPS b/third_party/libwebrtc/api/test/network_emulation/DEPS
new file mode 100644
index 0000000000..0cf128849d
--- /dev/null
+++ b/third_party/libwebrtc/api/test/network_emulation/DEPS
@@ -0,0 +1,7 @@
+specific_include_rules = {
+ ".*": [
+ "+rtc_base/socket_address.h",
+ "+rtc_base/ip_address.h",
+ "+rtc_base/copy_on_write_buffer.h",
+ ],
+}
diff --git a/third_party/libwebrtc/api/test/network_emulation/create_cross_traffic.cc b/third_party/libwebrtc/api/test/network_emulation/create_cross_traffic.cc
new file mode 100644
index 0000000000..36a535cec6
--- /dev/null
+++ b/third_party/libwebrtc/api/test/network_emulation/create_cross_traffic.cc
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/network_emulation/create_cross_traffic.h"
+
+#include <memory>
+
+#include "rtc_base/task_utils/repeating_task.h"
+#include "test/network/cross_traffic.h"
+
+namespace webrtc {
+
+std::unique_ptr<CrossTrafficGenerator> CreateRandomWalkCrossTraffic(
+ CrossTrafficRoute* traffic_route,
+ RandomWalkConfig config) {
+ return std::make_unique<test::RandomWalkCrossTraffic>(config, traffic_route);
+}
+
+std::unique_ptr<CrossTrafficGenerator> CreatePulsedPeaksCrossTraffic(
+ CrossTrafficRoute* traffic_route,
+ PulsedPeaksConfig config) {
+ return std::make_unique<test::PulsedPeaksCrossTraffic>(config, traffic_route);
+}
+
+std::unique_ptr<CrossTrafficGenerator> CreateFakeTcpCrossTraffic(
+ EmulatedRoute* send_route,
+ EmulatedRoute* ret_route,
+ FakeTcpConfig config) {
+ return std::make_unique<test::FakeTcpCrossTraffic>(config, send_route,
+ ret_route);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/network_emulation/create_cross_traffic.h b/third_party/libwebrtc/api/test/network_emulation/create_cross_traffic.h
new file mode 100644
index 0000000000..42fc855392
--- /dev/null
+++ b/third_party/libwebrtc/api/test/network_emulation/create_cross_traffic.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_TEST_NETWORK_EMULATION_CREATE_CROSS_TRAFFIC_H_
+#define API_TEST_NETWORK_EMULATION_CREATE_CROSS_TRAFFIC_H_
+
+#include <memory>
+
+#include "api/test/network_emulation/cross_traffic.h"
+#include "api/test/network_emulation_manager.h"
+
+namespace webrtc {
+
+// This API is still in development and can be changed without prior notice.
+
+std::unique_ptr<CrossTrafficGenerator> CreateRandomWalkCrossTraffic(
+ CrossTrafficRoute* traffic_route,
+ RandomWalkConfig config);
+
+std::unique_ptr<CrossTrafficGenerator> CreatePulsedPeaksCrossTraffic(
+ CrossTrafficRoute* traffic_route,
+ PulsedPeaksConfig config);
+
+std::unique_ptr<CrossTrafficGenerator> CreateFakeTcpCrossTraffic(
+ EmulatedRoute* send_route,
+ EmulatedRoute* ret_route,
+ FakeTcpConfig config);
+
+} // namespace webrtc
+
+#endif // API_TEST_NETWORK_EMULATION_CREATE_CROSS_TRAFFIC_H_
diff --git a/third_party/libwebrtc/api/test/network_emulation/cross_traffic.h b/third_party/libwebrtc/api/test/network_emulation/cross_traffic.h
new file mode 100644
index 0000000000..737a93c2fd
--- /dev/null
+++ b/third_party/libwebrtc/api/test/network_emulation/cross_traffic.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_TEST_NETWORK_EMULATION_CROSS_TRAFFIC_H_
+#define API_TEST_NETWORK_EMULATION_CROSS_TRAFFIC_H_
+
+#include "api/task_queue/task_queue_base.h"
+#include "api/test/network_emulation/network_emulation_interfaces.h"
+#include "api/units/data_rate.h"
+#include "api/units/data_size.h"
+#include "api/units/time_delta.h"
+#include "api/units/timestamp.h"
+
+namespace webrtc {
+
+// This API is still in development and can be changed without prior notice.
+
+// Represents the endpoint for cross traffic that is going through the network.
+// It can be used to emulate unexpected network load.
+class CrossTrafficRoute {
+ public:
+ virtual ~CrossTrafficRoute() = default;
+
+ // Triggers sending of dummy packets with size `packet_size` bytes.
+ virtual void TriggerPacketBurst(size_t num_packets, size_t packet_size) = 0;
+ // Sends a packet over the nodes. The content of the packet is unspecified;
+ // only the size metter for the emulation purposes.
+ virtual void SendPacket(size_t packet_size) = 0;
+ // Sends a packet over the nodes and runs `action` when it has been delivered.
+ virtual void NetworkDelayedAction(size_t packet_size,
+ std::function<void()> action) = 0;
+};
+
+// Describes a way of generating cross traffic on some route. Used by
+// NetworkEmulationManager to produce cross traffic during some period of time.
+class CrossTrafficGenerator {
+ public:
+ virtual ~CrossTrafficGenerator() = default;
+
+ // Time between Process calls.
+ virtual TimeDelta GetProcessInterval() const = 0;
+
+ // Called periodically by NetworkEmulationManager. Generates traffic on the
+ // route.
+ virtual void Process(Timestamp at_time) = 0;
+};
+
+// Config of a cross traffic generator. Generated traffic rises and falls
+// randomly.
+struct RandomWalkConfig {
+ int random_seed = 1;
+ DataRate peak_rate = DataRate::KilobitsPerSec(100);
+ DataSize min_packet_size = DataSize::Bytes(200);
+ TimeDelta min_packet_interval = TimeDelta::Millis(1);
+ TimeDelta update_interval = TimeDelta::Millis(200);
+ double variance = 0.6;
+ double bias = -0.1;
+};
+
+// Config of a cross traffic generator. Generated traffic has form of periodic
+// peaks alternating with periods of silence.
+struct PulsedPeaksConfig {
+ DataRate peak_rate = DataRate::KilobitsPerSec(100);
+ DataSize min_packet_size = DataSize::Bytes(200);
+ TimeDelta min_packet_interval = TimeDelta::Millis(1);
+ TimeDelta send_duration = TimeDelta::Millis(100);
+ TimeDelta hold_duration = TimeDelta::Millis(2000);
+};
+
+struct FakeTcpConfig {
+ DataSize packet_size = DataSize::Bytes(1200);
+ DataSize send_limit = DataSize::PlusInfinity();
+ TimeDelta process_interval = TimeDelta::Millis(200);
+ TimeDelta packet_timeout = TimeDelta::Seconds(1);
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_NETWORK_EMULATION_CROSS_TRAFFIC_H_
diff --git a/third_party/libwebrtc/api/test/network_emulation/network_emulation_interfaces.cc b/third_party/libwebrtc/api/test/network_emulation/network_emulation_interfaces.cc
new file mode 100644
index 0000000000..0f3a7f8ffd
--- /dev/null
+++ b/third_party/libwebrtc/api/test/network_emulation/network_emulation_interfaces.cc
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/network_emulation/network_emulation_interfaces.h"
+
+#include "rtc_base/net_helper.h"
+
+namespace webrtc {
+
+EmulatedIpPacket::EmulatedIpPacket(const rtc::SocketAddress& from,
+ const rtc::SocketAddress& to,
+ rtc::CopyOnWriteBuffer data,
+ Timestamp arrival_time,
+ uint16_t application_overhead)
+ : from(from),
+ to(to),
+ data(data),
+ headers_size(to.ipaddr().overhead() + application_overhead +
+ cricket::kUdpHeaderSize),
+ arrival_time(arrival_time) {
+ RTC_DCHECK(to.family() == AF_INET || to.family() == AF_INET6);
+}
+
+DataRate EmulatedNetworkOutgoingStats::AverageSendRate() const {
+ RTC_DCHECK_GE(packets_sent, 2);
+ RTC_DCHECK(first_packet_sent_time.IsFinite());
+ RTC_DCHECK(last_packet_sent_time.IsFinite());
+ return (bytes_sent - first_sent_packet_size) /
+ (last_packet_sent_time - first_packet_sent_time);
+}
+
+DataRate EmulatedNetworkIncomingStats::AverageReceiveRate() const {
+ RTC_DCHECK_GE(packets_received, 2);
+ RTC_DCHECK(first_packet_received_time.IsFinite());
+ RTC_DCHECK(last_packet_received_time.IsFinite());
+ return (bytes_received - first_received_packet_size) /
+ (last_packet_received_time - first_packet_received_time);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/network_emulation/network_emulation_interfaces.h b/third_party/libwebrtc/api/test/network_emulation/network_emulation_interfaces.h
new file mode 100644
index 0000000000..7cab07b75d
--- /dev/null
+++ b/third_party/libwebrtc/api/test/network_emulation/network_emulation_interfaces.h
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_TEST_NETWORK_EMULATION_NETWORK_EMULATION_INTERFACES_H_
+#define API_TEST_NETWORK_EMULATION_NETWORK_EMULATION_INTERFACES_H_
+
+#include <map>
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/numerics/samples_stats_counter.h"
+#include "api/units/data_rate.h"
+#include "api/units/data_size.h"
+#include "api/units/timestamp.h"
+#include "rtc_base/copy_on_write_buffer.h"
+#include "rtc_base/ip_address.h"
+#include "rtc_base/socket_address.h"
+
+namespace webrtc {
+
+struct EmulatedIpPacket {
+ public:
+ EmulatedIpPacket(const rtc::SocketAddress& from,
+ const rtc::SocketAddress& to,
+ rtc::CopyOnWriteBuffer data,
+ Timestamp arrival_time,
+ uint16_t application_overhead = 0);
+ ~EmulatedIpPacket() = default;
+ // This object is not copyable or assignable.
+ EmulatedIpPacket(const EmulatedIpPacket&) = delete;
+ EmulatedIpPacket& operator=(const EmulatedIpPacket&) = delete;
+ // This object is only moveable.
+ EmulatedIpPacket(EmulatedIpPacket&&) = default;
+ EmulatedIpPacket& operator=(EmulatedIpPacket&&) = default;
+
+ size_t size() const { return data.size(); }
+ const uint8_t* cdata() const { return data.cdata(); }
+
+ size_t ip_packet_size() const { return size() + headers_size; }
+ rtc::SocketAddress from;
+ rtc::SocketAddress to;
+ // Holds the UDP payload.
+ rtc::CopyOnWriteBuffer data;
+ uint16_t headers_size;
+ Timestamp arrival_time;
+};
+
+// Interface for handling IP packets from an emulated network. This is used with
+// EmulatedEndpoint to receive packets on a specific port.
+class EmulatedNetworkReceiverInterface {
+ public:
+ virtual ~EmulatedNetworkReceiverInterface() = default;
+
+ virtual void OnPacketReceived(EmulatedIpPacket packet) = 0;
+};
+
+struct EmulatedNetworkOutgoingStats {
+ int64_t packets_sent = 0;
+
+ DataSize bytes_sent = DataSize::Zero();
+
+ // Sizes of all sent packets.
+ // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
+ SamplesStatsCounter sent_packets_size;
+
+ DataSize first_sent_packet_size = DataSize::Zero();
+
+ // Time of the first packet sent or infinite value if no packets were sent.
+ Timestamp first_packet_sent_time = Timestamp::PlusInfinity();
+
+ // Time of the last packet sent or infinite value if no packets were sent.
+ Timestamp last_packet_sent_time = Timestamp::MinusInfinity();
+
+ // Returns average send rate. Requires that at least 2 packets were sent.
+ DataRate AverageSendRate() const;
+};
+
+struct EmulatedNetworkIncomingStats {
+ // Total amount of packets received with or without destination.
+ int64_t packets_received = 0;
+
+ // Total amount of bytes in received packets.
+ DataSize bytes_received = DataSize::Zero();
+
+ // Sizes of all received packets.
+ // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
+ SamplesStatsCounter received_packets_size;
+
+ // Total amount of packets that were received, but no destination was found.
+ int64_t packets_discarded_no_receiver = 0;
+
+ // Total amount of bytes in discarded packets.
+ DataSize bytes_discarded_no_receiver = DataSize::Zero();
+
+ // Sizes of all packets that were received, but no destination was found.
+ // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
+ SamplesStatsCounter packets_discarded_no_receiver_size;
+
+ DataSize first_received_packet_size = DataSize::Zero();
+
+ // Time of the first packet received or infinite value if no packets were
+ // received.
+ Timestamp first_packet_received_time = Timestamp::PlusInfinity();
+
+ // Time of the last packet received or infinite value if no packets were
+ // received.
+ Timestamp last_packet_received_time = Timestamp::MinusInfinity();
+
+ DataRate AverageReceiveRate() const;
+};
+
+struct EmulatedNetworkStats {
+ int64_t PacketsSent() const { return overall_outgoing_stats.packets_sent; }
+
+ DataSize BytesSent() const { return overall_outgoing_stats.bytes_sent; }
+
+ // Returns the timestamped sizes of all sent packets.
+ // Returned reference is valid until the next call to a non-const method.
+ // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
+ const SamplesStatsCounter& SentPacketsSizeCounter() const {
+ return overall_outgoing_stats.sent_packets_size;
+ }
+
+ DataSize FirstSentPacketSize() const {
+ return overall_outgoing_stats.first_sent_packet_size;
+ }
+
+ // Returns time of the first packet sent or infinite value if no packets were
+ // sent.
+ Timestamp FirstPacketSentTime() const {
+ return overall_outgoing_stats.first_packet_sent_time;
+ }
+
+ // Returns time of the last packet sent or infinite value if no packets were
+ // sent.
+ Timestamp LastPacketSentTime() const {
+ return overall_outgoing_stats.last_packet_sent_time;
+ }
+
+ DataRate AverageSendRate() const {
+ return overall_outgoing_stats.AverageSendRate();
+ }
+
+ // Total amount of packets received regardless of the destination address.
+ int64_t PacketsReceived() const {
+ return overall_incoming_stats.packets_received;
+ }
+
+ // Total amount of bytes in received packets.
+ DataSize BytesReceived() const {
+ return overall_incoming_stats.bytes_received;
+ }
+
+ // Returns the timestamped sizes of all received packets.
+ // Returned reference is valid until the next call to a non-const method.
+ // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
+ const SamplesStatsCounter& ReceivedPacketsSizeCounter() const {
+ return overall_incoming_stats.received_packets_size;
+ }
+
+ // Total amount of packets that were received, but no destination was found.
+ int64_t PacketsDiscardedNoReceiver() const {
+ return overall_incoming_stats.packets_discarded_no_receiver;
+ }
+
+ // Total amount of bytes in dropped packets.
+ DataSize BytesDiscardedNoReceiver() const {
+ return overall_incoming_stats.bytes_discarded_no_receiver;
+ }
+
+ // Returns counter with timestamped sizes of all packets that were received,
+ // but no destination was found.
+ // Returned reference is valid until the next call to a non-const method.
+ // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
+ const SamplesStatsCounter& PacketsDiscardedNoReceiverSizeCounter() const {
+ return overall_incoming_stats.packets_discarded_no_receiver_size;
+ }
+
+ DataSize FirstReceivedPacketSize() const {
+ return overall_incoming_stats.first_received_packet_size;
+ }
+
+ // Returns time of the first packet received or infinite value if no packets
+ // were received.
+ Timestamp FirstPacketReceivedTime() const {
+ return overall_incoming_stats.first_packet_received_time;
+ }
+
+ // Returns time of the last packet received or infinite value if no packets
+ // were received.
+ Timestamp LastPacketReceivedTime() const {
+ return overall_incoming_stats.last_packet_received_time;
+ }
+
+ DataRate AverageReceiveRate() const {
+ return overall_incoming_stats.AverageReceiveRate();
+ }
+
+ // List of IP addresses that were used to send data considered in this stats
+ // object.
+ std::vector<rtc::IPAddress> local_addresses;
+
+ // Overall outgoing stats for all IP addresses which were requested.
+ EmulatedNetworkOutgoingStats overall_outgoing_stats;
+
+ // Overall incoming stats for all IP addresses from which data was received
+ // on requested interfaces.
+ EmulatedNetworkIncomingStats overall_incoming_stats;
+
+ std::map<rtc::IPAddress, EmulatedNetworkOutgoingStats>
+ outgoing_stats_per_destination;
+ std::map<rtc::IPAddress, EmulatedNetworkIncomingStats>
+ incoming_stats_per_source;
+
+ // Duration between packet was received on network interface and was
+ // dispatched to the network in microseconds.
+ // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
+ SamplesStatsCounter sent_packets_queue_wait_time_us;
+};
+
+struct EmulatedNetworkNodeStats {
+ // Amount of time each packet spent in the emulated network node for which
+ // stats were collected.
+ //
+ // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
+ SamplesStatsCounter packet_transport_time;
+
+ // For each packet contains its size divided on the amount of time which it
+ // spent in the emulated network node for which stats were collected.
+ //
+ // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
+ SamplesStatsCounter size_to_packet_transport_time;
+};
+
+// EmulatedEndpoint is an abstraction for network interface on device. Instances
+// of this are created by NetworkEmulationManager::CreateEndpoint and
+// thread safe.
+class EmulatedEndpoint : public EmulatedNetworkReceiverInterface {
+ public:
+ // Send packet into network.
+ // `from` will be used to set source address for the packet in destination
+ // socket.
+ // `to` will be used for routing verification and picking right socket by port
+ // on destination endpoint.
+ virtual void SendPacket(const rtc::SocketAddress& from,
+ const rtc::SocketAddress& to,
+ rtc::CopyOnWriteBuffer packet_data,
+ uint16_t application_overhead = 0) = 0;
+
+ // Binds receiver to this endpoint to send and receive data.
+ // `desired_port` is a port that should be used. If it is equal to 0,
+ // endpoint will pick the first available port starting from
+ // `kFirstEphemeralPort`.
+ //
+ // Returns the port, that should be used (it will be equals to desired, if
+ // `desired_port` != 0 and is free or will be the one, selected by endpoint)
+ // or absl::nullopt if desired_port in used. Also fails if there are no more
+ // free ports to bind to.
+ //
+ // The Bind- and Unbind-methods must not be called from within a bound
+ // receiver's OnPacketReceived method.
+ virtual absl::optional<uint16_t> BindReceiver(
+ uint16_t desired_port,
+ EmulatedNetworkReceiverInterface* receiver) = 0;
+ // Unbinds receiver from the specified port. Do nothing if no receiver was
+ // bound before. After this method returns, no more packets can be delivered
+ // to the receiver, and it is safe to destroy it.
+ virtual void UnbindReceiver(uint16_t port) = 0;
+ // Binds receiver that will accept all packets which arrived on any port
+ // for which there are no bound receiver.
+ virtual void BindDefaultReceiver(
+ EmulatedNetworkReceiverInterface* receiver) = 0;
+ // Unbinds default receiver. Do nothing if no default receiver was bound
+ // before.
+ virtual void UnbindDefaultReceiver() = 0;
+ virtual rtc::IPAddress GetPeerLocalAddress() const = 0;
+
+ private:
+ // Ensure that there can be no other subclass than EmulatedEndpointImpl. This
+ // means that it's always safe to downcast EmulatedEndpoint instances to
+ // EmulatedEndpointImpl.
+ friend class EmulatedEndpointImpl;
+ EmulatedEndpoint() = default;
+};
+
+// Simulates a TCP connection, this roughly implements the Reno algorithm. In
+// difference from TCP this only support sending messages with a fixed length,
+// no streaming. This is useful to simulate signaling and cross traffic using
+// message based protocols such as HTTP. It differs from UDP messages in that
+// they are guranteed to be delivered eventually, even on lossy networks.
+class TcpMessageRoute {
+ public:
+ // Sends a TCP message of the given `size` over the route, `on_received` is
+ // called when the message has been delivered. Note that the connection
+ // parameters are reset iff there's no currently pending message on the route.
+ virtual void SendMessage(size_t size, std::function<void()> on_received) = 0;
+
+ protected:
+ ~TcpMessageRoute() = default;
+};
+} // namespace webrtc
+
+#endif // API_TEST_NETWORK_EMULATION_NETWORK_EMULATION_INTERFACES_H_
diff --git a/third_party/libwebrtc/api/test/network_emulation_manager.cc b/third_party/libwebrtc/api/test/network_emulation_manager.cc
new file mode 100644
index 0000000000..236e2f0e17
--- /dev/null
+++ b/third_party/libwebrtc/api/test/network_emulation_manager.cc
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/network_emulation_manager.h"
+
+#include <utility>
+
+#include "call/simulated_network.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+bool AbslParseFlag(absl::string_view text, TimeMode* mode, std::string* error) {
+ if (text == "realtime") {
+ *mode = TimeMode::kRealTime;
+ return true;
+ }
+ if (text == "simulated") {
+ *mode = TimeMode::kSimulated;
+ return true;
+ }
+ *error =
+ "Unknown value for TimeMode enum. Options are 'realtime' or 'simulated'";
+ return false;
+}
+
+std::string AbslUnparseFlag(TimeMode mode) {
+ switch (mode) {
+ case TimeMode::kRealTime:
+ return "realtime";
+ case TimeMode::kSimulated:
+ return "simulated";
+ }
+ RTC_CHECK_NOTREACHED();
+ return "unknown";
+}
+
+NetworkEmulationManager::SimulatedNetworkNode::Builder&
+NetworkEmulationManager::SimulatedNetworkNode::Builder::config(
+ BuiltInNetworkBehaviorConfig config) {
+ config_ = config;
+ return *this;
+}
+
+NetworkEmulationManager::SimulatedNetworkNode::Builder&
+NetworkEmulationManager::SimulatedNetworkNode::Builder::delay_ms(
+ int queue_delay_ms) {
+ config_.queue_delay_ms = queue_delay_ms;
+ return *this;
+}
+
+NetworkEmulationManager::SimulatedNetworkNode::Builder&
+NetworkEmulationManager::SimulatedNetworkNode::Builder::capacity_kbps(
+ int link_capacity_kbps) {
+ config_.link_capacity_kbps = link_capacity_kbps;
+ return *this;
+}
+
+NetworkEmulationManager::SimulatedNetworkNode::Builder&
+NetworkEmulationManager::SimulatedNetworkNode::Builder::capacity_Mbps(
+ int link_capacity_Mbps) {
+ config_.link_capacity_kbps = link_capacity_Mbps * 1000;
+ return *this;
+}
+
+NetworkEmulationManager::SimulatedNetworkNode::Builder&
+NetworkEmulationManager::SimulatedNetworkNode::Builder::loss(double loss_rate) {
+ config_.loss_percent = std::round(loss_rate * 100);
+ return *this;
+}
+
+NetworkEmulationManager::SimulatedNetworkNode::Builder&
+NetworkEmulationManager::SimulatedNetworkNode::Builder::packet_queue_length(
+ int max_queue_length_in_packets) {
+ config_.queue_length_packets = max_queue_length_in_packets;
+ return *this;
+}
+
+NetworkEmulationManager::SimulatedNetworkNode
+NetworkEmulationManager::SimulatedNetworkNode::Builder::Build(
+ uint64_t random_seed) const {
+ RTC_CHECK(net_);
+ return Build(net_, random_seed);
+}
+
+NetworkEmulationManager::SimulatedNetworkNode
+NetworkEmulationManager::SimulatedNetworkNode::Builder::Build(
+ NetworkEmulationManager* net,
+ uint64_t random_seed) const {
+ RTC_CHECK(net);
+ RTC_CHECK(net_ == nullptr || net_ == net);
+ SimulatedNetworkNode res;
+ auto behavior = std::make_unique<SimulatedNetwork>(config_, random_seed);
+ res.simulation = behavior.get();
+ res.node = net->CreateEmulatedNode(std::move(behavior));
+ return res;
+}
+
+std::pair<EmulatedNetworkManagerInterface*, EmulatedNetworkManagerInterface*>
+NetworkEmulationManager::CreateEndpointPairWithTwoWayRoutes(
+ const BuiltInNetworkBehaviorConfig& config) {
+ auto* alice_node = CreateEmulatedNode(config);
+ auto* bob_node = CreateEmulatedNode(config);
+
+ auto* alice_endpoint = CreateEndpoint(EmulatedEndpointConfig());
+ auto* bob_endpoint = CreateEndpoint(EmulatedEndpointConfig());
+
+ CreateRoute(alice_endpoint, {alice_node}, bob_endpoint);
+ CreateRoute(bob_endpoint, {bob_node}, alice_endpoint);
+
+ return {
+ CreateEmulatedNetworkManagerInterface({alice_endpoint}),
+ CreateEmulatedNetworkManagerInterface({bob_endpoint}),
+ };
+}
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/network_emulation_manager.h b/third_party/libwebrtc/api/test/network_emulation_manager.h
new file mode 100644
index 0000000000..bc9279d306
--- /dev/null
+++ b/third_party/libwebrtc/api/test/network_emulation_manager.h
@@ -0,0 +1,357 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_NETWORK_EMULATION_MANAGER_H_
+#define API_TEST_NETWORK_EMULATION_MANAGER_H_
+
+#include <functional>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "api/array_view.h"
+#include "api/packet_socket_factory.h"
+#include "api/test/network_emulation/cross_traffic.h"
+#include "api/test/network_emulation/network_emulation_interfaces.h"
+#include "api/test/peer_network_dependencies.h"
+#include "api/test/simulated_network.h"
+#include "api/test/time_controller.h"
+#include "api/units/timestamp.h"
+#include "rtc_base/network.h"
+#include "rtc_base/network_constants.h"
+#include "rtc_base/thread.h"
+
+namespace webrtc {
+
+// This API is still in development and can be changed without prior notice.
+
+// These classes are forward declared here, because they used as handles, to
+// make it possible for client code to operate with these abstractions and build
+// required network configuration. With forward declaration here implementation
+// is more readable, than with interfaces approach and cause user needn't any
+// API methods on these abstractions it is acceptable here.
+
+// EmulatedNetworkNode is an abstraction for some network in the real world,
+// like 3G network between peers, or Wi-Fi for one peer and LTE for another.
+// Multiple networks can be joined into chain emulating a network path from
+// one peer to another.
+class EmulatedNetworkNode;
+
+// EmulatedRoute is handle for single route from one network interface on one
+// peer device to another network interface on another peer device.
+class EmulatedRoute;
+
+enum class EmulatedNetworkStatsGatheringMode {
+ // Gather main network stats counters. See more details on which particular
+ // metrics are collected in the `EmulatedNetworkStats` and
+ // `EmulatedNetworkNodeStats` documentation.
+ kDefault,
+ // kDefault + also gather per packet statistics. In this mode more memory
+ // will be used.
+ kDebug
+};
+
+struct EmulatedEndpointConfig {
+ enum class IpAddressFamily { kIpv4, kIpv6 };
+
+ // If specified will be used to name endpoint for logging purposes.
+ absl::optional<std::string> name = absl::nullopt;
+ IpAddressFamily generated_ip_family = IpAddressFamily::kIpv4;
+ // If specified will be used as IP address for endpoint node. Must be unique
+ // among all created nodes.
+ absl::optional<rtc::IPAddress> ip;
+ // Should endpoint be enabled or not, when it will be created.
+ // Enabled endpoints will be available for webrtc to send packets.
+ bool start_as_enabled = true;
+ // Network type which will be used to represent endpoint to WebRTC.
+ rtc::AdapterType type = rtc::AdapterType::ADAPTER_TYPE_UNKNOWN;
+ // Allow endpoint to send packets specifying source IP address different to
+ // the current endpoint IP address. If false endpoint will crash if attempt
+ // to send such packet will be done.
+ bool allow_send_packet_with_different_source_ip = false;
+ // Allow endpoint to receive packet with destination IP address different to
+ // the current endpoint IP address. If false endpoint will crash if such
+ // packet will arrive.
+ bool allow_receive_packets_with_different_dest_ip = false;
+};
+
+struct EmulatedTURNServerConfig {
+ EmulatedEndpointConfig client_config;
+ EmulatedEndpointConfig peer_config;
+};
+
+// EmulatedTURNServer is an abstraction for a TURN server.
+class EmulatedTURNServerInterface {
+ public:
+ struct IceServerConfig {
+ std::string username;
+ std::string password;
+ std::string url;
+ };
+
+ virtual ~EmulatedTURNServerInterface() {}
+
+ // Get an IceServer configuration suitable to add to a PeerConnection.
+ virtual IceServerConfig GetIceServerConfig() const = 0;
+
+ // Get non-null client endpoint, an endpoint that accepts TURN allocations.
+ // This shall typically be connected to one or more webrtc endpoint.
+ virtual EmulatedEndpoint* GetClientEndpoint() const = 0;
+
+ // Returns socket address, which client should use to connect to TURN server
+ // and do TURN allocation.
+ virtual rtc::SocketAddress GetClientEndpointAddress() const = 0;
+
+ // Get non-null peer endpoint, that is "connected to the internet".
+ // This shall typically be connected to another TURN server.
+ virtual EmulatedEndpoint* GetPeerEndpoint() const = 0;
+};
+
+// Provide interface to obtain all required objects to inject network emulation
+// layer into PeerConnection. Also contains information about network interfaces
+// accessible by PeerConnection.
+class EmulatedNetworkManagerInterface {
+ public:
+ virtual ~EmulatedNetworkManagerInterface() = default;
+
+ // Returns non-null pointer to thread that have to be used as network thread
+ // for WebRTC to properly setup network emulation. Returned thread is owned
+ // by EmulatedNetworkManagerInterface implementation.
+ virtual rtc::Thread* network_thread() = 0;
+ // Returns non-null pointer to network manager that have to be injected into
+ // WebRTC to properly setup network emulation. Returned manager is owned by
+ // EmulatedNetworkManagerInterface implementation.
+ virtual rtc::NetworkManager* network_manager() = 0;
+ // Returns non-null pointer to packet socket factory that have to be injected
+ // into WebRTC to properly setup network emulation. Returned factory is owned
+ // by EmulatedNetworkManagerInterface implementation.
+ virtual rtc::PacketSocketFactory* packet_socket_factory() = 0;
+ webrtc::webrtc_pc_e2e::PeerNetworkDependencies network_dependencies() {
+ return {network_thread(), network_manager(), packet_socket_factory()};
+ }
+ // Returns list of endpoints that are associated with this instance. Pointers
+ // are guaranteed to be non-null and are owned by NetworkEmulationManager.
+ virtual std::vector<EmulatedEndpoint*> endpoints() const = 0;
+
+ // Passes summarized network stats for endpoints for this manager into
+ // specified `stats_callback`. Callback will be executed on network emulation
+ // internal task queue.
+ virtual void GetStats(
+ std::function<void(EmulatedNetworkStats)> stats_callback) const = 0;
+};
+
+enum class TimeMode { kRealTime, kSimulated };
+
+// Called implicitly when parsing an ABSL_FLAG of type TimeMode.
+// from the command line flag value `text`.
+// Returns `true` and sets `*mode` on success;
+// returns `false` and sets `*error` on failure.
+bool AbslParseFlag(absl::string_view text, TimeMode* mode, std::string* error);
+
+// AbslUnparseFlag returns a textual flag value corresponding to the TimeMode
+// `mode`.
+std::string AbslUnparseFlag(TimeMode mode);
+
+// Provides an API for creating and configuring emulated network layer.
+// All objects returned by this API are owned by NetworkEmulationManager itself
+// and will be deleted when manager will be deleted.
+class NetworkEmulationManager {
+ public:
+ // Helper struct to simplify creation of simulated network behaviors. Contains
+ // non-owning pointers as the underlying instances are owned by the manager.
+ struct SimulatedNetworkNode {
+ SimulatedNetworkInterface* simulation;
+ EmulatedNetworkNode* node;
+
+ class Builder {
+ public:
+ explicit Builder(NetworkEmulationManager* net) : net_(net) {}
+ Builder() : net_(nullptr) {}
+ Builder(const Builder&) = default;
+ // Sets the config state, note that this will replace any previously set
+ // values.
+ Builder& config(BuiltInNetworkBehaviorConfig config);
+ Builder& delay_ms(int queue_delay_ms);
+ Builder& capacity_kbps(int link_capacity_kbps);
+ Builder& capacity_Mbps(int link_capacity_Mbps);
+ Builder& loss(double loss_rate);
+ Builder& packet_queue_length(int max_queue_length_in_packets);
+ SimulatedNetworkNode Build(uint64_t random_seed = 1) const;
+ SimulatedNetworkNode Build(NetworkEmulationManager* net,
+ uint64_t random_seed = 1) const;
+
+ private:
+ NetworkEmulationManager* const net_;
+ BuiltInNetworkBehaviorConfig config_;
+ };
+ };
+ virtual ~NetworkEmulationManager() = default;
+
+ virtual TimeController* time_controller() = 0;
+ // Returns a mode in which underlying time controller operates.
+ virtual TimeMode time_mode() const = 0;
+
+ // Creates an emulated network node, which represents ideal network with
+ // unlimited capacity, no delay and no packet loss.
+ EmulatedNetworkNode* CreateUnconstrainedEmulatedNode() {
+ return CreateEmulatedNode(BuiltInNetworkBehaviorConfig());
+ }
+ // Creates an emulated network node, which represents single network in
+ // the emulated network layer. Uses default implementation on network behavior
+ // which can be configured with `config`. `random_seed` can be provided to
+ // alter randomization behavior.
+ virtual EmulatedNetworkNode* CreateEmulatedNode(
+ BuiltInNetworkBehaviorConfig config,
+ uint64_t random_seed = 1) = 0;
+ // Creates an emulated network node, which represents single network in
+ // the emulated network layer. `network_behavior` determines how created node
+ // will forward incoming packets to the next receiver.
+ virtual EmulatedNetworkNode* CreateEmulatedNode(
+ std::unique_ptr<NetworkBehaviorInterface> network_behavior) = 0;
+
+ virtual SimulatedNetworkNode::Builder NodeBuilder() = 0;
+
+ // Creates an emulated endpoint, which represents single network interface on
+ // the peer's device.
+ virtual EmulatedEndpoint* CreateEndpoint(EmulatedEndpointConfig config) = 0;
+ // Enable emulated endpoint to make it available for webrtc.
+ // Caller mustn't enable currently enabled endpoint.
+ virtual void EnableEndpoint(EmulatedEndpoint* endpoint) = 0;
+ // Disable emulated endpoint to make it unavailable for webrtc.
+ // Caller mustn't disable currently disabled endpoint.
+ virtual void DisableEndpoint(EmulatedEndpoint* endpoint) = 0;
+
+ // Creates a route between endpoints going through specified network nodes.
+ // This route is single direction only and describe how traffic that was
+ // sent by network interface `from` have to be delivered to the network
+ // interface `to`. Return object can be used to remove created route. The
+ // route must contains at least one network node inside it.
+ //
+ // Assume that E{0-9} are endpoints and N{0-9} are network nodes, then
+ // creation of the route have to follow these rules:
+ // 1. A route consists of a source endpoint, an ordered list of one or
+ // more network nodes, and a destination endpoint.
+ // 2. If (E1, ..., E2) is a route, then E1 != E2.
+ // In other words, the source and the destination may not be the same.
+ // 3. Given two simultaneously existing routes (E1, ..., E2) and
+ // (E3, ..., E4), either E1 != E3 or E2 != E4.
+ // In other words, there may be at most one route from any given source
+ // endpoint to any given destination endpoint.
+ // 4. Given two simultaneously existing routes (E1, ..., N1, ..., E2)
+ // and (E3, ..., N2, ..., E4), either N1 != N2 or E2 != E4.
+ // In other words, a network node may not belong to two routes that lead
+ // to the same destination endpoint.
+ virtual EmulatedRoute* CreateRoute(
+ EmulatedEndpoint* from,
+ const std::vector<EmulatedNetworkNode*>& via_nodes,
+ EmulatedEndpoint* to) = 0;
+
+ // Creates a route over the given `via_nodes` creating the required endpoints
+ // in the process. The returned EmulatedRoute pointer can be used in other
+ // calls as a transport route for message or cross traffic.
+ virtual EmulatedRoute* CreateRoute(
+ const std::vector<EmulatedNetworkNode*>& via_nodes) = 0;
+
+ // Creates a default route between endpoints going through specified network
+ // nodes. Default route is used for packet when there is no known route for
+ // packet's destination IP.
+ //
+ // This route is single direction only and describe how traffic that was
+ // sent by network interface `from` have to be delivered in case if routing
+ // was unspecified. Return object can be used to remove created route. The
+ // route must contains at least one network node inside it.
+ //
+ // Assume that E{0-9} are endpoints and N{0-9} are network nodes, then
+ // creation of the route have to follow these rules:
+ // 1. A route consists of a source endpoint, an ordered list of one or
+ // more network nodes, and a destination endpoint.
+ // 2. If (E1, ..., E2) is a route, then E1 != E2.
+ // In other words, the source and the destination may not be the same.
+ // 3. Given two simultaneously existing routes (E1, ..., E2) and
+ // (E3, ..., E4), either E1 != E3 or E2 != E4.
+ // In other words, there may be at most one route from any given source
+ // endpoint to any given destination endpoint.
+ // 4. Given two simultaneously existing routes (E1, ..., N1, ..., E2)
+ // and (E3, ..., N2, ..., E4), either N1 != N2 or E2 != E4.
+ // In other words, a network node may not belong to two routes that lead
+ // to the same destination endpoint.
+ // 5. Any node N can belong to only one default route.
+ virtual EmulatedRoute* CreateDefaultRoute(
+ EmulatedEndpoint* from,
+ const std::vector<EmulatedNetworkNode*>& via_nodes,
+ EmulatedEndpoint* to) = 0;
+
+ // Removes route previously created by CreateRoute(...).
+ // Caller mustn't call this function with route, that have been already
+ // removed earlier. Removing a route that is currently in use will lead to
+ // packets being dropped.
+ virtual void ClearRoute(EmulatedRoute* route) = 0;
+
+ // Creates a simulated TCP connection using `send_route` for traffic and
+ // `ret_route` for feedback. This can be used to emulate HTTP cross traffic
+ // and to implement realistic reliable signaling over lossy networks.
+ // TODO(srte): Handle clearing of the routes involved.
+ virtual TcpMessageRoute* CreateTcpRoute(EmulatedRoute* send_route,
+ EmulatedRoute* ret_route) = 0;
+
+ // Creates a route over the given `via_nodes`. Returns an object that can be
+ // used to emulate network load with cross traffic over the created route.
+ virtual CrossTrafficRoute* CreateCrossTrafficRoute(
+ const std::vector<EmulatedNetworkNode*>& via_nodes) = 0;
+
+ // Starts generating cross traffic using given `generator`. Takes ownership
+ // over the generator.
+ virtual CrossTrafficGenerator* StartCrossTraffic(
+ std::unique_ptr<CrossTrafficGenerator> generator) = 0;
+
+ // Stops generating cross traffic that was started using given `generator`.
+ // The `generator` shouldn't be used after and the reference may be invalid.
+ virtual void StopCrossTraffic(CrossTrafficGenerator* generator) = 0;
+
+ // Creates EmulatedNetworkManagerInterface which can be used then to inject
+ // network emulation layer into PeerConnection. `endpoints` - are available
+ // network interfaces for PeerConnection. If endpoint is enabled, it will be
+ // immediately available for PeerConnection, otherwise user will be able to
+ // enable endpoint later to make it available for PeerConnection.
+ virtual EmulatedNetworkManagerInterface*
+ CreateEmulatedNetworkManagerInterface(
+ const std::vector<EmulatedEndpoint*>& endpoints) = 0;
+
+ // Passes combined network stats for all specified `endpoints` into specified
+ // `stats_callback`. Callback will be executed on network emulation
+ // internal task queue.
+ virtual void GetStats(
+ rtc::ArrayView<EmulatedEndpoint* const> endpoints,
+ std::function<void(EmulatedNetworkStats)> stats_callback) = 0;
+
+ // Passes combined network stats for all specified `nodes` into specified
+ // `stats_callback`. Callback will be executed on network emulation
+ // internal task queue.
+ virtual void GetStats(
+ rtc::ArrayView<EmulatedNetworkNode* const> nodes,
+ std::function<void(EmulatedNetworkNodeStats)> stats_callback) = 0;
+
+ // Create a EmulatedTURNServer.
+ // The TURN server has 2 endpoints that need to be connected with routes,
+ // - GetClientEndpoint() - the endpoint that accepts TURN allocations.
+ // - GetPeerEndpoint() - the endpoint that is "connected to the internet".
+ virtual EmulatedTURNServerInterface* CreateTURNServer(
+ EmulatedTURNServerConfig config) = 0;
+
+ // Create a pair of EmulatedNetworkManagerInterfaces connected to each other.
+ std::pair<EmulatedNetworkManagerInterface*, EmulatedNetworkManagerInterface*>
+ CreateEndpointPairWithTwoWayRoutes(
+ const BuiltInNetworkBehaviorConfig& config);
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_NETWORK_EMULATION_MANAGER_H_
diff --git a/third_party/libwebrtc/api/test/pclf/BUILD.gn b/third_party/libwebrtc/api/test/pclf/BUILD.gn
new file mode 100644
index 0000000000..0526478e8b
--- /dev/null
+++ b/third_party/libwebrtc/api/test/pclf/BUILD.gn
@@ -0,0 +1,114 @@
+# Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+
+rtc_source_set("media_configuration") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "media_configuration.cc",
+ "media_configuration.h",
+ ]
+
+ deps = [
+ "../..:array_view",
+ "../..:audio_options_api",
+ "../..:audio_quality_analyzer_api",
+ "../..:callfactory_api",
+ "../..:fec_controller_api",
+ "../..:frame_generator_api",
+ "../..:function_view",
+ "../..:libjingle_peerconnection_api",
+ "../..:media_stream_interface",
+ "../..:packet_socket_factory",
+ "../..:peer_network_dependencies",
+ "../..:rtp_parameters",
+ "../..:simulated_network_api",
+ "../..:stats_observer_interface",
+ "../..:track_id_stream_info_map",
+ "../..:video_quality_analyzer_api",
+ "../../../modules/audio_processing:api",
+ "../../../rtc_base:checks",
+ "../../../rtc_base:network",
+ "../../../rtc_base:rtc_certificate_generator",
+ "../../../rtc_base:ssl",
+ "../../../rtc_base:stringutils",
+ "../../../rtc_base:threading",
+ "../../../test:fileutils",
+ "../../../test:video_test_support",
+ "../../../test/pc/e2e/analyzer/video:video_dumping",
+ "../../audio:audio_mixer_api",
+ "../../rtc_event_log",
+ "../../task_queue",
+ "../../transport:network_control",
+ "../../units:time_delta",
+ "../../video_codecs:video_codecs_api",
+ "../video:video_frame_writer",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/memory",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
+rtc_library("media_quality_test_params") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "media_quality_test_params.h" ]
+
+ deps = [
+ ":media_configuration",
+ "../../../api:callfactory_api",
+ "../../../api:fec_controller_api",
+ "../../../api:field_trials_view",
+ "../../../api:libjingle_peerconnection_api",
+ "../../../api:packet_socket_factory",
+ "../../../api/audio:audio_mixer_api",
+ "../../../api/rtc_event_log",
+ "../../../api/task_queue",
+ "../../../api/transport:network_control",
+ "../../../api/video_codecs:video_codecs_api",
+ "../../../modules/audio_processing:api",
+ "../../../p2p:rtc_p2p",
+ "../../../rtc_base:network",
+ "../../../rtc_base:rtc_certificate_generator",
+ "../../../rtc_base:ssl",
+ "../../../rtc_base:threading",
+ ]
+}
+
+rtc_library("peer_configurer") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "peer_configurer.cc",
+ "peer_configurer.h",
+ ]
+ deps = [
+ ":media_configuration",
+ ":media_quality_test_params",
+ "../../../api:callfactory_api",
+ "../../../api:create_peer_connection_quality_test_frame_generator",
+ "../../../api:fec_controller_api",
+ "../../../api:packet_socket_factory",
+ "../../../api:peer_network_dependencies",
+ "../../../api/audio:audio_mixer_api",
+ "../../../api/rtc_event_log",
+ "../../../api/task_queue",
+ "../../../api/transport:network_control",
+ "../../../api/video_codecs:video_codecs_api",
+ "../../../modules/audio_processing:api",
+ "../../../rtc_base:network",
+ "../../../rtc_base:rtc_certificate_generator",
+ "../../../rtc_base:ssl",
+ "../../../rtc_base:threading",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
+}
diff --git a/third_party/libwebrtc/api/test/pclf/DEPS b/third_party/libwebrtc/api/test/pclf/DEPS
new file mode 100644
index 0000000000..60cc0aeeb3
--- /dev/null
+++ b/third_party/libwebrtc/api/test/pclf/DEPS
@@ -0,0 +1,13 @@
+specific_include_rules = {
+ ".*": [
+ "+modules/audio_processing/include/audio_processing.h",
+ "+rtc_base/checks.h",
+ "+rtc_base/network.h",
+ "+rtc_base/rtc_certificate_generator.h",
+ "+rtc_base/ssl_certificate.h",
+ "+rtc_base/thread.h",
+ ],
+ "media_quality_test_params\.h": [
+ "+p2p/base/port_allocator.h",
+ ],
+}
diff --git a/third_party/libwebrtc/api/test/pclf/media_configuration.cc b/third_party/libwebrtc/api/test/pclf/media_configuration.cc
new file mode 100644
index 0000000000..56b9e52e01
--- /dev/null
+++ b/third_party/libwebrtc/api/test/pclf/media_configuration.cc
@@ -0,0 +1,314 @@
+/*
+ * Copyright 2022 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/pclf/media_configuration.h"
+
+#include <string>
+#include <utility>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/test/video/video_frame_writer.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/strings/string_builder.h"
+#include "test/pc/e2e/analyzer/video/video_dumping.h"
+#include "test/testsupport/file_utils.h"
+#include "test/testsupport/video_frame_writer.h"
+
+namespace webrtc {
+namespace webrtc_pc_e2e {
+namespace {
+
+std::string SpecToString(VideoResolution::Spec spec) {
+ switch (spec) {
+ case VideoResolution::Spec::kNone:
+ return "None";
+ case VideoResolution::Spec::kMaxFromSender:
+ return "MaxFromSender";
+ }
+}
+
+void AppendResolution(const VideoResolution& resolution,
+ rtc::StringBuilder& builder) {
+ builder << "_" << resolution.width() << "x" << resolution.height() << "_"
+ << resolution.fps();
+}
+
+} // namespace
+
+ScreenShareConfig::ScreenShareConfig(TimeDelta slide_change_interval)
+ : slide_change_interval(slide_change_interval) {
+ RTC_CHECK_GT(slide_change_interval.ms(), 0);
+}
+VideoSimulcastConfig::VideoSimulcastConfig(int simulcast_streams_count)
+ : simulcast_streams_count(simulcast_streams_count) {
+ RTC_CHECK_GT(simulcast_streams_count, 1);
+}
+EmulatedSFUConfig::EmulatedSFUConfig(int target_layer_index)
+ : target_layer_index(target_layer_index) {
+ RTC_CHECK_GE(target_layer_index, 0);
+}
+
+EmulatedSFUConfig::EmulatedSFUConfig(absl::optional<int> target_layer_index,
+ absl::optional<int> target_temporal_index)
+ : target_layer_index(target_layer_index),
+ target_temporal_index(target_temporal_index) {
+ RTC_CHECK_GE(target_temporal_index.value_or(0), 0);
+ if (target_temporal_index)
+ RTC_CHECK_GE(*target_temporal_index, 0);
+}
+
+VideoResolution::VideoResolution(size_t width, size_t height, int32_t fps)
+ : width_(width), height_(height), fps_(fps), spec_(Spec::kNone) {}
+VideoResolution::VideoResolution(Spec spec)
+ : width_(0), height_(0), fps_(0), spec_(spec) {}
+
+bool VideoResolution::operator==(const VideoResolution& other) const {
+ if (spec_ != Spec::kNone && spec_ == other.spec_) {
+ // If there is some particular spec set, then it doesn't matter what
+ // values we have in other fields.
+ return true;
+ }
+ return width_ == other.width_ && height_ == other.height_ &&
+ fps_ == other.fps_ && spec_ == other.spec_;
+}
+bool VideoResolution::operator!=(const VideoResolution& other) const {
+ return !(*this == other);
+}
+
+bool VideoResolution::IsRegular() const {
+ return spec_ == Spec::kNone;
+}
+std::string VideoResolution::ToString() const {
+ rtc::StringBuilder out;
+ out << "{ width=" << width_ << ", height=" << height_ << ", fps=" << fps_
+ << ", spec=" << SpecToString(spec_) << " }";
+ return out.Release();
+}
+
+VideoDumpOptions::VideoDumpOptions(
+ absl::string_view output_directory,
+ int sampling_modulo,
+ bool export_frame_ids,
+ std::function<std::unique_ptr<test::VideoFrameWriter>(
+ absl::string_view file_name_prefix,
+ const VideoResolution& resolution)> video_frame_writer_factory)
+ : output_directory_(output_directory),
+ sampling_modulo_(sampling_modulo),
+ export_frame_ids_(export_frame_ids),
+ video_frame_writer_factory_(video_frame_writer_factory) {
+ RTC_CHECK_GT(sampling_modulo, 0);
+}
+
+VideoDumpOptions::VideoDumpOptions(absl::string_view output_directory,
+ bool export_frame_ids)
+ : VideoDumpOptions(output_directory,
+ kDefaultSamplingModulo,
+ export_frame_ids) {}
+
+std::unique_ptr<test::VideoFrameWriter>
+VideoDumpOptions::CreateInputDumpVideoFrameWriter(
+ absl::string_view stream_label,
+ const VideoResolution& resolution) const {
+ std::unique_ptr<test::VideoFrameWriter> writer = video_frame_writer_factory_(
+ GetInputDumpFileName(stream_label, resolution), resolution);
+ absl::optional<std::string> frame_ids_file =
+ GetInputFrameIdsDumpFileName(stream_label, resolution);
+ if (frame_ids_file.has_value()) {
+ writer = CreateVideoFrameWithIdsWriter(std::move(writer), *frame_ids_file);
+ }
+ return writer;
+}
+
+std::unique_ptr<test::VideoFrameWriter>
+VideoDumpOptions::CreateOutputDumpVideoFrameWriter(
+ absl::string_view stream_label,
+ absl::string_view receiver,
+ const VideoResolution& resolution) const {
+ std::unique_ptr<test::VideoFrameWriter> writer = video_frame_writer_factory_(
+ GetOutputDumpFileName(stream_label, receiver, resolution), resolution);
+ absl::optional<std::string> frame_ids_file =
+ GetOutputFrameIdsDumpFileName(stream_label, receiver, resolution);
+ if (frame_ids_file.has_value()) {
+ writer = CreateVideoFrameWithIdsWriter(std::move(writer), *frame_ids_file);
+ }
+ return writer;
+}
+
+std::unique_ptr<test::VideoFrameWriter>
+VideoDumpOptions::Y4mVideoFrameWriterFactory(
+ absl::string_view file_name_prefix,
+ const VideoResolution& resolution) {
+ return std::make_unique<test::Y4mVideoFrameWriterImpl>(
+ std::string(file_name_prefix) + ".y4m", resolution.width(),
+ resolution.height(), resolution.fps());
+}
+
+std::string VideoDumpOptions::GetInputDumpFileName(
+ absl::string_view stream_label,
+ const VideoResolution& resolution) const {
+ rtc::StringBuilder file_name;
+ file_name << stream_label;
+ AppendResolution(resolution, file_name);
+ return test::JoinFilename(output_directory_, file_name.Release());
+}
+
+absl::optional<std::string> VideoDumpOptions::GetInputFrameIdsDumpFileName(
+ absl::string_view stream_label,
+ const VideoResolution& resolution) const {
+ if (!export_frame_ids_) {
+ return absl::nullopt;
+ }
+ return GetInputDumpFileName(stream_label, resolution) + ".frame_ids.txt";
+}
+
+std::string VideoDumpOptions::GetOutputDumpFileName(
+ absl::string_view stream_label,
+ absl::string_view receiver,
+ const VideoResolution& resolution) const {
+ rtc::StringBuilder file_name;
+ file_name << stream_label << "_" << receiver;
+ AppendResolution(resolution, file_name);
+ return test::JoinFilename(output_directory_, file_name.Release());
+}
+
+absl::optional<std::string> VideoDumpOptions::GetOutputFrameIdsDumpFileName(
+ absl::string_view stream_label,
+ absl::string_view receiver,
+ const VideoResolution& resolution) const {
+ if (!export_frame_ids_) {
+ return absl::nullopt;
+ }
+ return GetOutputDumpFileName(stream_label, receiver, resolution) +
+ ".frame_ids.txt";
+}
+
+std::string VideoDumpOptions::ToString() const {
+ rtc::StringBuilder out;
+ out << "{ output_directory_=" << output_directory_
+ << ", sampling_modulo_=" << sampling_modulo_
+ << ", export_frame_ids_=" << export_frame_ids_ << " }";
+ return out.Release();
+}
+
+VideoConfig::VideoConfig(const VideoResolution& resolution)
+ : width(resolution.width()),
+ height(resolution.height()),
+ fps(resolution.fps()) {
+ RTC_CHECK(resolution.IsRegular());
+}
+VideoConfig::VideoConfig(size_t width, size_t height, int32_t fps)
+ : width(width), height(height), fps(fps) {}
+VideoConfig::VideoConfig(std::string stream_label,
+ size_t width,
+ size_t height,
+ int32_t fps)
+ : width(width),
+ height(height),
+ fps(fps),
+ stream_label(std::move(stream_label)) {}
+
+AudioConfig::AudioConfig(std::string stream_label)
+ : stream_label(std::move(stream_label)) {}
+
+VideoCodecConfig::VideoCodecConfig(std::string name)
+ : name(std::move(name)), required_params() {}
+VideoCodecConfig::VideoCodecConfig(
+ std::string name,
+ std::map<std::string, std::string> required_params)
+ : name(std::move(name)), required_params(std::move(required_params)) {}
+
+absl::optional<VideoResolution> VideoSubscription::GetMaxResolution(
+ rtc::ArrayView<const VideoConfig> video_configs) {
+ std::vector<VideoResolution> resolutions;
+ for (const auto& video_config : video_configs) {
+ resolutions.push_back(video_config.GetResolution());
+ }
+ return GetMaxResolution(resolutions);
+}
+
+absl::optional<VideoResolution> VideoSubscription::GetMaxResolution(
+ rtc::ArrayView<const VideoResolution> resolutions) {
+ if (resolutions.empty()) {
+ return absl::nullopt;
+ }
+
+ VideoResolution max_resolution;
+ for (const VideoResolution& resolution : resolutions) {
+ if (max_resolution.width() < resolution.width()) {
+ max_resolution.set_width(resolution.width());
+ }
+ if (max_resolution.height() < resolution.height()) {
+ max_resolution.set_height(resolution.height());
+ }
+ if (max_resolution.fps() < resolution.fps()) {
+ max_resolution.set_fps(resolution.fps());
+ }
+ }
+ return max_resolution;
+}
+
+bool VideoSubscription::operator==(const VideoSubscription& other) const {
+ return default_resolution_ == other.default_resolution_ &&
+ peers_resolution_ == other.peers_resolution_;
+}
+bool VideoSubscription::operator!=(const VideoSubscription& other) const {
+ return !(*this == other);
+}
+
+VideoSubscription& VideoSubscription::SubscribeToPeer(
+ absl::string_view peer_name,
+ VideoResolution resolution) {
+ peers_resolution_[std::string(peer_name)] = resolution;
+ return *this;
+}
+
+VideoSubscription& VideoSubscription::SubscribeToAllPeers(
+ VideoResolution resolution) {
+ default_resolution_ = resolution;
+ return *this;
+}
+
+absl::optional<VideoResolution> VideoSubscription::GetResolutionForPeer(
+ absl::string_view peer_name) const {
+ auto it = peers_resolution_.find(std::string(peer_name));
+ if (it == peers_resolution_.end()) {
+ return default_resolution_;
+ }
+ return it->second;
+}
+
+std::vector<std::string> VideoSubscription::GetSubscribedPeers() const {
+ std::vector<std::string> subscribed_streams;
+ subscribed_streams.reserve(peers_resolution_.size());
+ for (const auto& entry : peers_resolution_) {
+ subscribed_streams.push_back(entry.first);
+ }
+ return subscribed_streams;
+}
+
+std::string VideoSubscription::ToString() const {
+ rtc::StringBuilder out;
+ out << "{ default_resolution_=[";
+ if (default_resolution_.has_value()) {
+ out << default_resolution_->ToString();
+ } else {
+ out << "undefined";
+ }
+ out << "], {";
+ for (const auto& [peer_name, resolution] : peers_resolution_) {
+ out << "[" << peer_name << ": " << resolution.ToString() << "], ";
+ }
+ out << "} }";
+ return out.Release();
+}
+} // namespace webrtc_pc_e2e
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/pclf/media_configuration.h b/third_party/libwebrtc/api/test/pclf/media_configuration.h
new file mode 100644
index 0000000000..8e841a265b
--- /dev/null
+++ b/third_party/libwebrtc/api/test/pclf/media_configuration.h
@@ -0,0 +1,484 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_TEST_PCLF_MEDIA_CONFIGURATION_H_
+#define API_TEST_PCLF_MEDIA_CONFIGURATION_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/async_resolver_factory.h"
+#include "api/audio/audio_mixer.h"
+#include "api/audio_options.h"
+#include "api/call/call_factory_interface.h"
+#include "api/fec_controller.h"
+#include "api/function_view.h"
+#include "api/media_stream_interface.h"
+#include "api/peer_connection_interface.h"
+#include "api/rtc_event_log/rtc_event_log_factory_interface.h"
+#include "api/rtp_parameters.h"
+#include "api/task_queue/task_queue_factory.h"
+#include "api/test/audio_quality_analyzer_interface.h"
+#include "api/test/frame_generator_interface.h"
+#include "api/test/peer_network_dependencies.h"
+#include "api/test/simulated_network.h"
+#include "api/test/stats_observer_interface.h"
+#include "api/test/track_id_stream_info_map.h"
+#include "api/test/video/video_frame_writer.h"
+#include "api/test/video_quality_analyzer_interface.h"
+#include "api/transport/network_control.h"
+#include "api/units/time_delta.h"
+#include "api/video_codecs/video_decoder_factory.h"
+#include "api/video_codecs/video_encoder.h"
+#include "api/video_codecs/video_encoder_factory.h"
+#include "modules/audio_processing/include/audio_processing.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/network.h"
+#include "rtc_base/rtc_certificate_generator.h"
+#include "rtc_base/ssl_certificate.h"
+#include "rtc_base/thread.h"
+
+namespace webrtc {
+namespace webrtc_pc_e2e {
+
+constexpr size_t kDefaultSlidesWidth = 1850;
+constexpr size_t kDefaultSlidesHeight = 1110;
+
+// The index of required capturing device in OS provided list of video
+// devices. On Linux and Windows the list will be obtained via
+// webrtc::VideoCaptureModule::DeviceInfo, on Mac OS via
+// [RTCCameraVideoCapturer captureDevices].
+enum class CapturingDeviceIndex : size_t {};
+
+// Contains parameters for screen share scrolling.
+//
+// If scrolling is enabled, then it will be done by putting sliding window
+// on source video and moving this window from top left corner to the
+// bottom right corner of the picture.
+//
+// In such case source dimensions must be greater or equal to the sliding
+// window dimensions. So `source_width` and `source_height` are the dimensions
+// of the source frame, while `VideoConfig::width` and `VideoConfig::height`
+// are the dimensions of the sliding window.
+//
+// Because `source_width` and `source_height` are dimensions of the source
+// frame, they have to be width and height of videos from
+// `ScreenShareConfig::slides_yuv_file_names`.
+//
+// Because scrolling have to be done on single slide it also requires, that
+// `duration` must be less or equal to
+// `ScreenShareConfig::slide_change_interval`.
+struct ScrollingParams {
+ // Duration of scrolling.
+ TimeDelta duration;
+ // Width of source slides video.
+ size_t source_width = kDefaultSlidesWidth;
+ // Height of source slides video.
+ size_t source_height = kDefaultSlidesHeight;
+};
+
+// Contains screen share video stream properties.
+struct ScreenShareConfig {
+ explicit ScreenShareConfig(TimeDelta slide_change_interval);
+
+ // Shows how long one slide should be presented on the screen during
+ // slide generation.
+ TimeDelta slide_change_interval;
+ // If true, slides will be generated programmatically. No scrolling params
+ // will be applied in such case.
+ bool generate_slides = false;
+ // If present scrolling will be applied. Please read extra requirement on
+ // `slides_yuv_file_names` for scrolling.
+ absl::optional<ScrollingParams> scrolling_params;
+ // Contains list of yuv files with slides.
+ //
+ // If empty, default set of slides will be used. In such case
+ // `VideoConfig::width` must be equal to `kDefaultSlidesWidth` and
+ // `VideoConfig::height` must be equal to `kDefaultSlidesHeight` or if
+ // `scrolling_params` are specified, then `ScrollingParams::source_width`
+ // must be equal to `kDefaultSlidesWidth` and
+ // `ScrollingParams::source_height` must be equal to `kDefaultSlidesHeight`.
+ std::vector<std::string> slides_yuv_file_names;
+};
+
+// Config for Vp8 simulcast or non-standard Vp9 SVC testing.
+//
+// To configure standard SVC setting, use `scalability_mode` in the
+// `encoding_params` array.
+// This configures Vp9 SVC by requesting simulcast layers, the request is
+// internally converted to a request for SVC layers.
+//
+// SVC support is limited:
+// During SVC testing there is no SFU, so framework will try to emulate SFU
+// behavior in regular p2p call. Because of it there are such limitations:
+// * if `target_spatial_index` is not equal to the highest spatial layer
+// then no packet/frame drops are allowed.
+//
+// If there will be any drops, that will affect requested layer, then
+// WebRTC SVC implementation will continue decoding only the highest
+// available layer and won't restore lower layers, so analyzer won't
+// receive required data which will cause wrong results or test failures.
+struct VideoSimulcastConfig {
+ explicit VideoSimulcastConfig(int simulcast_streams_count);
+
+ // Specified amount of simulcast streams/SVC layers, depending on which
+ // encoder is used.
+ int simulcast_streams_count;
+};
+
+// Configuration for the emulated Selective Forward Unit (SFU)
+//
+// The framework can optionally filter out frames that are decoded
+// using an emulated SFU.
+// When using simulcast or SVC, it's not always desirable to receive
+// all frames. In a real world call, a SFU will only forward a subset
+// of the frames.
+// The emulated SFU is not able to change its configuration dynamically,
+// if adaptation happens during the call, layers may be dropped and the
+// analyzer won't receive the required data which will cause wrong results or
+// test failures.
+struct EmulatedSFUConfig {
+ EmulatedSFUConfig() = default;
+ explicit EmulatedSFUConfig(int target_layer_index);
+ EmulatedSFUConfig(absl::optional<int> target_layer_index,
+ absl::optional<int> target_temporal_index);
+
+ // Specifies simulcast or spatial index of the video stream to analyze.
+ // There are 2 cases:
+ // 1. simulcast encoding is used:
+ // in such case `target_layer_index` will specify the index of
+ // simulcast stream, that should be analyzed. Other streams will be
+ // dropped.
+ // 2. SVC encoding is used:
+ // in such case `target_layer_index` will specify the top interesting
+ // spatial layer and all layers below, including target one will be
+ // processed. All layers above target one will be dropped.
+ // If not specified then all streams will be received and analyzed.
+ // When set, it instructs the framework to create an emulated Selective
+ // Forwarding Unit (SFU) that will propagate only the requested layers.
+ absl::optional<int> target_layer_index;
+ // Specifies the index of the maximum temporal unit to keep.
+ // If not specified then all temporal layers will be received and analyzed.
+ // When set, it instructs the framework to create an emulated Selective
+ // Forwarding Unit (SFU) that will propagate only up to the requested layer.
+ absl::optional<int> target_temporal_index;
+};
+
+class VideoResolution {
+ public:
+ // Determines special resolutions, which can't be expressed in terms of
+ // width, height and fps.
+ enum class Spec {
+ // No extra spec set. It describes a regular resolution described by
+ // width, height and fps.
+ kNone,
+ // Describes resolution which contains max value among all sender's
+ // video streams in each dimension (width, height, fps).
+ kMaxFromSender
+ };
+
+ VideoResolution(size_t width, size_t height, int32_t fps);
+ explicit VideoResolution(Spec spec = Spec::kNone);
+
+ bool operator==(const VideoResolution& other) const;
+ bool operator!=(const VideoResolution& other) const;
+
+ size_t width() const { return width_; }
+ void set_width(size_t width) { width_ = width; }
+ size_t height() const { return height_; }
+ void set_height(size_t height) { height_ = height; }
+ int32_t fps() const { return fps_; }
+ void set_fps(int32_t fps) { fps_ = fps; }
+
+ // Returns if it is a regular resolution or not. The resolution is regular
+ // if it's spec is `Spec::kNone`.
+ bool IsRegular() const;
+
+ std::string ToString() const;
+
+ private:
+ size_t width_ = 0;
+ size_t height_ = 0;
+ int32_t fps_ = 0;
+ Spec spec_ = Spec::kNone;
+};
+
+class VideoDumpOptions {
+ public:
+ static constexpr int kDefaultSamplingModulo = 1;
+
+ // output_directory - the output directory where stream will be dumped. The
+ // output files' names will be constructed as
+ // <stream_name>_<receiver_name>_<resolution>.<extension> for output dumps
+ // and <stream_name>_<resolution>.<extension> for input dumps.
+ // By default <extension> is "y4m". Resolution is in the format
+ // <width>x<height>_<fps>.
+ // sampling_modulo - the module for the video frames to be dumped. Modulo
+ // equals X means every Xth frame will be written to the dump file. The
+ // value must be greater than 0. (Default: 1)
+ // export_frame_ids - specifies if frame ids should be exported together
+ // with content of the stream. If true, an output file with the same name as
+ // video dump and suffix ".frame_ids.txt" will be created. It will contain
+ // the frame ids in the same order as original frames in the output
+ // file with stream content. File will contain one frame id per line.
+ // (Default: false)
+ // `video_frame_writer_factory` - factory function to create a video frame
+ // writer for input and output video files. (Default: Y4M video writer
+ // factory).
+ explicit VideoDumpOptions(
+ absl::string_view output_directory,
+ int sampling_modulo = kDefaultSamplingModulo,
+ bool export_frame_ids = false,
+ std::function<std::unique_ptr<test::VideoFrameWriter>(
+ absl::string_view file_name_prefix,
+ const VideoResolution& resolution)> video_frame_writer_factory =
+ Y4mVideoFrameWriterFactory);
+ VideoDumpOptions(absl::string_view output_directory, bool export_frame_ids);
+
+ VideoDumpOptions(const VideoDumpOptions&) = default;
+ VideoDumpOptions& operator=(const VideoDumpOptions&) = default;
+ VideoDumpOptions(VideoDumpOptions&&) = default;
+ VideoDumpOptions& operator=(VideoDumpOptions&&) = default;
+
+ std::string output_directory() const { return output_directory_; }
+ int sampling_modulo() const { return sampling_modulo_; }
+ bool export_frame_ids() const { return export_frame_ids_; }
+
+ std::unique_ptr<test::VideoFrameWriter> CreateInputDumpVideoFrameWriter(
+ absl::string_view stream_label,
+ const VideoResolution& resolution) const;
+
+ std::unique_ptr<test::VideoFrameWriter> CreateOutputDumpVideoFrameWriter(
+ absl::string_view stream_label,
+ absl::string_view receiver,
+ const VideoResolution& resolution) const;
+
+ std::string ToString() const;
+
+ private:
+ static std::unique_ptr<test::VideoFrameWriter> Y4mVideoFrameWriterFactory(
+ absl::string_view file_name_prefix,
+ const VideoResolution& resolution);
+ std::string GetInputDumpFileName(absl::string_view stream_label,
+ const VideoResolution& resolution) const;
+ // Returns file name for input frame ids dump if `export_frame_ids()` is
+ // true, absl::nullopt otherwise.
+ absl::optional<std::string> GetInputFrameIdsDumpFileName(
+ absl::string_view stream_label,
+ const VideoResolution& resolution) const;
+ std::string GetOutputDumpFileName(absl::string_view stream_label,
+ absl::string_view receiver,
+ const VideoResolution& resolution) const;
+ // Returns file name for output frame ids dump if `export_frame_ids()` is
+ // true, absl::nullopt otherwise.
+ absl::optional<std::string> GetOutputFrameIdsDumpFileName(
+ absl::string_view stream_label,
+ absl::string_view receiver,
+ const VideoResolution& resolution) const;
+
+ std::string output_directory_;
+ int sampling_modulo_ = 1;
+ bool export_frame_ids_ = false;
+ std::function<std::unique_ptr<test::VideoFrameWriter>(
+ absl::string_view file_name_prefix,
+ const VideoResolution& resolution)>
+ video_frame_writer_factory_;
+};
+
+// Contains properties of single video stream.
+struct VideoConfig {
+ explicit VideoConfig(const VideoResolution& resolution);
+ VideoConfig(size_t width, size_t height, int32_t fps);
+ VideoConfig(std::string stream_label,
+ size_t width,
+ size_t height,
+ int32_t fps);
+
+ // Video stream width.
+ size_t width;
+ // Video stream height.
+ size_t height;
+ int32_t fps;
+ VideoResolution GetResolution() const {
+ return VideoResolution(width, height, fps);
+ }
+
+ // Have to be unique among all specified configs for all peers in the call.
+ // Will be auto generated if omitted.
+ absl::optional<std::string> stream_label;
+ // Will be set for current video track. If equals to kText or kDetailed -
+ // screencast in on.
+ absl::optional<VideoTrackInterface::ContentHint> content_hint;
+ // If presented video will be transfered in simulcast/SVC mode depending on
+ // which encoder is used.
+ //
+ // Simulcast is supported only from 1st added peer. For VP8 simulcast only
+ // without RTX is supported so it will be automatically disabled for all
+ // simulcast tracks. For VP9 simulcast enables VP9 SVC mode and support RTX,
+ // but only on non-lossy networks. See more in documentation to
+ // VideoSimulcastConfig.
+ absl::optional<VideoSimulcastConfig> simulcast_config;
+ // Configuration for the emulated Selective Forward Unit (SFU).
+ absl::optional<EmulatedSFUConfig> emulated_sfu_config;
+ // Encoding parameters for both singlecast and per simulcast layer.
+ // If singlecast is used, if not empty, a single value can be provided.
+ // If simulcast is used, if not empty, `encoding_params` size have to be
+ // equal to `simulcast_config.simulcast_streams_count`. Will be used to set
+ // transceiver send encoding params for each layer.
+ // RtpEncodingParameters::rid may be changed by fixture implementation to
+ // ensure signaling correctness.
+ std::vector<RtpEncodingParameters> encoding_params;
+ // Count of temporal layers for video stream. This value will be set into
+ // each RtpEncodingParameters of RtpParameters of corresponding
+ // RtpSenderInterface for this video stream.
+ absl::optional<int> temporal_layers_count;
+ // If specified defines how input should be dumped. It is actually one of
+ // the test's output file, which contains copy of what was captured during
+ // the test for this video stream on sender side. It is useful when
+ // generator is used as input.
+ absl::optional<VideoDumpOptions> input_dump_options;
+ // If specified defines how output should be dumped on the receiver side for
+ // this stream. The produced files contain what was rendered for this video
+ // stream on receiver side per each receiver.
+ absl::optional<VideoDumpOptions> output_dump_options;
+ // If set to true uses fixed frame rate while dumping output video to the
+ // file. Requested `VideoSubscription::fps()` will be used as frame rate.
+ bool output_dump_use_fixed_framerate = false;
+ // If true will display input and output video on the user's screen.
+ bool show_on_screen = false;
+ // If specified, determines a sync group to which this video stream belongs.
+ // According to bugs.webrtc.org/4762 WebRTC supports synchronization only
+ // for pair of single audio and single video stream.
+ absl::optional<std::string> sync_group;
+ // If specified, it will be set into RtpParameters of corresponding
+ // RtpSenderInterface for this video stream.
+ // Note that this setting takes precedence over `content_hint`.
+ absl::optional<DegradationPreference> degradation_preference;
+};
+
+// Contains properties for audio in the call.
+struct AudioConfig {
+ enum Mode {
+ kGenerated,
+ kFile,
+ };
+
+ AudioConfig() = default;
+ explicit AudioConfig(std::string stream_label);
+
+ // Have to be unique among all specified configs for all peers in the call.
+ // Will be auto generated if omitted.
+ absl::optional<std::string> stream_label;
+ Mode mode = kGenerated;
+ // Have to be specified only if mode = kFile
+ absl::optional<std::string> input_file_name;
+ // If specified the input stream will be also copied to specified file.
+ absl::optional<std::string> input_dump_file_name;
+ // If specified the output stream will be copied to specified file.
+ absl::optional<std::string> output_dump_file_name;
+
+ // Audio options to use.
+ cricket::AudioOptions audio_options;
+ // Sampling frequency of input audio data (from file or generated).
+ int sampling_frequency_in_hz = 48000;
+ // If specified, determines a sync group to which this audio stream belongs.
+ // According to bugs.webrtc.org/4762 WebRTC supports synchronization only
+ // for pair of single audio and single video stream.
+ absl::optional<std::string> sync_group;
+};
+
+struct VideoCodecConfig {
+ explicit VideoCodecConfig(std::string name);
+ VideoCodecConfig(std::string name,
+ std::map<std::string, std::string> required_params);
+ // Next two fields are used to specify concrete video codec, that should be
+ // used in the test. Video code will be negotiated in SDP during offer/
+ // answer exchange.
+ // Video codec name. You can find valid names in
+ // media/base/media_constants.h
+ std::string name;
+ // Map of parameters, that have to be specified on SDP codec. Each parameter
+ // is described by key and value. Codec parameters will match the specified
+ // map if and only if for each key from `required_params` there will be
+ // a parameter with name equal to this key and parameter value will be equal
+ // to the value from `required_params` for this key.
+ // If empty then only name will be used to match the codec.
+ std::map<std::string, std::string> required_params;
+};
+
+// Subscription to the remote video streams. It declares which remote stream
+// peer should receive and in which resolution (width x height x fps).
+class VideoSubscription {
+ public:
+ // Returns the resolution constructed as maximum from all resolution
+ // dimensions: width, height and fps.
+ static absl::optional<VideoResolution> GetMaxResolution(
+ rtc::ArrayView<const VideoConfig> video_configs);
+ static absl::optional<VideoResolution> GetMaxResolution(
+ rtc::ArrayView<const VideoResolution> resolutions);
+
+ bool operator==(const VideoSubscription& other) const;
+ bool operator!=(const VideoSubscription& other) const;
+
+ // Subscribes receiver to all streams sent by the specified peer with
+ // specified resolution. It will override any resolution that was used in
+ // `SubscribeToAll` independently from methods call order.
+ VideoSubscription& SubscribeToPeer(
+ absl::string_view peer_name,
+ VideoResolution resolution =
+ VideoResolution(VideoResolution::Spec::kMaxFromSender));
+
+ // Subscribes receiver to the all sent streams with specified resolution.
+ // If any stream was subscribed to with `SubscribeTo` method that will
+ // override resolution passed to this function independently from methods
+ // call order.
+ VideoSubscription& SubscribeToAllPeers(
+ VideoResolution resolution =
+ VideoResolution(VideoResolution::Spec::kMaxFromSender));
+
+ // Returns resolution for specific sender. If no specific resolution was
+ // set for this sender, then will return resolution used for all streams.
+ // If subscription doesn't subscribe to all streams, `absl::nullopt` will be
+ // returned.
+ absl::optional<VideoResolution> GetResolutionForPeer(
+ absl::string_view peer_name) const;
+
+ // Returns a maybe empty list of senders for which peer explicitly
+ // subscribed to with specific resolution.
+ std::vector<std::string> GetSubscribedPeers() const;
+
+ std::string ToString() const;
+
+ private:
+ absl::optional<VideoResolution> default_resolution_ = absl::nullopt;
+ std::map<std::string, VideoResolution> peers_resolution_;
+};
+
+// Contains configuration for echo emulator.
+struct EchoEmulationConfig {
+ // Delay which represents the echo path delay, i.e. how soon rendered signal
+ // should reach capturer.
+ TimeDelta echo_delay = TimeDelta::Millis(50);
+};
+
+} // namespace webrtc_pc_e2e
+} // namespace webrtc
+
+#endif // API_TEST_PCLF_MEDIA_CONFIGURATION_H_
diff --git a/third_party/libwebrtc/api/test/pclf/media_quality_test_params.h b/third_party/libwebrtc/api/test/pclf/media_quality_test_params.h
new file mode 100644
index 0000000000..3377d31f68
--- /dev/null
+++ b/third_party/libwebrtc/api/test/pclf/media_quality_test_params.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_TEST_PCLF_MEDIA_QUALITY_TEST_PARAMS_H_
+#define API_TEST_PCLF_MEDIA_QUALITY_TEST_PARAMS_H_
+
+#include <cstddef>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "api/async_resolver_factory.h"
+#include "api/audio/audio_mixer.h"
+#include "api/call/call_factory_interface.h"
+#include "api/fec_controller.h"
+#include "api/field_trials_view.h"
+#include "api/rtc_event_log/rtc_event_log_factory_interface.h"
+#include "api/task_queue/task_queue_factory.h"
+#include "api/test/pclf/media_configuration.h"
+#include "api/transport/network_control.h"
+#include "api/video_codecs/video_decoder_factory.h"
+#include "api/video_codecs/video_encoder_factory.h"
+#include "modules/audio_processing/include/audio_processing.h"
+#include "p2p/base/port_allocator.h"
+#include "rtc_base/network.h"
+#include "rtc_base/rtc_certificate_generator.h"
+#include "rtc_base/ssl_certificate.h"
+#include "rtc_base/thread.h"
+
+namespace webrtc {
+namespace webrtc_pc_e2e {
+
+// Contains most part from PeerConnectionFactoryDependencies. Also all fields
+// are optional and defaults will be provided by fixture implementation if
+// any will be omitted.
+//
+// Separate class was introduced to clarify which components can be
+// overridden. For example worker and signaling threads will be provided by
+// fixture implementation. The same is applicable to the media engine. So user
+// can override only some parts of media engine like video encoder/decoder
+// factories.
+struct PeerConnectionFactoryComponents {
+ std::unique_ptr<TaskQueueFactory> task_queue_factory;
+ std::unique_ptr<CallFactoryInterface> call_factory;
+ std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory;
+ std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory;
+ std::unique_ptr<NetworkControllerFactoryInterface> network_controller_factory;
+ std::unique_ptr<NetEqFactory> neteq_factory;
+
+ // Will be passed to MediaEngineInterface, that will be used in
+ // PeerConnectionFactory.
+ std::unique_ptr<VideoEncoderFactory> video_encoder_factory;
+ std::unique_ptr<VideoDecoderFactory> video_decoder_factory;
+
+ std::unique_ptr<FieldTrialsView> trials;
+
+ rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing;
+ rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer;
+};
+
+// Contains most parts from PeerConnectionDependencies. Also all fields are
+// optional and defaults will be provided by fixture implementation if any
+// will be omitted.
+//
+// Separate class was introduced to clarify which components can be
+// overridden. For example observer, which is required to
+// PeerConnectionDependencies, will be provided by fixture implementation,
+// so client can't inject its own. Also only network manager can be overridden
+// inside port allocator.
+struct PeerConnectionComponents {
+ PeerConnectionComponents(rtc::NetworkManager* network_manager,
+ rtc::PacketSocketFactory* packet_socket_factory)
+ : network_manager(network_manager),
+ packet_socket_factory(packet_socket_factory) {
+ RTC_CHECK(network_manager);
+ }
+
+ rtc::NetworkManager* const network_manager;
+ rtc::PacketSocketFactory* const packet_socket_factory;
+ std::unique_ptr<webrtc::AsyncResolverFactory> async_resolver_factory;
+ std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator;
+ std::unique_ptr<rtc::SSLCertificateVerifier> tls_cert_verifier;
+ std::unique_ptr<IceTransportFactory> ice_transport_factory;
+};
+
+// Contains all components, that can be overridden in peer connection. Also
+// has a network thread, that will be used to communicate with another peers.
+struct InjectableComponents {
+ InjectableComponents(rtc::Thread* network_thread,
+ rtc::NetworkManager* network_manager,
+ rtc::PacketSocketFactory* packet_socket_factory)
+ : network_thread(network_thread),
+ worker_thread(nullptr),
+ pcf_dependencies(std::make_unique<PeerConnectionFactoryComponents>()),
+ pc_dependencies(
+ std::make_unique<PeerConnectionComponents>(network_manager,
+ packet_socket_factory)) {
+ RTC_CHECK(network_thread);
+ }
+
+ rtc::Thread* const network_thread;
+ rtc::Thread* worker_thread;
+
+ std::unique_ptr<PeerConnectionFactoryComponents> pcf_dependencies;
+ std::unique_ptr<PeerConnectionComponents> pc_dependencies;
+};
+
+// Contains information about call media streams (up to 1 audio stream and
+// unlimited amount of video streams) and rtc configuration, that will be used
+// to set up peer connection.
+struct Params {
+ // Peer name. If empty - default one will be set by the fixture.
+ absl::optional<std::string> name;
+ // If `audio_config` is set audio stream will be configured
+ absl::optional<AudioConfig> audio_config;
+ // Flags to set on `cricket::PortAllocator`. These flags will be added
+ // to the default ones that are presented on the port allocator.
+ uint32_t port_allocator_extra_flags = cricket::kDefaultPortAllocatorFlags;
+ // If `rtc_event_log_path` is set, an RTCEventLog will be saved in that
+ // location and it will be available for further analysis.
+ absl::optional<std::string> rtc_event_log_path;
+ // If `aec_dump_path` is set, an AEC dump will be saved in that location and
+ // it will be available for further analysis.
+ absl::optional<std::string> aec_dump_path;
+
+ bool use_ulp_fec = false;
+ bool use_flex_fec = false;
+ // Specifies how much video encoder target bitrate should be different than
+ // target bitrate, provided by WebRTC stack. Must be greater then 0. Can be
+ // used to emulate overshooting of video encoders. This multiplier will
+ // be applied for all video encoder on both sides for all layers. Bitrate
+ // estimated by WebRTC stack will be multiplied by this multiplier and then
+ // provided into VideoEncoder::SetRates(...).
+ double video_encoder_bitrate_multiplier = 1.0;
+
+ PeerConnectionInterface::RTCConfiguration rtc_configuration;
+ PeerConnectionInterface::RTCOfferAnswerOptions rtc_offer_answer_options;
+ BitrateSettings bitrate_settings;
+ std::vector<VideoCodecConfig> video_codecs;
+
+ // A list of RTP header extensions which will be enforced on all video streams
+ // added to this peer.
+ std::vector<std::string> extra_video_rtp_header_extensions;
+ // A list of RTP header extensions which will be enforced on all audio streams
+ // added to this peer.
+ std::vector<std::string> extra_audio_rtp_header_extensions;
+};
+
+// Contains parameters that maybe changed by test writer during the test call.
+struct ConfigurableParams {
+ // If `video_configs` is empty - no video should be added to the test call.
+ std::vector<VideoConfig> video_configs;
+
+ VideoSubscription video_subscription =
+ VideoSubscription().SubscribeToAllPeers();
+};
+
+// Contains parameters, that describe how long framework should run quality
+// test.
+struct RunParams {
+ explicit RunParams(TimeDelta run_duration) : run_duration(run_duration) {}
+
+ // Specifies how long the test should be run. This time shows how long
+ // the media should flow after connection was established and before
+ // it will be shut downed.
+ TimeDelta run_duration;
+
+ // If set to true peers will be able to use Flex FEC, otherwise they won't
+ // be able to negotiate it even if it's enabled on per peer level.
+ bool enable_flex_fec_support = false;
+ // If true will set conference mode in SDP media section for all video
+ // tracks for all peers.
+ bool use_conference_mode = false;
+ // If specified echo emulation will be done, by mixing the render audio into
+ // the capture signal. In such case input signal will be reduced by half to
+ // avoid saturation or compression in the echo path simulation.
+ absl::optional<EchoEmulationConfig> echo_emulation_config;
+};
+
+} // namespace webrtc_pc_e2e
+} // namespace webrtc
+
+#endif // API_TEST_PCLF_MEDIA_QUALITY_TEST_PARAMS_H_
diff --git a/third_party/libwebrtc/api/test/pclf/peer_configurer.cc b/third_party/libwebrtc/api/test/pclf/peer_configurer.cc
new file mode 100644
index 0000000000..2203a4c4f0
--- /dev/null
+++ b/third_party/libwebrtc/api/test/pclf/peer_configurer.cc
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/pclf/peer_configurer.h"
+
+#include <set>
+
+#include "absl/strings/string_view.h"
+#include "api/test/pclf/media_configuration.h"
+#include "api/test/pclf/media_quality_test_params.h"
+#include "api/test/peer_network_dependencies.h"
+
+namespace webrtc {
+namespace webrtc_pc_e2e {
+
+PeerConfigurer::PeerConfigurer(
+ const PeerNetworkDependencies& network_dependencies)
+ : components_(std::make_unique<InjectableComponents>(
+ network_dependencies.network_thread,
+ network_dependencies.network_manager,
+ network_dependencies.packet_socket_factory)),
+ params_(std::make_unique<Params>()),
+ configurable_params_(std::make_unique<ConfigurableParams>()) {}
+
+PeerConfigurer* PeerConfigurer::SetName(absl::string_view name) {
+ params_->name = std::string(name);
+ return this;
+}
+
+PeerConfigurer* PeerConfigurer::SetTaskQueueFactory(
+ std::unique_ptr<TaskQueueFactory> task_queue_factory) {
+ components_->pcf_dependencies->task_queue_factory =
+ std::move(task_queue_factory);
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetCallFactory(
+ std::unique_ptr<CallFactoryInterface> call_factory) {
+ components_->pcf_dependencies->call_factory = std::move(call_factory);
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetEventLogFactory(
+ std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory) {
+ components_->pcf_dependencies->event_log_factory =
+ std::move(event_log_factory);
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetFecControllerFactory(
+ std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory) {
+ components_->pcf_dependencies->fec_controller_factory =
+ std::move(fec_controller_factory);
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetNetworkControllerFactory(
+ std::unique_ptr<NetworkControllerFactoryInterface>
+ network_controller_factory) {
+ components_->pcf_dependencies->network_controller_factory =
+ std::move(network_controller_factory);
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetVideoEncoderFactory(
+ std::unique_ptr<VideoEncoderFactory> video_encoder_factory) {
+ components_->pcf_dependencies->video_encoder_factory =
+ std::move(video_encoder_factory);
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetVideoDecoderFactory(
+ std::unique_ptr<VideoDecoderFactory> video_decoder_factory) {
+ components_->pcf_dependencies->video_decoder_factory =
+ std::move(video_decoder_factory);
+ return this;
+}
+
+PeerConfigurer* PeerConfigurer::SetAsyncResolverFactory(
+ std::unique_ptr<webrtc::AsyncResolverFactory> async_resolver_factory) {
+ components_->pc_dependencies->async_resolver_factory =
+ std::move(async_resolver_factory);
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetRTCCertificateGenerator(
+ std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator) {
+ components_->pc_dependencies->cert_generator = std::move(cert_generator);
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetSSLCertificateVerifier(
+ std::unique_ptr<rtc::SSLCertificateVerifier> tls_cert_verifier) {
+ components_->pc_dependencies->tls_cert_verifier =
+ std::move(tls_cert_verifier);
+ return this;
+}
+
+PeerConfigurer* PeerConfigurer::AddVideoConfig(VideoConfig config) {
+ video_sources_.push_back(
+ CreateSquareFrameGenerator(config, /*type=*/absl::nullopt));
+ configurable_params_->video_configs.push_back(std::move(config));
+ return this;
+}
+PeerConfigurer* PeerConfigurer::AddVideoConfig(
+ VideoConfig config,
+ std::unique_ptr<test::FrameGeneratorInterface> generator) {
+ configurable_params_->video_configs.push_back(std::move(config));
+ video_sources_.push_back(std::move(generator));
+ return this;
+}
+PeerConfigurer* PeerConfigurer::AddVideoConfig(VideoConfig config,
+ CapturingDeviceIndex index) {
+ configurable_params_->video_configs.push_back(std::move(config));
+ video_sources_.push_back(index);
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetVideoSubscription(
+ VideoSubscription subscription) {
+ configurable_params_->video_subscription = std::move(subscription);
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetVideoCodecs(
+ std::vector<VideoCodecConfig> video_codecs) {
+ params_->video_codecs = std::move(video_codecs);
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetExtraVideoRtpHeaderExtensions(
+ std::vector<std::string> extensions) {
+ params_->extra_video_rtp_header_extensions = std::move(extensions);
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetAudioConfig(AudioConfig config) {
+ params_->audio_config = std::move(config);
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetExtraAudioRtpHeaderExtensions(
+ std::vector<std::string> extensions) {
+ params_->extra_audio_rtp_header_extensions = std::move(extensions);
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetUseUlpFEC(bool value) {
+ params_->use_ulp_fec = value;
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetUseFlexFEC(bool value) {
+ params_->use_flex_fec = value;
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetVideoEncoderBitrateMultiplier(
+ double multiplier) {
+ params_->video_encoder_bitrate_multiplier = multiplier;
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetNetEqFactory(
+ std::unique_ptr<NetEqFactory> neteq_factory) {
+ components_->pcf_dependencies->neteq_factory = std::move(neteq_factory);
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetAudioProcessing(
+ rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
+ components_->pcf_dependencies->audio_processing = audio_processing;
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetAudioMixer(
+ rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) {
+ components_->pcf_dependencies->audio_mixer = audio_mixer;
+ return this;
+}
+
+PeerConfigurer* PeerConfigurer::SetUseNetworkThreadAsWorkerThread() {
+ components_->worker_thread = components_->network_thread;
+ return this;
+}
+
+PeerConfigurer* PeerConfigurer::SetRtcEventLogPath(std::string path) {
+ params_->rtc_event_log_path = std::move(path);
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetAecDumpPath(std::string path) {
+ params_->aec_dump_path = std::move(path);
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetRTCConfiguration(
+ PeerConnectionInterface::RTCConfiguration configuration) {
+ params_->rtc_configuration = std::move(configuration);
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetRTCOfferAnswerOptions(
+ PeerConnectionInterface::RTCOfferAnswerOptions options) {
+ params_->rtc_offer_answer_options = std::move(options);
+ return this;
+}
+PeerConfigurer* PeerConfigurer::SetBitrateSettings(
+ BitrateSettings bitrate_settings) {
+ params_->bitrate_settings = bitrate_settings;
+ return this;
+}
+
+PeerConfigurer* PeerConfigurer::SetIceTransportFactory(
+ std::unique_ptr<IceTransportFactory> factory) {
+ components_->pc_dependencies->ice_transport_factory = std::move(factory);
+ return this;
+}
+
+PeerConfigurer* PeerConfigurer::SetPortAllocatorExtraFlags(
+ uint32_t extra_flags) {
+ params_->port_allocator_extra_flags = extra_flags;
+ return this;
+}
+std::unique_ptr<InjectableComponents> PeerConfigurer::ReleaseComponents() {
+ RTC_CHECK(components_);
+ auto components = std::move(components_);
+ components_ = nullptr;
+ return components;
+}
+
+// Returns Params and transfer ownership to the caller.
+// Can be called once.
+std::unique_ptr<Params> PeerConfigurer::ReleaseParams() {
+ RTC_CHECK(params_);
+ auto params = std::move(params_);
+ params_ = nullptr;
+ return params;
+}
+
+// Returns ConfigurableParams and transfer ownership to the caller.
+// Can be called once.
+std::unique_ptr<ConfigurableParams>
+PeerConfigurer::ReleaseConfigurableParams() {
+ RTC_CHECK(configurable_params_);
+ auto configurable_params = std::move(configurable_params_);
+ configurable_params_ = nullptr;
+ return configurable_params;
+}
+
+// Returns video sources and transfer frame generators ownership to the
+// caller. Can be called once.
+std::vector<PeerConfigurer::VideoSource> PeerConfigurer::ReleaseVideoSources() {
+ auto video_sources = std::move(video_sources_);
+ video_sources_.clear();
+ return video_sources;
+}
+
+} // namespace webrtc_pc_e2e
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/pclf/peer_configurer.h b/third_party/libwebrtc/api/test/pclf/peer_configurer.h
new file mode 100644
index 0000000000..996dc5cd89
--- /dev/null
+++ b/third_party/libwebrtc/api/test/pclf/peer_configurer.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_TEST_PCLF_PEER_CONFIGURER_H_
+#define API_TEST_PCLF_PEER_CONFIGURER_H_
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/async_resolver_factory.h"
+#include "api/audio/audio_mixer.h"
+#include "api/call/call_factory_interface.h"
+#include "api/fec_controller.h"
+#include "api/rtc_event_log/rtc_event_log_factory_interface.h"
+#include "api/task_queue/task_queue_factory.h"
+#include "api/test/create_peer_connection_quality_test_frame_generator.h"
+#include "api/test/pclf/media_configuration.h"
+#include "api/test/pclf/media_quality_test_params.h"
+#include "api/test/peer_network_dependencies.h"
+#include "api/transport/network_control.h"
+#include "api/video_codecs/video_decoder_factory.h"
+#include "api/video_codecs/video_encoder_factory.h"
+#include "modules/audio_processing/include/audio_processing.h"
+#include "rtc_base/network.h"
+#include "rtc_base/rtc_certificate_generator.h"
+#include "rtc_base/ssl_certificate.h"
+#include "rtc_base/thread.h"
+
+namespace webrtc {
+namespace webrtc_pc_e2e {
+
+// This class is used to fully configure one peer inside a call.
+class PeerConfigurer {
+ public:
+ using VideoSource =
+ absl::variant<std::unique_ptr<test::FrameGeneratorInterface>,
+ CapturingDeviceIndex>;
+
+ explicit PeerConfigurer(const PeerNetworkDependencies& network_dependencies);
+
+ // Sets peer name that will be used to report metrics related to this peer.
+ // If not set, some default name will be assigned. All names have to be
+ // unique.
+ PeerConfigurer* SetName(absl::string_view name);
+
+ // The parameters of the following 9 methods will be passed to the
+ // PeerConnectionFactoryInterface implementation that will be created for
+ // this peer.
+ PeerConfigurer* SetTaskQueueFactory(
+ std::unique_ptr<TaskQueueFactory> task_queue_factory);
+ PeerConfigurer* SetCallFactory(
+ std::unique_ptr<CallFactoryInterface> call_factory);
+ PeerConfigurer* SetEventLogFactory(
+ std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory);
+ PeerConfigurer* SetFecControllerFactory(
+ std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory);
+ PeerConfigurer* SetNetworkControllerFactory(
+ std::unique_ptr<NetworkControllerFactoryInterface>
+ network_controller_factory);
+ PeerConfigurer* SetVideoEncoderFactory(
+ std::unique_ptr<VideoEncoderFactory> video_encoder_factory);
+ PeerConfigurer* SetVideoDecoderFactory(
+ std::unique_ptr<VideoDecoderFactory> video_decoder_factory);
+ // Set a custom NetEqFactory to be used in the call.
+ PeerConfigurer* SetNetEqFactory(std::unique_ptr<NetEqFactory> neteq_factory);
+ PeerConfigurer* SetAudioProcessing(
+ rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing);
+ PeerConfigurer* SetAudioMixer(
+ rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer);
+
+ // Forces the Peerconnection to use the network thread as the worker thread.
+ // Ie, worker thread and the network thread is the same thread.
+ PeerConfigurer* SetUseNetworkThreadAsWorkerThread();
+
+ // The parameters of the following 4 methods will be passed to the
+ // PeerConnectionInterface implementation that will be created for this
+ // peer.
+ PeerConfigurer* SetAsyncResolverFactory(
+ std::unique_ptr<webrtc::AsyncResolverFactory> async_resolver_factory);
+ PeerConfigurer* SetRTCCertificateGenerator(
+ std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator);
+ PeerConfigurer* SetSSLCertificateVerifier(
+ std::unique_ptr<rtc::SSLCertificateVerifier> tls_cert_verifier);
+ PeerConfigurer* SetIceTransportFactory(
+ std::unique_ptr<IceTransportFactory> factory);
+ // Flags to set on `cricket::PortAllocator`. These flags will be added
+ // to the default ones that are presented on the port allocator.
+ // For possible values check p2p/base/port_allocator.h.
+ PeerConfigurer* SetPortAllocatorExtraFlags(uint32_t extra_flags);
+
+ // Add new video stream to the call that will be sent from this peer.
+ // Default implementation of video frames generator will be used.
+ PeerConfigurer* AddVideoConfig(VideoConfig config);
+ // Add new video stream to the call that will be sent from this peer with
+ // provided own implementation of video frames generator.
+ PeerConfigurer* AddVideoConfig(
+ VideoConfig config,
+ std::unique_ptr<test::FrameGeneratorInterface> generator);
+ // Add new video stream to the call that will be sent from this peer.
+ // Capturing device with specified index will be used to get input video.
+ PeerConfigurer* AddVideoConfig(VideoConfig config,
+ CapturingDeviceIndex capturing_device_index);
+ // Sets video subscription for the peer. By default subscription will
+ // include all streams with `VideoSubscription::kSameAsSendStream`
+ // resolution. To this behavior use this method.
+ PeerConfigurer* SetVideoSubscription(VideoSubscription subscription);
+ // Sets the list of video codecs used by the peer during the test. These
+ // codecs will be negotiated in SDP during offer/answer exchange. The order
+ // of these codecs during negotiation will be the same as in `video_codecs`.
+ // Codecs have to be available in codecs list provided by peer connection to
+ // be negotiated. If some of specified codecs won't be found, the test will
+ // crash.
+ PeerConfigurer* SetVideoCodecs(std::vector<VideoCodecConfig> video_codecs);
+ // Sets a list of RTP header extensions which will be enforced on all video
+ // streams added to this peer.
+ PeerConfigurer* SetExtraVideoRtpHeaderExtensions(
+ std::vector<std::string> extensions);
+ // Sets the audio stream for the call from this peer. If this method won't
+ // be invoked, this peer will send no audio.
+ PeerConfigurer* SetAudioConfig(AudioConfig config);
+ // Sets a list of RTP header extensions which will be enforced on all audio
+ // streams added to this peer.
+ PeerConfigurer* SetExtraAudioRtpHeaderExtensions(
+ std::vector<std::string> extensions);
+
+ // Set if ULP FEC should be used or not. False by default.
+ PeerConfigurer* SetUseUlpFEC(bool value);
+ // Set if Flex FEC should be used or not. False by default.
+ // Client also must enable `enable_flex_fec_support` in the `RunParams` to
+ // be able to use this feature.
+ PeerConfigurer* SetUseFlexFEC(bool value);
+ // Specifies how much video encoder target bitrate should be different than
+ // target bitrate, provided by WebRTC stack. Must be greater than 0. Can be
+ // used to emulate overshooting of video encoders. This multiplier will
+ // be applied for all video encoder on both sides for all layers. Bitrate
+ // estimated by WebRTC stack will be multiplied by this multiplier and then
+ // provided into VideoEncoder::SetRates(...). 1.0 by default.
+ PeerConfigurer* SetVideoEncoderBitrateMultiplier(double multiplier);
+
+ // If is set, an RTCEventLog will be saved in that location and it will be
+ // available for further analysis.
+ PeerConfigurer* SetRtcEventLogPath(std::string path);
+ // If is set, an AEC dump will be saved in that location and it will be
+ // available for further analysis.
+ PeerConfigurer* SetAecDumpPath(std::string path);
+ PeerConfigurer* SetRTCConfiguration(
+ PeerConnectionInterface::RTCConfiguration configuration);
+ PeerConfigurer* SetRTCOfferAnswerOptions(
+ PeerConnectionInterface::RTCOfferAnswerOptions options);
+ // Set bitrate parameters on PeerConnection. This constraints will be
+ // applied to all summed RTP streams for this peer.
+ PeerConfigurer* SetBitrateSettings(BitrateSettings bitrate_settings);
+
+ // Returns InjectableComponents and transfer ownership to the caller.
+ // Can be called once.
+ std::unique_ptr<InjectableComponents> ReleaseComponents();
+
+ // Returns Params and transfer ownership to the caller.
+ // Can be called once.
+ std::unique_ptr<Params> ReleaseParams();
+
+ // Returns ConfigurableParams and transfer ownership to the caller.
+ // Can be called once.
+ std::unique_ptr<ConfigurableParams> ReleaseConfigurableParams();
+
+ // Returns video sources and transfer frame generators ownership to the
+ // caller. Can be called once.
+ std::vector<VideoSource> ReleaseVideoSources();
+
+ InjectableComponents* components() { return components_.get(); }
+ Params* params() { return params_.get(); }
+ ConfigurableParams* configurable_params() {
+ return configurable_params_.get();
+ }
+ const Params& params() const { return *params_; }
+ const ConfigurableParams& configurable_params() const {
+ return *configurable_params_;
+ }
+ std::vector<VideoSource>* video_sources() { return &video_sources_; }
+
+ private:
+ std::unique_ptr<InjectableComponents> components_;
+ std::unique_ptr<Params> params_;
+ std::unique_ptr<ConfigurableParams> configurable_params_;
+ std::vector<VideoSource> video_sources_;
+};
+
+} // namespace webrtc_pc_e2e
+} // namespace webrtc
+
+#endif // API_TEST_PCLF_PEER_CONFIGURER_H_
diff --git a/third_party/libwebrtc/api/test/peer_network_dependencies.h b/third_party/libwebrtc/api/test/peer_network_dependencies.h
new file mode 100644
index 0000000000..6f85ad0a4d
--- /dev/null
+++ b/third_party/libwebrtc/api/test/peer_network_dependencies.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_PEER_NETWORK_DEPENDENCIES_H_
+#define API_TEST_PEER_NETWORK_DEPENDENCIES_H_
+
+#include "api/packet_socket_factory.h"
+#include "rtc_base/network.h"
+#include "rtc_base/thread.h"
+
+namespace webrtc {
+namespace webrtc_pc_e2e {
+
+// The network dependencies needed when adding a peer to tests using
+// PeerConnectionE2EQualityTestFixture.
+struct PeerNetworkDependencies {
+ rtc::Thread* network_thread;
+ rtc::NetworkManager* network_manager;
+ rtc::PacketSocketFactory* packet_socket_factory;
+};
+
+} // namespace webrtc_pc_e2e
+} // namespace webrtc
+
+#endif // API_TEST_PEER_NETWORK_DEPENDENCIES_H_
diff --git a/third_party/libwebrtc/api/test/peerconnection_quality_test_fixture.h b/third_party/libwebrtc/api/test/peerconnection_quality_test_fixture.h
new file mode 100644
index 0000000000..74470cdf86
--- /dev/null
+++ b/third_party/libwebrtc/api/test/peerconnection_quality_test_fixture.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_TEST_PEERCONNECTION_QUALITY_TEST_FIXTURE_H_
+#define API_TEST_PEERCONNECTION_QUALITY_TEST_FIXTURE_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/base/macros.h"
+#include "absl/memory/memory.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/async_resolver_factory.h"
+#include "api/audio/audio_mixer.h"
+#include "api/call/call_factory_interface.h"
+#include "api/fec_controller.h"
+#include "api/function_view.h"
+#include "api/media_stream_interface.h"
+#include "api/peer_connection_interface.h"
+#include "api/rtc_event_log/rtc_event_log_factory_interface.h"
+#include "api/rtp_parameters.h"
+#include "api/task_queue/task_queue_factory.h"
+#include "api/test/audio_quality_analyzer_interface.h"
+#include "api/test/frame_generator_interface.h"
+#include "api/test/pclf/media_configuration.h"
+#include "api/test/pclf/media_quality_test_params.h"
+#include "api/test/pclf/peer_configurer.h"
+#include "api/test/peer_network_dependencies.h"
+#include "api/test/simulated_network.h"
+#include "api/test/stats_observer_interface.h"
+#include "api/test/track_id_stream_info_map.h"
+#include "api/test/video/video_frame_writer.h"
+#include "api/test/video_quality_analyzer_interface.h"
+#include "api/transport/network_control.h"
+#include "api/units/time_delta.h"
+#include "api/video_codecs/video_decoder_factory.h"
+#include "api/video_codecs/video_encoder.h"
+#include "api/video_codecs/video_encoder_factory.h"
+#include "media/base/media_constants.h"
+#include "modules/audio_processing/include/audio_processing.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/network.h"
+#include "rtc_base/rtc_certificate_generator.h"
+#include "rtc_base/ssl_certificate.h"
+#include "rtc_base/thread.h"
+
+namespace webrtc {
+namespace webrtc_pc_e2e {
+
+// API is in development. Can be changed/removed without notice.
+class PeerConnectionE2EQualityTestFixture {
+ public:
+ // Represent an entity that will report quality metrics after test.
+ class QualityMetricsReporter : public StatsObserverInterface {
+ public:
+ virtual ~QualityMetricsReporter() = default;
+
+ // Invoked by framework after peer connection factory and peer connection
+ // itself will be created but before offer/answer exchange will be started.
+ // `test_case_name` is name of test case, that should be used to report all
+ // metrics.
+ // `reporter_helper` is a pointer to a class that will allow track_id to
+ // stream_id matching. The caller is responsible for ensuring the
+ // TrackIdStreamInfoMap will be valid from Start() to
+ // StopAndReportResults().
+ virtual void Start(absl::string_view test_case_name,
+ const TrackIdStreamInfoMap* reporter_helper) = 0;
+
+ // Invoked by framework after call is ended and peer connection factory and
+ // peer connection are destroyed.
+ virtual void StopAndReportResults() = 0;
+ };
+
+ // Represents single participant in call and can be used to perform different
+ // in-call actions. Might be extended in future.
+ class PeerHandle {
+ public:
+ virtual ~PeerHandle() = default;
+ };
+
+ virtual ~PeerConnectionE2EQualityTestFixture() = default;
+
+ // Add activity that will be executed on the best effort at least after
+ // `target_time_since_start` after call will be set up (after offer/answer
+ // exchange, ICE gathering will be done and ICE candidates will passed to
+ // remote side). `func` param is amount of time spent from the call set up.
+ virtual void ExecuteAt(TimeDelta target_time_since_start,
+ std::function<void(TimeDelta)> func) = 0;
+ // Add activity that will be executed every `interval` with first execution
+ // on the best effort at least after `initial_delay_since_start` after call
+ // will be set up (after all participants will be connected). `func` param is
+ // amount of time spent from the call set up.
+ virtual void ExecuteEvery(TimeDelta initial_delay_since_start,
+ TimeDelta interval,
+ std::function<void(TimeDelta)> func) = 0;
+
+ // Add stats reporter entity to observe the test.
+ virtual void AddQualityMetricsReporter(
+ std::unique_ptr<QualityMetricsReporter> quality_metrics_reporter) = 0;
+
+ // Add a new peer to the call and return an object through which caller
+ // can configure peer's behavior.
+ // `network_dependencies` are used to provide networking for peer's peer
+ // connection. Members must be non-null.
+ // `configurer` function will be used to configure peer in the call.
+ virtual PeerHandle* AddPeer(std::unique_ptr<PeerConfigurer> configurer) = 0;
+
+ // Runs the media quality test, which includes setting up the call with
+ // configured participants, running it according to provided `run_params` and
+ // terminating it properly at the end. During call duration media quality
+ // metrics are gathered, which are then reported to stdout and (if configured)
+ // to the json/protobuf output file through the WebRTC perf test results
+ // reporting system.
+ virtual void Run(RunParams run_params) = 0;
+
+ // Returns real test duration - the time of test execution measured during
+ // test. Client must call this method only after test is finished (after
+ // Run(...) method returned). Test execution time is time from end of call
+ // setup (offer/answer, ICE candidates exchange done and ICE connected) to
+ // start of call tear down (PeerConnection closed).
+ virtual TimeDelta GetRealTestDuration() const = 0;
+};
+
+} // namespace webrtc_pc_e2e
+} // namespace webrtc
+
+#endif // API_TEST_PEERCONNECTION_QUALITY_TEST_FIXTURE_H_
diff --git a/third_party/libwebrtc/api/test/peerconnection_quality_test_fixture_unittest.cc b/third_party/libwebrtc/api/test/peerconnection_quality_test_fixture_unittest.cc
new file mode 100644
index 0000000000..26ae8cf98f
--- /dev/null
+++ b/third_party/libwebrtc/api/test/peerconnection_quality_test_fixture_unittest.cc
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2022 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/peerconnection_quality_test_fixture.h"
+
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/test/pclf/media_configuration.h"
+#include "api/test/video/video_frame_writer.h"
+#include "rtc_base/gunit.h"
+#include "test/gmock.h"
+#include "test/testsupport/file_utils.h"
+
+namespace webrtc {
+namespace webrtc_pc_e2e {
+namespace {
+
+using ::testing::Eq;
+
+TEST(PclfVideoSubscriptionTest,
+ MaxFromSenderSpecEqualIndependentOfOtherFields) {
+ VideoResolution r1(VideoResolution::Spec::kMaxFromSender);
+ r1.set_width(1);
+ r1.set_height(2);
+ r1.set_fps(3);
+ VideoResolution r2(VideoResolution::Spec::kMaxFromSender);
+ r1.set_width(4);
+ r1.set_height(5);
+ r1.set_fps(6);
+ EXPECT_EQ(r1, r2);
+}
+
+TEST(PclfVideoSubscriptionTest, WhenSpecIsNotSetFieldsAreCompared) {
+ VideoResolution test_resolution(/*width=*/1, /*height=*/2,
+ /*fps=*/3);
+ VideoResolution equal_resolution(/*width=*/1, /*height=*/2,
+ /*fps=*/3);
+ VideoResolution different_width(/*width=*/10, /*height=*/2,
+ /*fps=*/3);
+ VideoResolution different_height(/*width=*/1, /*height=*/20,
+ /*fps=*/3);
+ VideoResolution different_fps(/*width=*/1, /*height=*/20,
+ /*fps=*/30);
+
+ EXPECT_EQ(test_resolution, equal_resolution);
+ EXPECT_NE(test_resolution, different_width);
+ EXPECT_NE(test_resolution, different_height);
+ EXPECT_NE(test_resolution, different_fps);
+}
+
+TEST(PclfVideoSubscriptionTest, GetMaxResolutionForEmptyReturnsNullopt) {
+ absl::optional<VideoResolution> resolution =
+ VideoSubscription::GetMaxResolution(std::vector<VideoConfig>{});
+ ASSERT_FALSE(resolution.has_value());
+}
+
+TEST(PclfVideoSubscriptionTest, GetMaxResolutionSelectMaxForEachDimention) {
+ VideoConfig max_width(/*width=*/1000, /*height=*/1, /*fps=*/1);
+ VideoConfig max_height(/*width=*/1, /*height=*/100, /*fps=*/1);
+ VideoConfig max_fps(/*width=*/1, /*height=*/1, /*fps=*/10);
+
+ absl::optional<VideoResolution> resolution =
+ VideoSubscription::GetMaxResolution(
+ std::vector<VideoConfig>{max_width, max_height, max_fps});
+ ASSERT_TRUE(resolution.has_value());
+ EXPECT_EQ(resolution->width(), static_cast<size_t>(1000));
+ EXPECT_EQ(resolution->height(), static_cast<size_t>(100));
+ EXPECT_EQ(resolution->fps(), 10);
+}
+
+struct TestVideoFrameWriter : public test::VideoFrameWriter {
+ public:
+ TestVideoFrameWriter(absl::string_view file_name_prefix,
+ const VideoResolution& resolution)
+ : file_name_prefix(file_name_prefix), resolution(resolution) {}
+
+ bool WriteFrame(const VideoFrame& frame) override { return true; }
+
+ void Close() override {}
+
+ std::string file_name_prefix;
+ VideoResolution resolution;
+};
+
+TEST(VideoDumpOptionsTest, InputVideoWriterHasCorrectFileName) {
+ VideoResolution resolution(/*width=*/1280, /*height=*/720, /*fps=*/30);
+
+ TestVideoFrameWriter* writer = nullptr;
+ VideoDumpOptions options("foo", /*sampling_modulo=*/1,
+ /*export_frame_ids=*/false,
+ /*video_frame_writer_factory=*/
+ [&](absl::string_view file_name_prefix,
+ const VideoResolution& resolution) {
+ auto out = std::make_unique<TestVideoFrameWriter>(
+ file_name_prefix, resolution);
+ writer = out.get();
+ return out;
+ });
+ std::unique_ptr<test::VideoFrameWriter> created_writer =
+ options.CreateInputDumpVideoFrameWriter("alice-video", resolution);
+
+ ASSERT_TRUE(writer != nullptr);
+ ASSERT_THAT(writer->file_name_prefix,
+ Eq(test::JoinFilename("foo", "alice-video_1280x720_30")));
+ ASSERT_THAT(writer->resolution, Eq(resolution));
+}
+
+TEST(VideoDumpOptionsTest, OutputVideoWriterHasCorrectFileName) {
+ VideoResolution resolution(/*width=*/1280, /*height=*/720, /*fps=*/30);
+
+ TestVideoFrameWriter* writer = nullptr;
+ VideoDumpOptions options("foo", /*sampling_modulo=*/1,
+ /*export_frame_ids=*/false,
+ /*video_frame_writer_factory=*/
+ [&](absl::string_view file_name_prefix,
+ const VideoResolution& resolution) {
+ auto out = std::make_unique<TestVideoFrameWriter>(
+ file_name_prefix, resolution);
+ writer = out.get();
+ return out;
+ });
+ std::unique_ptr<test::VideoFrameWriter> created_writer =
+ options.CreateOutputDumpVideoFrameWriter("alice-video", "bob",
+ resolution);
+
+ ASSERT_TRUE(writer != nullptr);
+ ASSERT_THAT(writer->file_name_prefix,
+ Eq(test::JoinFilename("foo", "alice-video_bob_1280x720_30")));
+ ASSERT_THAT(writer->resolution, Eq(resolution));
+}
+
+} // namespace
+} // namespace webrtc_pc_e2e
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/simulated_network.h b/third_party/libwebrtc/api/test/simulated_network.h
new file mode 100644
index 0000000000..04c5517c8d
--- /dev/null
+++ b/third_party/libwebrtc/api/test/simulated_network.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_SIMULATED_NETWORK_H_
+#define API_TEST_SIMULATED_NETWORK_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <deque>
+#include <queue>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "rtc_base/random.h"
+#include "rtc_base/thread_annotations.h"
+
+namespace webrtc {
+
+struct PacketInFlightInfo {
+ PacketInFlightInfo(size_t size, int64_t send_time_us, uint64_t packet_id)
+ : size(size), send_time_us(send_time_us), packet_id(packet_id) {}
+
+ size_t size;
+ int64_t send_time_us;
+ // Unique identifier for the packet in relation to other packets in flight.
+ uint64_t packet_id;
+};
+
+struct PacketDeliveryInfo {
+ static constexpr int kNotReceived = -1;
+ PacketDeliveryInfo(PacketInFlightInfo source, int64_t receive_time_us)
+ : receive_time_us(receive_time_us), packet_id(source.packet_id) {}
+
+ bool operator==(const PacketDeliveryInfo& other) const {
+ return receive_time_us == other.receive_time_us &&
+ packet_id == other.packet_id;
+ }
+
+ int64_t receive_time_us;
+ uint64_t packet_id;
+};
+
+// BuiltInNetworkBehaviorConfig is a built-in network behavior configuration
+// for built-in network behavior that will be used by WebRTC if no custom
+// NetworkBehaviorInterface is provided.
+struct BuiltInNetworkBehaviorConfig {
+ // Queue length in number of packets.
+ size_t queue_length_packets = 0;
+ // Delay in addition to capacity induced delay.
+ int queue_delay_ms = 0;
+ // Standard deviation of the extra delay.
+ int delay_standard_deviation_ms = 0;
+ // Link capacity in kbps.
+ int link_capacity_kbps = 0;
+ // Random packet loss.
+ int loss_percent = 0;
+ // If packets are allowed to be reordered.
+ bool allow_reordering = false;
+ // The average length of a burst of lost packets.
+ int avg_burst_loss_length = -1;
+ // Additional bytes to add to packet size.
+ int packet_overhead = 0;
+};
+
+// Interface that represents a Network behaviour.
+//
+// It is clients of this interface responsibility to enqueue and dequeue
+// packets (based on the estimated delivery time expressed by
+// NextDeliveryTimeUs).
+//
+// To enqueue packets, call EnqueuePacket:
+// EXPECT_TRUE(network.EnqueuePacket(
+// PacketInFlightInfo(/*size=*/1, /*send_time_us=*/0, /*packet_id=*/1)));
+//
+// To know when to call DequeueDeliverablePackets to pull packets out of the
+// network, call NextDeliveryTimeUs and schedule a task to invoke
+// DequeueDeliverablePackets (if not already scheduled).
+//
+// DequeueDeliverablePackets will return a vector of delivered packets, but this
+// vector can be empty in case of extra delay. In such case, make sure to invoke
+// NextDeliveryTimeUs and schedule a task to call DequeueDeliverablePackets for
+// the next estimated delivery of packets.
+//
+// std::vector<PacketDeliveryInfo> delivered_packets =
+// network.DequeueDeliverablePackets(/*receive_time_us=*/1000000);
+class NetworkBehaviorInterface {
+ public:
+ // Enqueues a packet in the network and returns true if the action was
+ // successful, false otherwise (for example, because the network capacity has
+ // been saturated). If the return value is false, the packet should be
+ // considered as dropped and it will not be returned by future calls
+ // to DequeueDeliverablePackets.
+ // Packets enqueued will exit the network when DequeueDeliverablePackets is
+ // called and enough time has passed (see NextDeliveryTimeUs).
+ virtual bool EnqueuePacket(PacketInFlightInfo packet_info) = 0;
+ // Retrieves all packets that should be delivered by the given receive time.
+ // Not all the packets in the returned std::vector are actually delivered.
+ // In order to know the state of each packet it is necessary to check the
+ // `receive_time_us` field of each packet. If that is set to
+ // PacketDeliveryInfo::kNotReceived then the packet is considered lost in the
+ // network.
+ virtual std::vector<PacketDeliveryInfo> DequeueDeliverablePackets(
+ int64_t receive_time_us) = 0;
+ // Returns time in microseconds when caller should call
+ // DequeueDeliverablePackets to get the next set of delivered packets. It is
+ // possible that no packet will be delivered by that time (e.g. in case of
+ // random extra delay), in such case this method should be called again to get
+ // the updated estimated delivery time.
+ virtual absl::optional<int64_t> NextDeliveryTimeUs() const = 0;
+ virtual ~NetworkBehaviorInterface() = default;
+};
+
+// Class simulating a network link. This is a simple and naive solution just
+// faking capacity and adding an extra transport delay in addition to the
+// capacity introduced delay.
+class SimulatedNetworkInterface : public NetworkBehaviorInterface {
+ public:
+ // Sets a new configuration.
+ virtual void SetConfig(const BuiltInNetworkBehaviorConfig& config) = 0;
+ virtual void UpdateConfig(
+ std::function<void(BuiltInNetworkBehaviorConfig*)> config_modifier) = 0;
+ // Pauses the network until `until_us`. This affects both delivery (calling
+ // DequeueDeliverablePackets before `until_us` results in an empty std::vector
+ // of packets) and capacity (the network is paused, so packets are not
+ // flowing and they will restart flowing at `until_us`).
+ virtual void PauseTransmissionUntil(int64_t until_us) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_SIMULATED_NETWORK_H_
diff --git a/third_party/libwebrtc/api/test/simulcast_test_fixture.h b/third_party/libwebrtc/api/test/simulcast_test_fixture.h
new file mode 100644
index 0000000000..c7130d2909
--- /dev/null
+++ b/third_party/libwebrtc/api/test/simulcast_test_fixture.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_SIMULCAST_TEST_FIXTURE_H_
+#define API_TEST_SIMULCAST_TEST_FIXTURE_H_
+
+namespace webrtc {
+namespace test {
+
+class SimulcastTestFixture {
+ public:
+ virtual ~SimulcastTestFixture() = default;
+
+ virtual void TestKeyFrameRequestsOnAllStreams() = 0;
+ virtual void TestKeyFrameRequestsOnSpecificStreams() = 0;
+ virtual void TestPaddingAllStreams() = 0;
+ virtual void TestPaddingTwoStreams() = 0;
+ virtual void TestPaddingTwoStreamsOneMaxedOut() = 0;
+ virtual void TestPaddingOneStream() = 0;
+ virtual void TestPaddingOneStreamTwoMaxedOut() = 0;
+ virtual void TestSendAllStreams() = 0;
+ virtual void TestDisablingStreams() = 0;
+ virtual void TestActiveStreams() = 0;
+ virtual void TestSwitchingToOneStream() = 0;
+ virtual void TestSwitchingToOneOddStream() = 0;
+ virtual void TestSwitchingToOneSmallStream() = 0;
+ virtual void TestSpatioTemporalLayers333PatternEncoder() = 0;
+ virtual void TestSpatioTemporalLayers321PatternEncoder() = 0;
+ virtual void TestStrideEncodeDecode() = 0;
+ virtual void TestDecodeWidthHeightSet() = 0;
+ virtual void
+ TestEncoderInfoForDefaultTemporalLayerProfileHasFpsAllocation() = 0;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_SIMULCAST_TEST_FIXTURE_H_
diff --git a/third_party/libwebrtc/api/test/stats_observer_interface.h b/third_party/libwebrtc/api/test/stats_observer_interface.h
new file mode 100644
index 0000000000..58d8f52d77
--- /dev/null
+++ b/third_party/libwebrtc/api/test/stats_observer_interface.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_STATS_OBSERVER_INTERFACE_H_
+#define API_TEST_STATS_OBSERVER_INTERFACE_H_
+
+#include "absl/strings/string_view.h"
+#include "api/stats/rtc_stats_report.h"
+
+namespace webrtc {
+namespace webrtc_pc_e2e {
+
+// API is in development and can be changed without notice.
+class StatsObserverInterface {
+ public:
+ virtual ~StatsObserverInterface() = default;
+
+ // Method called when stats reports are available for the PeerConnection
+ // identified by `pc_label`.
+ virtual void OnStatsReports(
+ absl::string_view pc_label,
+ const rtc::scoped_refptr<const RTCStatsReport>& report) = 0;
+};
+
+} // namespace webrtc_pc_e2e
+} // namespace webrtc
+
+#endif // API_TEST_STATS_OBSERVER_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/test/test_dependency_factory.cc b/third_party/libwebrtc/api/test/test_dependency_factory.cc
new file mode 100644
index 0000000000..41ad70cc3f
--- /dev/null
+++ b/third_party/libwebrtc/api/test/test_dependency_factory.cc
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/test_dependency_factory.h"
+
+#include <memory>
+#include <utility>
+
+#include "rtc_base/checks.h"
+#include "rtc_base/platform_thread_types.h"
+
+namespace webrtc {
+
+namespace {
+// This checks everything in this file gets called on the same thread. It's
+// static because it needs to look at the static methods too.
+bool IsValidTestDependencyFactoryThread() {
+ const rtc::PlatformThreadRef main_thread = rtc::CurrentThreadRef();
+ return rtc::IsThreadRefEqual(main_thread, rtc::CurrentThreadRef());
+}
+} // namespace
+
+std::unique_ptr<TestDependencyFactory> TestDependencyFactory::instance_ =
+ nullptr;
+
+const TestDependencyFactory& TestDependencyFactory::GetInstance() {
+ RTC_DCHECK(IsValidTestDependencyFactoryThread());
+ if (instance_ == nullptr) {
+ instance_ = std::make_unique<TestDependencyFactory>();
+ }
+ return *instance_;
+}
+
+void TestDependencyFactory::SetInstance(
+ std::unique_ptr<TestDependencyFactory> instance) {
+ RTC_DCHECK(IsValidTestDependencyFactoryThread());
+ RTC_CHECK(instance_ == nullptr);
+ instance_ = std::move(instance);
+}
+
+std::unique_ptr<VideoQualityTestFixtureInterface::InjectionComponents>
+TestDependencyFactory::CreateComponents() const {
+ RTC_DCHECK(IsValidTestDependencyFactoryThread());
+ return nullptr;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/test_dependency_factory.h b/third_party/libwebrtc/api/test/test_dependency_factory.h
new file mode 100644
index 0000000000..29f00b8070
--- /dev/null
+++ b/third_party/libwebrtc/api/test/test_dependency_factory.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_TEST_DEPENDENCY_FACTORY_H_
+#define API_TEST_TEST_DEPENDENCY_FACTORY_H_
+
+#include <memory>
+
+#include "api/test/video_quality_test_fixture.h"
+
+namespace webrtc {
+
+// Override this class if to inject custom components into WebRTC tests.
+// Not all WebRTC tests get their components from here, so you need to make
+// sure the tests you want actually use this class.
+//
+// This class is not thread safe and you need to make call calls from the same
+// (test main) thread.
+class TestDependencyFactory {
+ public:
+ virtual ~TestDependencyFactory() = default;
+
+ // The singleton MUST be stateless since tests execute in any order. It must
+ // be set before tests start executing.
+ static const TestDependencyFactory& GetInstance();
+ static void SetInstance(std::unique_ptr<TestDependencyFactory> instance);
+
+ // Returns the component a test should use. Returning nullptr means that the
+ // test is free to use whatever defaults it wants. The injection components
+ // themselves can be mutable, but we need to make new ones for every test that
+ // executes so state doesn't spread between tests.
+ virtual std::unique_ptr<VideoQualityTestFixtureInterface::InjectionComponents>
+ CreateComponents() const;
+
+ private:
+ static std::unique_ptr<TestDependencyFactory> instance_;
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_TEST_DEPENDENCY_FACTORY_H_
diff --git a/third_party/libwebrtc/api/test/time_controller.cc b/third_party/libwebrtc/api/test/time_controller.cc
new file mode 100644
index 0000000000..364dbc235d
--- /dev/null
+++ b/third_party/libwebrtc/api/test/time_controller.cc
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/test/time_controller.h"
+
+namespace webrtc {
+std::unique_ptr<TaskQueueFactory> TimeController::CreateTaskQueueFactory() {
+ class FactoryWrapper final : public TaskQueueFactory {
+ public:
+ explicit FactoryWrapper(TaskQueueFactory* inner_factory)
+ : inner_(inner_factory) {}
+ std::unique_ptr<TaskQueueBase, TaskQueueDeleter> CreateTaskQueue(
+ absl::string_view name,
+ Priority priority) const override {
+ return inner_->CreateTaskQueue(name, priority);
+ }
+
+ private:
+ TaskQueueFactory* const inner_;
+ };
+ return std::make_unique<FactoryWrapper>(GetTaskQueueFactory());
+}
+bool TimeController::Wait(const std::function<bool()>& condition,
+ TimeDelta max_duration) {
+ // Step size is chosen to be short enough to not significantly affect latency
+ // in real time tests while being long enough to avoid adding too much load to
+ // the system.
+ const auto kStep = TimeDelta::Millis(5);
+ for (auto elapsed = TimeDelta::Zero(); elapsed < max_duration;
+ elapsed += kStep) {
+ if (condition())
+ return true;
+ AdvanceTime(kStep);
+ }
+ return condition();
+}
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/time_controller.h b/third_party/libwebrtc/api/test/time_controller.h
new file mode 100644
index 0000000000..121f65cea9
--- /dev/null
+++ b/third_party/libwebrtc/api/test/time_controller.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_TEST_TIME_CONTROLLER_H_
+#define API_TEST_TIME_CONTROLLER_H_
+
+#include <functional>
+#include <memory>
+#include <string>
+
+#include "api/task_queue/task_queue_factory.h"
+#include "api/units/time_delta.h"
+#include "api/units/timestamp.h"
+#include "rtc_base/synchronization/yield_policy.h"
+#include "rtc_base/thread.h"
+#include "system_wrappers/include/clock.h"
+
+namespace webrtc {
+// Interface for controlling time progress. This allows us to execute test code
+// in either real time or simulated time by using different implementation of
+// this interface.
+class TimeController {
+ public:
+ virtual ~TimeController() = default;
+ // Provides a clock instance that follows implementation defined time
+ // progress.
+ virtual Clock* GetClock() = 0;
+ // The returned factory will created task queues that runs in implementation
+ // defined time domain.
+ virtual TaskQueueFactory* GetTaskQueueFactory() = 0;
+ // Simple helper to create an owned factory that can be used as a parameter
+ // for PeerConnectionFactory. Note that this might depend on the underlying
+ // time controller and therfore must be destroyed before the time controller
+ // is destroyed.
+ std::unique_ptr<TaskQueueFactory> CreateTaskQueueFactory();
+
+ // Creates an rtc::Thread instance. If `socket_server` is nullptr, a default
+ // noop socket server is created.
+ // Returned thread is not null and started.
+ virtual std::unique_ptr<rtc::Thread> CreateThread(
+ const std::string& name,
+ std::unique_ptr<rtc::SocketServer> socket_server = nullptr) = 0;
+
+ // Creates an rtc::Thread instance that ensure that it's set as the current
+ // thread.
+ virtual rtc::Thread* GetMainThread() = 0;
+ // Allow task queues and process threads created by this instance to execute
+ // for the given `duration`.
+ virtual void AdvanceTime(TimeDelta duration) = 0;
+
+ // Waits until condition() == true, polling condition() in small time
+ // intervals.
+ // Returns true if condition() was evaluated to true before `max_duration`
+ // elapsed and false otherwise.
+ bool Wait(const std::function<bool()>& condition,
+ TimeDelta max_duration = TimeDelta::Seconds(5));
+};
+
+// Interface for telling time, scheduling an event to fire at a particular time,
+// and waiting for time to pass.
+class ControlledAlarmClock {
+ public:
+ virtual ~ControlledAlarmClock() = default;
+
+ // Gets a clock that tells the alarm clock's notion of time.
+ virtual Clock* GetClock() = 0;
+
+ // Schedules the alarm to fire at `deadline`.
+ // An alarm clock only supports one deadline. Calls to `ScheduleAlarmAt` with
+ // an earlier deadline will reset the alarm to fire earlier.Calls to
+ // `ScheduleAlarmAt` with a later deadline are ignored. Returns true if the
+ // deadline changed, false otherwise.
+ virtual bool ScheduleAlarmAt(Timestamp deadline) = 0;
+
+ // Sets the callback that should be run when the alarm fires.
+ virtual void SetCallback(std::function<void()> callback) = 0;
+
+ // Waits for `duration` to pass, according to the alarm clock.
+ virtual void Sleep(TimeDelta duration) = 0;
+};
+
+} // namespace webrtc
+#endif // API_TEST_TIME_CONTROLLER_H_
diff --git a/third_party/libwebrtc/api/test/track_id_stream_info_map.h b/third_party/libwebrtc/api/test/track_id_stream_info_map.h
new file mode 100644
index 0000000000..b016de57a9
--- /dev/null
+++ b/third_party/libwebrtc/api/test/track_id_stream_info_map.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_TRACK_ID_STREAM_INFO_MAP_H_
+#define API_TEST_TRACK_ID_STREAM_INFO_MAP_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+
+namespace webrtc {
+namespace webrtc_pc_e2e {
+
+// Instances of `TrackIdStreamInfoMap` provide bookkeeping capabilities that
+// are useful to associate stats reports track_ids to the remote stream info.
+class TrackIdStreamInfoMap {
+ public:
+ struct StreamInfo {
+ std::string receiver_peer;
+ std::string stream_label;
+ std::string sync_group;
+ };
+
+ virtual ~TrackIdStreamInfoMap() = default;
+
+ // These methods must be called on the same thread where
+ // StatsObserverInterface::OnStatsReports is invoked.
+
+ // Precondition: `track_id` must be already mapped to stream info.
+ virtual StreamInfo GetStreamInfoFromTrackId(
+ absl::string_view track_id) const = 0;
+};
+
+} // namespace webrtc_pc_e2e
+} // namespace webrtc
+
+#endif // API_TEST_TRACK_ID_STREAM_INFO_MAP_H_
diff --git a/third_party/libwebrtc/api/test/video/BUILD.gn b/third_party/libwebrtc/api/test/video/BUILD.gn
new file mode 100644
index 0000000000..d24ffa5fa6
--- /dev/null
+++ b/third_party/libwebrtc/api/test/video/BUILD.gn
@@ -0,0 +1,31 @@
+# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+
+rtc_library("function_video_factory") {
+ visibility = [ "*" ]
+ testonly = true
+ public = [
+ "function_video_decoder_factory.h",
+ "function_video_encoder_factory.h",
+ ]
+
+ deps = [
+ "../../../rtc_base:checks",
+ "../../video_codecs:video_codecs_api",
+ ]
+}
+
+rtc_library("video_frame_writer") {
+ visibility = [ "*" ]
+ testonly = true
+ public = [ "video_frame_writer.h" ]
+
+ deps = [ "../../video:video_frame" ]
+}
diff --git a/third_party/libwebrtc/api/test/video/function_video_decoder_factory.h b/third_party/libwebrtc/api/test/video/function_video_decoder_factory.h
new file mode 100644
index 0000000000..2145c71bff
--- /dev/null
+++ b/third_party/libwebrtc/api/test/video/function_video_decoder_factory.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_VIDEO_FUNCTION_VIDEO_DECODER_FACTORY_H_
+#define API_TEST_VIDEO_FUNCTION_VIDEO_DECODER_FACTORY_H_
+
+#include <functional>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "api/video_codecs/sdp_video_format.h"
+#include "api/video_codecs/video_decoder.h"
+#include "api/video_codecs/video_decoder_factory.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+namespace test {
+
+// A decoder factory producing decoders by calling a supplied create function.
+class FunctionVideoDecoderFactory final : public VideoDecoderFactory {
+ public:
+ explicit FunctionVideoDecoderFactory(
+ std::function<std::unique_ptr<VideoDecoder>()> create)
+ : create_([create = std::move(create)](const SdpVideoFormat&) {
+ return create();
+ }) {}
+ explicit FunctionVideoDecoderFactory(
+ std::function<std::unique_ptr<VideoDecoder>(const SdpVideoFormat&)>
+ create)
+ : create_(std::move(create)) {}
+ FunctionVideoDecoderFactory(
+ std::function<std::unique_ptr<VideoDecoder>()> create,
+ std::vector<SdpVideoFormat> sdp_video_formats)
+ : create_([create = std::move(create)](const SdpVideoFormat&) {
+ return create();
+ }),
+ sdp_video_formats_(std::move(sdp_video_formats)) {}
+
+ std::vector<SdpVideoFormat> GetSupportedFormats() const override {
+ return sdp_video_formats_;
+ }
+
+ std::unique_ptr<VideoDecoder> CreateVideoDecoder(
+ const SdpVideoFormat& format) override {
+ return create_(format);
+ }
+
+ private:
+ const std::function<std::unique_ptr<VideoDecoder>(const SdpVideoFormat&)>
+ create_;
+ const std::vector<SdpVideoFormat> sdp_video_formats_;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_VIDEO_FUNCTION_VIDEO_DECODER_FACTORY_H_
diff --git a/third_party/libwebrtc/api/test/video/function_video_encoder_factory.h b/third_party/libwebrtc/api/test/video/function_video_encoder_factory.h
new file mode 100644
index 0000000000..98ece2bc94
--- /dev/null
+++ b/third_party/libwebrtc/api/test/video/function_video_encoder_factory.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_VIDEO_FUNCTION_VIDEO_ENCODER_FACTORY_H_
+#define API_TEST_VIDEO_FUNCTION_VIDEO_ENCODER_FACTORY_H_
+
+#include <functional>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "api/video_codecs/sdp_video_format.h"
+#include "api/video_codecs/video_encoder.h"
+#include "api/video_codecs/video_encoder_factory.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+namespace test {
+
+// An encoder factory producing encoders by calling a supplied create
+// function.
+class FunctionVideoEncoderFactory final : public VideoEncoderFactory {
+ public:
+ explicit FunctionVideoEncoderFactory(
+ std::function<std::unique_ptr<VideoEncoder>()> create)
+ : create_([create = std::move(create)](const SdpVideoFormat&) {
+ return create();
+ }) {}
+ explicit FunctionVideoEncoderFactory(
+ std::function<std::unique_ptr<VideoEncoder>(const SdpVideoFormat&)>
+ create)
+ : create_(std::move(create)) {}
+
+ // Unused by tests.
+ std::vector<SdpVideoFormat> GetSupportedFormats() const override {
+ RTC_DCHECK_NOTREACHED();
+ return {};
+ }
+
+ std::unique_ptr<VideoEncoder> CreateVideoEncoder(
+ const SdpVideoFormat& format) override {
+ return create_(format);
+ }
+
+ private:
+ const std::function<std::unique_ptr<VideoEncoder>(const SdpVideoFormat&)>
+ create_;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_VIDEO_FUNCTION_VIDEO_ENCODER_FACTORY_H_
diff --git a/third_party/libwebrtc/api/test/video/video_frame_writer.h b/third_party/libwebrtc/api/test/video/video_frame_writer.h
new file mode 100644
index 0000000000..ac72534890
--- /dev/null
+++ b/third_party/libwebrtc/api/test/video/video_frame_writer.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_VIDEO_VIDEO_FRAME_WRITER_H_
+#define API_TEST_VIDEO_VIDEO_FRAME_WRITER_H_
+
+#include "api/video/video_frame.h"
+
+namespace webrtc {
+namespace test {
+
+class VideoFrameWriter {
+ public:
+ virtual ~VideoFrameWriter() = default;
+
+ // Writes `VideoFrame` and returns true if operation was successful, false
+ // otherwise.
+ //
+ // Calling `WriteFrame` after `Close` is not allowed.
+ virtual bool WriteFrame(const VideoFrame& frame) = 0;
+
+ // Closes writer and cleans up all resources. No invocations to `WriteFrame`
+ // are allowed after `Close` was invoked.
+ virtual void Close() = 0;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_VIDEO_VIDEO_FRAME_WRITER_H_
diff --git a/third_party/libwebrtc/api/test/video_codec_tester.h b/third_party/libwebrtc/api/test/video_codec_tester.h
new file mode 100644
index 0000000000..0eaaa1b895
--- /dev/null
+++ b/third_party/libwebrtc/api/test/video_codec_tester.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_VIDEO_CODEC_TESTER_H_
+#define API_TEST_VIDEO_CODEC_TESTER_H_
+
+#include <memory>
+
+#include "absl/functional/any_invocable.h"
+#include "api/test/videocodec_test_stats.h"
+#include "api/video/encoded_image.h"
+#include "api/video/resolution.h"
+#include "api/video/video_frame.h"
+
+namespace webrtc {
+namespace test {
+
+// Interface for a video codec tester. The interface provides minimalistic set
+// of data structures that enables implementation of decode-only, encode-only
+// and encode-decode tests.
+class VideoCodecTester {
+ public:
+ // Pacing settings for codec input.
+ struct PacingSettings {
+ enum PacingMode {
+ // Pacing is not used. Frames are sent to codec back-to-back.
+ kNoPacing,
+ // Pace with the rate equal to the target video frame rate. Pacing time is
+ // derived from RTP timestamp.
+ kRealTime,
+ // Pace with the explicitly provided rate.
+ kConstantRate,
+ };
+ PacingMode mode = PacingMode::kNoPacing;
+ // Pacing rate for `kConstantRate` mode.
+ Frequency constant_rate = Frequency::Zero();
+ };
+
+ struct DecoderSettings {
+ PacingSettings pacing;
+ };
+
+ struct EncoderSettings {
+ PacingSettings pacing;
+ };
+
+ virtual ~VideoCodecTester() = default;
+
+ // Interface for a raw video frames source.
+ class RawVideoSource {
+ public:
+ virtual ~RawVideoSource() = default;
+
+ // Returns next frame. If no more frames to pull, returns `absl::nullopt`.
+ // For analysis and pacing purposes, frame must have RTP timestamp set. The
+ // timestamp must represent the target video frame rate and be unique.
+ virtual absl::optional<VideoFrame> PullFrame() = 0;
+
+ // Returns early pulled frame with RTP timestamp equal to `timestamp_rtp`.
+ virtual VideoFrame GetFrame(uint32_t timestamp_rtp,
+ Resolution resolution) = 0;
+ };
+
+ // Interface for a coded video frames source.
+ class CodedVideoSource {
+ public:
+ virtual ~CodedVideoSource() = default;
+
+ // Returns next frame. If no more frames to pull, returns `absl::nullopt`.
+ // For analysis and pacing purposes, frame must have RTP timestamp set. The
+ // timestamp must represent the target video frame rate and be unique.
+ virtual absl::optional<EncodedImage> PullFrame() = 0;
+ };
+
+ // Interface for a video encoder.
+ class Encoder {
+ public:
+ using EncodeCallback =
+ absl::AnyInvocable<void(const EncodedImage& encoded_frame)>;
+
+ virtual ~Encoder() = default;
+
+ virtual void Encode(const VideoFrame& frame, EncodeCallback callback) = 0;
+ };
+
+ // Interface for a video decoder.
+ class Decoder {
+ public:
+ using DecodeCallback =
+ absl::AnyInvocable<void(const VideoFrame& decoded_frame)>;
+
+ virtual ~Decoder() = default;
+
+ virtual void Decode(const EncodedImage& frame, DecodeCallback callback) = 0;
+ };
+
+ // Pulls coded video frames from `video_source` and passes them to `decoder`.
+ // Returns `VideoCodecTestStats` object that contains collected per-frame
+ // metrics.
+ virtual std::unique_ptr<VideoCodecTestStats> RunDecodeTest(
+ std::unique_ptr<CodedVideoSource> video_source,
+ std::unique_ptr<Decoder> decoder,
+ const DecoderSettings& decoder_settings) = 0;
+
+ // Pulls raw video frames from `video_source` and passes them to `encoder`.
+ // Returns `VideoCodecTestStats` object that contains collected per-frame
+ // metrics.
+ virtual std::unique_ptr<VideoCodecTestStats> RunEncodeTest(
+ std::unique_ptr<RawVideoSource> video_source,
+ std::unique_ptr<Encoder> encoder,
+ const EncoderSettings& encoder_settings) = 0;
+
+ // Pulls raw video frames from `video_source`, passes them to `encoder` and
+ // then passes encoded frames to `decoder`. Returns `VideoCodecTestStats`
+ // object that contains collected per-frame metrics.
+ virtual std::unique_ptr<VideoCodecTestStats> RunEncodeDecodeTest(
+ std::unique_ptr<RawVideoSource> video_source,
+ std::unique_ptr<Encoder> encoder,
+ std::unique_ptr<Decoder> decoder,
+ const EncoderSettings& encoder_settings,
+ const DecoderSettings& decoder_settings) = 0;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_VIDEO_CODEC_TESTER_H_
diff --git a/third_party/libwebrtc/api/test/video_quality_analyzer_interface.h b/third_party/libwebrtc/api/test/video_quality_analyzer_interface.h
new file mode 100644
index 0000000000..d35be8ca1a
--- /dev/null
+++ b/third_party/libwebrtc/api/test/video_quality_analyzer_interface.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_VIDEO_QUALITY_ANALYZER_INTERFACE_H_
+#define API_TEST_VIDEO_QUALITY_ANALYZER_INTERFACE_H_
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/test/stats_observer_interface.h"
+#include "api/video/encoded_image.h"
+#include "api/video/video_frame.h"
+#include "api/video_codecs/video_encoder.h"
+
+namespace webrtc {
+
+// API is in development and can be changed without notice.
+
+// Base interface for video quality analyzer for peer connection level end-2-end
+// tests. Interface has only one abstract method, which have to return frame id.
+// Other methods have empty implementation by default, so user can override only
+// required parts.
+//
+// VideoQualityAnalyzerInterface will be injected into WebRTC pipeline on both
+// sides of the call. Here is video data flow in WebRTC pipeline
+//
+// Alice:
+// ___________ ________ _________
+// | | | | | |
+// | Frame |-(A)→| WebRTC |-(B)→| Video |-(C)┐
+// | Generator | | Stack | | Decoder | |
+// ¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯ |
+// __↓________
+// | Transport |
+// | & |
+// | Network |
+// ¯¯|¯¯¯¯¯¯¯¯
+// Bob: |
+// _______ ________ _________ |
+// | | | | | | |
+// | Video |←(F)-| WebRTC |←(E)-| Video |←(D)----┘
+// | Sink | | Stack | | Decoder |
+// ¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯
+// The analyzer will be injected in all points from A to F.
+class VideoQualityAnalyzerInterface
+ : public webrtc_pc_e2e::StatsObserverInterface {
+ public:
+ // Contains extra statistic provided by video encoder.
+ struct EncoderStats {
+ std::string encoder_name = "unknown";
+ // TODO(hbos) https://crbug.com/webrtc/9547,
+ // https://crbug.com/webrtc/11443: improve stats API to make available
+ // there.
+ uint32_t target_encode_bitrate = 0;
+ // Encoder quantizer value.
+ int qp = -1;
+ };
+ // Contains extra statistic provided by video decoder.
+ struct DecoderStats {
+ std::string decoder_name = "unknown";
+ // Decode time provided by decoder itself. If decoder doesn’t produce such
+ // information can be omitted.
+ absl::optional<int32_t> decode_time_ms = absl::nullopt;
+ };
+
+ ~VideoQualityAnalyzerInterface() override = default;
+
+ // Will be called by framework before test.
+ // `test_case_name` is name of test case, that should be used to report all
+ // video metrics.
+ // `threads_count` is number of threads that analyzer can use for heavy
+ // calculations. Analyzer can perform simple calculations on the calling
+ // thread in each method, but should remember, that it is the same thread,
+ // that is used in video pipeline.
+ virtual void Start(std::string test_case_name,
+ rtc::ArrayView<const std::string> peer_names,
+ int max_threads_count) {}
+
+ // Will be called when frame was generated from the input stream.
+ // `peer_name` is name of the peer on which side frame was captured.
+ // Returns frame id, that will be set by framework to the frame.
+ virtual uint16_t OnFrameCaptured(absl::string_view peer_name,
+ const std::string& stream_label,
+ const VideoFrame& frame) = 0;
+ // Will be called before calling the encoder.
+ // `peer_name` is name of the peer on which side frame came to encoder.
+ virtual void OnFramePreEncode(absl::string_view peer_name,
+ const VideoFrame& frame) {}
+ // Will be called for each EncodedImage received from encoder. Single
+ // VideoFrame can produce multiple EncodedImages. Each encoded image will
+ // have id from VideoFrame.
+ // `peer_name` is name of the peer on which side frame was encoded.
+ virtual void OnFrameEncoded(absl::string_view peer_name,
+ uint16_t frame_id,
+ const EncodedImage& encoded_image,
+ const EncoderStats& stats,
+ bool discarded) {}
+ // Will be called for each frame dropped by encoder.
+ // `peer_name` is name of the peer on which side frame drop was detected.
+ virtual void OnFrameDropped(absl::string_view peer_name,
+ EncodedImageCallback::DropReason reason) {}
+ // Will be called before calling the decoder.
+ // `peer_name` is name of the peer on which side frame was received.
+ virtual void OnFramePreDecode(absl::string_view peer_name,
+ uint16_t frame_id,
+ const EncodedImage& encoded_image) {}
+ // Will be called after decoding the frame.
+ // `peer_name` is name of the peer on which side frame was decoded.
+ virtual void OnFrameDecoded(absl::string_view peer_name,
+ const VideoFrame& frame,
+ const DecoderStats& stats) {}
+ // Will be called when frame will be obtained from PeerConnection stack.
+ // `peer_name` is name of the peer on which side frame was rendered.
+ virtual void OnFrameRendered(absl::string_view peer_name,
+ const VideoFrame& frame) {}
+ // Will be called if encoder return not WEBRTC_VIDEO_CODEC_OK.
+ // All available codes are listed in
+ // modules/video_coding/include/video_error_codes.h
+ // `peer_name` is name of the peer on which side error acquired.
+ virtual void OnEncoderError(absl::string_view peer_name,
+ const VideoFrame& frame,
+ int32_t error_code) {}
+ // Will be called if decoder return not WEBRTC_VIDEO_CODEC_OK.
+ // All available codes are listed in
+ // modules/video_coding/include/video_error_codes.h
+ // `peer_name` is name of the peer on which side error acquired.
+ virtual void OnDecoderError(absl::string_view peer_name,
+ uint16_t frame_id,
+ int32_t error_code,
+ const DecoderStats& stats) {}
+ // Will be called every time new stats reports are available for the
+ // Peer Connection identified by `pc_label`.
+ void OnStatsReports(
+ absl::string_view pc_label,
+ const rtc::scoped_refptr<const RTCStatsReport>& report) override {}
+
+ // Will be called before test adds new participant in the middle of a call.
+ virtual void RegisterParticipantInCall(absl::string_view peer_name) {}
+ // Will be called after test removed existing participant in the middle of the
+ // call.
+ virtual void UnregisterParticipantInCall(absl::string_view peer_name) {}
+
+ // Tells analyzer that analysis complete and it should calculate final
+ // statistics.
+ virtual void Stop() {}
+
+ // Returns the last stream where this frame was captured. It means that if
+ // frame ids space wraps around, then stream label for frame id may change.
+ // It will crash, if the specified `frame_id` wasn't captured.
+ virtual std::string GetStreamLabel(uint16_t frame_id) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_VIDEO_QUALITY_ANALYZER_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/test/video_quality_test_fixture.h b/third_party/libwebrtc/api/test/video_quality_test_fixture.h
new file mode 100644
index 0000000000..b45faef286
--- /dev/null
+++ b/third_party/libwebrtc/api/test/video_quality_test_fixture.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_VIDEO_QUALITY_TEST_FIXTURE_H_
+#define API_TEST_VIDEO_QUALITY_TEST_FIXTURE_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "api/fec_controller.h"
+#include "api/media_types.h"
+#include "api/network_state_predictor.h"
+#include "api/test/simulated_network.h"
+#include "api/transport/bitrate_settings.h"
+#include "api/transport/network_control.h"
+#include "api/video_codecs/sdp_video_format.h"
+#include "api/video_codecs/video_decoder_factory.h"
+#include "api/video_codecs/video_encoder_factory.h"
+#include "video/config/video_encoder_config.h"
+
+namespace webrtc {
+
+class VideoQualityTestFixtureInterface {
+ public:
+ // Parameters are grouped into smaller structs to make it easier to set
+ // the desired elements and skip unused.
+ struct Params {
+ struct CallConfig {
+ bool send_side_bwe = false;
+ bool generic_descriptor = false;
+ bool dependency_descriptor = false;
+ BitrateConstraints call_bitrate_config;
+ int num_thumbnails = 0;
+ // Indicates if secondary_(video|ss|screenshare) structures are used.
+ bool dual_video = false;
+ } call;
+ struct Video {
+ bool enabled = false;
+ size_t width = 640;
+ size_t height = 480;
+ int32_t fps = 30;
+ int min_bitrate_bps = 50;
+ int target_bitrate_bps = 800;
+ int max_bitrate_bps = 800;
+ bool suspend_below_min_bitrate = false;
+ std::string codec = "VP8";
+ int num_temporal_layers = 1;
+ int selected_tl = -1;
+ int min_transmit_bps = 0;
+ bool ulpfec = false;
+ bool flexfec = false;
+ bool automatic_scaling = false;
+ std::string clip_path; // "Generator" to generate frames instead.
+ size_t capture_device_index = 0;
+ SdpVideoFormat::Parameters sdp_params;
+ double encoder_overshoot_factor = 0.0;
+ } video[2];
+ struct Audio {
+ bool enabled = false;
+ bool sync_video = false;
+ bool dtx = false;
+ bool use_real_adm = false;
+ absl::optional<std::string> ana_config;
+ } audio;
+ struct Screenshare {
+ bool enabled = false;
+ bool generate_slides = false;
+ int32_t slide_change_interval = 10;
+ int32_t scroll_duration = 0;
+ std::vector<std::string> slides;
+ } screenshare[2];
+ struct Analyzer {
+ std::string test_label;
+ double avg_psnr_threshold = 0.0; // (*)
+ double avg_ssim_threshold = 0.0; // (*)
+ int test_durations_secs = 0;
+ std::string graph_data_output_filename;
+ std::string graph_title;
+ } analyzer;
+ // Config for default simulation implementation. Must be nullopt if
+ // `sender_network` and `receiver_network` in InjectionComponents are
+ // non-null. May be nullopt even if `sender_network` and `receiver_network`
+ // are null; in that case, a default config will be used.
+ absl::optional<BuiltInNetworkBehaviorConfig> config;
+ struct SS { // Spatial scalability.
+ std::vector<VideoStream> streams; // If empty, one stream is assumed.
+ size_t selected_stream = 0;
+ int num_spatial_layers = 0;
+ int selected_sl = -1;
+ InterLayerPredMode inter_layer_pred = InterLayerPredMode::kOn;
+ // If empty, bitrates are generated in VP9Impl automatically.
+ std::vector<SpatialLayer> spatial_layers;
+ // If set, default parameters will be used instead of `streams`.
+ bool infer_streams = false;
+ } ss[2];
+ struct Logging {
+ std::string rtc_event_log_name;
+ std::string rtp_dump_name;
+ std::string encoded_frame_base_path;
+ } logging;
+ };
+
+ // Contains objects, that will be injected on different layers of test
+ // framework to override the behavior of system parts.
+ struct InjectionComponents {
+ InjectionComponents();
+ ~InjectionComponents();
+
+ // Simulations of sender and receiver networks. They must either both be
+ // null (in which case `config` from Params is used), or both be non-null
+ // (in which case `config` from Params must be nullopt).
+ std::unique_ptr<NetworkBehaviorInterface> sender_network;
+ std::unique_ptr<NetworkBehaviorInterface> receiver_network;
+
+ std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory;
+ std::unique_ptr<VideoEncoderFactory> video_encoder_factory;
+ std::unique_ptr<VideoDecoderFactory> video_decoder_factory;
+ std::unique_ptr<NetworkStatePredictorFactoryInterface>
+ network_state_predictor_factory;
+ std::unique_ptr<NetworkControllerFactoryInterface>
+ network_controller_factory;
+ };
+
+ virtual ~VideoQualityTestFixtureInterface() = default;
+
+ virtual void RunWithAnalyzer(const Params& params) = 0;
+ virtual void RunWithRenderers(const Params& params) = 0;
+
+ virtual const std::map<uint8_t, webrtc::MediaType>& payload_type_map() = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_VIDEO_QUALITY_TEST_FIXTURE_H_
diff --git a/third_party/libwebrtc/api/test/videocodec_test_fixture.h b/third_party/libwebrtc/api/test/videocodec_test_fixture.h
new file mode 100644
index 0000000000..dbf20993e2
--- /dev/null
+++ b/third_party/libwebrtc/api/test/videocodec_test_fixture.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_VIDEOCODEC_TEST_FIXTURE_H_
+#define API_TEST_VIDEOCODEC_TEST_FIXTURE_H_
+
+#include <string>
+#include <vector>
+
+#include "api/test/videocodec_test_stats.h"
+#include "api/video_codecs/h264_profile_level_id.h"
+#include "api/video_codecs/video_decoder_factory.h"
+#include "api/video_codecs/video_encoder_factory.h"
+#include "modules/video_coding/include/video_codec_interface.h"
+
+namespace webrtc {
+namespace test {
+
+// Rates for the encoder and the frame number when to apply profile.
+struct RateProfile {
+ size_t target_kbps;
+ double input_fps;
+ size_t frame_num;
+};
+
+struct RateControlThresholds {
+ double max_avg_bitrate_mismatch_percent;
+ double max_time_to_reach_target_bitrate_sec;
+ // TODO(ssilkin): Use absolute threshold for framerate.
+ double max_avg_framerate_mismatch_percent;
+ double max_avg_buffer_level_sec;
+ double max_max_key_frame_delay_sec;
+ double max_max_delta_frame_delay_sec;
+ size_t max_num_spatial_resizes;
+ size_t max_num_key_frames;
+};
+
+struct QualityThresholds {
+ double min_avg_psnr;
+ double min_min_psnr;
+ double min_avg_ssim;
+ double min_min_ssim;
+};
+
+struct BitstreamThresholds {
+ size_t max_max_nalu_size_bytes;
+};
+
+// NOTE: This class is still under development and may change without notice.
+class VideoCodecTestFixture {
+ public:
+ class EncodedFrameChecker {
+ public:
+ virtual ~EncodedFrameChecker() = default;
+ virtual void CheckEncodedFrame(VideoCodecType codec,
+ const EncodedImage& encoded_frame) const = 0;
+ };
+
+ struct Config {
+ Config();
+ void SetCodecSettings(std::string codec_name,
+ size_t num_simulcast_streams,
+ size_t num_spatial_layers,
+ size_t num_temporal_layers,
+ bool denoising_on,
+ bool frame_dropper_on,
+ bool spatial_resize_on,
+ size_t width,
+ size_t height);
+
+ size_t NumberOfCores() const;
+ size_t NumberOfTemporalLayers() const;
+ size_t NumberOfSpatialLayers() const;
+ size_t NumberOfSimulcastStreams() const;
+
+ std::string ToString() const;
+ std::string CodecName() const;
+
+ // Name of this config, to be used for accounting by the test runner.
+ std::string test_name;
+
+ // Plain name of YUV file to process without file extension.
+ std::string filename;
+ // Dimensions of test clip. Falls back to (codec_settings.width/height) if
+ // not set.
+ absl::optional<int> clip_width;
+ absl::optional<int> clip_height;
+ // Framerate of input clip. Defaults to 30fps if not set.
+ absl::optional<int> clip_fps;
+
+ // The resolution at which psnr/ssim comparisons should be made. Frames
+ // will be scaled to this size if different.
+ absl::optional<int> reference_width;
+ absl::optional<int> reference_height;
+
+ // File to process. This must be a video file in the YUV format.
+ std::string filepath;
+
+ // Number of frames to process.
+ size_t num_frames = 0;
+
+ // Bitstream constraints.
+ size_t max_payload_size_bytes = 1440;
+
+ // Should we decode the encoded frames?
+ bool decode = true;
+
+ // Force the encoder and decoder to use a single core for processing.
+ bool use_single_core = false;
+
+ // Should cpu usage be measured?
+ // If set to true, the encoding will run in real-time.
+ bool measure_cpu = false;
+
+ // Simulate frames arriving in real-time by adding delays between frames.
+ bool encode_in_real_time = false;
+
+ // Codec settings to use.
+ VideoCodec codec_settings;
+
+ // Name of the codec being tested.
+ std::string codec_name;
+
+ // Encoder and decoder format and parameters. If provided, format is used to
+ // instantiate the codec. If not provided, the test creates and uses the
+ // default `SdpVideoFormat` based on `codec_name`.
+ // Encoder and decoder name (`SdpVideoFormat::name`) should be the same as
+ // `codec_name`.
+ absl::optional<SdpVideoFormat> encoder_format;
+ absl::optional<SdpVideoFormat> decoder_format;
+
+ // H.264 specific settings.
+ struct H264CodecSettings {
+ H264Profile profile = H264Profile::kProfileConstrainedBaseline;
+ H264PacketizationMode packetization_mode =
+ H264PacketizationMode::NonInterleaved;
+ } h264_codec_settings;
+
+ // Custom checker that will be called for each frame.
+ const EncodedFrameChecker* encoded_frame_checker = nullptr;
+
+ // Print out frame level stats.
+ bool print_frame_level_stats = false;
+
+ // Path to a directory where encoded or/and decoded video should be saved.
+ std::string output_path;
+
+ // Should video be saved persistently to disk for post-run visualization?
+ struct VisualizationParams {
+ bool save_encoded_ivf = false;
+ bool save_decoded_y4m = false;
+ } visualization_params;
+
+ // Enables quality analysis for dropped frames.
+ bool analyze_quality_of_dropped_frames = false;
+ };
+
+ virtual ~VideoCodecTestFixture() = default;
+
+ virtual void RunTest(const std::vector<RateProfile>& rate_profiles,
+ const std::vector<RateControlThresholds>* rc_thresholds,
+ const std::vector<QualityThresholds>* quality_thresholds,
+ const BitstreamThresholds* bs_thresholds) = 0;
+ virtual VideoCodecTestStats& GetStats() = 0;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_VIDEOCODEC_TEST_FIXTURE_H_
diff --git a/third_party/libwebrtc/api/test/videocodec_test_stats.cc b/third_party/libwebrtc/api/test/videocodec_test_stats.cc
new file mode 100644
index 0000000000..f082b1e935
--- /dev/null
+++ b/third_party/libwebrtc/api/test/videocodec_test_stats.cc
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/videocodec_test_stats.h"
+
+#include "rtc_base/strings/string_builder.h"
+
+namespace webrtc {
+namespace test {
+
+VideoCodecTestStats::FrameStatistics::FrameStatistics(size_t frame_number,
+ size_t rtp_timestamp,
+ size_t spatial_idx)
+ : frame_number(frame_number),
+ rtp_timestamp(rtp_timestamp),
+ spatial_idx(spatial_idx) {}
+
+std::string VideoCodecTestStats::FrameStatistics::ToString() const {
+ rtc::StringBuilder ss;
+ for (const auto& entry : ToMap()) {
+ if (ss.size() > 0) {
+ ss << " ";
+ }
+ ss << entry.first << " " << entry.second;
+ }
+ return ss.Release();
+}
+
+std::map<std::string, std::string> VideoCodecTestStats::FrameStatistics::ToMap()
+ const {
+ std::map<std::string, std::string> map;
+ map["frame_number"] = std::to_string(frame_number);
+ map["decoded_width"] = std::to_string(decoded_width);
+ map["decoded_height"] = std::to_string(decoded_height);
+ map["spatial_idx"] = std::to_string(spatial_idx);
+ map["temporal_idx"] = std::to_string(temporal_idx);
+ map["inter_layer_predicted"] = std::to_string(inter_layer_predicted);
+ map["non_ref_for_inter_layer_pred"] =
+ std::to_string(non_ref_for_inter_layer_pred);
+ map["frame_type"] = std::to_string(static_cast<int>(frame_type));
+ map["length_bytes"] = std::to_string(length_bytes);
+ map["qp"] = std::to_string(qp);
+ map["psnr"] = std::to_string(psnr);
+ map["psnr_y"] = std::to_string(psnr_y);
+ map["psnr_u"] = std::to_string(psnr_u);
+ map["psnr_v"] = std::to_string(psnr_v);
+ map["ssim"] = std::to_string(ssim);
+ map["encode_time_us"] = std::to_string(encode_time_us);
+ map["decode_time_us"] = std::to_string(decode_time_us);
+ map["rtp_timestamp"] = std::to_string(rtp_timestamp);
+ map["target_bitrate_kbps"] = std::to_string(target_bitrate_kbps);
+ map["target_framerate_fps"] = std::to_string(target_framerate_fps);
+ return map;
+}
+
+std::string VideoCodecTestStats::VideoStatistics::ToString(
+ std::string prefix) const {
+ rtc::StringBuilder ss;
+ for (const auto& entry : ToMap()) {
+ if (ss.size() > 0) {
+ ss << "\n";
+ }
+ ss << prefix << entry.first << ": " << entry.second;
+ }
+ return ss.Release();
+}
+
+std::map<std::string, std::string> VideoCodecTestStats::VideoStatistics::ToMap()
+ const {
+ std::map<std::string, std::string> map;
+ map["target_bitrate_kbps"] = std::to_string(target_bitrate_kbps);
+ map["input_framerate_fps"] = std::to_string(input_framerate_fps);
+ map["spatial_idx"] = std::to_string(spatial_idx);
+ map["temporal_idx"] = std::to_string(temporal_idx);
+ map["width"] = std::to_string(width);
+ map["height"] = std::to_string(height);
+ map["length_bytes"] = std::to_string(length_bytes);
+ map["bitrate_kbps"] = std::to_string(bitrate_kbps);
+ map["framerate_fps"] = std::to_string(framerate_fps);
+ map["enc_speed_fps"] = std::to_string(enc_speed_fps);
+ map["dec_speed_fps"] = std::to_string(dec_speed_fps);
+ map["avg_encode_latency_sec"] = std::to_string(avg_encode_latency_sec);
+ map["max_encode_latency_sec"] = std::to_string(max_encode_latency_sec);
+ map["avg_decode_latency_sec"] = std::to_string(avg_decode_latency_sec);
+ map["max_decode_latency_sec"] = std::to_string(max_decode_latency_sec);
+ map["avg_delay_sec"] = std::to_string(avg_delay_sec);
+ map["max_key_frame_delay_sec"] = std::to_string(max_key_frame_delay_sec);
+ map["max_delta_frame_delay_sec"] = std::to_string(max_delta_frame_delay_sec);
+ map["time_to_reach_target_bitrate_sec"] =
+ std::to_string(time_to_reach_target_bitrate_sec);
+ map["avg_bitrate_mismatch_pct"] = std::to_string(avg_bitrate_mismatch_pct);
+ map["avg_framerate_mismatch_pct"] =
+ std::to_string(avg_framerate_mismatch_pct);
+ map["avg_key_frame_size_bytes"] = std::to_string(avg_key_frame_size_bytes);
+ map["avg_delta_frame_size_bytes"] =
+ std::to_string(avg_delta_frame_size_bytes);
+ map["avg_qp"] = std::to_string(avg_qp);
+ map["avg_psnr"] = std::to_string(avg_psnr);
+ map["min_psnr"] = std::to_string(min_psnr);
+ map["avg_ssim"] = std::to_string(avg_ssim);
+ map["min_ssim"] = std::to_string(min_ssim);
+ map["num_input_frames"] = std::to_string(num_input_frames);
+ map["num_encoded_frames"] = std::to_string(num_encoded_frames);
+ map["num_decoded_frames"] = std::to_string(num_decoded_frames);
+ map["num_dropped_frames"] =
+ std::to_string(num_input_frames - num_encoded_frames);
+ map["num_key_frames"] = std::to_string(num_key_frames);
+ map["num_spatial_resizes"] = std::to_string(num_spatial_resizes);
+ map["max_nalu_size_bytes"] = std::to_string(max_nalu_size_bytes);
+ return map;
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/test/videocodec_test_stats.h b/third_party/libwebrtc/api/test/videocodec_test_stats.h
new file mode 100644
index 0000000000..12c60638db
--- /dev/null
+++ b/third_party/libwebrtc/api/test/videocodec_test_stats.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TEST_VIDEOCODEC_TEST_STATS_H_
+#define API_TEST_VIDEOCODEC_TEST_STATS_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/units/data_rate.h"
+#include "api/units/frequency.h"
+#include "api/video/video_frame_type.h"
+
+namespace webrtc {
+namespace test {
+
+// Statistics for a sequence of processed frames. This class is not thread safe.
+class VideoCodecTestStats {
+ public:
+ // Statistics for one processed frame.
+ struct FrameStatistics {
+ FrameStatistics(size_t frame_number,
+ size_t rtp_timestamp,
+ size_t spatial_idx);
+
+ std::string ToString() const;
+
+ // Returns name -> value text map of frame statistics.
+ std::map<std::string, std::string> ToMap() const;
+
+ size_t frame_number = 0;
+ size_t rtp_timestamp = 0;
+
+ // Encoding.
+ int64_t encode_start_ns = 0;
+ int encode_return_code = 0;
+ bool encoding_successful = false;
+ size_t encode_time_us = 0;
+ size_t target_bitrate_kbps = 0;
+ double target_framerate_fps = 0.0;
+ size_t length_bytes = 0;
+ VideoFrameType frame_type = VideoFrameType::kVideoFrameDelta;
+
+ // Layering.
+ size_t spatial_idx = 0;
+ size_t temporal_idx = 0;
+ bool inter_layer_predicted = false;
+ bool non_ref_for_inter_layer_pred = true;
+
+ // H264 specific.
+ size_t max_nalu_size_bytes = 0;
+
+ // Decoding.
+ int64_t decode_start_ns = 0;
+ int decode_return_code = 0;
+ bool decoding_successful = false;
+ size_t decode_time_us = 0;
+ size_t decoded_width = 0;
+ size_t decoded_height = 0;
+
+ // Quantization.
+ int qp = -1;
+
+ // Quality.
+ bool quality_analysis_successful = false;
+ float psnr_y = 0.0f;
+ float psnr_u = 0.0f;
+ float psnr_v = 0.0f;
+ float psnr = 0.0f; // 10 * log10(255^2 / (mse_y + mse_u + mse_v)).
+ float ssim = 0.0f; // 0.8 * ssim_y + 0.1 * (ssim_u + ssim_v).
+ };
+
+ struct VideoStatistics {
+ std::string ToString(std::string prefix) const;
+
+ // Returns name -> value text map of video statistics.
+ std::map<std::string, std::string> ToMap() const;
+
+ size_t target_bitrate_kbps = 0;
+ float input_framerate_fps = 0.0f;
+
+ size_t spatial_idx = 0;
+ size_t temporal_idx = 0;
+
+ size_t width = 0;
+ size_t height = 0;
+
+ size_t length_bytes = 0;
+ size_t bitrate_kbps = 0;
+ float framerate_fps = 0;
+
+ float enc_speed_fps = 0.0f;
+ float dec_speed_fps = 0.0f;
+
+ float avg_encode_latency_sec = 0.0f;
+ float max_encode_latency_sec = 0.0f;
+ float avg_decode_latency_sec = 0.0f;
+ float max_decode_latency_sec = 0.0f;
+
+ float avg_delay_sec = 0.0f;
+ float max_key_frame_delay_sec = 0.0f;
+ float max_delta_frame_delay_sec = 0.0f;
+ float time_to_reach_target_bitrate_sec = 0.0f;
+ float avg_bitrate_mismatch_pct = 0.0f;
+ float avg_framerate_mismatch_pct = 0.0f;
+
+ float avg_key_frame_size_bytes = 0.0f;
+ float avg_delta_frame_size_bytes = 0.0f;
+ float avg_qp = 0.0f;
+
+ float avg_psnr_y = 0.0f;
+ float avg_psnr_u = 0.0f;
+ float avg_psnr_v = 0.0f;
+ float avg_psnr = 0.0f;
+ float min_psnr = 0.0f;
+ float avg_ssim = 0.0f;
+ float min_ssim = 0.0f;
+
+ size_t num_input_frames = 0;
+ size_t num_encoded_frames = 0;
+ size_t num_decoded_frames = 0;
+ size_t num_key_frames = 0;
+ size_t num_spatial_resizes = 0;
+ size_t max_nalu_size_bytes = 0;
+ };
+
+ virtual ~VideoCodecTestStats() = default;
+
+ virtual std::vector<FrameStatistics> GetFrameStatistics() const = 0;
+
+ virtual std::vector<VideoStatistics> SliceAndCalcLayerVideoStatistic(
+ size_t first_frame_num,
+ size_t last_frame_num) = 0;
+
+ virtual VideoStatistics CalcVideoStatistic(size_t first_frame,
+ size_t last_frame,
+ DataRate target_bitrate,
+ Frequency target_framerate) = 0;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // API_TEST_VIDEOCODEC_TEST_STATS_H_
diff --git a/third_party/libwebrtc/api/transport/BUILD.gn b/third_party/libwebrtc/api/transport/BUILD.gn
new file mode 100644
index 0000000000..e0b31122b2
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/BUILD.gn
@@ -0,0 +1,167 @@
+# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../webrtc.gni")
+
+rtc_library("bitrate_settings") {
+ visibility = [ "*" ]
+ sources = [
+ "bitrate_settings.cc",
+ "bitrate_settings.h",
+ ]
+ deps = [ "../../rtc_base/system:rtc_export" ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_source_set("enums") {
+ visibility = [ "*" ]
+ sources = [ "enums.h" ]
+}
+
+rtc_library("network_control") {
+ visibility = [ "*" ]
+ sources = [
+ "network_control.h",
+ "network_types.cc",
+ "network_types.h",
+ ]
+
+ deps = [
+ "../../api:field_trials_view",
+ "../rtc_event_log",
+ "../units:data_rate",
+ "../units:data_size",
+ "../units:time_delta",
+ "../units:timestamp",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
+rtc_library("field_trial_based_config") {
+ visibility = [ "*" ]
+ sources = [
+ "field_trial_based_config.cc",
+ "field_trial_based_config.h",
+ ]
+ deps = [
+ "../../api:field_trials_registry",
+ "../../system_wrappers:field_trial",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
+}
+
+rtc_source_set("datagram_transport_interface") {
+ visibility = [ "*" ]
+ sources = [ "data_channel_transport_interface.h" ]
+ deps = [
+ "..:array_view",
+ "..:rtc_error",
+ "../../rtc_base:copy_on_write_buffer",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_library("goog_cc") {
+ visibility = [ "*" ]
+ sources = [
+ "goog_cc_factory.cc",
+ "goog_cc_factory.h",
+ ]
+ deps = [
+ ":network_control",
+ "..:network_state_predictor_api",
+ "../../api:field_trials_view",
+ "../../modules/congestion_controller/goog_cc",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/base:core_headers" ]
+}
+
+rtc_source_set("sctp_transport_factory_interface") {
+ visibility = [ "*" ]
+ sources = [ "sctp_transport_factory_interface.h" ]
+}
+
+rtc_source_set("stun_types") {
+if (!build_with_mozilla) {
+ visibility = [ "*" ]
+ sources = [
+ "stun.cc",
+ "stun.h",
+ ]
+
+ deps = [
+ "../../api:array_view",
+ "../../rtc_base:byte_buffer",
+ "../../rtc_base:byte_order",
+ "../../rtc_base:checks",
+ "../../rtc_base:crc32",
+ "../../rtc_base:ip_address",
+ "../../rtc_base:logging",
+ "../../rtc_base:socket_address",
+ "../../rtc_base:ssl",
+ "../../system_wrappers:metrics",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
+}
+}
+
+if (rtc_include_tests) {
+ rtc_source_set("test_feedback_generator_interface") {
+ testonly = true
+ sources = [ "test/feedback_generator_interface.h" ]
+ deps = [
+ ":network_control",
+ "..:simulated_network_api",
+ ]
+ }
+ rtc_library("test_feedback_generator") {
+ testonly = true
+ sources = [
+ "test/create_feedback_generator.cc",
+ "test/create_feedback_generator.h",
+ ]
+ visibility = [ "*" ]
+ deps = [
+ ":network_control",
+ ":test_feedback_generator_interface",
+ "../../test/network:feedback_generator",
+ ]
+ }
+}
+
+if (rtc_include_tests) {
+ rtc_source_set("stun_unittest") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "stun_unittest.cc" ]
+ deps = [
+ ":stun_types",
+ "../../rtc_base:byte_buffer",
+ "../../rtc_base:byte_order",
+ "../../rtc_base:macromagic",
+ "../../rtc_base:socket_address",
+ "../../system_wrappers:metrics",
+ "../../test:test_support",
+ "//testing/gtest",
+ ]
+ }
+}
+
+if (rtc_include_tests) {
+ rtc_source_set("mock_network_control") {
+ testonly = true
+ sources = [ "test/mock_network_control.h" ]
+ deps = [
+ ":network_control",
+ "../../test:test_support",
+ ]
+ }
+}
diff --git a/third_party/libwebrtc/api/transport/DEPS b/third_party/libwebrtc/api/transport/DEPS
new file mode 100644
index 0000000000..53a68e0e85
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/DEPS
@@ -0,0 +1,7 @@
+specific_include_rules = {
+ "stun\.h": [
+ "+rtc_base/byte_buffer.h",
+ "+rtc_base/ip_address.h",
+ "+rtc_base/socket_address.h",
+ ],
+}
diff --git a/third_party/libwebrtc/api/transport/OWNERS b/third_party/libwebrtc/api/transport/OWNERS
new file mode 100644
index 0000000000..5991f6fc56
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/OWNERS
@@ -0,0 +1,2 @@
+srte@webrtc.org
+terelius@webrtc.org
diff --git a/third_party/libwebrtc/api/transport/bitrate_settings.cc b/third_party/libwebrtc/api/transport/bitrate_settings.cc
new file mode 100644
index 0000000000..c72bd82791
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/bitrate_settings.cc
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/transport/bitrate_settings.h"
+
+namespace webrtc {
+
+BitrateSettings::BitrateSettings() = default;
+BitrateSettings::~BitrateSettings() = default;
+BitrateSettings::BitrateSettings(const BitrateSettings&) = default;
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/transport/bitrate_settings.h b/third_party/libwebrtc/api/transport/bitrate_settings.h
new file mode 100644
index 0000000000..562309a46c
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/bitrate_settings.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TRANSPORT_BITRATE_SETTINGS_H_
+#define API_TRANSPORT_BITRATE_SETTINGS_H_
+
+#include <algorithm>
+
+#include "absl/types/optional.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Configuration of send bitrate. The `start_bitrate_bps` value is
+// used for multiple purposes, both as a prior in the bandwidth
+// estimator, and for initial configuration of the encoder. We may
+// want to create separate apis for those, and use a smaller struct
+// with only the min and max constraints.
+struct RTC_EXPORT BitrateSettings {
+ BitrateSettings();
+ ~BitrateSettings();
+ BitrateSettings(const BitrateSettings&);
+ // 0 <= min <= start <= max should hold for set parameters.
+ absl::optional<int> min_bitrate_bps;
+ absl::optional<int> start_bitrate_bps;
+ absl::optional<int> max_bitrate_bps;
+};
+
+// TODO(srte): BitrateConstraints and BitrateSettings should be merged.
+// Both represent the same kind data, but are using different default
+// initializer and representation of unset values.
+struct BitrateConstraints {
+ int min_bitrate_bps = 0;
+ int start_bitrate_bps = kDefaultStartBitrateBps;
+ int max_bitrate_bps = -1;
+
+ private:
+ static constexpr int kDefaultStartBitrateBps = 300000;
+};
+
+} // namespace webrtc
+
+#endif // API_TRANSPORT_BITRATE_SETTINGS_H_
diff --git a/third_party/libwebrtc/api/transport/bitrate_settings_gn/moz.build b/third_party/libwebrtc/api/transport/bitrate_settings_gn/moz.build
new file mode 100644
index 0000000000..fba5b45a5d
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/bitrate_settings_gn/moz.build
@@ -0,0 +1,217 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/transport/bitrate_settings.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("bitrate_settings_gn")
diff --git a/third_party/libwebrtc/api/transport/data_channel_transport_interface.h b/third_party/libwebrtc/api/transport/data_channel_transport_interface.h
new file mode 100644
index 0000000000..cdae6fee19
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/data_channel_transport_interface.h
@@ -0,0 +1,125 @@
+/* Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This is an experimental interface and is subject to change without notice.
+
+#ifndef API_TRANSPORT_DATA_CHANNEL_TRANSPORT_INTERFACE_H_
+#define API_TRANSPORT_DATA_CHANNEL_TRANSPORT_INTERFACE_H_
+
+#include "absl/types/optional.h"
+#include "api/rtc_error.h"
+#include "rtc_base/copy_on_write_buffer.h"
+
+namespace webrtc {
+
+// Supported types of application data messages.
+enum class DataMessageType {
+ // Application data buffer with the binary bit unset.
+ kText,
+
+ // Application data buffer with the binary bit set.
+ kBinary,
+
+ // Transport-agnostic control messages, such as open or open-ack messages.
+ kControl,
+};
+
+// Parameters for sending data. The parameters may change from message to
+// message, even within a single channel. For example, control messages may be
+// sent reliably and in-order, even if the data channel is configured for
+// unreliable delivery.
+struct SendDataParams {
+ DataMessageType type = DataMessageType::kText;
+
+ // Whether to deliver the message in order with respect to other ordered
+ // messages with the same channel_id.
+ bool ordered = false;
+
+ // If set, the maximum number of times this message may be
+ // retransmitted by the transport before it is dropped.
+ // Setting this value to zero disables retransmission.
+ // Valid values are in the range [0-UINT16_MAX].
+ // `max_rtx_count` and `max_rtx_ms` may not be set simultaneously.
+ absl::optional<int> max_rtx_count;
+
+ // If set, the maximum number of milliseconds for which the transport
+ // may retransmit this message before it is dropped.
+ // Setting this value to zero disables retransmission.
+ // Valid values are in the range [0-UINT16_MAX].
+ // `max_rtx_count` and `max_rtx_ms` may not be set simultaneously.
+ absl::optional<int> max_rtx_ms;
+};
+
+// Sink for callbacks related to a data channel.
+class DataChannelSink {
+ public:
+ virtual ~DataChannelSink() = default;
+
+ // Callback issued when data is received by the transport.
+ virtual void OnDataReceived(int channel_id,
+ DataMessageType type,
+ const rtc::CopyOnWriteBuffer& buffer) = 0;
+
+ // Callback issued when a remote data channel begins the closing procedure.
+ // Messages sent after the closing procedure begins will not be transmitted.
+ virtual void OnChannelClosing(int channel_id) = 0;
+
+ // Callback issued when a (remote or local) data channel completes the closing
+ // procedure. Closing channels become closed after all pending data has been
+ // transmitted.
+ virtual void OnChannelClosed(int channel_id) = 0;
+
+ // Callback issued when the data channel becomes ready to send.
+ // This callback will be issued immediately when the data channel sink is
+ // registered if the transport is ready at that time. This callback may be
+ // invoked again following send errors (eg. due to the transport being
+ // temporarily blocked or unavailable).
+ virtual void OnReadyToSend() = 0;
+
+ // Callback issued when the data channel becomes unusable (closed).
+ // TODO(https://crbug.com/webrtc/10360): Make pure virtual when all
+ // consumers updated.
+ virtual void OnTransportClosed(RTCError error) {}
+};
+
+// Transport for data channels.
+class DataChannelTransportInterface {
+ public:
+ virtual ~DataChannelTransportInterface() = default;
+
+ // Opens a data `channel_id` for sending. May return an error if the
+ // specified `channel_id` is unusable. Must be called before `SendData`.
+ virtual RTCError OpenChannel(int channel_id) = 0;
+
+ // Sends a data buffer to the remote endpoint using the given send parameters.
+ // `buffer` may not be larger than 256 KiB. Returns an error if the send
+ // fails.
+ virtual RTCError SendData(int channel_id,
+ const SendDataParams& params,
+ const rtc::CopyOnWriteBuffer& buffer) = 0;
+
+ // Closes `channel_id` gracefully. Returns an error if `channel_id` is not
+ // open. Data sent after the closing procedure begins will not be
+ // transmitted. The channel becomes closed after pending data is transmitted.
+ virtual RTCError CloseChannel(int channel_id) = 0;
+
+ // Sets a sink for data messages and channel state callbacks. Before media
+ // transport is destroyed, the sink must be unregistered by setting it to
+ // nullptr.
+ virtual void SetDataSink(DataChannelSink* sink) = 0;
+
+ // Returns whether this data channel transport is ready to send.
+ // Note: the default implementation always returns false (as it assumes no one
+ // has implemented the interface). This default implementation is temporary.
+ virtual bool IsReadyToSend() const = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_TRANSPORT_DATA_CHANNEL_TRANSPORT_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/transport/datagram_transport_interface_gn/moz.build b/third_party/libwebrtc/api/transport/datagram_transport_interface_gn/moz.build
new file mode 100644
index 0000000000..ac59bcbcde
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/datagram_transport_interface_gn/moz.build
@@ -0,0 +1,209 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("datagram_transport_interface_gn")
diff --git a/third_party/libwebrtc/api/transport/enums.h b/third_party/libwebrtc/api/transport/enums.h
new file mode 100644
index 0000000000..3bc8fd1529
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/enums.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2018 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TRANSPORT_ENUMS_H_
+#define API_TRANSPORT_ENUMS_H_
+
+namespace webrtc {
+
+// See https://w3c.github.io/webrtc-pc/#rtcicetransportstate
+// Note that kFailed is currently not a terminal state, and a transport might
+// incorrectly be marked as failed while gathering candidates, see
+// bugs.webrtc.org/8833
+enum class IceTransportState {
+ kNew,
+ kChecking,
+ kConnected,
+ kCompleted,
+ kFailed,
+ kDisconnected,
+ kClosed,
+};
+
+enum PortPrunePolicy {
+ NO_PRUNE, // Do not prune.
+ PRUNE_BASED_ON_PRIORITY, // Prune lower-priority ports on the same network.
+ KEEP_FIRST_READY // Keep the first ready port and prune the rest
+ // on the same network.
+};
+
+enum class VpnPreference {
+ kDefault, // No VPN preference.
+ kOnlyUseVpn, // only use VPN connections.
+ kNeverUseVpn, // never use VPN connections
+ kPreferVpn, // use a VPN connection if possible,
+ // i.e VPN connections sorts first.
+ kAvoidVpn, // only use VPN if there is no other connections,
+ // i.e VPN connections sorts last.
+};
+
+} // namespace webrtc
+
+#endif // API_TRANSPORT_ENUMS_H_
diff --git a/third_party/libwebrtc/api/transport/field_trial_based_config.cc b/third_party/libwebrtc/api/transport/field_trial_based_config.cc
new file mode 100644
index 0000000000..0cef30f054
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/field_trial_based_config.cc
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/transport/field_trial_based_config.h"
+
+#include "system_wrappers/include/field_trial.h"
+
+namespace webrtc {
+std::string FieldTrialBasedConfig::GetValue(absl::string_view key) const {
+ return webrtc::field_trial::FindFullName(std::string(key));
+}
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/transport/field_trial_based_config.h b/third_party/libwebrtc/api/transport/field_trial_based_config.h
new file mode 100644
index 0000000000..d47140e579
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/field_trial_based_config.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_TRANSPORT_FIELD_TRIAL_BASED_CONFIG_H_
+#define API_TRANSPORT_FIELD_TRIAL_BASED_CONFIG_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "api/field_trials_registry.h"
+
+namespace webrtc {
+// Implementation using the field trial API fo the key value lookup.
+class FieldTrialBasedConfig : public FieldTrialsRegistry {
+ private:
+ std::string GetValue(absl::string_view key) const override;
+};
+} // namespace webrtc
+
+#endif // API_TRANSPORT_FIELD_TRIAL_BASED_CONFIG_H_
diff --git a/third_party/libwebrtc/api/transport/field_trial_based_config_gn/moz.build b/third_party/libwebrtc/api/transport/field_trial_based_config_gn/moz.build
new file mode 100644
index 0000000000..1ef79b4d20
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/field_trial_based_config_gn/moz.build
@@ -0,0 +1,225 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/transport/field_trial_based_config.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("field_trial_based_config_gn")
diff --git a/third_party/libwebrtc/api/transport/goog_cc_factory.cc b/third_party/libwebrtc/api/transport/goog_cc_factory.cc
new file mode 100644
index 0000000000..fd1189901f
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/goog_cc_factory.cc
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/transport/goog_cc_factory.h"
+
+#include <memory>
+#include <utility>
+
+#include "modules/congestion_controller/goog_cc/goog_cc_network_control.h"
+
+namespace webrtc {
+GoogCcNetworkControllerFactory::GoogCcNetworkControllerFactory(
+ RtcEventLog* event_log)
+ : event_log_(event_log) {}
+
+GoogCcNetworkControllerFactory::GoogCcNetworkControllerFactory(
+ NetworkStatePredictorFactoryInterface* network_state_predictor_factory) {
+ factory_config_.network_state_predictor_factory =
+ network_state_predictor_factory;
+}
+
+GoogCcNetworkControllerFactory::GoogCcNetworkControllerFactory(
+ GoogCcFactoryConfig config)
+ : factory_config_(std::move(config)) {}
+
+std::unique_ptr<NetworkControllerInterface>
+GoogCcNetworkControllerFactory::Create(NetworkControllerConfig config) {
+ if (event_log_)
+ config.event_log = event_log_;
+ GoogCcConfig goog_cc_config;
+ goog_cc_config.feedback_only = factory_config_.feedback_only;
+ if (factory_config_.network_state_estimator_factory) {
+ RTC_DCHECK(config.key_value_config);
+ goog_cc_config.network_state_estimator =
+ factory_config_.network_state_estimator_factory->Create(
+ config.key_value_config);
+ }
+ if (factory_config_.network_state_predictor_factory) {
+ goog_cc_config.network_state_predictor =
+ factory_config_.network_state_predictor_factory
+ ->CreateNetworkStatePredictor();
+ }
+ return std::make_unique<GoogCcNetworkController>(config,
+ std::move(goog_cc_config));
+}
+
+TimeDelta GoogCcNetworkControllerFactory::GetProcessInterval() const {
+ const int64_t kUpdateIntervalMs = 25;
+ return TimeDelta::Millis(kUpdateIntervalMs);
+}
+
+GoogCcFeedbackNetworkControllerFactory::GoogCcFeedbackNetworkControllerFactory(
+ RtcEventLog* event_log)
+ : GoogCcNetworkControllerFactory(event_log) {
+ factory_config_.feedback_only = true;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/transport/goog_cc_factory.h b/third_party/libwebrtc/api/transport/goog_cc_factory.h
new file mode 100644
index 0000000000..e12755d745
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/goog_cc_factory.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TRANSPORT_GOOG_CC_FACTORY_H_
+#define API_TRANSPORT_GOOG_CC_FACTORY_H_
+#include <memory>
+
+#include "absl/base/attributes.h"
+#include "api/network_state_predictor.h"
+#include "api/transport/network_control.h"
+
+namespace webrtc {
+class RtcEventLog;
+
+struct GoogCcFactoryConfig {
+ std::unique_ptr<NetworkStateEstimatorFactory>
+ network_state_estimator_factory = nullptr;
+ NetworkStatePredictorFactoryInterface* network_state_predictor_factory =
+ nullptr;
+ bool feedback_only = false;
+};
+
+class GoogCcNetworkControllerFactory
+ : public NetworkControllerFactoryInterface {
+ public:
+ GoogCcNetworkControllerFactory() = default;
+ ABSL_DEPRECATED("")
+ explicit GoogCcNetworkControllerFactory(RtcEventLog* event_log);
+ explicit GoogCcNetworkControllerFactory(
+ NetworkStatePredictorFactoryInterface* network_state_predictor_factory);
+
+ explicit GoogCcNetworkControllerFactory(GoogCcFactoryConfig config);
+ std::unique_ptr<NetworkControllerInterface> Create(
+ NetworkControllerConfig config) override;
+ TimeDelta GetProcessInterval() const override;
+
+ protected:
+ RtcEventLog* const event_log_ = nullptr;
+ GoogCcFactoryConfig factory_config_;
+};
+
+// Deprecated, use GoogCcFactoryConfig to enable feedback only mode instead.
+// Factory to create packet feedback only GoogCC, this can be used for
+// connections providing packet receive time feedback but no other reports.
+class ABSL_DEPRECATED("use GoogCcFactoryConfig instead")
+ GoogCcFeedbackNetworkControllerFactory
+ : public GoogCcNetworkControllerFactory {
+ public:
+ explicit GoogCcFeedbackNetworkControllerFactory(RtcEventLog* event_log);
+};
+
+} // namespace webrtc
+
+#endif // API_TRANSPORT_GOOG_CC_FACTORY_H_
diff --git a/third_party/libwebrtc/api/transport/goog_cc_gn/moz.build b/third_party/libwebrtc/api/transport/goog_cc_gn/moz.build
new file mode 100644
index 0000000000..95cbec37f0
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/goog_cc_gn/moz.build
@@ -0,0 +1,232 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/transport/goog_cc_factory.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "rt"
+ ]
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "crypt32",
+ "iphlpapi",
+ "secur32",
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("goog_cc_gn")
diff --git a/third_party/libwebrtc/api/transport/network_control.h b/third_party/libwebrtc/api/transport/network_control.h
new file mode 100644
index 0000000000..862322443d
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/network_control.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TRANSPORT_NETWORK_CONTROL_H_
+#define API_TRANSPORT_NETWORK_CONTROL_H_
+#include <stdint.h>
+
+#include <memory>
+
+#include "absl/base/attributes.h"
+#include "api/field_trials_view.h"
+#include "api/rtc_event_log/rtc_event_log.h"
+#include "api/transport/network_types.h"
+
+namespace webrtc {
+
+class TargetTransferRateObserver {
+ public:
+ virtual ~TargetTransferRateObserver() = default;
+ // Called to indicate target transfer rate as well as giving information about
+ // the current estimate of network parameters.
+ virtual void OnTargetTransferRate(TargetTransferRate) = 0;
+ // Called to provide updates to the expected target rate in case it changes
+ // before the first call to OnTargetTransferRate.
+ virtual void OnStartRateUpdate(DataRate) {}
+};
+
+// Configuration sent to factory create function. The parameters here are
+// optional to use for a network controller implementation.
+struct NetworkControllerConfig {
+ // The initial constraints to start with, these can be changed at any later
+ // time by calls to OnTargetRateConstraints. Note that the starting rate
+ // has to be set initially to provide a starting state for the network
+ // controller, even though the field is marked as optional.
+ TargetRateConstraints constraints;
+ // Initial stream specific configuration, these are changed at any later time
+ // by calls to OnStreamsConfig.
+ StreamsConfig stream_based_config;
+
+ // Optional override of configuration of WebRTC internals. Using nullptr here
+ // indicates that the field trial API will be used.
+ const FieldTrialsView* key_value_config = nullptr;
+ // Optional override of event log.
+ RtcEventLog* event_log = nullptr;
+};
+
+// NetworkControllerInterface is implemented by network controllers. A network
+// controller is a class that uses information about network state and traffic
+// to estimate network parameters such as round trip time and bandwidth. Network
+// controllers does not guarantee thread safety, the interface must be used in a
+// non-concurrent fashion.
+class NetworkControllerInterface {
+ public:
+ virtual ~NetworkControllerInterface() = default;
+
+ // Called when network availabilty changes.
+ ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnNetworkAvailability(
+ NetworkAvailability) = 0;
+ // Called when the receiving or sending endpoint changes address.
+ ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnNetworkRouteChange(
+ NetworkRouteChange) = 0;
+ // Called periodically with a periodicy as specified by
+ // NetworkControllerFactoryInterface::GetProcessInterval.
+ ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnProcessInterval(
+ ProcessInterval) = 0;
+ // Called when remotely calculated bitrate is received.
+ ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnRemoteBitrateReport(
+ RemoteBitrateReport) = 0;
+ // Called round trip time has been calculated by protocol specific mechanisms.
+ ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnRoundTripTimeUpdate(
+ RoundTripTimeUpdate) = 0;
+ // Called when a packet is sent on the network.
+ ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnSentPacket(
+ SentPacket) = 0;
+ // Called when a packet is received from the remote client.
+ ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnReceivedPacket(
+ ReceivedPacket) = 0;
+ // Called when the stream specific configuration has been updated.
+ ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnStreamsConfig(
+ StreamsConfig) = 0;
+ // Called when target transfer rate constraints has been changed.
+ ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnTargetRateConstraints(
+ TargetRateConstraints) = 0;
+ // Called when a protocol specific calculation of packet loss has been made.
+ ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnTransportLossReport(
+ TransportLossReport) = 0;
+ // Called with per packet feedback regarding receive time.
+ ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnTransportPacketsFeedback(
+ TransportPacketsFeedback) = 0;
+ // Called with network state estimate updates.
+ ABSL_MUST_USE_RESULT virtual NetworkControlUpdate OnNetworkStateEstimate(
+ NetworkStateEstimate) = 0;
+};
+
+// NetworkControllerFactoryInterface is an interface for creating a network
+// controller.
+class NetworkControllerFactoryInterface {
+ public:
+ virtual ~NetworkControllerFactoryInterface() = default;
+
+ // Used to create a new network controller, requires an observer to be
+ // provided to handle callbacks.
+ virtual std::unique_ptr<NetworkControllerInterface> Create(
+ NetworkControllerConfig config) = 0;
+ // Returns the interval by which the network controller expects
+ // OnProcessInterval calls.
+ virtual TimeDelta GetProcessInterval() const = 0;
+};
+
+// Under development, subject to change without notice.
+class NetworkStateEstimator {
+ public:
+ // Gets the current best estimate according to the estimator.
+ virtual absl::optional<NetworkStateEstimate> GetCurrentEstimate() = 0;
+ // Called with per packet feedback regarding receive time.
+ // Used when the NetworkStateEstimator runs in the sending endpoint.
+ virtual void OnTransportPacketsFeedback(const TransportPacketsFeedback&) = 0;
+ // Called with per packet feedback regarding receive time.
+ // Used when the NetworkStateEstimator runs in the receiving endpoint.
+ virtual void OnReceivedPacket(const PacketResult&) {}
+ // Called when the receiving or sending endpoint changes address.
+ virtual void OnRouteChange(const NetworkRouteChange&) = 0;
+ virtual ~NetworkStateEstimator() = default;
+};
+class NetworkStateEstimatorFactory {
+ public:
+ virtual std::unique_ptr<NetworkStateEstimator> Create(
+ const FieldTrialsView* key_value_config) = 0;
+ virtual ~NetworkStateEstimatorFactory() = default;
+};
+} // namespace webrtc
+
+#endif // API_TRANSPORT_NETWORK_CONTROL_H_
diff --git a/third_party/libwebrtc/api/transport/network_control_gn/moz.build b/third_party/libwebrtc/api/transport/network_control_gn/moz.build
new file mode 100644
index 0000000000..181843597f
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/network_control_gn/moz.build
@@ -0,0 +1,225 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/transport/network_types.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("network_control_gn")
diff --git a/third_party/libwebrtc/api/transport/network_types.cc b/third_party/libwebrtc/api/transport/network_types.cc
new file mode 100644
index 0000000000..d6495ce490
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/network_types.cc
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/transport/network_types.h"
+
+#include <algorithm>
+
+namespace webrtc {
+StreamsConfig::StreamsConfig() = default;
+StreamsConfig::StreamsConfig(const StreamsConfig&) = default;
+StreamsConfig::~StreamsConfig() = default;
+
+TargetRateConstraints::TargetRateConstraints() = default;
+TargetRateConstraints::TargetRateConstraints(const TargetRateConstraints&) =
+ default;
+TargetRateConstraints::~TargetRateConstraints() = default;
+
+NetworkRouteChange::NetworkRouteChange() = default;
+NetworkRouteChange::NetworkRouteChange(const NetworkRouteChange&) = default;
+NetworkRouteChange::~NetworkRouteChange() = default;
+
+PacketResult::PacketResult() = default;
+PacketResult::PacketResult(const PacketResult& other) = default;
+PacketResult::~PacketResult() = default;
+
+bool PacketResult::ReceiveTimeOrder::operator()(const PacketResult& lhs,
+ const PacketResult& rhs) {
+ if (lhs.receive_time != rhs.receive_time)
+ return lhs.receive_time < rhs.receive_time;
+ if (lhs.sent_packet.send_time != rhs.sent_packet.send_time)
+ return lhs.sent_packet.send_time < rhs.sent_packet.send_time;
+ return lhs.sent_packet.sequence_number < rhs.sent_packet.sequence_number;
+}
+
+TransportPacketsFeedback::TransportPacketsFeedback() = default;
+TransportPacketsFeedback::TransportPacketsFeedback(
+ const TransportPacketsFeedback& other) = default;
+TransportPacketsFeedback::~TransportPacketsFeedback() = default;
+
+std::vector<PacketResult> TransportPacketsFeedback::ReceivedWithSendInfo()
+ const {
+ std::vector<PacketResult> res;
+ for (const PacketResult& fb : packet_feedbacks) {
+ if (fb.IsReceived()) {
+ res.push_back(fb);
+ }
+ }
+ return res;
+}
+
+std::vector<PacketResult> TransportPacketsFeedback::LostWithSendInfo() const {
+ std::vector<PacketResult> res;
+ for (const PacketResult& fb : packet_feedbacks) {
+ if (!fb.IsReceived()) {
+ res.push_back(fb);
+ }
+ }
+ return res;
+}
+
+std::vector<PacketResult> TransportPacketsFeedback::PacketsWithFeedback()
+ const {
+ return packet_feedbacks;
+}
+
+std::vector<PacketResult> TransportPacketsFeedback::SortedByReceiveTime()
+ const {
+ std::vector<PacketResult> res;
+ for (const PacketResult& fb : packet_feedbacks) {
+ if (fb.IsReceived()) {
+ res.push_back(fb);
+ }
+ }
+ std::sort(res.begin(), res.end(), PacketResult::ReceiveTimeOrder());
+ return res;
+}
+
+NetworkControlUpdate::NetworkControlUpdate() = default;
+NetworkControlUpdate::NetworkControlUpdate(const NetworkControlUpdate&) =
+ default;
+NetworkControlUpdate::~NetworkControlUpdate() = default;
+
+PacedPacketInfo::PacedPacketInfo() = default;
+
+PacedPacketInfo::PacedPacketInfo(int probe_cluster_id,
+ int probe_cluster_min_probes,
+ int probe_cluster_min_bytes)
+ : probe_cluster_id(probe_cluster_id),
+ probe_cluster_min_probes(probe_cluster_min_probes),
+ probe_cluster_min_bytes(probe_cluster_min_bytes) {}
+
+bool PacedPacketInfo::operator==(const PacedPacketInfo& rhs) const {
+ return send_bitrate_bps == rhs.send_bitrate_bps &&
+ probe_cluster_id == rhs.probe_cluster_id &&
+ probe_cluster_min_probes == rhs.probe_cluster_min_probes &&
+ probe_cluster_min_bytes == rhs.probe_cluster_min_bytes;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/transport/network_types.h b/third_party/libwebrtc/api/transport/network_types.h
new file mode 100644
index 0000000000..29a7cf7705
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/network_types.h
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TRANSPORT_NETWORK_TYPES_H_
+#define API_TRANSPORT_NETWORK_TYPES_H_
+#include <stdint.h>
+
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/units/data_rate.h"
+#include "api/units/data_size.h"
+#include "api/units/time_delta.h"
+#include "api/units/timestamp.h"
+
+namespace webrtc {
+
+// Configuration
+
+// Represents constraints and rates related to the currently enabled streams.
+// This is used as input to the congestion controller via the StreamsConfig
+// struct.
+struct BitrateAllocationLimits {
+ // The total minimum send bitrate required by all sending streams.
+ DataRate min_allocatable_rate = DataRate::Zero();
+ // The total maximum allocatable bitrate for all currently available streams.
+ DataRate max_allocatable_rate = DataRate::Zero();
+ // The max bitrate to use for padding. The sum of the per-stream max padding
+ // rate.
+ DataRate max_padding_rate = DataRate::Zero();
+};
+
+// Use StreamsConfig for information about streams that is required for specific
+// adjustments to the algorithms in network controllers. Especially useful
+// for experiments.
+struct StreamsConfig {
+ StreamsConfig();
+ StreamsConfig(const StreamsConfig&);
+ ~StreamsConfig();
+ Timestamp at_time = Timestamp::PlusInfinity();
+ absl::optional<bool> requests_alr_probing;
+ absl::optional<double> pacing_factor;
+
+ // TODO(srte): Use BitrateAllocationLimits here.
+ absl::optional<DataRate> min_total_allocated_bitrate;
+ absl::optional<DataRate> max_padding_rate;
+ absl::optional<DataRate> max_total_allocated_bitrate;
+};
+
+struct TargetRateConstraints {
+ TargetRateConstraints();
+ TargetRateConstraints(const TargetRateConstraints&);
+ ~TargetRateConstraints();
+ Timestamp at_time = Timestamp::PlusInfinity();
+ absl::optional<DataRate> min_data_rate;
+ absl::optional<DataRate> max_data_rate;
+ // The initial bandwidth estimate to base target rate on. This should be used
+ // as the basis for initial OnTargetTransferRate and OnPacerConfig callbacks.
+ absl::optional<DataRate> starting_rate;
+};
+
+// Send side information
+
+struct NetworkAvailability {
+ Timestamp at_time = Timestamp::PlusInfinity();
+ bool network_available = false;
+};
+
+struct NetworkRouteChange {
+ NetworkRouteChange();
+ NetworkRouteChange(const NetworkRouteChange&);
+ ~NetworkRouteChange();
+ Timestamp at_time = Timestamp::PlusInfinity();
+ // The TargetRateConstraints are set here so they can be changed synchronously
+ // when network route changes.
+ TargetRateConstraints constraints;
+};
+
+struct PacedPacketInfo {
+ PacedPacketInfo();
+ PacedPacketInfo(int probe_cluster_id,
+ int probe_cluster_min_probes,
+ int probe_cluster_min_bytes);
+
+ bool operator==(const PacedPacketInfo& rhs) const;
+
+ // TODO(srte): Move probing info to a separate, optional struct.
+ static constexpr int kNotAProbe = -1;
+ int send_bitrate_bps = -1;
+ int probe_cluster_id = kNotAProbe;
+ int probe_cluster_min_probes = -1;
+ int probe_cluster_min_bytes = -1;
+ int probe_cluster_bytes_sent = 0;
+};
+
+struct SentPacket {
+ Timestamp send_time = Timestamp::PlusInfinity();
+ // Size of packet with overhead up to IP layer.
+ DataSize size = DataSize::Zero();
+ // Size of preceeding packets that are not part of feedback.
+ DataSize prior_unacked_data = DataSize::Zero();
+ // Probe cluster id and parameters including bitrate, number of packets and
+ // number of bytes.
+ PacedPacketInfo pacing_info;
+ // True if the packet is an audio packet, false for video, padding, RTX etc.
+ bool audio = false;
+ // Transport independent sequence number, any tracked packet should have a
+ // sequence number that is unique over the whole call and increasing by 1 for
+ // each packet.
+ int64_t sequence_number;
+ // Tracked data in flight when the packet was sent, excluding unacked data.
+ DataSize data_in_flight = DataSize::Zero();
+};
+
+struct ReceivedPacket {
+ Timestamp send_time = Timestamp::MinusInfinity();
+ Timestamp receive_time = Timestamp::PlusInfinity();
+ DataSize size = DataSize::Zero();
+};
+
+// Transport level feedback
+
+struct RemoteBitrateReport {
+ Timestamp receive_time = Timestamp::PlusInfinity();
+ DataRate bandwidth = DataRate::Infinity();
+};
+
+struct RoundTripTimeUpdate {
+ Timestamp receive_time = Timestamp::PlusInfinity();
+ TimeDelta round_trip_time = TimeDelta::PlusInfinity();
+ bool smoothed = false;
+};
+
+struct TransportLossReport {
+ Timestamp receive_time = Timestamp::PlusInfinity();
+ Timestamp start_time = Timestamp::PlusInfinity();
+ Timestamp end_time = Timestamp::PlusInfinity();
+ uint64_t packets_lost_delta = 0;
+ uint64_t packets_received_delta = 0;
+};
+
+// Packet level feedback
+
+struct PacketResult {
+ class ReceiveTimeOrder {
+ public:
+ bool operator()(const PacketResult& lhs, const PacketResult& rhs);
+ };
+
+ PacketResult();
+ PacketResult(const PacketResult&);
+ ~PacketResult();
+
+ inline bool IsReceived() const { return !receive_time.IsPlusInfinity(); }
+
+ SentPacket sent_packet;
+ Timestamp receive_time = Timestamp::PlusInfinity();
+};
+
+struct TransportPacketsFeedback {
+ TransportPacketsFeedback();
+ TransportPacketsFeedback(const TransportPacketsFeedback& other);
+ ~TransportPacketsFeedback();
+
+ Timestamp feedback_time = Timestamp::PlusInfinity();
+ Timestamp first_unacked_send_time = Timestamp::PlusInfinity();
+ DataSize data_in_flight = DataSize::Zero();
+ DataSize prior_in_flight = DataSize::Zero();
+ std::vector<PacketResult> packet_feedbacks;
+
+ // Arrival times for messages without send time information.
+ std::vector<Timestamp> sendless_arrival_times;
+
+ std::vector<PacketResult> ReceivedWithSendInfo() const;
+ std::vector<PacketResult> LostWithSendInfo() const;
+ std::vector<PacketResult> PacketsWithFeedback() const;
+ std::vector<PacketResult> SortedByReceiveTime() const;
+};
+
+// Network estimation
+
+struct NetworkEstimate {
+ Timestamp at_time = Timestamp::PlusInfinity();
+ // Deprecated, use TargetTransferRate::target_rate instead.
+ DataRate bandwidth = DataRate::Infinity();
+ TimeDelta round_trip_time = TimeDelta::PlusInfinity();
+ TimeDelta bwe_period = TimeDelta::PlusInfinity();
+
+ float loss_rate_ratio = 0;
+};
+
+// Network control
+
+struct PacerConfig {
+ Timestamp at_time = Timestamp::PlusInfinity();
+ // Pacer should send at most data_window data over time_window duration.
+ DataSize data_window = DataSize::Infinity();
+ TimeDelta time_window = TimeDelta::PlusInfinity();
+ // Pacer should send at least pad_window data over time_window duration.
+ DataSize pad_window = DataSize::Zero();
+ DataRate data_rate() const { return data_window / time_window; }
+ DataRate pad_rate() const { return pad_window / time_window; }
+};
+
+struct ProbeClusterConfig {
+ Timestamp at_time = Timestamp::PlusInfinity();
+ DataRate target_data_rate = DataRate::Zero();
+ TimeDelta target_duration = TimeDelta::Zero();
+ int32_t target_probe_count = 0;
+ int32_t id = 0;
+};
+
+struct TargetTransferRate {
+ Timestamp at_time = Timestamp::PlusInfinity();
+ // The estimate on which the target rate is based on.
+ NetworkEstimate network_estimate;
+ DataRate target_rate = DataRate::Zero();
+ DataRate stable_target_rate = DataRate::Zero();
+ double cwnd_reduce_ratio = 0;
+};
+
+// Contains updates of network controller comand state. Using optionals to
+// indicate whether a member has been updated. The array of probe clusters
+// should be used to send out probes if not empty.
+struct NetworkControlUpdate {
+ NetworkControlUpdate();
+ NetworkControlUpdate(const NetworkControlUpdate&);
+ ~NetworkControlUpdate();
+ absl::optional<DataSize> congestion_window;
+ absl::optional<PacerConfig> pacer_config;
+ std::vector<ProbeClusterConfig> probe_cluster_configs;
+ absl::optional<TargetTransferRate> target_rate;
+};
+
+// Process control
+struct ProcessInterval {
+ Timestamp at_time = Timestamp::PlusInfinity();
+ absl::optional<DataSize> pacer_queue;
+};
+
+// Under development, subject to change without notice.
+struct NetworkStateEstimate {
+ double confidence = NAN;
+ // The time the estimate was received/calculated.
+ Timestamp update_time = Timestamp::MinusInfinity();
+ Timestamp last_receive_time = Timestamp::MinusInfinity();
+ Timestamp last_send_time = Timestamp::MinusInfinity();
+
+ // Total estimated link capacity.
+ DataRate link_capacity = DataRate::MinusInfinity();
+ // Used as a safe measure of available capacity.
+ DataRate link_capacity_lower = DataRate::MinusInfinity();
+ // Used as limit for increasing bitrate.
+ DataRate link_capacity_upper = DataRate::MinusInfinity();
+
+ TimeDelta pre_link_buffer_delay = TimeDelta::MinusInfinity();
+ TimeDelta post_link_buffer_delay = TimeDelta::MinusInfinity();
+ TimeDelta propagation_delay = TimeDelta::MinusInfinity();
+
+ // Only for debugging
+ TimeDelta time_delta = TimeDelta::MinusInfinity();
+ Timestamp last_feed_time = Timestamp::MinusInfinity();
+ double cross_delay_rate = NAN;
+ double spike_delay_rate = NAN;
+ DataRate link_capacity_std_dev = DataRate::MinusInfinity();
+ DataRate link_capacity_min = DataRate::MinusInfinity();
+ double cross_traffic_ratio = NAN;
+};
+} // namespace webrtc
+
+#endif // API_TRANSPORT_NETWORK_TYPES_H_
diff --git a/third_party/libwebrtc/api/transport/rtp/BUILD.gn b/third_party/libwebrtc/api/transport/rtp/BUILD.gn
new file mode 100644
index 0000000000..205bbcc988
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/rtp/BUILD.gn
@@ -0,0 +1,37 @@
+# Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+
+rtc_source_set("rtp_source") {
+ visibility = [ "*" ]
+ sources = [ "rtp_source.h" ]
+ deps = [
+ "../../../api:rtp_headers",
+ "../../../api/units:time_delta",
+ "../../../rtc_base:checks",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_source_set("dependency_descriptor") {
+ visibility = [ "*" ]
+ sources = [
+ "dependency_descriptor.cc",
+ "dependency_descriptor.h",
+ ]
+ deps = [
+ "../../../rtc_base:checks",
+ "../../video:render_resolution",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/container:inlined_vector",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
diff --git a/third_party/libwebrtc/api/transport/rtp/dependency_descriptor.cc b/third_party/libwebrtc/api/transport/rtp/dependency_descriptor.cc
new file mode 100644
index 0000000000..e784853cd6
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/rtp/dependency_descriptor.cc
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/transport/rtp/dependency_descriptor.h"
+
+#include "absl/container/inlined_vector.h"
+#include "absl/strings/string_view.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+constexpr int DependencyDescriptor::kMaxSpatialIds;
+constexpr int DependencyDescriptor::kMaxTemporalIds;
+constexpr int DependencyDescriptor::kMaxTemplates;
+constexpr int DependencyDescriptor::kMaxDecodeTargets;
+
+namespace webrtc_impl {
+
+absl::InlinedVector<DecodeTargetIndication, 10> StringToDecodeTargetIndications(
+ absl::string_view symbols) {
+ absl::InlinedVector<DecodeTargetIndication, 10> dtis;
+ dtis.reserve(symbols.size());
+ for (char symbol : symbols) {
+ DecodeTargetIndication indication;
+ switch (symbol) {
+ case '-':
+ indication = DecodeTargetIndication::kNotPresent;
+ break;
+ case 'D':
+ indication = DecodeTargetIndication::kDiscardable;
+ break;
+ case 'R':
+ indication = DecodeTargetIndication::kRequired;
+ break;
+ case 'S':
+ indication = DecodeTargetIndication::kSwitch;
+ break;
+ default:
+ RTC_DCHECK_NOTREACHED();
+ }
+ dtis.push_back(indication);
+ }
+ return dtis;
+}
+
+} // namespace webrtc_impl
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/transport/rtp/dependency_descriptor.h b/third_party/libwebrtc/api/transport/rtp/dependency_descriptor.h
new file mode 100644
index 0000000000..0db600918e
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/rtp/dependency_descriptor.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TRANSPORT_RTP_DEPENDENCY_DESCRIPTOR_H_
+#define API_TRANSPORT_RTP_DEPENDENCY_DESCRIPTOR_H_
+
+#include <stdint.h>
+
+#include <initializer_list>
+#include <memory>
+#include <vector>
+
+#include "absl/container/inlined_vector.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "api/video/render_resolution.h"
+
+namespace webrtc {
+// Structures to build and parse dependency descriptor as described in
+// https://aomediacodec.github.io/av1-rtp-spec/#dependency-descriptor-rtp-header-extension
+
+// Relationship of a frame to a Decode target.
+enum class DecodeTargetIndication {
+ kNotPresent = 0, // DecodeTargetInfo symbol '-'
+ kDiscardable = 1, // DecodeTargetInfo symbol 'D'
+ kSwitch = 2, // DecodeTargetInfo symbol 'S'
+ kRequired = 3 // DecodeTargetInfo symbol 'R'
+};
+
+struct FrameDependencyTemplate {
+ // Setters are named briefly to chain them when building the template.
+ FrameDependencyTemplate& S(int spatial_layer);
+ FrameDependencyTemplate& T(int temporal_layer);
+ FrameDependencyTemplate& Dtis(absl::string_view dtis);
+ FrameDependencyTemplate& FrameDiffs(std::initializer_list<int> diffs);
+ FrameDependencyTemplate& ChainDiffs(std::initializer_list<int> diffs);
+
+ friend bool operator==(const FrameDependencyTemplate& lhs,
+ const FrameDependencyTemplate& rhs) {
+ return lhs.spatial_id == rhs.spatial_id &&
+ lhs.temporal_id == rhs.temporal_id &&
+ lhs.decode_target_indications == rhs.decode_target_indications &&
+ lhs.frame_diffs == rhs.frame_diffs &&
+ lhs.chain_diffs == rhs.chain_diffs;
+ }
+
+ int spatial_id = 0;
+ int temporal_id = 0;
+ absl::InlinedVector<DecodeTargetIndication, 10> decode_target_indications;
+ absl::InlinedVector<int, 4> frame_diffs;
+ absl::InlinedVector<int, 4> chain_diffs;
+};
+
+struct FrameDependencyStructure {
+ friend bool operator==(const FrameDependencyStructure& lhs,
+ const FrameDependencyStructure& rhs) {
+ return lhs.num_decode_targets == rhs.num_decode_targets &&
+ lhs.num_chains == rhs.num_chains &&
+ lhs.decode_target_protected_by_chain ==
+ rhs.decode_target_protected_by_chain &&
+ lhs.resolutions == rhs.resolutions && lhs.templates == rhs.templates;
+ }
+
+ int structure_id = 0;
+ int num_decode_targets = 0;
+ int num_chains = 0;
+ // If chains are used (num_chains > 0), maps decode target index into index of
+ // the chain protecting that target.
+ absl::InlinedVector<int, 10> decode_target_protected_by_chain;
+ absl::InlinedVector<RenderResolution, 4> resolutions;
+ std::vector<FrameDependencyTemplate> templates;
+};
+
+struct DependencyDescriptor {
+ static constexpr int kMaxSpatialIds = 4;
+ static constexpr int kMaxTemporalIds = 8;
+ static constexpr int kMaxDecodeTargets = 32;
+ static constexpr int kMaxTemplates = 64;
+
+ bool first_packet_in_frame = true;
+ bool last_packet_in_frame = true;
+ int frame_number = 0;
+ FrameDependencyTemplate frame_dependencies;
+ absl::optional<RenderResolution> resolution;
+ absl::optional<uint32_t> active_decode_targets_bitmask;
+ std::unique_ptr<FrameDependencyStructure> attached_structure;
+};
+
+// Below are implementation details.
+namespace webrtc_impl {
+absl::InlinedVector<DecodeTargetIndication, 10> StringToDecodeTargetIndications(
+ absl::string_view indication_symbols);
+} // namespace webrtc_impl
+
+inline FrameDependencyTemplate& FrameDependencyTemplate::S(int spatial_layer) {
+ this->spatial_id = spatial_layer;
+ return *this;
+}
+inline FrameDependencyTemplate& FrameDependencyTemplate::T(int temporal_layer) {
+ this->temporal_id = temporal_layer;
+ return *this;
+}
+inline FrameDependencyTemplate& FrameDependencyTemplate::Dtis(
+ absl::string_view dtis) {
+ this->decode_target_indications =
+ webrtc_impl::StringToDecodeTargetIndications(dtis);
+ return *this;
+}
+inline FrameDependencyTemplate& FrameDependencyTemplate::FrameDiffs(
+ std::initializer_list<int> diffs) {
+ this->frame_diffs.assign(diffs.begin(), diffs.end());
+ return *this;
+}
+inline FrameDependencyTemplate& FrameDependencyTemplate::ChainDiffs(
+ std::initializer_list<int> diffs) {
+ this->chain_diffs.assign(diffs.begin(), diffs.end());
+ return *this;
+}
+
+} // namespace webrtc
+
+#endif // API_TRANSPORT_RTP_DEPENDENCY_DESCRIPTOR_H_
diff --git a/third_party/libwebrtc/api/transport/rtp/dependency_descriptor_gn/moz.build b/third_party/libwebrtc/api/transport/rtp/dependency_descriptor_gn/moz.build
new file mode 100644
index 0000000000..0ee9e1fa1b
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/rtp/dependency_descriptor_gn/moz.build
@@ -0,0 +1,221 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/transport/rtp/dependency_descriptor.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("dependency_descriptor_gn")
diff --git a/third_party/libwebrtc/api/transport/rtp/rtp_source.h b/third_party/libwebrtc/api/transport/rtp/rtp_source.h
new file mode 100644
index 0000000000..e51dcd70b6
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/rtp/rtp_source.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TRANSPORT_RTP_RTP_SOURCE_H_
+#define API_TRANSPORT_RTP_RTP_SOURCE_H_
+
+#include <stdint.h>
+
+#include "absl/types/optional.h"
+#include "api/rtp_headers.h"
+#include "api/units/time_delta.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+enum class RtpSourceType {
+ SSRC,
+ CSRC,
+};
+
+class RtpSource {
+ public:
+ struct Extensions {
+ absl::optional<uint8_t> audio_level;
+
+ // Fields from the Absolute Capture Time header extension:
+ // http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time
+ absl::optional<AbsoluteCaptureTime> absolute_capture_time;
+
+ // Clock offset between the local clock and the capturer's clock.
+ // Do not confuse with `AbsoluteCaptureTime::estimated_capture_clock_offset`
+ // which instead represents the clock offset between a remote sender and the
+ // capturer. The following holds:
+ // Capture's NTP Clock = Local NTP Clock + Local-Capture Clock Offset
+ absl::optional<TimeDelta> local_capture_clock_offset;
+ };
+
+ RtpSource() = delete;
+
+ RtpSource(int64_t timestamp_ms,
+ uint32_t source_id,
+ RtpSourceType source_type,
+ uint32_t rtp_timestamp,
+ const RtpSource::Extensions& extensions)
+ : timestamp_ms_(timestamp_ms),
+ source_id_(source_id),
+ source_type_(source_type),
+ extensions_(extensions),
+ rtp_timestamp_(rtp_timestamp) {}
+
+ RtpSource(const RtpSource&) = default;
+ RtpSource& operator=(const RtpSource&) = default;
+ ~RtpSource() = default;
+
+ int64_t timestamp_ms() const { return timestamp_ms_; }
+ void update_timestamp_ms(int64_t timestamp_ms) {
+ RTC_DCHECK_LE(timestamp_ms_, timestamp_ms);
+ timestamp_ms_ = timestamp_ms;
+ }
+
+ // The identifier of the source can be the CSRC or the SSRC.
+ uint32_t source_id() const { return source_id_; }
+
+ // The source can be either a contributing source or a synchronization source.
+ RtpSourceType source_type() const { return source_type_; }
+
+ absl::optional<uint8_t> audio_level() const {
+ return extensions_.audio_level;
+ }
+
+ void set_audio_level(const absl::optional<uint8_t>& level) {
+ extensions_.audio_level = level;
+ }
+
+ uint32_t rtp_timestamp() const { return rtp_timestamp_; }
+
+ absl::optional<AbsoluteCaptureTime> absolute_capture_time() const {
+ return extensions_.absolute_capture_time;
+ }
+
+ absl::optional<TimeDelta> local_capture_clock_offset() const {
+ return extensions_.local_capture_clock_offset;
+ }
+
+ bool operator==(const RtpSource& o) const {
+ return timestamp_ms_ == o.timestamp_ms() && source_id_ == o.source_id() &&
+ source_type_ == o.source_type() &&
+ extensions_.audio_level == o.extensions_.audio_level &&
+ extensions_.absolute_capture_time ==
+ o.extensions_.absolute_capture_time &&
+ rtp_timestamp_ == o.rtp_timestamp();
+ }
+
+ private:
+ int64_t timestamp_ms_;
+ uint32_t source_id_;
+ RtpSourceType source_type_;
+ RtpSource::Extensions extensions_;
+ uint32_t rtp_timestamp_;
+};
+
+} // namespace webrtc
+
+#endif // API_TRANSPORT_RTP_RTP_SOURCE_H_
diff --git a/third_party/libwebrtc/api/transport/rtp/rtp_source_gn/moz.build b/third_party/libwebrtc/api/transport/rtp/rtp_source_gn/moz.build
new file mode 100644
index 0000000000..b43f4a77ec
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/rtp/rtp_source_gn/moz.build
@@ -0,0 +1,209 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("rtp_source_gn")
diff --git a/third_party/libwebrtc/api/transport/sctp_transport_factory_interface.h b/third_party/libwebrtc/api/transport/sctp_transport_factory_interface.h
new file mode 100644
index 0000000000..4fc8af5bad
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/sctp_transport_factory_interface.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TRANSPORT_SCTP_TRANSPORT_FACTORY_INTERFACE_H_
+#define API_TRANSPORT_SCTP_TRANSPORT_FACTORY_INTERFACE_H_
+
+#include <memory>
+
+// These classes are not part of the API, and are treated as opaque pointers.
+namespace cricket {
+class SctpTransportInternal;
+} // namespace cricket
+
+namespace rtc {
+class PacketTransportInternal;
+} // namespace rtc
+
+namespace webrtc {
+
+// Factory class which can be used to allow fake SctpTransports to be injected
+// for testing. An application is not intended to implement this interface nor
+// 'cricket::SctpTransportInternal' because SctpTransportInternal is not
+// guaranteed to remain stable in future WebRTC versions.
+class SctpTransportFactoryInterface {
+ public:
+ virtual ~SctpTransportFactoryInterface() = default;
+
+ // Create an SCTP transport using `channel` for the underlying transport.
+ virtual std::unique_ptr<cricket::SctpTransportInternal> CreateSctpTransport(
+ rtc::PacketTransportInternal* channel) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_TRANSPORT_SCTP_TRANSPORT_FACTORY_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/transport/stun.cc b/third_party/libwebrtc/api/transport/stun.cc
new file mode 100644
index 0000000000..1098c6720e
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/stun.cc
@@ -0,0 +1,1515 @@
+/*
+ * Copyright 2004 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/transport/stun.h"
+
+#include <string.h>
+
+#include <algorithm>
+#include <cstdint>
+#include <iterator>
+#include <memory>
+#include <utility>
+
+#include "rtc_base/byte_order.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/crc32.h"
+#include "rtc_base/helpers.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/message_digest.h"
+#include "system_wrappers/include/metrics.h"
+
+using rtc::ByteBufferReader;
+using rtc::ByteBufferWriter;
+
+namespace cricket {
+
+namespace {
+
+const int k127Utf8CharactersLengthInBytes = 508;
+const int kMessageIntegrityAttributeLength = 20;
+const int kTheoreticalMaximumAttributeLength = 65535;
+
+uint32_t ReduceTransactionId(absl::string_view transaction_id) {
+ RTC_DCHECK(transaction_id.length() == cricket::kStunTransactionIdLength ||
+ transaction_id.length() == cricket::kStunLegacyTransactionIdLength)
+ << transaction_id.length();
+ ByteBufferReader reader(transaction_id.data(), transaction_id.size());
+ uint32_t result = 0;
+ uint32_t next;
+ while (reader.ReadUInt32(&next)) {
+ result ^= next;
+ }
+ return result;
+}
+
+// Check the maximum length of a BYTE_STRING attribute against specifications.
+bool LengthValid(int type, int length) {
+ // "Less than 509 bytes" is intended to indicate a maximum of 127
+ // UTF-8 characters, which may take up to 4 bytes per character.
+ switch (type) {
+ case STUN_ATTR_USERNAME:
+ return length <=
+ k127Utf8CharactersLengthInBytes; // RFC 8489 section 14.3
+ case STUN_ATTR_MESSAGE_INTEGRITY:
+ return length ==
+ kMessageIntegrityAttributeLength; // RFC 8489 section 14.5
+ case STUN_ATTR_REALM:
+ return length <=
+ k127Utf8CharactersLengthInBytes; // RFC 8489 section 14.9
+ case STUN_ATTR_NONCE:
+ return length <=
+ k127Utf8CharactersLengthInBytes; // RFC 8489 section 14.10
+ case STUN_ATTR_SOFTWARE:
+ return length <=
+ k127Utf8CharactersLengthInBytes; // RFC 8489 section 14.14
+ case STUN_ATTR_DATA:
+ // No length restriction in RFC; it's the content of an UDP datagram,
+ // which in theory can be up to 65.535 bytes.
+ // TODO(bugs.webrtc.org/12179): Write a test to find the real limit.
+ return length <= kTheoreticalMaximumAttributeLength;
+ default:
+ // Return an arbitrary restriction for all other types.
+ return length <= kTheoreticalMaximumAttributeLength;
+ }
+ RTC_DCHECK_NOTREACHED();
+ return true;
+}
+
+} // namespace
+
+const char STUN_ERROR_REASON_TRY_ALTERNATE_SERVER[] = "Try Alternate Server";
+const char STUN_ERROR_REASON_BAD_REQUEST[] = "Bad Request";
+const char STUN_ERROR_REASON_UNAUTHORIZED[] = "Unauthorized";
+const char STUN_ERROR_REASON_UNKNOWN_ATTRIBUTE[] = "Unknown Attribute";
+const char STUN_ERROR_REASON_FORBIDDEN[] = "Forbidden";
+const char STUN_ERROR_REASON_ALLOCATION_MISMATCH[] = "Allocation Mismatch";
+const char STUN_ERROR_REASON_STALE_NONCE[] = "Stale Nonce";
+const char STUN_ERROR_REASON_WRONG_CREDENTIALS[] = "Wrong Credentials";
+const char STUN_ERROR_REASON_UNSUPPORTED_PROTOCOL[] = "Unsupported Protocol";
+const char STUN_ERROR_REASON_ROLE_CONFLICT[] = "Role Conflict";
+const char STUN_ERROR_REASON_SERVER_ERROR[] = "Server Error";
+
+const char TURN_MAGIC_COOKIE_VALUE[] = {'\x72', '\xC6', '\x4B', '\xC6'};
+const char EMPTY_TRANSACTION_ID[] = "0000000000000000";
+const uint32_t STUN_FINGERPRINT_XOR_VALUE = 0x5354554E;
+const int SERVER_NOT_REACHABLE_ERROR = 701;
+
+// StunMessage
+
+StunMessage::StunMessage()
+ : StunMessage(STUN_INVALID_MESSAGE_TYPE, EMPTY_TRANSACTION_ID) {}
+
+StunMessage::StunMessage(uint16_t type)
+ : StunMessage(type, GenerateTransactionId()) {}
+
+StunMessage::StunMessage(uint16_t type, absl::string_view transaction_id)
+ : type_(type),
+ transaction_id_(transaction_id),
+ reduced_transaction_id_(ReduceTransactionId(transaction_id_)) {
+ RTC_DCHECK(IsValidTransactionId(transaction_id_));
+}
+
+StunMessage::~StunMessage() = default;
+
+bool StunMessage::IsLegacy() const {
+ if (transaction_id_.size() == kStunLegacyTransactionIdLength)
+ return true;
+ RTC_DCHECK(transaction_id_.size() == kStunTransactionIdLength);
+ return false;
+}
+
+static bool DesignatedExpertRange(int attr_type) {
+ return (attr_type >= 0x4000 && attr_type <= 0x7FFF) ||
+ (attr_type >= 0xC000 && attr_type <= 0xFFFF);
+}
+
+void StunMessage::AddAttribute(std::unique_ptr<StunAttribute> attr) {
+ // Fail any attributes that aren't valid for this type of message,
+ // but allow any type for the range that in the RFC is reserved for
+ // the "designated experts".
+ if (!DesignatedExpertRange(attr->type())) {
+ RTC_DCHECK_EQ(attr->value_type(), GetAttributeValueType(attr->type()));
+ }
+
+ attr->SetOwner(this);
+ size_t attr_length = attr->length();
+ if (attr_length % 4 != 0) {
+ attr_length += (4 - (attr_length % 4));
+ }
+ length_ += static_cast<uint16_t>(attr_length + 4);
+
+ attrs_.push_back(std::move(attr));
+}
+
+std::unique_ptr<StunAttribute> StunMessage::RemoveAttribute(int type) {
+ std::unique_ptr<StunAttribute> attribute;
+ for (auto it = attrs_.rbegin(); it != attrs_.rend(); ++it) {
+ if ((*it)->type() == type) {
+ attribute = std::move(*it);
+ attrs_.erase(std::next(it).base());
+ break;
+ }
+ }
+ if (attribute) {
+ attribute->SetOwner(nullptr);
+ size_t attr_length = attribute->length();
+ if (attr_length % 4 != 0) {
+ attr_length += (4 - (attr_length % 4));
+ }
+ length_ -= static_cast<uint16_t>(attr_length + 4);
+ }
+ return attribute;
+}
+
+void StunMessage::ClearAttributes() {
+ for (auto it = attrs_.rbegin(); it != attrs_.rend(); ++it) {
+ (*it)->SetOwner(nullptr);
+ }
+ attrs_.clear();
+ length_ = 0;
+}
+
+std::vector<uint16_t> StunMessage::GetNonComprehendedAttributes() const {
+ std::vector<uint16_t> unknown_attributes;
+ for (auto& attr : attrs_) {
+ // "comprehension-required" range is 0x0000-0x7FFF.
+ if (attr->type() >= 0x0000 && attr->type() <= 0x7FFF &&
+ GetAttributeValueType(attr->type()) == STUN_VALUE_UNKNOWN) {
+ unknown_attributes.push_back(attr->type());
+ }
+ }
+ return unknown_attributes;
+}
+
+const StunAddressAttribute* StunMessage::GetAddress(int type) const {
+ switch (type) {
+ case STUN_ATTR_MAPPED_ADDRESS: {
+ // Return XOR-MAPPED-ADDRESS when MAPPED-ADDRESS attribute is
+ // missing.
+ const StunAttribute* mapped_address =
+ GetAttribute(STUN_ATTR_MAPPED_ADDRESS);
+ if (!mapped_address)
+ mapped_address = GetAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS);
+ return reinterpret_cast<const StunAddressAttribute*>(mapped_address);
+ }
+
+ default:
+ return static_cast<const StunAddressAttribute*>(GetAttribute(type));
+ }
+}
+
+const StunUInt32Attribute* StunMessage::GetUInt32(int type) const {
+ return static_cast<const StunUInt32Attribute*>(GetAttribute(type));
+}
+
+const StunUInt64Attribute* StunMessage::GetUInt64(int type) const {
+ return static_cast<const StunUInt64Attribute*>(GetAttribute(type));
+}
+
+const StunByteStringAttribute* StunMessage::GetByteString(int type) const {
+ return static_cast<const StunByteStringAttribute*>(GetAttribute(type));
+}
+
+const StunUInt16ListAttribute* StunMessage::GetUInt16List(int type) const {
+ return static_cast<const StunUInt16ListAttribute*>(GetAttribute(type));
+}
+
+const StunErrorCodeAttribute* StunMessage::GetErrorCode() const {
+ return static_cast<const StunErrorCodeAttribute*>(
+ GetAttribute(STUN_ATTR_ERROR_CODE));
+}
+
+int StunMessage::GetErrorCodeValue() const {
+ const StunErrorCodeAttribute* error_attribute = GetErrorCode();
+ return error_attribute ? error_attribute->code() : STUN_ERROR_GLOBAL_FAILURE;
+}
+
+const StunUInt16ListAttribute* StunMessage::GetUnknownAttributes() const {
+ return static_cast<const StunUInt16ListAttribute*>(
+ GetAttribute(STUN_ATTR_UNKNOWN_ATTRIBUTES));
+}
+
+StunMessage::IntegrityStatus StunMessage::ValidateMessageIntegrity(
+ const std::string& password) {
+ RTC_DCHECK(integrity_ == IntegrityStatus::kNotSet)
+ << "Usage error: Verification should only be done once";
+ password_ = password;
+ if (GetByteString(STUN_ATTR_MESSAGE_INTEGRITY)) {
+ if (ValidateMessageIntegrityOfType(
+ STUN_ATTR_MESSAGE_INTEGRITY, kStunMessageIntegritySize,
+ buffer_.c_str(), buffer_.size(), password)) {
+ integrity_ = IntegrityStatus::kIntegrityOk;
+ } else {
+ integrity_ = IntegrityStatus::kIntegrityBad;
+ }
+ } else if (GetByteString(STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32)) {
+ if (ValidateMessageIntegrityOfType(
+ STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32, kStunMessageIntegrity32Size,
+ buffer_.c_str(), buffer_.size(), password)) {
+ integrity_ = IntegrityStatus::kIntegrityOk;
+ } else {
+ integrity_ = IntegrityStatus::kIntegrityBad;
+ }
+ } else {
+ integrity_ = IntegrityStatus::kNoIntegrity;
+ }
+ // Log the result of integrity checking. See crbug.com/1177125 for background.
+ // Convert args to integer for the benefit of the macros.
+ int bucket_count = static_cast<int>(IntegrityStatus::kMaxValue) + 1;
+ int integrity = static_cast<int>(integrity_);
+ if (IsStunRequestType(type_)) {
+ RTC_HISTOGRAM_ENUMERATION("WebRTC.Stun.Integrity.Request", integrity,
+ bucket_count);
+ } else if (IsStunSuccessResponseType(type_)) {
+ RTC_HISTOGRAM_ENUMERATION("WebRTC.Stun.Integrity.Response", integrity,
+ bucket_count);
+ } else if (IsStunIndicationType(type_)) {
+ RTC_HISTOGRAM_ENUMERATION("WebRTC.Stun.Integrity.Indication", integrity,
+ bucket_count);
+ } else {
+ RTC_DCHECK(IsStunErrorResponseType(type_));
+ auto* error_attribute = GetErrorCode();
+ if (!error_attribute) {
+ RTC_HISTOGRAM_ENUMERATION(
+ "WebRTC.Stun.Integrity.ErrorResponse.NoErrorAttribute", integrity,
+ bucket_count);
+ } else {
+ switch (error_attribute->code()) {
+ case STUN_ERROR_TRY_ALTERNATE:
+ RTC_HISTOGRAM_ENUMERATION(
+ "WebRTC.Stun.Integrity.ErrorResponse.TryAlternate", integrity,
+ bucket_count);
+ break;
+ case STUN_ERROR_BAD_REQUEST:
+ RTC_HISTOGRAM_ENUMERATION(
+ "WebRTC.Stun.Integrity.ErrorResponse.BadRequest", integrity,
+ bucket_count);
+ break;
+ case STUN_ERROR_UNAUTHORIZED:
+ RTC_HISTOGRAM_ENUMERATION(
+ "WebRTC.Stun.Integrity.ErrorResponse.Unauthorized", integrity,
+ bucket_count);
+ break;
+ case STUN_ERROR_UNKNOWN_ATTRIBUTE:
+ RTC_HISTOGRAM_ENUMERATION(
+ "WebRTC.Stun.Integrity.ErrorResponse.UnknownAttribute", integrity,
+ bucket_count);
+ break;
+ case STUN_ERROR_STALE_NONCE:
+ RTC_HISTOGRAM_ENUMERATION(
+ "WebRTC.Stun.Integrity.ErrorResponse.StaleNonce", integrity,
+ bucket_count);
+ break;
+ case STUN_ERROR_SERVER_ERROR:
+ RTC_HISTOGRAM_ENUMERATION(
+ "WebRTC.Stun.Integrity.ErrorResponse.ServerError", integrity,
+ bucket_count);
+ break;
+ case STUN_ERROR_GLOBAL_FAILURE:
+ RTC_HISTOGRAM_ENUMERATION(
+ "WebRTC.Stun.Integrity.ErrorResponse.GlobalFailure", integrity,
+ bucket_count);
+ break;
+ default:
+ RTC_HISTOGRAM_ENUMERATION(
+ "WebRTC.Stun.Integrity.ErrorResponse.ErrorOther", integrity,
+ bucket_count);
+ break;
+ }
+ }
+ }
+ return integrity_;
+}
+
+StunMessage::IntegrityStatus StunMessage::RevalidateMessageIntegrity(
+ const std::string& password) {
+ RTC_LOG(LS_INFO) << "Message revalidation, old status was "
+ << static_cast<int>(integrity_);
+ integrity_ = IntegrityStatus::kNotSet;
+ return ValidateMessageIntegrity(password);
+}
+
+bool StunMessage::ValidateMessageIntegrityForTesting(
+ const char* data,
+ size_t size,
+ const std::string& password) {
+ return ValidateMessageIntegrityOfType(STUN_ATTR_MESSAGE_INTEGRITY,
+ kStunMessageIntegritySize, data, size,
+ password);
+}
+
+bool StunMessage::ValidateMessageIntegrity32ForTesting(
+ const char* data,
+ size_t size,
+ const std::string& password) {
+ return ValidateMessageIntegrityOfType(STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32,
+ kStunMessageIntegrity32Size, data, size,
+ password);
+}
+
+// Deprecated
+bool StunMessage::ValidateMessageIntegrity(const char* data,
+ size_t size,
+ const std::string& password) {
+ return ValidateMessageIntegrityOfType(STUN_ATTR_MESSAGE_INTEGRITY,
+ kStunMessageIntegritySize, data, size,
+ password);
+}
+
+// Deprecated
+bool StunMessage::ValidateMessageIntegrity32(const char* data,
+ size_t size,
+ const std::string& password) {
+ return ValidateMessageIntegrityOfType(STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32,
+ kStunMessageIntegrity32Size, data, size,
+ password);
+}
+
+// Verifies a STUN message has a valid MESSAGE-INTEGRITY attribute, using the
+// procedure outlined in RFC 5389, section 15.4.
+bool StunMessage::ValidateMessageIntegrityOfType(int mi_attr_type,
+ size_t mi_attr_size,
+ const char* data,
+ size_t size,
+ const std::string& password) {
+ RTC_DCHECK(mi_attr_size <= kStunMessageIntegritySize);
+
+ // Verifying the size of the message.
+ if ((size % 4) != 0 || size < kStunHeaderSize) {
+ return false;
+ }
+
+ // Getting the message length from the STUN header.
+ uint16_t msg_length = rtc::GetBE16(&data[2]);
+ if (size != (msg_length + kStunHeaderSize)) {
+ return false;
+ }
+
+ // Finding Message Integrity attribute in stun message.
+ size_t current_pos = kStunHeaderSize;
+ bool has_message_integrity_attr = false;
+ while (current_pos + 4 <= size) {
+ uint16_t attr_type, attr_length;
+ // Getting attribute type and length.
+ attr_type = rtc::GetBE16(&data[current_pos]);
+ attr_length = rtc::GetBE16(&data[current_pos + sizeof(attr_type)]);
+
+ // If M-I, sanity check it, and break out.
+ if (attr_type == mi_attr_type) {
+ if (attr_length != mi_attr_size ||
+ current_pos + sizeof(attr_type) + sizeof(attr_length) + attr_length >
+ size) {
+ return false;
+ }
+ has_message_integrity_attr = true;
+ break;
+ }
+
+ // Otherwise, skip to the next attribute.
+ current_pos += sizeof(attr_type) + sizeof(attr_length) + attr_length;
+ if ((attr_length % 4) != 0) {
+ current_pos += (4 - (attr_length % 4));
+ }
+ }
+
+ if (!has_message_integrity_attr) {
+ return false;
+ }
+
+ // Getting length of the message to calculate Message Integrity.
+ size_t mi_pos = current_pos;
+ std::unique_ptr<char[]> temp_data(new char[current_pos]);
+ memcpy(temp_data.get(), data, current_pos);
+ if (size > mi_pos + kStunAttributeHeaderSize + mi_attr_size) {
+ // Stun message has other attributes after message integrity.
+ // Adjust the length parameter in stun message to calculate HMAC.
+ size_t extra_offset =
+ size - (mi_pos + kStunAttributeHeaderSize + mi_attr_size);
+ size_t new_adjusted_len = size - extra_offset - kStunHeaderSize;
+
+ // Writing new length of the STUN message @ Message Length in temp buffer.
+ // 0 1 2 3
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // |0 0| STUN Message Type | Message Length |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ rtc::SetBE16(temp_data.get() + 2, static_cast<uint16_t>(new_adjusted_len));
+ }
+
+ char hmac[kStunMessageIntegritySize];
+ size_t ret =
+ rtc::ComputeHmac(rtc::DIGEST_SHA_1, password.c_str(), password.size(),
+ temp_data.get(), mi_pos, hmac, sizeof(hmac));
+ RTC_DCHECK(ret == sizeof(hmac));
+ if (ret != sizeof(hmac)) {
+ return false;
+ }
+
+ // Comparing the calculated HMAC with the one present in the message.
+ return memcmp(data + current_pos + kStunAttributeHeaderSize, hmac,
+ mi_attr_size) == 0;
+}
+
+bool StunMessage::AddMessageIntegrity(absl::string_view password) {
+ return AddMessageIntegrityOfType(STUN_ATTR_MESSAGE_INTEGRITY,
+ kStunMessageIntegritySize, password);
+}
+
+bool StunMessage::AddMessageIntegrity32(absl::string_view password) {
+ return AddMessageIntegrityOfType(STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32,
+ kStunMessageIntegrity32Size, password);
+}
+
+bool StunMessage::AddMessageIntegrityOfType(int attr_type,
+ size_t attr_size,
+ absl::string_view key) {
+ // Add the attribute with a dummy value. Since this is a known attribute, it
+ // can't fail.
+ RTC_DCHECK(attr_size <= kStunMessageIntegritySize);
+ auto msg_integrity_attr_ptr = std::make_unique<StunByteStringAttribute>(
+ attr_type, std::string(attr_size, '0'));
+ auto* msg_integrity_attr = msg_integrity_attr_ptr.get();
+ AddAttribute(std::move(msg_integrity_attr_ptr));
+
+ // Calculate the HMAC for the message.
+ ByteBufferWriter buf;
+ if (!Write(&buf))
+ return false;
+
+ int msg_len_for_hmac = static_cast<int>(
+ buf.Length() - kStunAttributeHeaderSize - msg_integrity_attr->length());
+ char hmac[kStunMessageIntegritySize];
+ size_t ret =
+ rtc::ComputeHmac(rtc::DIGEST_SHA_1, key.data(), key.size(), buf.Data(),
+ msg_len_for_hmac, hmac, sizeof(hmac));
+ RTC_DCHECK(ret == sizeof(hmac));
+ if (ret != sizeof(hmac)) {
+ RTC_LOG(LS_ERROR) << "HMAC computation failed. Message-Integrity "
+ "has dummy value.";
+ return false;
+ }
+
+ // Insert correct HMAC into the attribute.
+ msg_integrity_attr->CopyBytes(hmac, attr_size);
+ password_ = std::string(key);
+ integrity_ = IntegrityStatus::kIntegrityOk;
+ return true;
+}
+
+// Verifies a message is in fact a STUN message, by performing the checks
+// outlined in RFC 5389, section 7.3, including the FINGERPRINT check detailed
+// in section 15.5.
+bool StunMessage::ValidateFingerprint(const char* data, size_t size) {
+ // Check the message length.
+ size_t fingerprint_attr_size =
+ kStunAttributeHeaderSize + StunUInt32Attribute::SIZE;
+ if (size % 4 != 0 || size < kStunHeaderSize + fingerprint_attr_size)
+ return false;
+
+ // Skip the rest if the magic cookie isn't present.
+ const char* magic_cookie =
+ data + kStunTransactionIdOffset - kStunMagicCookieLength;
+ if (rtc::GetBE32(magic_cookie) != kStunMagicCookie)
+ return false;
+
+ // Check the fingerprint type and length.
+ const char* fingerprint_attr_data = data + size - fingerprint_attr_size;
+ if (rtc::GetBE16(fingerprint_attr_data) != STUN_ATTR_FINGERPRINT ||
+ rtc::GetBE16(fingerprint_attr_data + sizeof(uint16_t)) !=
+ StunUInt32Attribute::SIZE)
+ return false;
+
+ // Check the fingerprint value.
+ uint32_t fingerprint =
+ rtc::GetBE32(fingerprint_attr_data + kStunAttributeHeaderSize);
+ return ((fingerprint ^ STUN_FINGERPRINT_XOR_VALUE) ==
+ rtc::ComputeCrc32(data, size - fingerprint_attr_size));
+}
+
+// static
+std::string StunMessage::GenerateTransactionId() {
+ return rtc::CreateRandomString(kStunTransactionIdLength);
+}
+
+bool StunMessage::IsStunMethod(rtc::ArrayView<int> methods,
+ const char* data,
+ size_t size) {
+ // Check the message length.
+ if (size % 4 != 0 || size < kStunHeaderSize)
+ return false;
+
+ // Skip the rest if the magic cookie isn't present.
+ const char* magic_cookie =
+ data + kStunTransactionIdOffset - kStunMagicCookieLength;
+ if (rtc::GetBE32(magic_cookie) != kStunMagicCookie)
+ return false;
+
+ int method = rtc::GetBE16(data);
+ for (int m : methods) {
+ if (m == method) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool StunMessage::AddFingerprint() {
+ // Add the attribute with a dummy value. Since this is a known attribute,
+ // it can't fail.
+ auto fingerprint_attr_ptr =
+ std::make_unique<StunUInt32Attribute>(STUN_ATTR_FINGERPRINT, 0);
+ auto* fingerprint_attr = fingerprint_attr_ptr.get();
+ AddAttribute(std::move(fingerprint_attr_ptr));
+
+ // Calculate the CRC-32 for the message and insert it.
+ ByteBufferWriter buf;
+ if (!Write(&buf))
+ return false;
+
+ int msg_len_for_crc32 = static_cast<int>(
+ buf.Length() - kStunAttributeHeaderSize - fingerprint_attr->length());
+ uint32_t c = rtc::ComputeCrc32(buf.Data(), msg_len_for_crc32);
+
+ // Insert the correct CRC-32, XORed with a constant, into the attribute.
+ fingerprint_attr->SetValue(c ^ STUN_FINGERPRINT_XOR_VALUE);
+ return true;
+}
+
+bool StunMessage::Read(ByteBufferReader* buf) {
+ // Keep a copy of the buffer data around for later verification.
+ buffer_.assign(buf->Data(), buf->Length());
+
+ if (!buf->ReadUInt16(&type_)) {
+ return false;
+ }
+
+ if (type_ & 0x8000) {
+ // RTP and RTCP set the MSB of first byte, since first two bits are version,
+ // and version is always 2 (10). If set, this is not a STUN packet.
+ return false;
+ }
+
+ if (!buf->ReadUInt16(&length_)) {
+ return false;
+ }
+
+ std::string magic_cookie;
+ if (!buf->ReadString(&magic_cookie, kStunMagicCookieLength)) {
+ return false;
+ }
+
+ std::string transaction_id;
+ if (!buf->ReadString(&transaction_id, kStunTransactionIdLength)) {
+ return false;
+ }
+
+ uint32_t magic_cookie_int;
+ static_assert(sizeof(magic_cookie_int) == kStunMagicCookieLength,
+ "Integer size mismatch: magic_cookie_int and kStunMagicCookie");
+ std::memcpy(&magic_cookie_int, magic_cookie.data(), sizeof(magic_cookie_int));
+ if (rtc::NetworkToHost32(magic_cookie_int) != kStunMagicCookie) {
+ // If magic cookie is invalid it means that the peer implements
+ // RFC3489 instead of RFC5389.
+ transaction_id.insert(0, magic_cookie);
+ }
+ RTC_DCHECK(IsValidTransactionId(transaction_id));
+ transaction_id_ = transaction_id;
+ reduced_transaction_id_ = ReduceTransactionId(transaction_id_);
+
+ if (length_ != buf->Length()) {
+ return false;
+ }
+
+ attrs_.resize(0);
+
+ size_t rest = buf->Length() - length_;
+ while (buf->Length() > rest) {
+ uint16_t attr_type, attr_length;
+ if (!buf->ReadUInt16(&attr_type))
+ return false;
+ if (!buf->ReadUInt16(&attr_length))
+ return false;
+
+ std::unique_ptr<StunAttribute> attr(
+ CreateAttribute(attr_type, attr_length));
+ if (!attr) {
+ // Skip any unknown or malformed attributes.
+ if ((attr_length % 4) != 0) {
+ attr_length += (4 - (attr_length % 4));
+ }
+ if (!buf->Consume(attr_length)) {
+ return false;
+ }
+ } else {
+ if (!attr->Read(buf)) {
+ return false;
+ }
+ attrs_.push_back(std::move(attr));
+ }
+ }
+
+ RTC_DCHECK(buf->Length() == rest);
+ return true;
+}
+
+bool StunMessage::Write(ByteBufferWriter* buf) const {
+ buf->WriteUInt16(type_);
+ buf->WriteUInt16(length_);
+ if (!IsLegacy())
+ buf->WriteUInt32(stun_magic_cookie_);
+ buf->WriteString(transaction_id_);
+
+ for (const auto& attr : attrs_) {
+ buf->WriteUInt16(attr->type());
+ buf->WriteUInt16(static_cast<uint16_t>(attr->length()));
+ if (!attr->Write(buf)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+StunMessage* StunMessage::CreateNew() const {
+ return new StunMessage();
+}
+
+void StunMessage::SetStunMagicCookie(uint32_t val) {
+ stun_magic_cookie_ = val;
+}
+
+void StunMessage::SetTransactionIdForTesting(absl::string_view transaction_id) {
+ RTC_DCHECK(IsValidTransactionId(transaction_id));
+ transaction_id_ = std::string(transaction_id);
+ reduced_transaction_id_ = ReduceTransactionId(transaction_id_);
+}
+
+StunAttributeValueType StunMessage::GetAttributeValueType(int type) const {
+ switch (type) {
+ case STUN_ATTR_MAPPED_ADDRESS:
+ return STUN_VALUE_ADDRESS;
+ case STUN_ATTR_USERNAME:
+ return STUN_VALUE_BYTE_STRING;
+ case STUN_ATTR_MESSAGE_INTEGRITY:
+ return STUN_VALUE_BYTE_STRING;
+ case STUN_ATTR_ERROR_CODE:
+ return STUN_VALUE_ERROR_CODE;
+ case STUN_ATTR_UNKNOWN_ATTRIBUTES:
+ return STUN_VALUE_UINT16_LIST;
+ case STUN_ATTR_REALM:
+ return STUN_VALUE_BYTE_STRING;
+ case STUN_ATTR_NONCE:
+ return STUN_VALUE_BYTE_STRING;
+ case STUN_ATTR_XOR_MAPPED_ADDRESS:
+ return STUN_VALUE_XOR_ADDRESS;
+ case STUN_ATTR_SOFTWARE:
+ return STUN_VALUE_BYTE_STRING;
+ case STUN_ATTR_ALTERNATE_SERVER:
+ return STUN_VALUE_ADDRESS;
+ case STUN_ATTR_FINGERPRINT:
+ return STUN_VALUE_UINT32;
+ case STUN_ATTR_RETRANSMIT_COUNT:
+ return STUN_VALUE_UINT32;
+ case STUN_ATTR_GOOG_LAST_ICE_CHECK_RECEIVED:
+ return STUN_VALUE_BYTE_STRING;
+ case STUN_ATTR_GOOG_MISC_INFO:
+ return STUN_VALUE_UINT16_LIST;
+ default:
+ return STUN_VALUE_UNKNOWN;
+ }
+}
+
+StunAttribute* StunMessage::CreateAttribute(int type, size_t length) /*const*/ {
+ StunAttributeValueType value_type = GetAttributeValueType(type);
+ if (value_type != STUN_VALUE_UNKNOWN) {
+ return StunAttribute::Create(value_type, type,
+ static_cast<uint16_t>(length), this);
+ } else if (DesignatedExpertRange(type)) {
+ // Read unknown attributes as STUN_VALUE_BYTE_STRING
+ return StunAttribute::Create(STUN_VALUE_BYTE_STRING, type,
+ static_cast<uint16_t>(length), this);
+ } else {
+ return NULL;
+ }
+}
+
+const StunAttribute* StunMessage::GetAttribute(int type) const {
+ for (const auto& attr : attrs_) {
+ if (attr->type() == type) {
+ return attr.get();
+ }
+ }
+ return NULL;
+}
+
+bool StunMessage::IsValidTransactionId(absl::string_view transaction_id) {
+ return transaction_id.size() == kStunTransactionIdLength ||
+ transaction_id.size() == kStunLegacyTransactionIdLength;
+}
+
+bool StunMessage::EqualAttributes(
+ const StunMessage* other,
+ std::function<bool(int type)> attribute_type_mask) const {
+ RTC_DCHECK(other != nullptr);
+ rtc::ByteBufferWriter tmp_buffer_ptr1;
+ rtc::ByteBufferWriter tmp_buffer_ptr2;
+ for (const auto& attr : attrs_) {
+ if (attribute_type_mask(attr->type())) {
+ const StunAttribute* other_attr = other->GetAttribute(attr->type());
+ if (other_attr == nullptr) {
+ return false;
+ }
+ tmp_buffer_ptr1.Clear();
+ tmp_buffer_ptr2.Clear();
+ attr->Write(&tmp_buffer_ptr1);
+ other_attr->Write(&tmp_buffer_ptr2);
+ if (tmp_buffer_ptr1.Length() != tmp_buffer_ptr2.Length()) {
+ return false;
+ }
+ if (memcmp(tmp_buffer_ptr1.Data(), tmp_buffer_ptr2.Data(),
+ tmp_buffer_ptr1.Length()) != 0) {
+ return false;
+ }
+ }
+ }
+
+ for (const auto& attr : other->attrs_) {
+ if (attribute_type_mask(attr->type())) {
+ const StunAttribute* own_attr = GetAttribute(attr->type());
+ if (own_attr == nullptr) {
+ return false;
+ }
+ // we have already compared all values...
+ }
+ }
+ return true;
+}
+
+// StunAttribute
+
+StunAttribute::StunAttribute(uint16_t type, uint16_t length)
+ : type_(type), length_(length) {}
+
+void StunAttribute::ConsumePadding(ByteBufferReader* buf) const {
+ int remainder = length_ % 4;
+ if (remainder > 0) {
+ buf->Consume(4 - remainder);
+ }
+}
+
+void StunAttribute::WritePadding(ByteBufferWriter* buf) const {
+ int remainder = length_ % 4;
+ if (remainder > 0) {
+ char zeroes[4] = {0};
+ buf->WriteBytes(zeroes, 4 - remainder);
+ }
+}
+
+StunAttribute* StunAttribute::Create(StunAttributeValueType value_type,
+ uint16_t type,
+ uint16_t length,
+ StunMessage* owner) {
+ switch (value_type) {
+ case STUN_VALUE_ADDRESS:
+ return new StunAddressAttribute(type, length);
+ case STUN_VALUE_XOR_ADDRESS:
+ return new StunXorAddressAttribute(type, length, owner);
+ case STUN_VALUE_UINT32:
+ return new StunUInt32Attribute(type);
+ case STUN_VALUE_UINT64:
+ return new StunUInt64Attribute(type);
+ case STUN_VALUE_BYTE_STRING:
+ return new StunByteStringAttribute(type, length);
+ case STUN_VALUE_ERROR_CODE:
+ return new StunErrorCodeAttribute(type, length);
+ case STUN_VALUE_UINT16_LIST:
+ return new StunUInt16ListAttribute(type, length);
+ default:
+ return NULL;
+ }
+}
+
+std::unique_ptr<StunAddressAttribute> StunAttribute::CreateAddress(
+ uint16_t type) {
+ return std::make_unique<StunAddressAttribute>(type, 0);
+}
+
+std::unique_ptr<StunXorAddressAttribute> StunAttribute::CreateXorAddress(
+ uint16_t type) {
+ return std::make_unique<StunXorAddressAttribute>(type, 0, nullptr);
+}
+
+std::unique_ptr<StunUInt64Attribute> StunAttribute::CreateUInt64(
+ uint16_t type) {
+ return std::make_unique<StunUInt64Attribute>(type);
+}
+
+std::unique_ptr<StunUInt32Attribute> StunAttribute::CreateUInt32(
+ uint16_t type) {
+ return std::make_unique<StunUInt32Attribute>(type);
+}
+
+std::unique_ptr<StunByteStringAttribute> StunAttribute::CreateByteString(
+ uint16_t type) {
+ return std::make_unique<StunByteStringAttribute>(type, 0);
+}
+
+std::unique_ptr<StunErrorCodeAttribute> StunAttribute::CreateErrorCode() {
+ return std::make_unique<StunErrorCodeAttribute>(
+ STUN_ATTR_ERROR_CODE, StunErrorCodeAttribute::MIN_SIZE);
+}
+
+std::unique_ptr<StunUInt16ListAttribute>
+StunAttribute::CreateUInt16ListAttribute(uint16_t type) {
+ return std::make_unique<StunUInt16ListAttribute>(type, 0);
+}
+
+std::unique_ptr<StunUInt16ListAttribute>
+StunAttribute::CreateUnknownAttributes() {
+ return std::make_unique<StunUInt16ListAttribute>(STUN_ATTR_UNKNOWN_ATTRIBUTES,
+ 0);
+}
+
+StunAddressAttribute::StunAddressAttribute(uint16_t type,
+ const rtc::SocketAddress& addr)
+ : StunAttribute(type, 0) {
+ SetAddress(addr);
+}
+
+StunAddressAttribute::StunAddressAttribute(uint16_t type, uint16_t length)
+ : StunAttribute(type, length) {}
+
+StunAttributeValueType StunAddressAttribute::value_type() const {
+ return STUN_VALUE_ADDRESS;
+}
+
+bool StunAddressAttribute::Read(ByteBufferReader* buf) {
+ uint8_t dummy;
+ if (!buf->ReadUInt8(&dummy))
+ return false;
+
+ uint8_t stun_family;
+ if (!buf->ReadUInt8(&stun_family)) {
+ return false;
+ }
+ uint16_t port;
+ if (!buf->ReadUInt16(&port))
+ return false;
+ if (stun_family == STUN_ADDRESS_IPV4) {
+ in_addr v4addr;
+ if (length() != SIZE_IP4) {
+ return false;
+ }
+ if (!buf->ReadBytes(reinterpret_cast<char*>(&v4addr), sizeof(v4addr))) {
+ return false;
+ }
+ rtc::IPAddress ipaddr(v4addr);
+ SetAddress(rtc::SocketAddress(ipaddr, port));
+ } else if (stun_family == STUN_ADDRESS_IPV6) {
+ in6_addr v6addr;
+ if (length() != SIZE_IP6) {
+ return false;
+ }
+ if (!buf->ReadBytes(reinterpret_cast<char*>(&v6addr), sizeof(v6addr))) {
+ return false;
+ }
+ rtc::IPAddress ipaddr(v6addr);
+ SetAddress(rtc::SocketAddress(ipaddr, port));
+ } else {
+ return false;
+ }
+ return true;
+}
+
+bool StunAddressAttribute::Write(ByteBufferWriter* buf) const {
+ StunAddressFamily address_family = family();
+ if (address_family == STUN_ADDRESS_UNDEF) {
+ RTC_LOG(LS_ERROR) << "Error writing address attribute: unknown family.";
+ return false;
+ }
+ buf->WriteUInt8(0);
+ buf->WriteUInt8(address_family);
+ buf->WriteUInt16(address_.port());
+ switch (address_.family()) {
+ case AF_INET: {
+ in_addr v4addr = address_.ipaddr().ipv4_address();
+ buf->WriteBytes(reinterpret_cast<char*>(&v4addr), sizeof(v4addr));
+ break;
+ }
+ case AF_INET6: {
+ in6_addr v6addr = address_.ipaddr().ipv6_address();
+ buf->WriteBytes(reinterpret_cast<char*>(&v6addr), sizeof(v6addr));
+ break;
+ }
+ }
+ return true;
+}
+
+StunXorAddressAttribute::StunXorAddressAttribute(uint16_t type,
+ const rtc::SocketAddress& addr)
+ : StunAddressAttribute(type, addr), owner_(NULL) {}
+
+StunXorAddressAttribute::StunXorAddressAttribute(uint16_t type,
+ uint16_t length,
+ StunMessage* owner)
+ : StunAddressAttribute(type, length), owner_(owner) {}
+
+StunAttributeValueType StunXorAddressAttribute::value_type() const {
+ return STUN_VALUE_XOR_ADDRESS;
+}
+
+void StunXorAddressAttribute::SetOwner(StunMessage* owner) {
+ owner_ = owner;
+}
+
+rtc::IPAddress StunXorAddressAttribute::GetXoredIP() const {
+ if (owner_) {
+ rtc::IPAddress ip = ipaddr();
+ switch (ip.family()) {
+ case AF_INET: {
+ in_addr v4addr = ip.ipv4_address();
+ v4addr.s_addr =
+ (v4addr.s_addr ^ rtc::HostToNetwork32(kStunMagicCookie));
+ return rtc::IPAddress(v4addr);
+ }
+ case AF_INET6: {
+ in6_addr v6addr = ip.ipv6_address();
+ const std::string& transaction_id = owner_->transaction_id();
+ if (transaction_id.length() == kStunTransactionIdLength) {
+ uint32_t transactionid_as_ints[3];
+ memcpy(&transactionid_as_ints[0], transaction_id.c_str(),
+ transaction_id.length());
+ uint32_t* ip_as_ints = reinterpret_cast<uint32_t*>(&v6addr.s6_addr);
+ // Transaction ID is in network byte order, but magic cookie
+ // is stored in host byte order.
+ ip_as_ints[0] =
+ (ip_as_ints[0] ^ rtc::HostToNetwork32(kStunMagicCookie));
+ ip_as_ints[1] = (ip_as_ints[1] ^ transactionid_as_ints[0]);
+ ip_as_ints[2] = (ip_as_ints[2] ^ transactionid_as_ints[1]);
+ ip_as_ints[3] = (ip_as_ints[3] ^ transactionid_as_ints[2]);
+ return rtc::IPAddress(v6addr);
+ }
+ break;
+ }
+ }
+ }
+ // Invalid ip family or transaction ID, or missing owner.
+ // Return an AF_UNSPEC address.
+ return rtc::IPAddress();
+}
+
+bool StunXorAddressAttribute::Read(ByteBufferReader* buf) {
+ if (!StunAddressAttribute::Read(buf))
+ return false;
+ uint16_t xoredport = port() ^ (kStunMagicCookie >> 16);
+ rtc::IPAddress xored_ip = GetXoredIP();
+ SetAddress(rtc::SocketAddress(xored_ip, xoredport));
+ return true;
+}
+
+bool StunXorAddressAttribute::Write(ByteBufferWriter* buf) const {
+ StunAddressFamily address_family = family();
+ if (address_family == STUN_ADDRESS_UNDEF) {
+ RTC_LOG(LS_ERROR) << "Error writing xor-address attribute: unknown family.";
+ return false;
+ }
+ rtc::IPAddress xored_ip = GetXoredIP();
+ if (xored_ip.family() == AF_UNSPEC) {
+ return false;
+ }
+ buf->WriteUInt8(0);
+ buf->WriteUInt8(family());
+ buf->WriteUInt16(port() ^ (kStunMagicCookie >> 16));
+ switch (xored_ip.family()) {
+ case AF_INET: {
+ in_addr v4addr = xored_ip.ipv4_address();
+ buf->WriteBytes(reinterpret_cast<const char*>(&v4addr), sizeof(v4addr));
+ break;
+ }
+ case AF_INET6: {
+ in6_addr v6addr = xored_ip.ipv6_address();
+ buf->WriteBytes(reinterpret_cast<const char*>(&v6addr), sizeof(v6addr));
+ break;
+ }
+ }
+ return true;
+}
+
+StunUInt32Attribute::StunUInt32Attribute(uint16_t type, uint32_t value)
+ : StunAttribute(type, SIZE), bits_(value) {}
+
+StunUInt32Attribute::StunUInt32Attribute(uint16_t type)
+ : StunAttribute(type, SIZE), bits_(0) {}
+
+StunAttributeValueType StunUInt32Attribute::value_type() const {
+ return STUN_VALUE_UINT32;
+}
+
+bool StunUInt32Attribute::GetBit(size_t index) const {
+ RTC_DCHECK(index < 32);
+ return static_cast<bool>((bits_ >> index) & 0x1);
+}
+
+void StunUInt32Attribute::SetBit(size_t index, bool value) {
+ RTC_DCHECK(index < 32);
+ bits_ &= ~(1 << index);
+ bits_ |= value ? (1 << index) : 0;
+}
+
+bool StunUInt32Attribute::Read(ByteBufferReader* buf) {
+ if (length() != SIZE || !buf->ReadUInt32(&bits_))
+ return false;
+ return true;
+}
+
+bool StunUInt32Attribute::Write(ByteBufferWriter* buf) const {
+ buf->WriteUInt32(bits_);
+ return true;
+}
+
+StunUInt64Attribute::StunUInt64Attribute(uint16_t type, uint64_t value)
+ : StunAttribute(type, SIZE), bits_(value) {}
+
+StunUInt64Attribute::StunUInt64Attribute(uint16_t type)
+ : StunAttribute(type, SIZE), bits_(0) {}
+
+StunAttributeValueType StunUInt64Attribute::value_type() const {
+ return STUN_VALUE_UINT64;
+}
+
+bool StunUInt64Attribute::Read(ByteBufferReader* buf) {
+ if (length() != SIZE || !buf->ReadUInt64(&bits_))
+ return false;
+ return true;
+}
+
+bool StunUInt64Attribute::Write(ByteBufferWriter* buf) const {
+ buf->WriteUInt64(bits_);
+ return true;
+}
+
+StunByteStringAttribute::StunByteStringAttribute(uint16_t type)
+ : StunAttribute(type, 0), bytes_(NULL) {}
+
+StunByteStringAttribute::StunByteStringAttribute(uint16_t type,
+ absl::string_view str)
+ : StunAttribute(type, 0), bytes_(NULL) {
+ CopyBytes(str);
+}
+
+StunByteStringAttribute::StunByteStringAttribute(uint16_t type,
+ const void* bytes,
+ size_t length)
+ : StunAttribute(type, 0), bytes_(NULL) {
+ CopyBytes(bytes, length);
+}
+
+StunByteStringAttribute::StunByteStringAttribute(uint16_t type, uint16_t length)
+ : StunAttribute(type, length), bytes_(NULL) {}
+
+StunByteStringAttribute::~StunByteStringAttribute() {
+ delete[] bytes_;
+}
+
+StunAttributeValueType StunByteStringAttribute::value_type() const {
+ return STUN_VALUE_BYTE_STRING;
+}
+
+void StunByteStringAttribute::CopyBytes(absl::string_view bytes) {
+ char* new_bytes = new char[bytes.size()];
+ memcpy(new_bytes, bytes.data(), bytes.size());
+ SetBytes(new_bytes, bytes.size());
+}
+
+void StunByteStringAttribute::CopyBytes(const void* bytes, size_t length) {
+ char* new_bytes = new char[length];
+ memcpy(new_bytes, bytes, length);
+ SetBytes(new_bytes, length);
+}
+
+uint8_t StunByteStringAttribute::GetByte(size_t index) const {
+ RTC_DCHECK(bytes_ != NULL);
+ RTC_DCHECK(index < length());
+ return static_cast<uint8_t>(bytes_[index]);
+}
+
+void StunByteStringAttribute::SetByte(size_t index, uint8_t value) {
+ RTC_DCHECK(bytes_ != NULL);
+ RTC_DCHECK(index < length());
+ bytes_[index] = value;
+}
+
+bool StunByteStringAttribute::Read(ByteBufferReader* buf) {
+ bytes_ = new char[length()];
+ if (!buf->ReadBytes(bytes_, length())) {
+ return false;
+ }
+
+ ConsumePadding(buf);
+ return true;
+}
+
+bool StunByteStringAttribute::Write(ByteBufferWriter* buf) const {
+ // Check that length is legal according to specs
+ if (!LengthValid(type(), length())) {
+ return false;
+ }
+ buf->WriteBytes(bytes_, length());
+ WritePadding(buf);
+ return true;
+}
+
+void StunByteStringAttribute::SetBytes(char* bytes, size_t length) {
+ delete[] bytes_;
+ bytes_ = bytes;
+ SetLength(static_cast<uint16_t>(length));
+}
+
+const uint16_t StunErrorCodeAttribute::MIN_SIZE = 4;
+
+StunErrorCodeAttribute::StunErrorCodeAttribute(uint16_t type,
+ int code,
+ const std::string& reason)
+ : StunAttribute(type, 0) {
+ SetCode(code);
+ SetReason(reason);
+}
+
+StunErrorCodeAttribute::StunErrorCodeAttribute(uint16_t type, uint16_t length)
+ : StunAttribute(type, length), class_(0), number_(0) {}
+
+StunErrorCodeAttribute::~StunErrorCodeAttribute() {}
+
+StunAttributeValueType StunErrorCodeAttribute::value_type() const {
+ return STUN_VALUE_ERROR_CODE;
+}
+
+int StunErrorCodeAttribute::code() const {
+ return class_ * 100 + number_;
+}
+
+void StunErrorCodeAttribute::SetCode(int code) {
+ class_ = static_cast<uint8_t>(code / 100);
+ number_ = static_cast<uint8_t>(code % 100);
+}
+
+void StunErrorCodeAttribute::SetReason(const std::string& reason) {
+ SetLength(MIN_SIZE + static_cast<uint16_t>(reason.size()));
+ reason_ = reason;
+}
+
+bool StunErrorCodeAttribute::Read(ByteBufferReader* buf) {
+ uint32_t val;
+ if (length() < MIN_SIZE || !buf->ReadUInt32(&val))
+ return false;
+
+ if ((val >> 11) != 0)
+ RTC_LOG(LS_ERROR) << "error-code bits not zero";
+
+ class_ = ((val >> 8) & 0x7);
+ number_ = (val & 0xff);
+
+ if (!buf->ReadString(&reason_, length() - 4))
+ return false;
+
+ ConsumePadding(buf);
+ return true;
+}
+
+bool StunErrorCodeAttribute::Write(ByteBufferWriter* buf) const {
+ buf->WriteUInt32(class_ << 8 | number_);
+ buf->WriteString(reason_);
+ WritePadding(buf);
+ return true;
+}
+
+StunUInt16ListAttribute::StunUInt16ListAttribute(uint16_t type, uint16_t length)
+ : StunAttribute(type, length) {
+ attr_types_ = new std::vector<uint16_t>();
+}
+
+StunUInt16ListAttribute::~StunUInt16ListAttribute() {
+ delete attr_types_;
+}
+
+StunAttributeValueType StunUInt16ListAttribute::value_type() const {
+ return STUN_VALUE_UINT16_LIST;
+}
+
+size_t StunUInt16ListAttribute::Size() const {
+ return attr_types_->size();
+}
+
+uint16_t StunUInt16ListAttribute::GetType(int index) const {
+ return (*attr_types_)[index];
+}
+
+void StunUInt16ListAttribute::SetType(int index, uint16_t value) {
+ (*attr_types_)[index] = value;
+}
+
+void StunUInt16ListAttribute::AddType(uint16_t value) {
+ attr_types_->push_back(value);
+ SetLength(static_cast<uint16_t>(attr_types_->size() * 2));
+}
+
+void StunUInt16ListAttribute::AddTypeAtIndex(uint16_t index, uint16_t value) {
+ if (attr_types_->size() < static_cast<size_t>(index + 1)) {
+ attr_types_->resize(index + 1);
+ }
+ (*attr_types_)[index] = value;
+ SetLength(static_cast<uint16_t>(attr_types_->size() * 2));
+}
+
+bool StunUInt16ListAttribute::Read(ByteBufferReader* buf) {
+ if (length() % 2) {
+ return false;
+ }
+
+ for (size_t i = 0; i < length() / 2; i++) {
+ uint16_t attr;
+ if (!buf->ReadUInt16(&attr))
+ return false;
+ attr_types_->push_back(attr);
+ }
+ // Padding of these attributes is done in RFC 5389 style. This is
+ // slightly different from RFC3489, but it shouldn't be important.
+ // RFC3489 pads out to a 32 bit boundary by duplicating one of the
+ // entries in the list (not necessarily the last one - it's unspecified).
+ // RFC5389 pads on the end, and the bytes are always ignored.
+ ConsumePadding(buf);
+ return true;
+}
+
+bool StunUInt16ListAttribute::Write(ByteBufferWriter* buf) const {
+ for (size_t i = 0; i < attr_types_->size(); ++i) {
+ buf->WriteUInt16((*attr_types_)[i]);
+ }
+ WritePadding(buf);
+ return true;
+}
+
+std::string StunMethodToString(int msg_type) {
+ switch (msg_type) {
+ case STUN_BINDING_REQUEST:
+ return "STUN BINDING request";
+ case STUN_BINDING_INDICATION:
+ return "STUN BINDING indication";
+ case STUN_BINDING_RESPONSE:
+ return "STUN BINDING response";
+ case STUN_BINDING_ERROR_RESPONSE:
+ return "STUN BINDING error response";
+ case GOOG_PING_REQUEST:
+ return "GOOG PING request";
+ case GOOG_PING_RESPONSE:
+ return "GOOG PING response";
+ case GOOG_PING_ERROR_RESPONSE:
+ return "GOOG PING error response";
+ case STUN_ALLOCATE_REQUEST:
+ return "TURN ALLOCATE request";
+ case STUN_ALLOCATE_RESPONSE:
+ return "TURN ALLOCATE response";
+ case STUN_ALLOCATE_ERROR_RESPONSE:
+ return "TURN ALLOCATE error response";
+ case TURN_REFRESH_REQUEST:
+ return "TURN REFRESH request";
+ case TURN_REFRESH_RESPONSE:
+ return "TURN REFRESH response";
+ case TURN_REFRESH_ERROR_RESPONSE:
+ return "TURN REFRESH error response";
+ case TURN_SEND_INDICATION:
+ return "TURN SEND INDICATION";
+ case TURN_DATA_INDICATION:
+ return "TURN DATA INDICATION";
+ case TURN_CREATE_PERMISSION_REQUEST:
+ return "TURN CREATE PERMISSION request";
+ case TURN_CREATE_PERMISSION_RESPONSE:
+ return "TURN CREATE PERMISSION response";
+ case TURN_CREATE_PERMISSION_ERROR_RESPONSE:
+ return "TURN CREATE PERMISSION error response";
+ case TURN_CHANNEL_BIND_REQUEST:
+ return "TURN CHANNEL BIND request";
+ case TURN_CHANNEL_BIND_RESPONSE:
+ return "TURN CHANNEL BIND response";
+ case TURN_CHANNEL_BIND_ERROR_RESPONSE:
+ return "TURN CHANNEL BIND error response";
+ default:
+ return "UNKNOWN<" + std::to_string(msg_type) + ">";
+ }
+}
+
+int GetStunSuccessResponseType(int req_type) {
+ return IsStunRequestType(req_type) ? (req_type | 0x100) : -1;
+}
+
+int GetStunErrorResponseType(int req_type) {
+ return IsStunRequestType(req_type) ? (req_type | 0x110) : -1;
+}
+
+bool IsStunRequestType(int msg_type) {
+ return ((msg_type & kStunTypeMask) == 0x000);
+}
+
+bool IsStunIndicationType(int msg_type) {
+ return ((msg_type & kStunTypeMask) == 0x010);
+}
+
+bool IsStunSuccessResponseType(int msg_type) {
+ return ((msg_type & kStunTypeMask) == 0x100);
+}
+
+bool IsStunErrorResponseType(int msg_type) {
+ return ((msg_type & kStunTypeMask) == 0x110);
+}
+
+bool ComputeStunCredentialHash(const std::string& username,
+ const std::string& realm,
+ const std::string& password,
+ std::string* hash) {
+ // http://tools.ietf.org/html/rfc5389#section-15.4
+ // long-term credentials will be calculated using the key and key is
+ // key = MD5(username ":" realm ":" SASLprep(password))
+ std::string input = username;
+ input += ':';
+ input += realm;
+ input += ':';
+ input += password;
+
+ char digest[rtc::MessageDigest::kMaxSize];
+ size_t size = rtc::ComputeDigest(rtc::DIGEST_MD5, input.c_str(), input.size(),
+ digest, sizeof(digest));
+ if (size == 0) {
+ return false;
+ }
+
+ *hash = std::string(digest, size);
+ return true;
+}
+
+std::unique_ptr<StunAttribute> CopyStunAttribute(
+ const StunAttribute& attribute,
+ rtc::ByteBufferWriter* tmp_buffer_ptr) {
+ ByteBufferWriter tmpBuffer;
+ if (tmp_buffer_ptr == nullptr) {
+ tmp_buffer_ptr = &tmpBuffer;
+ }
+
+ std::unique_ptr<StunAttribute> copy(StunAttribute::Create(
+ attribute.value_type(), attribute.type(),
+ static_cast<uint16_t>(attribute.length()), nullptr));
+
+ if (!copy) {
+ return nullptr;
+ }
+ tmp_buffer_ptr->Clear();
+ if (!attribute.Write(tmp_buffer_ptr)) {
+ return nullptr;
+ }
+ rtc::ByteBufferReader reader(*tmp_buffer_ptr);
+ if (!copy->Read(&reader)) {
+ return nullptr;
+ }
+
+ return copy;
+}
+
+StunAttributeValueType RelayMessage::GetAttributeValueType(int type) const {
+ switch (type) {
+ case STUN_ATTR_LIFETIME:
+ return STUN_VALUE_UINT32;
+ case STUN_ATTR_MAGIC_COOKIE:
+ return STUN_VALUE_BYTE_STRING;
+ case STUN_ATTR_BANDWIDTH:
+ return STUN_VALUE_UINT32;
+ case STUN_ATTR_DESTINATION_ADDRESS:
+ return STUN_VALUE_ADDRESS;
+ case STUN_ATTR_SOURCE_ADDRESS2:
+ return STUN_VALUE_ADDRESS;
+ case STUN_ATTR_DATA:
+ return STUN_VALUE_BYTE_STRING;
+ case STUN_ATTR_OPTIONS:
+ return STUN_VALUE_UINT32;
+ default:
+ return StunMessage::GetAttributeValueType(type);
+ }
+}
+
+StunMessage* RelayMessage::CreateNew() const {
+ return new RelayMessage();
+}
+
+StunAttributeValueType TurnMessage::GetAttributeValueType(int type) const {
+ switch (type) {
+ case STUN_ATTR_CHANNEL_NUMBER:
+ return STUN_VALUE_UINT32;
+ case STUN_ATTR_TURN_LIFETIME:
+ return STUN_VALUE_UINT32;
+ case STUN_ATTR_XOR_PEER_ADDRESS:
+ return STUN_VALUE_XOR_ADDRESS;
+ case STUN_ATTR_DATA:
+ return STUN_VALUE_BYTE_STRING;
+ case STUN_ATTR_XOR_RELAYED_ADDRESS:
+ return STUN_VALUE_XOR_ADDRESS;
+ case STUN_ATTR_EVEN_PORT:
+ return STUN_VALUE_BYTE_STRING;
+ case STUN_ATTR_REQUESTED_TRANSPORT:
+ return STUN_VALUE_UINT32;
+ case STUN_ATTR_DONT_FRAGMENT:
+ return STUN_VALUE_BYTE_STRING;
+ case STUN_ATTR_RESERVATION_TOKEN:
+ return STUN_VALUE_BYTE_STRING;
+ default:
+ return StunMessage::GetAttributeValueType(type);
+ }
+}
+
+StunMessage* TurnMessage::CreateNew() const {
+ return new TurnMessage();
+}
+
+StunAttributeValueType IceMessage::GetAttributeValueType(int type) const {
+ switch (type) {
+ case STUN_ATTR_PRIORITY:
+ case STUN_ATTR_GOOG_NETWORK_INFO:
+ case STUN_ATTR_NOMINATION:
+ return STUN_VALUE_UINT32;
+ case STUN_ATTR_USE_CANDIDATE:
+ return STUN_VALUE_BYTE_STRING;
+ case STUN_ATTR_ICE_CONTROLLED:
+ return STUN_VALUE_UINT64;
+ case STUN_ATTR_ICE_CONTROLLING:
+ return STUN_VALUE_UINT64;
+ default:
+ return StunMessage::GetAttributeValueType(type);
+ }
+}
+
+StunMessage* IceMessage::CreateNew() const {
+ return new IceMessage();
+}
+
+std::unique_ptr<StunMessage> StunMessage::Clone() const {
+ std::unique_ptr<StunMessage> copy(CreateNew());
+ if (!copy) {
+ return nullptr;
+ }
+ rtc::ByteBufferWriter buf;
+ if (!Write(&buf)) {
+ return nullptr;
+ }
+ rtc::ByteBufferReader reader(buf);
+ if (!copy->Read(&reader)) {
+ return nullptr;
+ }
+ return copy;
+}
+
+} // namespace cricket
diff --git a/third_party/libwebrtc/api/transport/stun.h b/third_party/libwebrtc/api/transport/stun.h
new file mode 100644
index 0000000000..c2c9ad4b9c
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/stun.h
@@ -0,0 +1,798 @@
+/*
+ * Copyright 2004 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TRANSPORT_STUN_H_
+#define API_TRANSPORT_STUN_H_
+
+// This file contains classes for dealing with the STUN protocol, as specified
+// in RFC 5389, and its descendants.
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <functional>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/array_view.h"
+#include "rtc_base/byte_buffer.h"
+#include "rtc_base/ip_address.h"
+#include "rtc_base/socket_address.h"
+
+namespace cricket {
+
+// These are the types of STUN messages defined in RFC 5389.
+enum StunMessageType : uint16_t {
+ STUN_INVALID_MESSAGE_TYPE = 0x0000,
+ STUN_BINDING_REQUEST = 0x0001,
+ STUN_BINDING_INDICATION = 0x0011,
+ STUN_BINDING_RESPONSE = 0x0101,
+ STUN_BINDING_ERROR_RESPONSE = 0x0111,
+
+ // Method 0x80, GOOG-PING is a variant of STUN BINDING
+ // that is sent instead of a STUN BINDING if the binding
+ // was identical to the one before.
+ GOOG_PING_REQUEST = 0x200,
+ GOOG_PING_RESPONSE = 0x300,
+ GOOG_PING_ERROR_RESPONSE = 0x310,
+};
+
+// These are all known STUN attributes, defined in RFC 5389 and elsewhere.
+// Next to each is the name of the class (T is StunTAttribute) that implements
+// that type.
+// RETRANSMIT_COUNT is the number of outstanding pings without a response at
+// the time the packet is generated.
+enum StunAttributeType {
+ STUN_ATTR_MAPPED_ADDRESS = 0x0001, // Address
+ STUN_ATTR_USERNAME = 0x0006, // ByteString
+ STUN_ATTR_MESSAGE_INTEGRITY = 0x0008, // ByteString, 20 bytes
+ STUN_ATTR_ERROR_CODE = 0x0009, // ErrorCode
+ STUN_ATTR_UNKNOWN_ATTRIBUTES = 0x000a, // UInt16List
+ STUN_ATTR_REALM = 0x0014, // ByteString
+ STUN_ATTR_NONCE = 0x0015, // ByteString
+ STUN_ATTR_XOR_MAPPED_ADDRESS = 0x0020, // XorAddress
+ STUN_ATTR_SOFTWARE = 0x8022, // ByteString
+ STUN_ATTR_ALTERNATE_SERVER = 0x8023, // Address
+ STUN_ATTR_FINGERPRINT = 0x8028, // UInt32
+ STUN_ATTR_RETRANSMIT_COUNT = 0xFF00 // UInt32
+};
+
+// These are the types of the values associated with the attributes above.
+// This allows us to perform some basic validation when reading or adding
+// attributes. Note that these values are for our own use, and not defined in
+// RFC 5389.
+enum StunAttributeValueType {
+ STUN_VALUE_UNKNOWN = 0,
+ STUN_VALUE_ADDRESS = 1,
+ STUN_VALUE_XOR_ADDRESS = 2,
+ STUN_VALUE_UINT32 = 3,
+ STUN_VALUE_UINT64 = 4,
+ STUN_VALUE_BYTE_STRING = 5,
+ STUN_VALUE_ERROR_CODE = 6,
+ STUN_VALUE_UINT16_LIST = 7
+};
+
+// These are the types of STUN addresses defined in RFC 5389.
+enum StunAddressFamily {
+ // NB: UNDEF is not part of the STUN spec.
+ STUN_ADDRESS_UNDEF = 0,
+ STUN_ADDRESS_IPV4 = 1,
+ STUN_ADDRESS_IPV6 = 2
+};
+
+// These are the types of STUN error codes defined in RFC 5389.
+enum StunErrorCode {
+ STUN_ERROR_TRY_ALTERNATE = 300,
+ STUN_ERROR_BAD_REQUEST = 400,
+ STUN_ERROR_UNAUTHORIZED = 401,
+ STUN_ERROR_UNKNOWN_ATTRIBUTE = 420,
+ STUN_ERROR_STALE_NONCE = 438,
+ STUN_ERROR_SERVER_ERROR = 500,
+ STUN_ERROR_GLOBAL_FAILURE = 600
+};
+
+// Strings for the error codes above.
+extern const char STUN_ERROR_REASON_TRY_ALTERNATE_SERVER[];
+extern const char STUN_ERROR_REASON_BAD_REQUEST[];
+extern const char STUN_ERROR_REASON_UNAUTHORIZED[];
+extern const char STUN_ERROR_REASON_UNKNOWN_ATTRIBUTE[];
+extern const char STUN_ERROR_REASON_STALE_NONCE[];
+extern const char STUN_ERROR_REASON_SERVER_ERROR[];
+
+// The mask used to determine whether a STUN message is a request/response etc.
+const uint32_t kStunTypeMask = 0x0110;
+
+// STUN Attribute header length.
+const size_t kStunAttributeHeaderSize = 4;
+
+// Following values correspond to RFC5389.
+const size_t kStunHeaderSize = 20;
+const size_t kStunTransactionIdOffset = 8;
+const size_t kStunTransactionIdLength = 12;
+const uint32_t kStunMagicCookie = 0x2112A442;
+constexpr size_t kStunMagicCookieLength = sizeof(kStunMagicCookie);
+
+// Following value corresponds to an earlier version of STUN from
+// RFC3489.
+const size_t kStunLegacyTransactionIdLength = 16;
+
+// STUN Message Integrity HMAC length.
+const size_t kStunMessageIntegritySize = 20;
+// Size of STUN_ATTR_MESSAGE_INTEGRITY_32
+const size_t kStunMessageIntegrity32Size = 4;
+
+class StunAddressAttribute;
+class StunAttribute;
+class StunByteStringAttribute;
+class StunErrorCodeAttribute;
+class StunUInt16ListAttribute;
+class StunUInt32Attribute;
+class StunUInt64Attribute;
+class StunXorAddressAttribute;
+
+// Records a complete STUN/TURN message. Each message consists of a type and
+// any number of attributes. Each attribute is parsed into an instance of an
+// appropriate class (see above). The Get* methods will return instances of
+// that attribute class.
+class StunMessage {
+ public:
+ // Constructs a StunMessage with an invalid type and empty, legacy length
+ // (16 bytes, RFC3489) transaction id.
+ StunMessage();
+
+ // Construct a `StunMessage` with a specific type and generate a new
+ // 12 byte transaction id (RFC5389).
+ explicit StunMessage(uint16_t type);
+
+ StunMessage(uint16_t type, absl::string_view transaction_id);
+
+ virtual ~StunMessage();
+
+ // The verification status of the message. This is checked on parsing,
+ // or set by AddMessageIntegrity.
+ // These values are persisted to logs. Entries should not be renumbered and
+ // numeric values should never be reused.
+ enum class IntegrityStatus {
+ kNotSet = 0,
+ kNoIntegrity = 1, // Message-integrity attribute missing
+ kIntegrityOk = 2, // Message-integrity checked OK
+ kIntegrityBad = 3, // Message-integrity verification failed
+ kMaxValue = kIntegrityBad,
+ };
+
+ int type() const { return type_; }
+ size_t length() const { return length_; }
+ const std::string& transaction_id() const { return transaction_id_; }
+ uint32_t reduced_transaction_id() const { return reduced_transaction_id_; }
+
+ // Returns true if the message confirms to RFC3489 rather than
+ // RFC5389. The main difference between the two versions of the STUN
+ // protocol is the presence of the magic cookie and different length
+ // of transaction ID. For outgoing packets the version of the protocol
+ // is determined by the lengths of the transaction ID.
+ bool IsLegacy() const;
+
+ [[deprecated]] void SetType(int type) { type_ = static_cast<uint16_t>(type); }
+ [[deprecated]] bool SetTransactionID(absl::string_view transaction_id) {
+ if (!IsValidTransactionId(transaction_id))
+ return false;
+ SetTransactionIdForTesting(transaction_id);
+ return true;
+ }
+
+ // Get a list of all of the attribute types in the "comprehension required"
+ // range that were not recognized.
+ std::vector<uint16_t> GetNonComprehendedAttributes() const;
+
+ // Gets the desired attribute value, or NULL if no such attribute type exists.
+ const StunAddressAttribute* GetAddress(int type) const;
+ const StunUInt32Attribute* GetUInt32(int type) const;
+ const StunUInt64Attribute* GetUInt64(int type) const;
+ const StunByteStringAttribute* GetByteString(int type) const;
+ const StunUInt16ListAttribute* GetUInt16List(int type) const;
+
+ // Gets these specific attribute values.
+ const StunErrorCodeAttribute* GetErrorCode() const;
+ // Returns the code inside the error code attribute, if present, and
+ // STUN_ERROR_GLOBAL_FAILURE otherwise.
+ int GetErrorCodeValue() const;
+ const StunUInt16ListAttribute* GetUnknownAttributes() const;
+
+ // Takes ownership of the specified attribute and adds it to the message.
+ void AddAttribute(std::unique_ptr<StunAttribute> attr);
+
+ // Remove the last occurrence of an attribute.
+ std::unique_ptr<StunAttribute> RemoveAttribute(int type);
+
+ // Remote all attributes and releases them.
+ void ClearAttributes();
+
+ // Validates that a STUN message has a correct MESSAGE-INTEGRITY value.
+ // This uses the buffered raw-format message stored by Read().
+ IntegrityStatus ValidateMessageIntegrity(const std::string& password);
+
+ // Revalidates the STUN message with (possibly) a new password.
+ // Indicates that calling logic needs review - probably previous call
+ // was checking with the wrong password.
+ IntegrityStatus RevalidateMessageIntegrity(const std::string& password);
+
+ // Returns the current integrity status of the message.
+ IntegrityStatus integrity() const { return integrity_; }
+
+ // Shortcut for checking if integrity is verified.
+ bool IntegrityOk() const {
+ return integrity_ == IntegrityStatus::kIntegrityOk;
+ }
+
+ // Returns the password attribute used to set or check the integrity.
+ // Can only be called after adding or checking the integrity.
+ std::string password() const {
+ RTC_DCHECK(integrity_ != IntegrityStatus::kNotSet);
+ return password_;
+ }
+
+ // Adds a MESSAGE-INTEGRITY attribute that is valid for the current message.
+ bool AddMessageIntegrity(absl::string_view password);
+
+ // Adds a STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32 attribute that is valid for the
+ // current message.
+ bool AddMessageIntegrity32(absl::string_view password);
+
+ // Verify that a buffer has stun magic cookie and one of the specified
+ // methods. Note that it does not check for the existance of FINGERPRINT.
+ static bool IsStunMethod(rtc::ArrayView<int> methods,
+ const char* data,
+ size_t size);
+
+ // Verifies that a given buffer is STUN by checking for a correct FINGERPRINT.
+ static bool ValidateFingerprint(const char* data, size_t size);
+
+ // Generates a new 12 byte (RFC5389) transaction id.
+ static std::string GenerateTransactionId();
+
+ // Adds a FINGERPRINT attribute that is valid for the current message.
+ bool AddFingerprint();
+
+ // Parses the STUN packet in the given buffer and records it here. The
+ // return value indicates whether this was successful.
+ bool Read(rtc::ByteBufferReader* buf);
+
+ // Writes this object into a STUN packet. The return value indicates whether
+ // this was successful.
+ bool Write(rtc::ByteBufferWriter* buf) const;
+
+ // Creates an empty message. Overridable by derived classes.
+ virtual StunMessage* CreateNew() const;
+
+ // Modify the stun magic cookie used for this STUN message.
+ // This is used for testing.
+ [[deprecated]] void SetStunMagicCookie(uint32_t val);
+
+ // Change the internal transaction id. Used only for testing.
+ void SetTransactionIdForTesting(absl::string_view transaction_id);
+
+ // Contruct a copy of `this`.
+ std::unique_ptr<StunMessage> Clone() const;
+
+ // Check if the attributes of this StunMessage equals those of `other`
+ // for all attributes that `attribute_type_mask` return true
+ bool EqualAttributes(const StunMessage* other,
+ std::function<bool(int type)> attribute_type_mask) const;
+
+ // Validates that a STUN message in byte buffer form
+ // has a correct MESSAGE-INTEGRITY value.
+ // These functions are not recommended and will be deprecated; use
+ // ValidateMessageIntegrity(password) on the parsed form instead.
+ [[deprecated("Use member function")]] static bool ValidateMessageIntegrity(
+ const char* data,
+ size_t size,
+ const std::string& password);
+ [[deprecated("Use member function")]] static bool ValidateMessageIntegrity32(
+ const char* data,
+ size_t size,
+ const std::string& password);
+
+ // Expose raw-buffer ValidateMessageIntegrity function for testing.
+ static bool ValidateMessageIntegrityForTesting(const char* data,
+ size_t size,
+ const std::string& password);
+ // Expose raw-buffer ValidateMessageIntegrity function for testing.
+ static bool ValidateMessageIntegrity32ForTesting(const char* data,
+ size_t size,
+ const std::string& password);
+
+ protected:
+ // Verifies that the given attribute is allowed for this message.
+ virtual StunAttributeValueType GetAttributeValueType(int type) const;
+
+ std::vector<std::unique_ptr<StunAttribute>> attrs_;
+
+ private:
+ StunAttribute* CreateAttribute(int type, size_t length) /* const*/;
+ const StunAttribute* GetAttribute(int type) const;
+ static bool IsValidTransactionId(absl::string_view transaction_id);
+ bool AddMessageIntegrityOfType(int mi_attr_type,
+ size_t mi_attr_size,
+ absl::string_view key);
+ static bool ValidateMessageIntegrityOfType(int mi_attr_type,
+ size_t mi_attr_size,
+ const char* data,
+ size_t size,
+ const std::string& password);
+
+ uint16_t type_ = STUN_INVALID_MESSAGE_TYPE;
+ uint16_t length_ = 0;
+ std::string transaction_id_;
+ uint32_t reduced_transaction_id_ = 0;
+ uint32_t stun_magic_cookie_ = kStunMagicCookie;
+ // The original buffer for messages created by Read().
+ std::string buffer_;
+ IntegrityStatus integrity_ = IntegrityStatus::kNotSet;
+ std::string password_;
+};
+
+// Base class for all STUN/TURN attributes.
+class StunAttribute {
+ public:
+ virtual ~StunAttribute() {}
+
+ int type() const { return type_; }
+ size_t length() const { return length_; }
+
+ // Return the type of this attribute.
+ virtual StunAttributeValueType value_type() const = 0;
+
+ // Only XorAddressAttribute needs this so far.
+ virtual void SetOwner(StunMessage* owner) {}
+
+ // Reads the body (not the type or length) for this type of attribute from
+ // the given buffer. Return value is true if successful.
+ virtual bool Read(rtc::ByteBufferReader* buf) = 0;
+
+ // Writes the body (not the type or length) to the given buffer. Return
+ // value is true if successful.
+ virtual bool Write(rtc::ByteBufferWriter* buf) const = 0;
+
+ // Creates an attribute object with the given type and smallest length.
+ static StunAttribute* Create(StunAttributeValueType value_type,
+ uint16_t type,
+ uint16_t length,
+ StunMessage* owner);
+ // TODO(?): Allow these create functions to take parameters, to reduce
+ // the amount of work callers need to do to initialize attributes.
+ static std::unique_ptr<StunAddressAttribute> CreateAddress(uint16_t type);
+ static std::unique_ptr<StunXorAddressAttribute> CreateXorAddress(
+ uint16_t type);
+ static std::unique_ptr<StunUInt32Attribute> CreateUInt32(uint16_t type);
+ static std::unique_ptr<StunUInt64Attribute> CreateUInt64(uint16_t type);
+ static std::unique_ptr<StunByteStringAttribute> CreateByteString(
+ uint16_t type);
+ static std::unique_ptr<StunUInt16ListAttribute> CreateUInt16ListAttribute(
+ uint16_t type);
+ static std::unique_ptr<StunErrorCodeAttribute> CreateErrorCode();
+ static std::unique_ptr<StunUInt16ListAttribute> CreateUnknownAttributes();
+
+ protected:
+ StunAttribute(uint16_t type, uint16_t length);
+ void SetLength(uint16_t length) { length_ = length; }
+ void WritePadding(rtc::ByteBufferWriter* buf) const;
+ void ConsumePadding(rtc::ByteBufferReader* buf) const;
+
+ private:
+ uint16_t type_;
+ uint16_t length_;
+};
+
+// Implements STUN attributes that record an Internet address.
+class StunAddressAttribute : public StunAttribute {
+ public:
+ static const uint16_t SIZE_UNDEF = 0;
+ static const uint16_t SIZE_IP4 = 8;
+ static const uint16_t SIZE_IP6 = 20;
+ StunAddressAttribute(uint16_t type, const rtc::SocketAddress& addr);
+ StunAddressAttribute(uint16_t type, uint16_t length);
+
+ StunAttributeValueType value_type() const override;
+
+ StunAddressFamily family() const {
+ switch (address_.ipaddr().family()) {
+ case AF_INET:
+ return STUN_ADDRESS_IPV4;
+ case AF_INET6:
+ return STUN_ADDRESS_IPV6;
+ }
+ return STUN_ADDRESS_UNDEF;
+ }
+
+ const rtc::SocketAddress& GetAddress() const { return address_; }
+ const rtc::IPAddress& ipaddr() const { return address_.ipaddr(); }
+ uint16_t port() const { return address_.port(); }
+
+ void SetAddress(const rtc::SocketAddress& addr) {
+ address_ = addr;
+ EnsureAddressLength();
+ }
+ void SetIP(const rtc::IPAddress& ip) {
+ address_.SetIP(ip);
+ EnsureAddressLength();
+ }
+ void SetPort(uint16_t port) { address_.SetPort(port); }
+
+ bool Read(rtc::ByteBufferReader* buf) override;
+ bool Write(rtc::ByteBufferWriter* buf) const override;
+
+ private:
+ void EnsureAddressLength() {
+ switch (family()) {
+ case STUN_ADDRESS_IPV4: {
+ SetLength(SIZE_IP4);
+ break;
+ }
+ case STUN_ADDRESS_IPV6: {
+ SetLength(SIZE_IP6);
+ break;
+ }
+ default: {
+ SetLength(SIZE_UNDEF);
+ break;
+ }
+ }
+ }
+ rtc::SocketAddress address_;
+};
+
+// Implements STUN attributes that record an Internet address. When encoded
+// in a STUN message, the address contained in this attribute is XORed with the
+// transaction ID of the message.
+class StunXorAddressAttribute : public StunAddressAttribute {
+ public:
+ StunXorAddressAttribute(uint16_t type, const rtc::SocketAddress& addr);
+ StunXorAddressAttribute(uint16_t type, uint16_t length, StunMessage* owner);
+
+ StunAttributeValueType value_type() const override;
+ void SetOwner(StunMessage* owner) override;
+ bool Read(rtc::ByteBufferReader* buf) override;
+ bool Write(rtc::ByteBufferWriter* buf) const override;
+
+ private:
+ rtc::IPAddress GetXoredIP() const;
+ StunMessage* owner_;
+};
+
+// Implements STUN attributes that record a 32-bit integer.
+class StunUInt32Attribute : public StunAttribute {
+ public:
+ static const uint16_t SIZE = 4;
+ StunUInt32Attribute(uint16_t type, uint32_t value);
+ explicit StunUInt32Attribute(uint16_t type);
+
+ StunAttributeValueType value_type() const override;
+
+ uint32_t value() const { return bits_; }
+ void SetValue(uint32_t bits) { bits_ = bits; }
+
+ bool GetBit(size_t index) const;
+ void SetBit(size_t index, bool value);
+
+ bool Read(rtc::ByteBufferReader* buf) override;
+ bool Write(rtc::ByteBufferWriter* buf) const override;
+
+ private:
+ uint32_t bits_;
+};
+
+class StunUInt64Attribute : public StunAttribute {
+ public:
+ static const uint16_t SIZE = 8;
+ StunUInt64Attribute(uint16_t type, uint64_t value);
+ explicit StunUInt64Attribute(uint16_t type);
+
+ StunAttributeValueType value_type() const override;
+
+ uint64_t value() const { return bits_; }
+ void SetValue(uint64_t bits) { bits_ = bits; }
+
+ bool Read(rtc::ByteBufferReader* buf) override;
+ bool Write(rtc::ByteBufferWriter* buf) const override;
+
+ private:
+ uint64_t bits_;
+};
+
+// Implements STUN attributes that record an arbitrary byte string.
+class StunByteStringAttribute : public StunAttribute {
+ public:
+ explicit StunByteStringAttribute(uint16_t type);
+ StunByteStringAttribute(uint16_t type, absl::string_view str);
+ StunByteStringAttribute(uint16_t type, const void* bytes, size_t length);
+ StunByteStringAttribute(uint16_t type, uint16_t length);
+ ~StunByteStringAttribute() override;
+
+ StunAttributeValueType value_type() const override;
+
+ const char* bytes() const { return bytes_; }
+ absl::string_view string_view() const {
+ return absl::string_view(bytes_, length());
+ }
+
+ [[deprecated]] std::string GetString() const {
+ return std::string(bytes_, length());
+ }
+
+ void CopyBytes(const void* bytes, size_t length);
+ void CopyBytes(absl::string_view bytes);
+
+ uint8_t GetByte(size_t index) const;
+ void SetByte(size_t index, uint8_t value);
+
+ bool Read(rtc::ByteBufferReader* buf) override;
+ bool Write(rtc::ByteBufferWriter* buf) const override;
+
+ private:
+ void SetBytes(char* bytes, size_t length);
+
+ char* bytes_;
+};
+
+// Implements STUN attributes that record an error code.
+class StunErrorCodeAttribute : public StunAttribute {
+ public:
+ static const uint16_t MIN_SIZE;
+ StunErrorCodeAttribute(uint16_t type, int code, const std::string& reason);
+ StunErrorCodeAttribute(uint16_t type, uint16_t length);
+ ~StunErrorCodeAttribute() override;
+
+ StunAttributeValueType value_type() const override;
+
+ // The combined error and class, e.g. 0x400.
+ int code() const;
+ void SetCode(int code);
+
+ // The individual error components.
+ int eclass() const { return class_; }
+ int number() const { return number_; }
+ const std::string& reason() const { return reason_; }
+ void SetClass(uint8_t eclass) { class_ = eclass; }
+ void SetNumber(uint8_t number) { number_ = number; }
+ void SetReason(const std::string& reason);
+
+ bool Read(rtc::ByteBufferReader* buf) override;
+ bool Write(rtc::ByteBufferWriter* buf) const override;
+
+ private:
+ uint8_t class_;
+ uint8_t number_;
+ std::string reason_;
+};
+
+// Implements STUN attributes that record a list of attribute names.
+class StunUInt16ListAttribute : public StunAttribute {
+ public:
+ StunUInt16ListAttribute(uint16_t type, uint16_t length);
+ ~StunUInt16ListAttribute() override;
+
+ StunAttributeValueType value_type() const override;
+
+ size_t Size() const;
+ uint16_t GetType(int index) const;
+ void SetType(int index, uint16_t value);
+ void AddType(uint16_t value);
+ void AddTypeAtIndex(uint16_t index, uint16_t value);
+
+ bool Read(rtc::ByteBufferReader* buf) override;
+ bool Write(rtc::ByteBufferWriter* buf) const override;
+
+ private:
+ std::vector<uint16_t>* attr_types_;
+};
+
+// Return a string e.g "STUN BINDING request".
+std::string StunMethodToString(int msg_type);
+
+// Returns the (successful) response type for the given request type.
+// Returns -1 if `request_type` is not a valid request type.
+int GetStunSuccessResponseType(int request_type);
+
+// Returns the error response type for the given request type.
+// Returns -1 if `request_type` is not a valid request type.
+int GetStunErrorResponseType(int request_type);
+
+// Returns whether a given message is a request type.
+bool IsStunRequestType(int msg_type);
+
+// Returns whether a given message is an indication type.
+bool IsStunIndicationType(int msg_type);
+
+// Returns whether a given response is a success type.
+bool IsStunSuccessResponseType(int msg_type);
+
+// Returns whether a given response is an error type.
+bool IsStunErrorResponseType(int msg_type);
+
+// Computes the STUN long-term credential hash.
+bool ComputeStunCredentialHash(const std::string& username,
+ const std::string& realm,
+ const std::string& password,
+ std::string* hash);
+
+// Make a copy af `attribute` and return a new StunAttribute.
+// This is useful if you don't care about what kind of attribute you
+// are handling.
+//
+// The implementation copies by calling Write() followed by Read().
+//
+// If `tmp_buffer` is supplied this buffer will be used, otherwise
+// a buffer will created in the method.
+std::unique_ptr<StunAttribute> CopyStunAttribute(
+ const StunAttribute& attribute,
+ rtc::ByteBufferWriter* tmp_buffer_ptr = 0);
+
+// TODO(?): Move the TURN/ICE stuff below out to separate files.
+extern const char TURN_MAGIC_COOKIE_VALUE[4];
+
+// "GTURN" STUN methods.
+// TODO(?): Rename these methods to GTURN_ to make it clear they aren't
+// part of standard STUN/TURN.
+enum RelayMessageType {
+ // For now, using the same defs from TurnMessageType below.
+ // STUN_ALLOCATE_REQUEST = 0x0003,
+ // STUN_ALLOCATE_RESPONSE = 0x0103,
+ // STUN_ALLOCATE_ERROR_RESPONSE = 0x0113,
+ STUN_SEND_REQUEST = 0x0004,
+ STUN_SEND_RESPONSE = 0x0104,
+ STUN_SEND_ERROR_RESPONSE = 0x0114,
+ STUN_DATA_INDICATION = 0x0115,
+};
+
+// "GTURN"-specific STUN attributes.
+// TODO(?): Rename these attributes to GTURN_ to avoid conflicts.
+enum RelayAttributeType {
+ STUN_ATTR_LIFETIME = 0x000d, // UInt32
+ STUN_ATTR_MAGIC_COOKIE = 0x000f, // ByteString, 4 bytes
+ STUN_ATTR_BANDWIDTH = 0x0010, // UInt32
+ STUN_ATTR_DESTINATION_ADDRESS = 0x0011, // Address
+ STUN_ATTR_SOURCE_ADDRESS2 = 0x0012, // Address
+ STUN_ATTR_DATA = 0x0013, // ByteString
+ STUN_ATTR_OPTIONS = 0x8001, // UInt32
+};
+
+// A "GTURN" STUN message.
+class RelayMessage : public StunMessage {
+ public:
+ using StunMessage::StunMessage;
+
+ protected:
+ StunAttributeValueType GetAttributeValueType(int type) const override;
+ StunMessage* CreateNew() const override;
+};
+
+// Defined in TURN RFC 5766.
+enum TurnMessageType : uint16_t {
+ STUN_ALLOCATE_REQUEST = 0x0003,
+ STUN_ALLOCATE_RESPONSE = 0x0103,
+ STUN_ALLOCATE_ERROR_RESPONSE = 0x0113,
+ TURN_REFRESH_REQUEST = 0x0004,
+ TURN_REFRESH_RESPONSE = 0x0104,
+ TURN_REFRESH_ERROR_RESPONSE = 0x0114,
+ TURN_SEND_INDICATION = 0x0016,
+ TURN_DATA_INDICATION = 0x0017,
+ TURN_CREATE_PERMISSION_REQUEST = 0x0008,
+ TURN_CREATE_PERMISSION_RESPONSE = 0x0108,
+ TURN_CREATE_PERMISSION_ERROR_RESPONSE = 0x0118,
+ TURN_CHANNEL_BIND_REQUEST = 0x0009,
+ TURN_CHANNEL_BIND_RESPONSE = 0x0109,
+ TURN_CHANNEL_BIND_ERROR_RESPONSE = 0x0119,
+};
+
+enum TurnAttributeType {
+ STUN_ATTR_CHANNEL_NUMBER = 0x000C, // UInt32
+ STUN_ATTR_TURN_LIFETIME = 0x000d, // UInt32
+ STUN_ATTR_XOR_PEER_ADDRESS = 0x0012, // XorAddress
+ // TODO(mallinath) - Uncomment after RelayAttributes are renamed.
+ // STUN_ATTR_DATA = 0x0013, // ByteString
+ STUN_ATTR_XOR_RELAYED_ADDRESS = 0x0016, // XorAddress
+ STUN_ATTR_EVEN_PORT = 0x0018, // ByteString, 1 byte.
+ STUN_ATTR_REQUESTED_TRANSPORT = 0x0019, // UInt32
+ STUN_ATTR_DONT_FRAGMENT = 0x001A, // No content, Length = 0
+ STUN_ATTR_RESERVATION_TOKEN = 0x0022, // ByteString, 8 bytes.
+ // TODO(mallinath) - Rename STUN_ATTR_TURN_LIFETIME to STUN_ATTR_LIFETIME and
+ // STUN_ATTR_TURN_DATA to STUN_ATTR_DATA. Also rename RelayMessage attributes
+ // by appending G to attribute name.
+};
+
+// RFC 5766-defined errors.
+enum TurnErrorType {
+ STUN_ERROR_FORBIDDEN = 403,
+ STUN_ERROR_ALLOCATION_MISMATCH = 437,
+ STUN_ERROR_WRONG_CREDENTIALS = 441,
+ STUN_ERROR_UNSUPPORTED_PROTOCOL = 442
+};
+
+extern const int SERVER_NOT_REACHABLE_ERROR;
+
+extern const char STUN_ERROR_REASON_FORBIDDEN[];
+extern const char STUN_ERROR_REASON_ALLOCATION_MISMATCH[];
+extern const char STUN_ERROR_REASON_WRONG_CREDENTIALS[];
+extern const char STUN_ERROR_REASON_UNSUPPORTED_PROTOCOL[];
+class TurnMessage : public StunMessage {
+ public:
+ using StunMessage::StunMessage;
+
+ protected:
+ StunAttributeValueType GetAttributeValueType(int type) const override;
+ StunMessage* CreateNew() const override;
+};
+
+enum IceAttributeType {
+ // RFC 5245 ICE STUN attributes.
+ STUN_ATTR_PRIORITY = 0x0024, // UInt32
+ STUN_ATTR_USE_CANDIDATE = 0x0025, // No content, Length = 0
+ STUN_ATTR_ICE_CONTROLLED = 0x8029, // UInt64
+ STUN_ATTR_ICE_CONTROLLING = 0x802A, // UInt64
+ // The following attributes are in the comprehension-optional range
+ // (0xC000-0xFFFF) and are not registered with IANA. These STUN attributes are
+ // intended for ICE and should NOT be used in generic use cases of STUN
+ // messages.
+ //
+ // Note that the value 0xC001 has already been assigned by IANA to
+ // ENF-FLOW-DESCRIPTION
+ // (https://www.iana.org/assignments/stun-parameters/stun-parameters.xml).
+ STUN_ATTR_NOMINATION = 0xC001, // UInt32
+ // UInt32. The higher 16 bits are the network ID. The lower 16 bits are the
+ // network cost.
+ STUN_ATTR_GOOG_NETWORK_INFO = 0xC057,
+ // Experimental: Transaction ID of the last connectivity check received.
+ STUN_ATTR_GOOG_LAST_ICE_CHECK_RECEIVED = 0xC058,
+ // Uint16List. Miscellaneous attributes for future extension.
+ STUN_ATTR_GOOG_MISC_INFO = 0xC059,
+ // Obsolete.
+ STUN_ATTR_GOOG_OBSOLETE_1 = 0xC05A,
+ STUN_ATTR_GOOG_CONNECTION_ID = 0xC05B, // Not yet implemented.
+ STUN_ATTR_GOOG_DELTA = 0xC05C, // Not yet implemented.
+ STUN_ATTR_GOOG_DELTA_ACK = 0xC05D, // Not yet implemented.
+ // MESSAGE-INTEGRITY truncated to 32-bit.
+ STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32 = 0xC060,
+};
+
+// When adding new attributes to STUN_ATTR_GOOG_MISC_INFO
+// (which is a list of uint16_t), append the indices of these attributes below
+// and do NOT change the existing indices. The indices of attributes must be
+// consistent with those used in ConnectionRequest::Prepare when forming a STUN
+// message for the ICE connectivity check, and they are used when parsing a
+// received STUN message.
+enum class IceGoogMiscInfoBindingRequestAttributeIndex {
+ SUPPORT_GOOG_PING_VERSION = 0,
+};
+
+enum class IceGoogMiscInfoBindingResponseAttributeIndex {
+ SUPPORT_GOOG_PING_VERSION = 0,
+};
+
+// RFC 5245-defined errors.
+enum IceErrorCode {
+ STUN_ERROR_ROLE_CONFLICT = 487,
+};
+extern const char STUN_ERROR_REASON_ROLE_CONFLICT[];
+
+// A RFC 5245 ICE STUN message.
+class IceMessage : public StunMessage {
+ public:
+ using StunMessage::StunMessage;
+
+ protected:
+ StunAttributeValueType GetAttributeValueType(int type) const override;
+ StunMessage* CreateNew() const override;
+};
+
+} // namespace cricket
+
+#endif // API_TRANSPORT_STUN_H_
diff --git a/third_party/libwebrtc/api/transport/stun_types_gn/moz.build b/third_party/libwebrtc/api/transport/stun_types_gn/moz.build
new file mode 100644
index 0000000000..dd75da361b
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/stun_types_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("stun_types_gn")
diff --git a/third_party/libwebrtc/api/transport/stun_unittest.cc b/third_party/libwebrtc/api/transport/stun_unittest.cc
new file mode 100644
index 0000000000..96ad45843b
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/stun_unittest.cc
@@ -0,0 +1,1882 @@
+/*
+ * Copyright 2004 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/transport/stun.h"
+
+#include <string.h>
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "rtc_base/arraysize.h"
+#include "rtc_base/byte_buffer.h"
+#include "rtc_base/byte_order.h"
+#include "rtc_base/socket_address.h"
+#include "system_wrappers/include/metrics.h"
+#include "test/gtest.h"
+
+namespace cricket {
+
+class StunTest : public ::testing::Test {
+ protected:
+ void CheckStunHeader(const StunMessage& msg,
+ StunMessageType expected_type,
+ size_t expected_length) {
+ ASSERT_EQ(expected_type, msg.type());
+ ASSERT_EQ(expected_length, msg.length());
+ }
+
+ void CheckStunTransactionID(const StunMessage& msg,
+ const unsigned char* expectedID,
+ size_t length) {
+ ASSERT_EQ(length, msg.transaction_id().size());
+ ASSERT_EQ(length == kStunTransactionIdLength + 4, msg.IsLegacy());
+ ASSERT_EQ(length == kStunTransactionIdLength, !msg.IsLegacy());
+ ASSERT_EQ(0, memcmp(msg.transaction_id().c_str(), expectedID, length));
+ }
+
+ void CheckStunAddressAttribute(const StunAddressAttribute* addr,
+ StunAddressFamily expected_family,
+ int expected_port,
+ const rtc::IPAddress& expected_address) {
+ ASSERT_EQ(expected_family, addr->family());
+ ASSERT_EQ(expected_port, addr->port());
+
+ if (addr->family() == STUN_ADDRESS_IPV4) {
+ in_addr v4_address = expected_address.ipv4_address();
+ in_addr stun_address = addr->ipaddr().ipv4_address();
+ ASSERT_EQ(0, memcmp(&v4_address, &stun_address, sizeof(stun_address)));
+ } else if (addr->family() == STUN_ADDRESS_IPV6) {
+ in6_addr v6_address = expected_address.ipv6_address();
+ in6_addr stun_address = addr->ipaddr().ipv6_address();
+ ASSERT_EQ(0, memcmp(&v6_address, &stun_address, sizeof(stun_address)));
+ } else {
+ ASSERT_TRUE(addr->family() == STUN_ADDRESS_IPV6 ||
+ addr->family() == STUN_ADDRESS_IPV4);
+ }
+ }
+
+ size_t ReadStunMessageTestCase(StunMessage* msg,
+ const unsigned char* testcase,
+ size_t size) {
+ const char* input = reinterpret_cast<const char*>(testcase);
+ rtc::ByteBufferReader buf(input, size);
+ if (msg->Read(&buf)) {
+ // Returns the size the stun message should report itself as being
+ return (size - 20);
+ } else {
+ return 0;
+ }
+ }
+};
+
+// Sample STUN packets with various attributes
+// Gathered by wiresharking pjproject's pjnath test programs
+// pjproject available at www.pjsip.org
+
+// clang-format off
+// clang formatting doesn't respect inline comments.
+
+static const unsigned char kStunMessageWithIPv6MappedAddress[] = {
+ 0x00, 0x01, 0x00, 0x18, // message header
+ 0x21, 0x12, 0xa4, 0x42, // transaction id
+ 0x29, 0x1f, 0xcd, 0x7c,
+ 0xba, 0x58, 0xab, 0xd7,
+ 0xf2, 0x41, 0x01, 0x00,
+ 0x00, 0x01, 0x00, 0x14, // Address type (mapped), length
+ 0x00, 0x02, 0xb8, 0x81, // family (IPv6), port
+ 0x24, 0x01, 0xfa, 0x00, // an IPv6 address
+ 0x00, 0x04, 0x10, 0x00,
+ 0xbe, 0x30, 0x5b, 0xff,
+ 0xfe, 0xe5, 0x00, 0xc3
+};
+
+static const unsigned char kStunMessageWithIPv4MappedAddress[] = {
+ 0x01, 0x01, 0x00, 0x0c, // binding response, length 12
+ 0x21, 0x12, 0xa4, 0x42, // magic cookie
+ 0x29, 0x1f, 0xcd, 0x7c, // transaction ID
+ 0xba, 0x58, 0xab, 0xd7,
+ 0xf2, 0x41, 0x01, 0x00,
+ 0x00, 0x01, 0x00, 0x08, // Mapped, 8 byte length
+ 0x00, 0x01, 0x9d, 0xfc, // AF_INET, unxor-ed port
+ 0xac, 0x17, 0x44, 0xe6 // IPv4 address
+};
+
+// Test XOR-mapped IP addresses:
+static const unsigned char kStunMessageWithIPv6XorMappedAddress[] = {
+ 0x01, 0x01, 0x00, 0x18, // message header (binding response)
+ 0x21, 0x12, 0xa4, 0x42, // magic cookie (rfc5389)
+ 0xe3, 0xa9, 0x46, 0xe1, // transaction ID
+ 0x7c, 0x00, 0xc2, 0x62,
+ 0x54, 0x08, 0x01, 0x00,
+ 0x00, 0x20, 0x00, 0x14, // Address Type (XOR), length
+ 0x00, 0x02, 0xcb, 0x5b, // family, XOR-ed port
+ 0x05, 0x13, 0x5e, 0x42, // XOR-ed IPv6 address
+ 0xe3, 0xad, 0x56, 0xe1,
+ 0xc2, 0x30, 0x99, 0x9d,
+ 0xaa, 0xed, 0x01, 0xc3
+};
+
+static const unsigned char kStunMessageWithIPv4XorMappedAddress[] = {
+ 0x01, 0x01, 0x00, 0x0c, // message header (binding response)
+ 0x21, 0x12, 0xa4, 0x42, // magic cookie
+ 0x29, 0x1f, 0xcd, 0x7c, // transaction ID
+ 0xba, 0x58, 0xab, 0xd7,
+ 0xf2, 0x41, 0x01, 0x00,
+ 0x00, 0x20, 0x00, 0x08, // address type (xor), length
+ 0x00, 0x01, 0xfc, 0xb5, // family (AF_INET), XOR-ed port
+ 0x8d, 0x05, 0xe0, 0xa4 // IPv4 address
+};
+
+// ByteString Attribute (username)
+static const unsigned char kStunMessageWithByteStringAttribute[] = {
+ 0x00, 0x01, 0x00, 0x0c,
+ 0x21, 0x12, 0xa4, 0x42,
+ 0xe3, 0xa9, 0x46, 0xe1,
+ 0x7c, 0x00, 0xc2, 0x62,
+ 0x54, 0x08, 0x01, 0x00,
+ 0x00, 0x06, 0x00, 0x08, // username attribute (length 8)
+ 0x61, 0x62, 0x63, 0x64, // abcdefgh
+ 0x65, 0x66, 0x67, 0x68
+};
+
+// Message with an unknown but comprehensible optional attribute.
+// Parsing should succeed despite this unknown attribute.
+static const unsigned char kStunMessageWithUnknownAttribute[] = {
+ 0x00, 0x01, 0x00, 0x14,
+ 0x21, 0x12, 0xa4, 0x42,
+ 0xe3, 0xa9, 0x46, 0xe1,
+ 0x7c, 0x00, 0xc2, 0x62,
+ 0x54, 0x08, 0x01, 0x00,
+ 0x00, 0xaa, 0x00, 0x07, // Unknown attribute, length 7 (needs padding!)
+ 0x61, 0x62, 0x63, 0x64, // abcdefg + padding
+ 0x65, 0x66, 0x67, 0x00,
+ 0x00, 0x06, 0x00, 0x03, // Followed by a known attribute we can
+ 0x61, 0x62, 0x63, 0x00 // check for (username of length 3)
+};
+
+// ByteString Attribute (username) with padding byte
+static const unsigned char kStunMessageWithPaddedByteStringAttribute[] = {
+ 0x00, 0x01, 0x00, 0x08,
+ 0x21, 0x12, 0xa4, 0x42,
+ 0xe3, 0xa9, 0x46, 0xe1,
+ 0x7c, 0x00, 0xc2, 0x62,
+ 0x54, 0x08, 0x01, 0x00,
+ 0x00, 0x06, 0x00, 0x03, // username attribute (length 3)
+ 0x61, 0x62, 0x63, 0xcc // abc
+};
+
+// Message with an Unknown Attributes (uint16_t list) attribute.
+static const unsigned char kStunMessageWithUInt16ListAttribute[] = {
+ 0x00, 0x01, 0x00, 0x0c,
+ 0x21, 0x12, 0xa4, 0x42,
+ 0xe3, 0xa9, 0x46, 0xe1,
+ 0x7c, 0x00, 0xc2, 0x62,
+ 0x54, 0x08, 0x01, 0x00,
+ 0x00, 0x0a, 0x00, 0x06, // username attribute (length 6)
+ 0x00, 0x01, 0x10, 0x00, // three attributes plus padding
+ 0xAB, 0xCU, 0xBE, 0xEF
+};
+
+// Error response message (unauthorized)
+static const unsigned char kStunMessageWithErrorAttribute[] = {
+ 0x01, 0x11, 0x00, 0x14,
+ 0x21, 0x12, 0xa4, 0x42,
+ 0x29, 0x1f, 0xcd, 0x7c,
+ 0xba, 0x58, 0xab, 0xd7,
+ 0xf2, 0x41, 0x01, 0x00,
+ 0x00, 0x09, 0x00, 0x10,
+ 0x00, 0x00, 0x04, 0x01,
+ 0x55, 0x6e, 0x61, 0x75,
+ 0x74, 0x68, 0x6f, 0x72,
+ 0x69, 0x7a, 0x65, 0x64
+};
+
+// Sample messages with an invalid length Field
+
+// The actual length in bytes of the invalid messages (including STUN header)
+static const int kRealLengthOfInvalidLengthTestCases = 32;
+
+static const unsigned char kStunMessageWithZeroLength[] = {
+ 0x00, 0x01, 0x00, 0x00, // length of 0 (last 2 bytes)
+ 0x21, 0x12, 0xA4, 0x42, // magic cookie
+ '0', '1', '2', '3', // transaction id
+ '4', '5', '6', '7',
+ '8', '9', 'a', 'b',
+ 0x00, 0x20, 0x00, 0x08, // xor mapped address
+ 0x00, 0x01, 0x21, 0x1F,
+ 0x21, 0x12, 0xA4, 0x53,
+};
+
+static const unsigned char kStunMessageWithExcessLength[] = {
+ 0x00, 0x01, 0x00, 0x55, // length of 85
+ 0x21, 0x12, 0xA4, 0x42, // magic cookie
+ '0', '1', '2', '3', // transaction id
+ '4', '5', '6', '7',
+ '8', '9', 'a', 'b',
+ 0x00, 0x20, 0x00, 0x08, // xor mapped address
+ 0x00, 0x01, 0x21, 0x1F,
+ 0x21, 0x12, 0xA4, 0x53,
+};
+
+static const unsigned char kStunMessageWithSmallLength[] = {
+ 0x00, 0x01, 0x00, 0x03, // length of 3
+ 0x21, 0x12, 0xA4, 0x42, // magic cookie
+ '0', '1', '2', '3', // transaction id
+ '4', '5', '6', '7',
+ '8', '9', 'a', 'b',
+ 0x00, 0x20, 0x00, 0x08, // xor mapped address
+ 0x00, 0x01, 0x21, 0x1F,
+ 0x21, 0x12, 0xA4, 0x53,
+};
+
+static const unsigned char kStunMessageWithBadHmacAtEnd[] = {
+ 0x00, 0x01, 0x00, 0x14, // message length exactly 20
+ 0x21, 0x12, 0xA4, 0x42, // magic cookie
+ '0', '1', '2', '3', // transaction ID
+ '4', '5', '6', '7',
+ '8', '9', 'a', 'b',
+ 0x00, 0x08, 0x00, 0x14, // type=STUN_ATTR_MESSAGE_INTEGRITY, length=20
+ '0', '0', '0', '0', // We lied, there are only 16 bytes of HMAC.
+ '0', '0', '0', '0',
+ '0', '0', '0', '0',
+ '0', '0', '0', '0',
+};
+
+// RTCP packet, for testing we correctly ignore non stun packet types.
+// V=2, P=false, RC=0, Type=200, Len=6, Sender-SSRC=85, etc
+static const unsigned char kRtcpPacket[] = {
+ 0x80, 0xc8, 0x00, 0x06, 0x00, 0x00, 0x00, 0x55,
+ 0xce, 0xa5, 0x18, 0x3a, 0x39, 0xcc, 0x7d, 0x09,
+ 0x23, 0xed, 0x19, 0x07, 0x00, 0x00, 0x01, 0x56,
+ 0x00, 0x03, 0x73, 0x50,
+};
+
+
+// RFC5769 Test Vectors
+// Software name (request): "STUN test client" (without quotes)
+// Software name (response): "test vector" (without quotes)
+// Username: "evtj:h6vY" (without quotes)
+// Password: "VOkJxbRl1RmTxUk/WvJxBt" (without quotes)
+static const unsigned char kRfc5769SampleMsgTransactionId[] = {
+ 0xb7, 0xe7, 0xa7, 0x01, 0xbc, 0x34, 0xd6, 0x86, 0xfa, 0x87, 0xdf, 0xae
+};
+static const char kRfc5769SampleMsgClientSoftware[] = "STUN test client";
+static const char kRfc5769SampleMsgServerSoftware[] = "test vector";
+static const char kRfc5769SampleMsgUsername[] = "evtj:h6vY";
+static const char kRfc5769SampleMsgPassword[] = "VOkJxbRl1RmTxUk/WvJxBt";
+static const rtc::SocketAddress kRfc5769SampleMsgMappedAddress(
+ "192.0.2.1", 32853);
+static const rtc::SocketAddress kRfc5769SampleMsgIPv6MappedAddress(
+ "2001:db8:1234:5678:11:2233:4455:6677", 32853);
+
+static const unsigned char kRfc5769SampleMsgWithAuthTransactionId[] = {
+ 0x78, 0xad, 0x34, 0x33, 0xc6, 0xad, 0x72, 0xc0, 0x29, 0xda, 0x41, 0x2e
+};
+static const char kRfc5769SampleMsgWithAuthUsername[] =
+ "\xe3\x83\x9e\xe3\x83\x88\xe3\x83\xaa\xe3\x83\x83\xe3\x82\xaf\xe3\x82\xb9";
+static const char kRfc5769SampleMsgWithAuthPassword[] = "TheMatrIX";
+static const char kRfc5769SampleMsgWithAuthNonce[] =
+ "f//499k954d6OL34oL9FSTvy64sA";
+static const char kRfc5769SampleMsgWithAuthRealm[] = "example.org";
+
+// 2.1. Sample Request
+static const unsigned char kRfc5769SampleRequest[] = {
+ 0x00, 0x01, 0x00, 0x58, // Request type and message length
+ 0x21, 0x12, 0xa4, 0x42, // Magic cookie
+ 0xb7, 0xe7, 0xa7, 0x01, // }
+ 0xbc, 0x34, 0xd6, 0x86, // } Transaction ID
+ 0xfa, 0x87, 0xdf, 0xae, // }
+ 0x80, 0x22, 0x00, 0x10, // SOFTWARE attribute header
+ 0x53, 0x54, 0x55, 0x4e, // }
+ 0x20, 0x74, 0x65, 0x73, // } User-agent...
+ 0x74, 0x20, 0x63, 0x6c, // } ...name
+ 0x69, 0x65, 0x6e, 0x74, // }
+ 0x00, 0x24, 0x00, 0x04, // PRIORITY attribute header
+ 0x6e, 0x00, 0x01, 0xff, // ICE priority value
+ 0x80, 0x29, 0x00, 0x08, // ICE-CONTROLLED attribute header
+ 0x93, 0x2f, 0xf9, 0xb1, // } Pseudo-random tie breaker...
+ 0x51, 0x26, 0x3b, 0x36, // } ...for ICE control
+ 0x00, 0x06, 0x00, 0x09, // USERNAME attribute header
+ 0x65, 0x76, 0x74, 0x6a, // }
+ 0x3a, 0x68, 0x36, 0x76, // } Username (9 bytes) and padding (3 bytes)
+ 0x59, 0x20, 0x20, 0x20, // }
+ 0x00, 0x08, 0x00, 0x14, // MESSAGE-INTEGRITY attribute header
+ 0x9a, 0xea, 0xa7, 0x0c, // }
+ 0xbf, 0xd8, 0xcb, 0x56, // }
+ 0x78, 0x1e, 0xf2, 0xb5, // } HMAC-SHA1 fingerprint
+ 0xb2, 0xd3, 0xf2, 0x49, // }
+ 0xc1, 0xb5, 0x71, 0xa2, // }
+ 0x80, 0x28, 0x00, 0x04, // FINGERPRINT attribute header
+ 0xe5, 0x7a, 0x3b, 0xcf // CRC32 fingerprint
+};
+
+// 2.1. Sample Request
+static const unsigned char kSampleRequestMI32[] = {
+ 0x00, 0x01, 0x00, 0x48, // Request type and message length
+ 0x21, 0x12, 0xa4, 0x42, // Magic cookie
+ 0xb7, 0xe7, 0xa7, 0x01, // }
+ 0xbc, 0x34, 0xd6, 0x86, // } Transaction ID
+ 0xfa, 0x87, 0xdf, 0xae, // }
+ 0x80, 0x22, 0x00, 0x10, // SOFTWARE attribute header
+ 0x53, 0x54, 0x55, 0x4e, // }
+ 0x20, 0x74, 0x65, 0x73, // } User-agent...
+ 0x74, 0x20, 0x63, 0x6c, // } ...name
+ 0x69, 0x65, 0x6e, 0x74, // }
+ 0x00, 0x24, 0x00, 0x04, // PRIORITY attribute header
+ 0x6e, 0x00, 0x01, 0xff, // ICE priority value
+ 0x80, 0x29, 0x00, 0x08, // ICE-CONTROLLED attribute header
+ 0x93, 0x2f, 0xf9, 0xb1, // } Pseudo-random tie breaker...
+ 0x51, 0x26, 0x3b, 0x36, // } ...for ICE control
+ 0x00, 0x06, 0x00, 0x09, // USERNAME attribute header
+ 0x65, 0x76, 0x74, 0x6a, // }
+ 0x3a, 0x68, 0x36, 0x76, // } Username (9 bytes) and padding (3 bytes)
+ 0x59, 0x20, 0x20, 0x20, // }
+ 0xC0, 0x60, 0x00, 0x04, // MESSAGE-INTEGRITY-32 attribute header
+ 0x45, 0x45, 0xce, 0x7c, // } HMAC-SHA1 fingerprint (first 32 bit)
+ 0x80, 0x28, 0x00, 0x04, // FINGERPRINT attribute header
+ 0xe5, 0x7a, 0x3b, 0xcf // CRC32 fingerprint
+};
+
+// 2.2. Sample IPv4 Response
+static const unsigned char kRfc5769SampleResponse[] = {
+ 0x01, 0x01, 0x00, 0x3c, // Response type and message length
+ 0x21, 0x12, 0xa4, 0x42, // Magic cookie
+ 0xb7, 0xe7, 0xa7, 0x01, // }
+ 0xbc, 0x34, 0xd6, 0x86, // } Transaction ID
+ 0xfa, 0x87, 0xdf, 0xae, // }
+ 0x80, 0x22, 0x00, 0x0b, // SOFTWARE attribute header
+ 0x74, 0x65, 0x73, 0x74, // }
+ 0x20, 0x76, 0x65, 0x63, // } UTF-8 server name
+ 0x74, 0x6f, 0x72, 0x20, // }
+ 0x00, 0x20, 0x00, 0x08, // XOR-MAPPED-ADDRESS attribute header
+ 0x00, 0x01, 0xa1, 0x47, // Address family (IPv4) and xor'd mapped port
+ 0xe1, 0x12, 0xa6, 0x43, // Xor'd mapped IPv4 address
+ 0x00, 0x08, 0x00, 0x14, // MESSAGE-INTEGRITY attribute header
+ 0x2b, 0x91, 0xf5, 0x99, // }
+ 0xfd, 0x9e, 0x90, 0xc3, // }
+ 0x8c, 0x74, 0x89, 0xf9, // } HMAC-SHA1 fingerprint
+ 0x2a, 0xf9, 0xba, 0x53, // }
+ 0xf0, 0x6b, 0xe7, 0xd7, // }
+ 0x80, 0x28, 0x00, 0x04, // FINGERPRINT attribute header
+ 0xc0, 0x7d, 0x4c, 0x96 // CRC32 fingerprint
+};
+
+// 2.3. Sample IPv6 Response
+static const unsigned char kRfc5769SampleResponseIPv6[] = {
+ 0x01, 0x01, 0x00, 0x48, // Response type and message length
+ 0x21, 0x12, 0xa4, 0x42, // Magic cookie
+ 0xb7, 0xe7, 0xa7, 0x01, // }
+ 0xbc, 0x34, 0xd6, 0x86, // } Transaction ID
+ 0xfa, 0x87, 0xdf, 0xae, // }
+ 0x80, 0x22, 0x00, 0x0b, // SOFTWARE attribute header
+ 0x74, 0x65, 0x73, 0x74, // }
+ 0x20, 0x76, 0x65, 0x63, // } UTF-8 server name
+ 0x74, 0x6f, 0x72, 0x20, // }
+ 0x00, 0x20, 0x00, 0x14, // XOR-MAPPED-ADDRESS attribute header
+ 0x00, 0x02, 0xa1, 0x47, // Address family (IPv6) and xor'd mapped port.
+ 0x01, 0x13, 0xa9, 0xfa, // }
+ 0xa5, 0xd3, 0xf1, 0x79, // } Xor'd mapped IPv6 address
+ 0xbc, 0x25, 0xf4, 0xb5, // }
+ 0xbe, 0xd2, 0xb9, 0xd9, // }
+ 0x00, 0x08, 0x00, 0x14, // MESSAGE-INTEGRITY attribute header
+ 0xa3, 0x82, 0x95, 0x4e, // }
+ 0x4b, 0xe6, 0x7b, 0xf1, // }
+ 0x17, 0x84, 0xc9, 0x7c, // } HMAC-SHA1 fingerprint
+ 0x82, 0x92, 0xc2, 0x75, // }
+ 0xbf, 0xe3, 0xed, 0x41, // }
+ 0x80, 0x28, 0x00, 0x04, // FINGERPRINT attribute header
+ 0xc8, 0xfb, 0x0b, 0x4c // CRC32 fingerprint
+};
+
+// 2.4. Sample Request with Long-Term Authentication
+static const unsigned char kRfc5769SampleRequestLongTermAuth[] = {
+ 0x00, 0x01, 0x00, 0x60, // Request type and message length
+ 0x21, 0x12, 0xa4, 0x42, // Magic cookie
+ 0x78, 0xad, 0x34, 0x33, // }
+ 0xc6, 0xad, 0x72, 0xc0, // } Transaction ID
+ 0x29, 0xda, 0x41, 0x2e, // }
+ 0x00, 0x06, 0x00, 0x12, // USERNAME attribute header
+ 0xe3, 0x83, 0x9e, 0xe3, // }
+ 0x83, 0x88, 0xe3, 0x83, // }
+ 0xaa, 0xe3, 0x83, 0x83, // } Username value (18 bytes) and padding (2 bytes)
+ 0xe3, 0x82, 0xaf, 0xe3, // }
+ 0x82, 0xb9, 0x00, 0x00, // }
+ 0x00, 0x15, 0x00, 0x1c, // NONCE attribute header
+ 0x66, 0x2f, 0x2f, 0x34, // }
+ 0x39, 0x39, 0x6b, 0x39, // }
+ 0x35, 0x34, 0x64, 0x36, // }
+ 0x4f, 0x4c, 0x33, 0x34, // } Nonce value
+ 0x6f, 0x4c, 0x39, 0x46, // }
+ 0x53, 0x54, 0x76, 0x79, // }
+ 0x36, 0x34, 0x73, 0x41, // }
+ 0x00, 0x14, 0x00, 0x0b, // REALM attribute header
+ 0x65, 0x78, 0x61, 0x6d, // }
+ 0x70, 0x6c, 0x65, 0x2e, // } Realm value (11 bytes) and padding (1 byte)
+ 0x6f, 0x72, 0x67, 0x00, // }
+ 0x00, 0x08, 0x00, 0x14, // MESSAGE-INTEGRITY attribute header
+ 0xf6, 0x70, 0x24, 0x65, // }
+ 0x6d, 0xd6, 0x4a, 0x3e, // }
+ 0x02, 0xb8, 0xe0, 0x71, // } HMAC-SHA1 fingerprint
+ 0x2e, 0x85, 0xc9, 0xa2, // }
+ 0x8c, 0xa8, 0x96, 0x66 // }
+};
+
+// Length parameter is changed to 0x38 from 0x58.
+// AddMessageIntegrity will add MI information and update the length param
+// accordingly.
+static const unsigned char kRfc5769SampleRequestWithoutMI[] = {
+ 0x00, 0x01, 0x00, 0x38, // Request type and message length
+ 0x21, 0x12, 0xa4, 0x42, // Magic cookie
+ 0xb7, 0xe7, 0xa7, 0x01, // }
+ 0xbc, 0x34, 0xd6, 0x86, // } Transaction ID
+ 0xfa, 0x87, 0xdf, 0xae, // }
+ 0x80, 0x22, 0x00, 0x10, // SOFTWARE attribute header
+ 0x53, 0x54, 0x55, 0x4e, // }
+ 0x20, 0x74, 0x65, 0x73, // } User-agent...
+ 0x74, 0x20, 0x63, 0x6c, // } ...name
+ 0x69, 0x65, 0x6e, 0x74, // }
+ 0x00, 0x24, 0x00, 0x04, // PRIORITY attribute header
+ 0x6e, 0x00, 0x01, 0xff, // ICE priority value
+ 0x80, 0x29, 0x00, 0x08, // ICE-CONTROLLED attribute header
+ 0x93, 0x2f, 0xf9, 0xb1, // } Pseudo-random tie breaker...
+ 0x51, 0x26, 0x3b, 0x36, // } ...for ICE control
+ 0x00, 0x06, 0x00, 0x09, // USERNAME attribute header
+ 0x65, 0x76, 0x74, 0x6a, // }
+ 0x3a, 0x68, 0x36, 0x76, // } Username (9 bytes) and padding (3 bytes)
+ 0x59, 0x20, 0x20, 0x20 // }
+};
+
+// This HMAC differs from the RFC 5769 SampleRequest message. This differs
+// because spec uses 0x20 for the padding where as our implementation uses 0.
+static const unsigned char kCalculatedHmac1[] = {
+ 0x79, 0x07, 0xc2, 0xd2, // }
+ 0xed, 0xbf, 0xea, 0x48, // }
+ 0x0e, 0x4c, 0x76, 0xd8, // } HMAC-SHA1 fingerprint
+ 0x29, 0x62, 0xd5, 0xc3, // }
+ 0x74, 0x2a, 0xf9, 0xe3 // }
+};
+
+// This truncated HMAC differs from kCalculatedHmac1
+// above since the sum is computed including header
+// and the header is different since the message is shorter
+// than when MESSAGE-INTEGRITY is used.
+static const unsigned char kCalculatedHmac1_32[] = {
+ 0xda, 0x39, 0xde, 0x5d, // }
+};
+
+// Length parameter is changed to 0x1c from 0x3c.
+// AddMessageIntegrity will add MI information and update the length param
+// accordingly.
+static const unsigned char kRfc5769SampleResponseWithoutMI[] = {
+ 0x01, 0x01, 0x00, 0x1c, // Response type and message length
+ 0x21, 0x12, 0xa4, 0x42, // Magic cookie
+ 0xb7, 0xe7, 0xa7, 0x01, // }
+ 0xbc, 0x34, 0xd6, 0x86, // } Transaction ID
+ 0xfa, 0x87, 0xdf, 0xae, // }
+ 0x80, 0x22, 0x00, 0x0b, // SOFTWARE attribute header
+ 0x74, 0x65, 0x73, 0x74, // }
+ 0x20, 0x76, 0x65, 0x63, // } UTF-8 server name
+ 0x74, 0x6f, 0x72, 0x20, // }
+ 0x00, 0x20, 0x00, 0x08, // XOR-MAPPED-ADDRESS attribute header
+ 0x00, 0x01, 0xa1, 0x47, // Address family (IPv4) and xor'd mapped port
+ 0xe1, 0x12, 0xa6, 0x43 // Xor'd mapped IPv4 address
+};
+
+// This HMAC differs from the RFC 5769 SampleResponse message. This differs
+// because spec uses 0x20 for the padding where as our implementation uses 0.
+static const unsigned char kCalculatedHmac2[] = {
+ 0x5d, 0x6b, 0x58, 0xbe, // }
+ 0xad, 0x94, 0xe0, 0x7e, // }
+ 0xef, 0x0d, 0xfc, 0x12, // } HMAC-SHA1 fingerprint
+ 0x82, 0xa2, 0xbd, 0x08, // }
+ 0x43, 0x14, 0x10, 0x28 // }
+};
+
+// This truncated HMAC differs from kCalculatedHmac2
+// above since the sum is computed including header
+// and the header is different since the message is shorter
+// than when MESSAGE-INTEGRITY is used.
+static const unsigned char kCalculatedHmac2_32[] = {
+ 0xe7, 0x5c, 0xd3, 0x16, // }
+};
+
+// clang-format on
+
+// A transaction ID without the 'magic cookie' portion
+// pjnat's test programs use this transaction ID a lot.
+const unsigned char kTestTransactionId1[] = {0x029, 0x01f, 0x0cd, 0x07c,
+ 0x0ba, 0x058, 0x0ab, 0x0d7,
+ 0x0f2, 0x041, 0x001, 0x000};
+
+// They use this one sometimes too.
+const unsigned char kTestTransactionId2[] = {0x0e3, 0x0a9, 0x046, 0x0e1,
+ 0x07c, 0x000, 0x0c2, 0x062,
+ 0x054, 0x008, 0x001, 0x000};
+
+const in6_addr kIPv6TestAddress1 = {
+ {{0x24, 0x01, 0xfa, 0x00, 0x00, 0x04, 0x10, 0x00, 0xbe, 0x30, 0x5b, 0xff,
+ 0xfe, 0xe5, 0x00, 0xc3}}};
+const in6_addr kIPv6TestAddress2 = {
+ {{0x24, 0x01, 0xfa, 0x00, 0x00, 0x04, 0x10, 0x12, 0x06, 0x0c, 0xce, 0xff,
+ 0xfe, 0x1f, 0x61, 0xa4}}};
+
+#ifdef WEBRTC_POSIX
+const in_addr kIPv4TestAddress1 = {0xe64417ac};
+#elif defined WEBRTC_WIN
+// Windows in_addr has a union with a uchar[] array first.
+const in_addr kIPv4TestAddress1 = {{{0x0ac, 0x017, 0x044, 0x0e6}}};
+#endif
+const char kTestUserName1[] = "abcdefgh";
+const char kTestUserName2[] = "abc";
+const char kTestErrorReason[] = "Unauthorized";
+const int kTestErrorClass = 4;
+const int kTestErrorNumber = 1;
+const int kTestErrorCode = 401;
+
+const int kTestMessagePort1 = 59977;
+const int kTestMessagePort2 = 47233;
+const int kTestMessagePort3 = 56743;
+const int kTestMessagePort4 = 40444;
+
+#define ReadStunMessage(X, Y) ReadStunMessageTestCase(X, Y, sizeof(Y));
+
+// Test that the GetStun*Type and IsStun*Type methods work as expected.
+TEST_F(StunTest, MessageTypes) {
+ EXPECT_EQ(STUN_BINDING_RESPONSE,
+ GetStunSuccessResponseType(STUN_BINDING_REQUEST));
+ EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE,
+ GetStunErrorResponseType(STUN_BINDING_REQUEST));
+ EXPECT_EQ(-1, GetStunSuccessResponseType(STUN_BINDING_INDICATION));
+ EXPECT_EQ(-1, GetStunSuccessResponseType(STUN_BINDING_RESPONSE));
+ EXPECT_EQ(-1, GetStunSuccessResponseType(STUN_BINDING_ERROR_RESPONSE));
+ EXPECT_EQ(-1, GetStunErrorResponseType(STUN_BINDING_INDICATION));
+ EXPECT_EQ(-1, GetStunErrorResponseType(STUN_BINDING_RESPONSE));
+ EXPECT_EQ(-1, GetStunErrorResponseType(STUN_BINDING_ERROR_RESPONSE));
+
+ int types[] = {STUN_BINDING_REQUEST, STUN_BINDING_INDICATION,
+ STUN_BINDING_RESPONSE, STUN_BINDING_ERROR_RESPONSE};
+ for (size_t i = 0; i < arraysize(types); ++i) {
+ EXPECT_EQ(i == 0U, IsStunRequestType(types[i]));
+ EXPECT_EQ(i == 1U, IsStunIndicationType(types[i]));
+ EXPECT_EQ(i == 2U, IsStunSuccessResponseType(types[i]));
+ EXPECT_EQ(i == 3U, IsStunErrorResponseType(types[i]));
+ EXPECT_EQ(1, types[i] & 0xFEEF);
+ }
+}
+
+TEST_F(StunTest, ReadMessageWithIPv4AddressAttribute) {
+ StunMessage msg;
+ size_t size = ReadStunMessage(&msg, kStunMessageWithIPv4MappedAddress);
+ CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
+ CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
+
+ const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
+ rtc::IPAddress test_address(kIPv4TestAddress1);
+ CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4, kTestMessagePort4,
+ test_address);
+}
+
+TEST_F(StunTest, ReadMessageWithIPv4XorAddressAttribute) {
+ StunMessage msg;
+ StunMessage msg2;
+ size_t size = ReadStunMessage(&msg, kStunMessageWithIPv4XorMappedAddress);
+ CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
+ CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
+
+ const StunAddressAttribute* addr =
+ msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
+ rtc::IPAddress test_address(kIPv4TestAddress1);
+ CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4, kTestMessagePort3,
+ test_address);
+}
+
+TEST_F(StunTest, ReadMessageWithIPv6AddressAttribute) {
+ StunMessage msg;
+ size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6MappedAddress);
+ CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
+ CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
+
+ rtc::IPAddress test_address(kIPv6TestAddress1);
+
+ const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
+ CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6, kTestMessagePort2,
+ test_address);
+}
+
+TEST_F(StunTest, ReadMessageWithInvalidAddressAttribute) {
+ StunMessage msg;
+ size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6MappedAddress);
+ CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
+ CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
+
+ rtc::IPAddress test_address(kIPv6TestAddress1);
+
+ const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
+ CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6, kTestMessagePort2,
+ test_address);
+}
+
+TEST_F(StunTest, ReadMessageWithIPv6XorAddressAttribute) {
+ StunMessage msg;
+ size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6XorMappedAddress);
+
+ rtc::IPAddress test_address(kIPv6TestAddress1);
+
+ CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
+ CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
+
+ const StunAddressAttribute* addr =
+ msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
+ CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6, kTestMessagePort1,
+ test_address);
+}
+
+// Read the RFC5389 fields from the RFC5769 sample STUN request.
+TEST_F(StunTest, ReadRfc5769RequestMessage) {
+ StunMessage msg;
+ size_t size = ReadStunMessage(&msg, kRfc5769SampleRequest);
+ CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
+ CheckStunTransactionID(msg, kRfc5769SampleMsgTransactionId,
+ kStunTransactionIdLength);
+
+ const StunByteStringAttribute* software =
+ msg.GetByteString(STUN_ATTR_SOFTWARE);
+ ASSERT_TRUE(software != NULL);
+ EXPECT_EQ(kRfc5769SampleMsgClientSoftware, software->string_view());
+
+ const StunByteStringAttribute* username =
+ msg.GetByteString(STUN_ATTR_USERNAME);
+ ASSERT_TRUE(username != NULL);
+ EXPECT_EQ(kRfc5769SampleMsgUsername, username->string_view());
+
+ // Actual M-I value checked in a later test.
+ ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
+
+ // Fingerprint checked in a later test, but double-check the value here.
+ const StunUInt32Attribute* fingerprint = msg.GetUInt32(STUN_ATTR_FINGERPRINT);
+ ASSERT_TRUE(fingerprint != NULL);
+ EXPECT_EQ(0xe57a3bcf, fingerprint->value());
+}
+
+// Read the RFC5389 fields from the RFC5769 sample STUN response.
+TEST_F(StunTest, ReadRfc5769ResponseMessage) {
+ StunMessage msg;
+ size_t size = ReadStunMessage(&msg, kRfc5769SampleResponse);
+ CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
+ CheckStunTransactionID(msg, kRfc5769SampleMsgTransactionId,
+ kStunTransactionIdLength);
+
+ const StunByteStringAttribute* software =
+ msg.GetByteString(STUN_ATTR_SOFTWARE);
+ ASSERT_TRUE(software != NULL);
+ EXPECT_EQ(kRfc5769SampleMsgServerSoftware, software->string_view());
+
+ const StunAddressAttribute* mapped_address =
+ msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
+ ASSERT_TRUE(mapped_address != NULL);
+ EXPECT_EQ(kRfc5769SampleMsgMappedAddress, mapped_address->GetAddress());
+
+ // Actual M-I and fingerprint checked in later tests.
+ ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
+ ASSERT_TRUE(msg.GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
+}
+
+// Read the RFC5389 fields from the RFC5769 sample STUN response for IPv6.
+TEST_F(StunTest, ReadRfc5769ResponseMessageIPv6) {
+ StunMessage msg;
+ size_t size = ReadStunMessage(&msg, kRfc5769SampleResponseIPv6);
+ CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
+ CheckStunTransactionID(msg, kRfc5769SampleMsgTransactionId,
+ kStunTransactionIdLength);
+
+ const StunByteStringAttribute* software =
+ msg.GetByteString(STUN_ATTR_SOFTWARE);
+ ASSERT_TRUE(software != NULL);
+ EXPECT_EQ(kRfc5769SampleMsgServerSoftware, software->string_view());
+
+ const StunAddressAttribute* mapped_address =
+ msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
+ ASSERT_TRUE(mapped_address != NULL);
+ EXPECT_EQ(kRfc5769SampleMsgIPv6MappedAddress, mapped_address->GetAddress());
+
+ // Actual M-I and fingerprint checked in later tests.
+ ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
+ ASSERT_TRUE(msg.GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
+}
+
+// Read the RFC5389 fields from the RFC5769 sample STUN response with auth.
+TEST_F(StunTest, ReadRfc5769RequestMessageLongTermAuth) {
+ StunMessage msg;
+ size_t size = ReadStunMessage(&msg, kRfc5769SampleRequestLongTermAuth);
+ CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
+ CheckStunTransactionID(msg, kRfc5769SampleMsgWithAuthTransactionId,
+ kStunTransactionIdLength);
+
+ const StunByteStringAttribute* username =
+ msg.GetByteString(STUN_ATTR_USERNAME);
+ ASSERT_TRUE(username != NULL);
+ EXPECT_EQ(kRfc5769SampleMsgWithAuthUsername, username->string_view());
+
+ const StunByteStringAttribute* nonce = msg.GetByteString(STUN_ATTR_NONCE);
+ ASSERT_TRUE(nonce != NULL);
+ EXPECT_EQ(kRfc5769SampleMsgWithAuthNonce, nonce->string_view());
+
+ const StunByteStringAttribute* realm = msg.GetByteString(STUN_ATTR_REALM);
+ ASSERT_TRUE(realm != NULL);
+ EXPECT_EQ(kRfc5769SampleMsgWithAuthRealm, realm->string_view());
+
+ // No fingerprint, actual M-I checked in later tests.
+ ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
+ ASSERT_TRUE(msg.GetUInt32(STUN_ATTR_FINGERPRINT) == NULL);
+}
+
+// The RFC3489 packet in this test is the same as
+// kStunMessageWithIPv4MappedAddress, but with a different value where the
+// magic cookie was.
+TEST_F(StunTest, ReadLegacyMessage) {
+ unsigned char rfc3489_packet[sizeof(kStunMessageWithIPv4MappedAddress)];
+ memcpy(rfc3489_packet, kStunMessageWithIPv4MappedAddress,
+ sizeof(kStunMessageWithIPv4MappedAddress));
+ // Overwrite the magic cookie here.
+ memcpy(&rfc3489_packet[4], "ABCD", 4);
+
+ StunMessage msg;
+ size_t size = ReadStunMessage(&msg, rfc3489_packet);
+ CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
+ CheckStunTransactionID(msg, &rfc3489_packet[4], kStunTransactionIdLength + 4);
+
+ const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
+ rtc::IPAddress test_address(kIPv4TestAddress1);
+ CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4, kTestMessagePort4,
+ test_address);
+}
+
+TEST_F(StunTest, SetIPv6XorAddressAttributeOwner) {
+ StunMessage msg;
+ size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6XorMappedAddress);
+
+ rtc::IPAddress test_address(kIPv6TestAddress1);
+
+ CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
+ CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
+
+ const StunAddressAttribute* addr =
+ msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
+ CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6, kTestMessagePort1,
+ test_address);
+
+ // Owner with a different transaction ID.
+ StunMessage msg2(STUN_INVALID_MESSAGE_TYPE, "ABCDABCDABCD");
+ StunXorAddressAttribute addr2(STUN_ATTR_XOR_MAPPED_ADDRESS, 20, NULL);
+ addr2.SetIP(addr->ipaddr());
+ addr2.SetPort(addr->port());
+ addr2.SetOwner(&msg2);
+ // The internal IP address shouldn't change.
+ ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());
+
+ rtc::ByteBufferWriter correct_buf;
+ rtc::ByteBufferWriter wrong_buf;
+ EXPECT_TRUE(addr->Write(&correct_buf));
+ EXPECT_TRUE(addr2.Write(&wrong_buf));
+ // But when written out, the buffers should look different.
+ ASSERT_NE(0,
+ memcmp(correct_buf.Data(), wrong_buf.Data(), wrong_buf.Length()));
+ // And when reading a known good value, the address should be wrong.
+ rtc::ByteBufferReader read_buf(correct_buf);
+ addr2.Read(&read_buf);
+ ASSERT_NE(addr->ipaddr(), addr2.ipaddr());
+ addr2.SetIP(addr->ipaddr());
+ addr2.SetPort(addr->port());
+ // Try writing with no owner at all, should fail and write nothing.
+ addr2.SetOwner(NULL);
+ ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());
+ wrong_buf.Clear();
+ EXPECT_FALSE(addr2.Write(&wrong_buf));
+ ASSERT_EQ(0U, wrong_buf.Length());
+}
+
+TEST_F(StunTest, SetIPv4XorAddressAttributeOwner) {
+ // Unlike the IPv6XorAddressAttributeOwner test, IPv4 XOR address attributes
+ // should _not_ be affected by a change in owner. IPv4 XOR address uses the
+ // magic cookie value which is fixed.
+ StunMessage msg;
+ size_t size = ReadStunMessage(&msg, kStunMessageWithIPv4XorMappedAddress);
+
+ rtc::IPAddress test_address(kIPv4TestAddress1);
+
+ CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
+ CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
+
+ const StunAddressAttribute* addr =
+ msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
+ CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4, kTestMessagePort3,
+ test_address);
+
+ // Owner with a different transaction ID.
+ StunMessage msg2(STUN_INVALID_MESSAGE_TYPE, "ABCDABCDABCD");
+ StunXorAddressAttribute addr2(STUN_ATTR_XOR_MAPPED_ADDRESS, 20, NULL);
+ addr2.SetIP(addr->ipaddr());
+ addr2.SetPort(addr->port());
+ addr2.SetOwner(&msg2);
+ // The internal IP address shouldn't change.
+ ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());
+
+ rtc::ByteBufferWriter correct_buf;
+ rtc::ByteBufferWriter wrong_buf;
+ EXPECT_TRUE(addr->Write(&correct_buf));
+ EXPECT_TRUE(addr2.Write(&wrong_buf));
+ // The same address data should be written.
+ ASSERT_EQ(0,
+ memcmp(correct_buf.Data(), wrong_buf.Data(), wrong_buf.Length()));
+ // And an attribute should be able to un-XOR an address belonging to a message
+ // with a different transaction ID.
+ rtc::ByteBufferReader read_buf(correct_buf);
+ EXPECT_TRUE(addr2.Read(&read_buf));
+ ASSERT_EQ(addr->ipaddr(), addr2.ipaddr());
+
+ // However, no owner is still an error, should fail and write nothing.
+ addr2.SetOwner(NULL);
+ ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());
+ wrong_buf.Clear();
+ EXPECT_FALSE(addr2.Write(&wrong_buf));
+}
+
+TEST_F(StunTest, CreateIPv6AddressAttribute) {
+ rtc::IPAddress test_ip(kIPv6TestAddress2);
+
+ auto addr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
+ rtc::SocketAddress test_addr(test_ip, kTestMessagePort2);
+ addr->SetAddress(test_addr);
+
+ CheckStunAddressAttribute(addr.get(), STUN_ADDRESS_IPV6, kTestMessagePort2,
+ test_ip);
+}
+
+TEST_F(StunTest, CreateIPv4AddressAttribute) {
+ struct in_addr test_in_addr;
+ test_in_addr.s_addr = 0xBEB0B0BE;
+ rtc::IPAddress test_ip(test_in_addr);
+
+ auto addr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
+ rtc::SocketAddress test_addr(test_ip, kTestMessagePort2);
+ addr->SetAddress(test_addr);
+
+ CheckStunAddressAttribute(addr.get(), STUN_ADDRESS_IPV4, kTestMessagePort2,
+ test_ip);
+}
+
+// Test that we don't care what order we set the parts of an address
+TEST_F(StunTest, CreateAddressInArbitraryOrder) {
+ auto addr = StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
+ // Port first
+ addr->SetPort(kTestMessagePort1);
+ addr->SetIP(rtc::IPAddress(kIPv4TestAddress1));
+ ASSERT_EQ(kTestMessagePort1, addr->port());
+ ASSERT_EQ(rtc::IPAddress(kIPv4TestAddress1), addr->ipaddr());
+
+ auto addr2 = StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
+ // IP first
+ addr2->SetIP(rtc::IPAddress(kIPv4TestAddress1));
+ addr2->SetPort(kTestMessagePort2);
+ ASSERT_EQ(kTestMessagePort2, addr2->port());
+ ASSERT_EQ(rtc::IPAddress(kIPv4TestAddress1), addr2->ipaddr());
+}
+
+TEST_F(StunTest, WriteMessageWithIPv6AddressAttribute) {
+ size_t size = sizeof(kStunMessageWithIPv6MappedAddress);
+
+ rtc::IPAddress test_ip(kIPv6TestAddress1);
+
+ StunMessage msg(
+ STUN_BINDING_REQUEST,
+ std::string(reinterpret_cast<const char*>(kTestTransactionId1),
+ kStunTransactionIdLength));
+ CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
+
+ auto addr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
+ rtc::SocketAddress test_addr(test_ip, kTestMessagePort2);
+ addr->SetAddress(test_addr);
+ msg.AddAttribute(std::move(addr));
+
+ CheckStunHeader(msg, STUN_BINDING_REQUEST, (size - 20));
+
+ rtc::ByteBufferWriter out;
+ EXPECT_TRUE(msg.Write(&out));
+ ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv6MappedAddress));
+ int len1 = static_cast<int>(out.Length());
+ rtc::ByteBufferReader read_buf(out);
+ std::string bytes;
+ read_buf.ReadString(&bytes, len1);
+ ASSERT_EQ(0, memcmp(bytes.c_str(), kStunMessageWithIPv6MappedAddress, len1));
+}
+
+TEST_F(StunTest, WriteMessageWithIPv4AddressAttribute) {
+ size_t size = sizeof(kStunMessageWithIPv4MappedAddress);
+
+ rtc::IPAddress test_ip(kIPv4TestAddress1);
+
+ StunMessage msg(
+ STUN_BINDING_RESPONSE,
+ std::string(reinterpret_cast<const char*>(kTestTransactionId1),
+ kStunTransactionIdLength));
+ CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
+
+ auto addr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
+ rtc::SocketAddress test_addr(test_ip, kTestMessagePort4);
+ addr->SetAddress(test_addr);
+ msg.AddAttribute(std::move(addr));
+
+ CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20));
+
+ rtc::ByteBufferWriter out;
+ EXPECT_TRUE(msg.Write(&out));
+ ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv4MappedAddress));
+ int len1 = static_cast<int>(out.Length());
+ rtc::ByteBufferReader read_buf(out);
+ std::string bytes;
+ read_buf.ReadString(&bytes, len1);
+ ASSERT_EQ(0, memcmp(bytes.c_str(), kStunMessageWithIPv4MappedAddress, len1));
+}
+
+TEST_F(StunTest, WriteMessageWithIPv6XorAddressAttribute) {
+ size_t size = sizeof(kStunMessageWithIPv6XorMappedAddress);
+
+ rtc::IPAddress test_ip(kIPv6TestAddress1);
+
+ StunMessage msg(
+ STUN_BINDING_RESPONSE,
+ std::string(reinterpret_cast<const char*>(kTestTransactionId2),
+ kStunTransactionIdLength));
+ CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
+
+ auto addr = StunAttribute::CreateXorAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
+ rtc::SocketAddress test_addr(test_ip, kTestMessagePort1);
+ addr->SetAddress(test_addr);
+ msg.AddAttribute(std::move(addr));
+
+ CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20));
+
+ rtc::ByteBufferWriter out;
+ EXPECT_TRUE(msg.Write(&out));
+ ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv6XorMappedAddress));
+ int len1 = static_cast<int>(out.Length());
+ rtc::ByteBufferReader read_buf(out);
+ std::string bytes;
+ read_buf.ReadString(&bytes, len1);
+ ASSERT_EQ(0,
+ memcmp(bytes.c_str(), kStunMessageWithIPv6XorMappedAddress, len1));
+}
+
+TEST_F(StunTest, WriteMessageWithIPv4XoreAddressAttribute) {
+ size_t size = sizeof(kStunMessageWithIPv4XorMappedAddress);
+
+ rtc::IPAddress test_ip(kIPv4TestAddress1);
+
+ StunMessage msg(
+ STUN_BINDING_RESPONSE,
+ std::string(reinterpret_cast<const char*>(kTestTransactionId1),
+ kStunTransactionIdLength));
+ CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
+
+ auto addr = StunAttribute::CreateXorAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
+ rtc::SocketAddress test_addr(test_ip, kTestMessagePort3);
+ addr->SetAddress(test_addr);
+ msg.AddAttribute(std::move(addr));
+
+ CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20));
+
+ rtc::ByteBufferWriter out;
+ EXPECT_TRUE(msg.Write(&out));
+ ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv4XorMappedAddress));
+ int len1 = static_cast<int>(out.Length());
+ rtc::ByteBufferReader read_buf(out);
+ std::string bytes;
+ read_buf.ReadString(&bytes, len1);
+ ASSERT_EQ(0,
+ memcmp(bytes.c_str(), kStunMessageWithIPv4XorMappedAddress, len1));
+}
+
+TEST_F(StunTest, ReadByteStringAttribute) {
+ StunMessage msg;
+ size_t size = ReadStunMessage(&msg, kStunMessageWithByteStringAttribute);
+
+ CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
+ CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
+ const StunByteStringAttribute* username =
+ msg.GetByteString(STUN_ATTR_USERNAME);
+ ASSERT_TRUE(username != NULL);
+ EXPECT_EQ(kTestUserName1, username->string_view());
+}
+
+TEST_F(StunTest, ReadPaddedByteStringAttribute) {
+ StunMessage msg;
+ size_t size =
+ ReadStunMessage(&msg, kStunMessageWithPaddedByteStringAttribute);
+ ASSERT_NE(0U, size);
+ CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
+ CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
+ const StunByteStringAttribute* username =
+ msg.GetByteString(STUN_ATTR_USERNAME);
+ ASSERT_TRUE(username != NULL);
+ EXPECT_EQ(kTestUserName2, username->string_view());
+}
+
+TEST_F(StunTest, ReadErrorCodeAttribute) {
+ StunMessage msg;
+ size_t size = ReadStunMessage(&msg, kStunMessageWithErrorAttribute);
+
+ CheckStunHeader(msg, STUN_BINDING_ERROR_RESPONSE, size);
+ CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
+ const StunErrorCodeAttribute* errorcode = msg.GetErrorCode();
+ ASSERT_TRUE(errorcode != NULL);
+ EXPECT_EQ(kTestErrorClass, errorcode->eclass());
+ EXPECT_EQ(kTestErrorNumber, errorcode->number());
+ EXPECT_EQ(kTestErrorReason, errorcode->reason());
+ EXPECT_EQ(kTestErrorCode, errorcode->code());
+ EXPECT_EQ(kTestErrorCode, msg.GetErrorCodeValue());
+}
+
+// Test that GetErrorCodeValue returns STUN_ERROR_GLOBAL_FAILURE if the message
+// in question doesn't have an error code attribute, rather than crashing.
+TEST_F(StunTest, GetErrorCodeValueWithNoErrorAttribute) {
+ StunMessage msg;
+ ReadStunMessage(&msg, kStunMessageWithIPv6MappedAddress);
+ EXPECT_EQ(STUN_ERROR_GLOBAL_FAILURE, msg.GetErrorCodeValue());
+}
+
+TEST_F(StunTest, ReadMessageWithAUInt16ListAttribute) {
+ StunMessage msg;
+ size_t size = ReadStunMessage(&msg, kStunMessageWithUInt16ListAttribute);
+ CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
+ const StunUInt16ListAttribute* types = msg.GetUnknownAttributes();
+ ASSERT_TRUE(types != NULL);
+ EXPECT_EQ(3U, types->Size());
+ EXPECT_EQ(0x1U, types->GetType(0));
+ EXPECT_EQ(0x1000U, types->GetType(1));
+ EXPECT_EQ(0xAB0CU, types->GetType(2));
+}
+
+TEST_F(StunTest, ReadMessageWithAnUnknownAttribute) {
+ StunMessage msg;
+ size_t size = ReadStunMessage(&msg, kStunMessageWithUnknownAttribute);
+ CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
+
+ // Parsing should have succeeded and there should be a USERNAME attribute
+ const StunByteStringAttribute* username =
+ msg.GetByteString(STUN_ATTR_USERNAME);
+ ASSERT_TRUE(username != NULL);
+ EXPECT_EQ(kTestUserName2, username->string_view());
+}
+
+TEST_F(StunTest, WriteMessageWithAnErrorCodeAttribute) {
+ size_t size = sizeof(kStunMessageWithErrorAttribute);
+
+ StunMessage msg(
+ STUN_BINDING_ERROR_RESPONSE,
+ std::string(reinterpret_cast<const char*>(kTestTransactionId1),
+ kStunTransactionIdLength));
+ CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
+ auto errorcode = StunAttribute::CreateErrorCode();
+ errorcode->SetCode(kTestErrorCode);
+ errorcode->SetReason(kTestErrorReason);
+ msg.AddAttribute(std::move(errorcode));
+ CheckStunHeader(msg, STUN_BINDING_ERROR_RESPONSE, (size - 20));
+
+ rtc::ByteBufferWriter out;
+ EXPECT_TRUE(msg.Write(&out));
+ ASSERT_EQ(size, out.Length());
+ // No padding.
+ ASSERT_EQ(0, memcmp(out.Data(), kStunMessageWithErrorAttribute, size));
+}
+
+TEST_F(StunTest, WriteMessageWithAUInt16ListAttribute) {
+ size_t size = sizeof(kStunMessageWithUInt16ListAttribute);
+
+ StunMessage msg(
+ STUN_BINDING_REQUEST,
+ std::string(reinterpret_cast<const char*>(kTestTransactionId2),
+ kStunTransactionIdLength));
+ CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
+ auto list = StunAttribute::CreateUnknownAttributes();
+ list->AddType(0x1U);
+ list->AddType(0x1000U);
+ list->AddType(0xAB0CU);
+ msg.AddAttribute(std::move(list));
+ CheckStunHeader(msg, STUN_BINDING_REQUEST, (size - 20));
+
+ rtc::ByteBufferWriter out;
+ EXPECT_TRUE(msg.Write(&out));
+ ASSERT_EQ(size, out.Length());
+ // Check everything up to the padding.
+ ASSERT_EQ(0,
+ memcmp(out.Data(), kStunMessageWithUInt16ListAttribute, size - 2));
+}
+
+// Test that we fail to read messages with invalid lengths.
+void CheckFailureToRead(const unsigned char* testcase, size_t length) {
+ StunMessage msg;
+ const char* input = reinterpret_cast<const char*>(testcase);
+ rtc::ByteBufferReader buf(input, length);
+ ASSERT_FALSE(msg.Read(&buf));
+}
+
+TEST_F(StunTest, FailToReadInvalidMessages) {
+ CheckFailureToRead(kStunMessageWithZeroLength,
+ kRealLengthOfInvalidLengthTestCases);
+ CheckFailureToRead(kStunMessageWithSmallLength,
+ kRealLengthOfInvalidLengthTestCases);
+ CheckFailureToRead(kStunMessageWithExcessLength,
+ kRealLengthOfInvalidLengthTestCases);
+}
+
+// Test that we properly fail to read a non-STUN message.
+TEST_F(StunTest, FailToReadRtcpPacket) {
+ CheckFailureToRead(kRtcpPacket, sizeof(kRtcpPacket));
+}
+
+// Check our STUN message validation code against the RFC5769 test messages.
+TEST_F(StunTest, ValidateMessageIntegrity) {
+ // Try the messages from RFC 5769.
+ EXPECT_TRUE(StunMessage::ValidateMessageIntegrityForTesting(
+ reinterpret_cast<const char*>(kRfc5769SampleRequest),
+ sizeof(kRfc5769SampleRequest), kRfc5769SampleMsgPassword));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
+ reinterpret_cast<const char*>(kRfc5769SampleRequest),
+ sizeof(kRfc5769SampleRequest), "InvalidPassword"));
+
+ EXPECT_TRUE(StunMessage::ValidateMessageIntegrityForTesting(
+ reinterpret_cast<const char*>(kRfc5769SampleResponse),
+ sizeof(kRfc5769SampleResponse), kRfc5769SampleMsgPassword));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
+ reinterpret_cast<const char*>(kRfc5769SampleResponse),
+ sizeof(kRfc5769SampleResponse), "InvalidPassword"));
+
+ EXPECT_TRUE(StunMessage::ValidateMessageIntegrityForTesting(
+ reinterpret_cast<const char*>(kRfc5769SampleResponseIPv6),
+ sizeof(kRfc5769SampleResponseIPv6), kRfc5769SampleMsgPassword));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
+ reinterpret_cast<const char*>(kRfc5769SampleResponseIPv6),
+ sizeof(kRfc5769SampleResponseIPv6), "InvalidPassword"));
+
+ // We first need to compute the key for the long-term authentication HMAC.
+ std::string key;
+ ComputeStunCredentialHash(kRfc5769SampleMsgWithAuthUsername,
+ kRfc5769SampleMsgWithAuthRealm,
+ kRfc5769SampleMsgWithAuthPassword, &key);
+ EXPECT_TRUE(StunMessage::ValidateMessageIntegrityForTesting(
+ reinterpret_cast<const char*>(kRfc5769SampleRequestLongTermAuth),
+ sizeof(kRfc5769SampleRequestLongTermAuth), key));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
+ reinterpret_cast<const char*>(kRfc5769SampleRequestLongTermAuth),
+ sizeof(kRfc5769SampleRequestLongTermAuth), "InvalidPassword"));
+
+ // Try some edge cases.
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
+ reinterpret_cast<const char*>(kStunMessageWithZeroLength),
+ sizeof(kStunMessageWithZeroLength), kRfc5769SampleMsgPassword));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
+ reinterpret_cast<const char*>(kStunMessageWithExcessLength),
+ sizeof(kStunMessageWithExcessLength), kRfc5769SampleMsgPassword));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
+ reinterpret_cast<const char*>(kStunMessageWithSmallLength),
+ sizeof(kStunMessageWithSmallLength), kRfc5769SampleMsgPassword));
+
+ // Again, but with the lengths matching what is claimed in the headers.
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
+ reinterpret_cast<const char*>(kStunMessageWithZeroLength),
+ kStunHeaderSize + rtc::GetBE16(&kStunMessageWithZeroLength[2]),
+ kRfc5769SampleMsgPassword));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
+ reinterpret_cast<const char*>(kStunMessageWithExcessLength),
+ kStunHeaderSize + rtc::GetBE16(&kStunMessageWithExcessLength[2]),
+ kRfc5769SampleMsgPassword));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
+ reinterpret_cast<const char*>(kStunMessageWithSmallLength),
+ kStunHeaderSize + rtc::GetBE16(&kStunMessageWithSmallLength[2]),
+ kRfc5769SampleMsgPassword));
+
+ // Check that a too-short HMAC doesn't cause buffer overflow.
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
+ reinterpret_cast<const char*>(kStunMessageWithBadHmacAtEnd),
+ sizeof(kStunMessageWithBadHmacAtEnd), kRfc5769SampleMsgPassword));
+
+ // Test that munging a single bit anywhere in the message causes the
+ // message-integrity check to fail, unless it is after the M-I attribute.
+ char buf[sizeof(kRfc5769SampleRequest)];
+ memcpy(buf, kRfc5769SampleRequest, sizeof(kRfc5769SampleRequest));
+ for (size_t i = 0; i < sizeof(buf); ++i) {
+ buf[i] ^= 0x01;
+ if (i > 0)
+ buf[i - 1] ^= 0x01;
+ EXPECT_EQ(i >= sizeof(buf) - 8,
+ StunMessage::ValidateMessageIntegrityForTesting(
+ buf, sizeof(buf), kRfc5769SampleMsgPassword));
+ }
+}
+
+// Validate that we generate correct MESSAGE-INTEGRITY attributes.
+// Note the use of IceMessage instead of StunMessage; this is necessary because
+// the RFC5769 test messages used include attributes not found in basic STUN.
+TEST_F(StunTest, AddMessageIntegrity) {
+ IceMessage msg;
+ rtc::ByteBufferReader buf(
+ reinterpret_cast<const char*>(kRfc5769SampleRequestWithoutMI),
+ sizeof(kRfc5769SampleRequestWithoutMI));
+ EXPECT_TRUE(msg.Read(&buf));
+ EXPECT_TRUE(msg.AddMessageIntegrity(kRfc5769SampleMsgPassword));
+ const StunByteStringAttribute* mi_attr =
+ msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
+ EXPECT_EQ(20U, mi_attr->length());
+ EXPECT_EQ(
+ 0, memcmp(mi_attr->bytes(), kCalculatedHmac1, sizeof(kCalculatedHmac1)));
+
+ rtc::ByteBufferWriter buf1;
+ EXPECT_TRUE(msg.Write(&buf1));
+ EXPECT_TRUE(StunMessage::ValidateMessageIntegrityForTesting(
+ reinterpret_cast<const char*>(buf1.Data()), buf1.Length(),
+ kRfc5769SampleMsgPassword));
+
+ IceMessage msg2;
+ rtc::ByteBufferReader buf2(
+ reinterpret_cast<const char*>(kRfc5769SampleResponseWithoutMI),
+ sizeof(kRfc5769SampleResponseWithoutMI));
+ EXPECT_TRUE(msg2.Read(&buf2));
+ EXPECT_TRUE(msg2.AddMessageIntegrity(kRfc5769SampleMsgPassword));
+ const StunByteStringAttribute* mi_attr2 =
+ msg2.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
+ EXPECT_EQ(20U, mi_attr2->length());
+ EXPECT_EQ(
+ 0, memcmp(mi_attr2->bytes(), kCalculatedHmac2, sizeof(kCalculatedHmac2)));
+
+ rtc::ByteBufferWriter buf3;
+ EXPECT_TRUE(msg2.Write(&buf3));
+ EXPECT_TRUE(StunMessage::ValidateMessageIntegrityForTesting(
+ reinterpret_cast<const char*>(buf3.Data()), buf3.Length(),
+ kRfc5769SampleMsgPassword));
+}
+
+// Check our STUN message validation code against the RFC5769 test messages.
+TEST_F(StunTest, ValidateMessageIntegrity32) {
+ // Try the messages from RFC 5769.
+ EXPECT_TRUE(StunMessage::ValidateMessageIntegrity32ForTesting(
+ reinterpret_cast<const char*>(kSampleRequestMI32),
+ sizeof(kSampleRequestMI32), kRfc5769SampleMsgPassword));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrity32ForTesting(
+ reinterpret_cast<const char*>(kSampleRequestMI32),
+ sizeof(kSampleRequestMI32), "InvalidPassword"));
+
+ // Try some edge cases.
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrity32ForTesting(
+ reinterpret_cast<const char*>(kStunMessageWithZeroLength),
+ sizeof(kStunMessageWithZeroLength), kRfc5769SampleMsgPassword));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrity32ForTesting(
+ reinterpret_cast<const char*>(kStunMessageWithExcessLength),
+ sizeof(kStunMessageWithExcessLength), kRfc5769SampleMsgPassword));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrity32ForTesting(
+ reinterpret_cast<const char*>(kStunMessageWithSmallLength),
+ sizeof(kStunMessageWithSmallLength), kRfc5769SampleMsgPassword));
+
+ // Again, but with the lengths matching what is claimed in the headers.
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrity32ForTesting(
+ reinterpret_cast<const char*>(kStunMessageWithZeroLength),
+ kStunHeaderSize + rtc::GetBE16(&kStunMessageWithZeroLength[2]),
+ kRfc5769SampleMsgPassword));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrity32ForTesting(
+ reinterpret_cast<const char*>(kStunMessageWithExcessLength),
+ kStunHeaderSize + rtc::GetBE16(&kStunMessageWithExcessLength[2]),
+ kRfc5769SampleMsgPassword));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrity32ForTesting(
+ reinterpret_cast<const char*>(kStunMessageWithSmallLength),
+ kStunHeaderSize + rtc::GetBE16(&kStunMessageWithSmallLength[2]),
+ kRfc5769SampleMsgPassword));
+
+ // Check that a too-short HMAC doesn't cause buffer overflow.
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrity32ForTesting(
+ reinterpret_cast<const char*>(kStunMessageWithBadHmacAtEnd),
+ sizeof(kStunMessageWithBadHmacAtEnd), kRfc5769SampleMsgPassword));
+
+ // Test that munging a single bit anywhere in the message causes the
+ // message-integrity check to fail, unless it is after the M-I attribute.
+ char buf[sizeof(kSampleRequestMI32)];
+ memcpy(buf, kSampleRequestMI32, sizeof(kSampleRequestMI32));
+ for (size_t i = 0; i < sizeof(buf); ++i) {
+ buf[i] ^= 0x01;
+ if (i > 0)
+ buf[i - 1] ^= 0x01;
+ EXPECT_EQ(i >= sizeof(buf) - 8,
+ StunMessage::ValidateMessageIntegrity32ForTesting(
+ buf, sizeof(buf), kRfc5769SampleMsgPassword));
+ }
+}
+
+// Validate that we generate correct MESSAGE-INTEGRITY-32 attributes.
+TEST_F(StunTest, AddMessageIntegrity32) {
+ IceMessage msg;
+ rtc::ByteBufferReader buf(
+ reinterpret_cast<const char*>(kRfc5769SampleRequestWithoutMI),
+ sizeof(kRfc5769SampleRequestWithoutMI));
+ EXPECT_TRUE(msg.Read(&buf));
+ EXPECT_TRUE(msg.AddMessageIntegrity32(kRfc5769SampleMsgPassword));
+ const StunByteStringAttribute* mi_attr =
+ msg.GetByteString(STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32);
+ EXPECT_EQ(4U, mi_attr->length());
+ EXPECT_EQ(0, memcmp(mi_attr->bytes(), kCalculatedHmac1_32,
+ sizeof(kCalculatedHmac1_32)));
+
+ rtc::ByteBufferWriter buf1;
+ EXPECT_TRUE(msg.Write(&buf1));
+ EXPECT_TRUE(StunMessage::ValidateMessageIntegrity32ForTesting(
+ reinterpret_cast<const char*>(buf1.Data()), buf1.Length(),
+ kRfc5769SampleMsgPassword));
+
+ IceMessage msg2;
+ rtc::ByteBufferReader buf2(
+ reinterpret_cast<const char*>(kRfc5769SampleResponseWithoutMI),
+ sizeof(kRfc5769SampleResponseWithoutMI));
+ EXPECT_TRUE(msg2.Read(&buf2));
+ EXPECT_TRUE(msg2.AddMessageIntegrity32(kRfc5769SampleMsgPassword));
+ const StunByteStringAttribute* mi_attr2 =
+ msg2.GetByteString(STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32);
+ EXPECT_EQ(4U, mi_attr2->length());
+ EXPECT_EQ(0, memcmp(mi_attr2->bytes(), kCalculatedHmac2_32,
+ sizeof(kCalculatedHmac2_32)));
+
+ rtc::ByteBufferWriter buf3;
+ EXPECT_TRUE(msg2.Write(&buf3));
+ EXPECT_TRUE(StunMessage::ValidateMessageIntegrity32ForTesting(
+ reinterpret_cast<const char*>(buf3.Data()), buf3.Length(),
+ kRfc5769SampleMsgPassword));
+}
+
+// Validate that the message validates if both MESSAGE-INTEGRITY-32 and
+// MESSAGE-INTEGRITY are present in the message.
+// This is not expected to be used, but is not forbidden.
+TEST_F(StunTest, AddMessageIntegrity32AndMessageIntegrity) {
+ IceMessage msg;
+ auto attr = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
+ attr->CopyBytes("keso", sizeof("keso"));
+ msg.AddAttribute(std::move(attr));
+ msg.AddMessageIntegrity32("password1");
+ msg.AddMessageIntegrity("password2");
+
+ rtc::ByteBufferWriter buf1;
+ EXPECT_TRUE(msg.Write(&buf1));
+ EXPECT_TRUE(StunMessage::ValidateMessageIntegrity32ForTesting(
+ reinterpret_cast<const char*>(buf1.Data()), buf1.Length(), "password1"));
+ EXPECT_TRUE(StunMessage::ValidateMessageIntegrityForTesting(
+ reinterpret_cast<const char*>(buf1.Data()), buf1.Length(), "password2"));
+
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrity32ForTesting(
+ reinterpret_cast<const char*>(buf1.Data()), buf1.Length(), "password2"));
+ EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
+ reinterpret_cast<const char*>(buf1.Data()), buf1.Length(), "password1"));
+}
+
+// Check our STUN message validation code against the RFC5769 test messages.
+TEST_F(StunTest, ValidateFingerprint) {
+ EXPECT_TRUE(StunMessage::ValidateFingerprint(
+ reinterpret_cast<const char*>(kRfc5769SampleRequest),
+ sizeof(kRfc5769SampleRequest)));
+ EXPECT_TRUE(StunMessage::ValidateFingerprint(
+ reinterpret_cast<const char*>(kRfc5769SampleResponse),
+ sizeof(kRfc5769SampleResponse)));
+ EXPECT_TRUE(StunMessage::ValidateFingerprint(
+ reinterpret_cast<const char*>(kRfc5769SampleResponseIPv6),
+ sizeof(kRfc5769SampleResponseIPv6)));
+
+ EXPECT_FALSE(StunMessage::ValidateFingerprint(
+ reinterpret_cast<const char*>(kStunMessageWithZeroLength),
+ sizeof(kStunMessageWithZeroLength)));
+ EXPECT_FALSE(StunMessage::ValidateFingerprint(
+ reinterpret_cast<const char*>(kStunMessageWithExcessLength),
+ sizeof(kStunMessageWithExcessLength)));
+ EXPECT_FALSE(StunMessage::ValidateFingerprint(
+ reinterpret_cast<const char*>(kStunMessageWithSmallLength),
+ sizeof(kStunMessageWithSmallLength)));
+
+ // Test that munging a single bit anywhere in the message causes the
+ // fingerprint check to fail.
+ char buf[sizeof(kRfc5769SampleRequest)];
+ memcpy(buf, kRfc5769SampleRequest, sizeof(kRfc5769SampleRequest));
+ for (size_t i = 0; i < sizeof(buf); ++i) {
+ buf[i] ^= 0x01;
+ if (i > 0)
+ buf[i - 1] ^= 0x01;
+ EXPECT_FALSE(StunMessage::ValidateFingerprint(buf, sizeof(buf)));
+ }
+ // Put them all back to normal and the check should pass again.
+ buf[sizeof(buf) - 1] ^= 0x01;
+ EXPECT_TRUE(StunMessage::ValidateFingerprint(buf, sizeof(buf)));
+}
+
+TEST_F(StunTest, AddFingerprint) {
+ IceMessage msg;
+ rtc::ByteBufferReader buf(
+ reinterpret_cast<const char*>(kRfc5769SampleRequestWithoutMI),
+ sizeof(kRfc5769SampleRequestWithoutMI));
+ EXPECT_TRUE(msg.Read(&buf));
+ EXPECT_TRUE(msg.AddFingerprint());
+
+ rtc::ByteBufferWriter buf1;
+ EXPECT_TRUE(msg.Write(&buf1));
+ EXPECT_TRUE(StunMessage::ValidateFingerprint(
+ reinterpret_cast<const char*>(buf1.Data()), buf1.Length()));
+}
+
+// Sample "GTURN" relay message.
+// clang-format off
+// clang formatting doesn't respect inline comments.
+static const unsigned char kRelayMessage[] = {
+ 0x00, 0x01, 0x00, 88, // message header
+ 0x21, 0x12, 0xA4, 0x42, // magic cookie
+ '0', '1', '2', '3', // transaction id
+ '4', '5', '6', '7',
+ '8', '9', 'a', 'b',
+ 0x00, 0x01, 0x00, 8, // mapped address
+ 0x00, 0x01, 0x00, 13,
+ 0x00, 0x00, 0x00, 17,
+ 0x00, 0x06, 0x00, 12, // username
+ 'a', 'b', 'c', 'd',
+ 'e', 'f', 'g', 'h',
+ 'i', 'j', 'k', 'l',
+ 0x00, 0x0d, 0x00, 4, // lifetime
+ 0x00, 0x00, 0x00, 11,
+ 0x00, 0x0f, 0x00, 4, // magic cookie
+ 0x72, 0xc6, 0x4b, 0xc6,
+ 0x00, 0x10, 0x00, 4, // bandwidth
+ 0x00, 0x00, 0x00, 6,
+ 0x00, 0x11, 0x00, 8, // destination address
+ 0x00, 0x01, 0x00, 13,
+ 0x00, 0x00, 0x00, 17,
+ 0x00, 0x12, 0x00, 8, // source address 2
+ 0x00, 0x01, 0x00, 13,
+ 0x00, 0x00, 0x00, 17,
+ 0x00, 0x13, 0x00, 7, // data
+ 'a', 'b', 'c', 'd',
+ 'e', 'f', 'g', 0 // DATA must be padded per rfc5766.
+};
+// clang-format on
+
+// Test that we can read the GTURN-specific fields.
+TEST_F(StunTest, ReadRelayMessage) {
+ RelayMessage msg;
+
+ const char* input = reinterpret_cast<const char*>(kRelayMessage);
+ size_t size = sizeof(kRelayMessage);
+ rtc::ByteBufferReader buf(input, size);
+ EXPECT_TRUE(msg.Read(&buf));
+
+ EXPECT_EQ(STUN_BINDING_REQUEST, msg.type());
+ EXPECT_EQ(size - 20, msg.length());
+ EXPECT_EQ("0123456789ab", msg.transaction_id());
+
+ RelayMessage msg2(STUN_BINDING_REQUEST, "0123456789ab");
+
+ in_addr legacy_in_addr;
+ legacy_in_addr.s_addr = htonl(17U);
+ rtc::IPAddress legacy_ip(legacy_in_addr);
+
+ const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
+ ASSERT_TRUE(addr != NULL);
+ EXPECT_EQ(1, addr->family());
+ EXPECT_EQ(13, addr->port());
+ EXPECT_EQ(legacy_ip, addr->ipaddr());
+
+ auto addr2 = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
+ addr2->SetPort(13);
+ addr2->SetIP(legacy_ip);
+ msg2.AddAttribute(std::move(addr2));
+
+ const StunByteStringAttribute* bytes = msg.GetByteString(STUN_ATTR_USERNAME);
+ ASSERT_TRUE(bytes != NULL);
+ EXPECT_EQ(12U, bytes->length());
+ EXPECT_EQ("abcdefghijkl", bytes->string_view());
+
+ auto bytes2 = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
+ bytes2->CopyBytes("abcdefghijkl");
+ msg2.AddAttribute(std::move(bytes2));
+
+ const StunUInt32Attribute* uval = msg.GetUInt32(STUN_ATTR_LIFETIME);
+ ASSERT_TRUE(uval != NULL);
+ EXPECT_EQ(11U, uval->value());
+
+ auto uval2 = StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
+ uval2->SetValue(11);
+ msg2.AddAttribute(std::move(uval2));
+
+ bytes = msg.GetByteString(STUN_ATTR_MAGIC_COOKIE);
+ ASSERT_TRUE(bytes != NULL);
+ EXPECT_EQ(4U, bytes->length());
+ EXPECT_EQ(0, memcmp(bytes->bytes(), TURN_MAGIC_COOKIE_VALUE,
+ sizeof(TURN_MAGIC_COOKIE_VALUE)));
+
+ bytes2 = StunAttribute::CreateByteString(STUN_ATTR_MAGIC_COOKIE);
+ bytes2->CopyBytes(reinterpret_cast<const char*>(TURN_MAGIC_COOKIE_VALUE),
+ sizeof(TURN_MAGIC_COOKIE_VALUE));
+ msg2.AddAttribute(std::move(bytes2));
+
+ uval = msg.GetUInt32(STUN_ATTR_BANDWIDTH);
+ ASSERT_TRUE(uval != NULL);
+ EXPECT_EQ(6U, uval->value());
+
+ uval2 = StunAttribute::CreateUInt32(STUN_ATTR_BANDWIDTH);
+ uval2->SetValue(6);
+ msg2.AddAttribute(std::move(uval2));
+
+ addr = msg.GetAddress(STUN_ATTR_DESTINATION_ADDRESS);
+ ASSERT_TRUE(addr != NULL);
+ EXPECT_EQ(1, addr->family());
+ EXPECT_EQ(13, addr->port());
+ EXPECT_EQ(legacy_ip, addr->ipaddr());
+
+ addr2 = StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
+ addr2->SetPort(13);
+ addr2->SetIP(legacy_ip);
+ msg2.AddAttribute(std::move(addr2));
+
+ addr = msg.GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
+ ASSERT_TRUE(addr != NULL);
+ EXPECT_EQ(1, addr->family());
+ EXPECT_EQ(13, addr->port());
+ EXPECT_EQ(legacy_ip, addr->ipaddr());
+
+ addr2 = StunAttribute::CreateAddress(STUN_ATTR_SOURCE_ADDRESS2);
+ addr2->SetPort(13);
+ addr2->SetIP(legacy_ip);
+ msg2.AddAttribute(std::move(addr2));
+
+ bytes = msg.GetByteString(STUN_ATTR_DATA);
+ ASSERT_TRUE(bytes != NULL);
+ EXPECT_EQ(7U, bytes->length());
+ EXPECT_EQ("abcdefg", bytes->string_view());
+
+ bytes2 = StunAttribute::CreateByteString(STUN_ATTR_DATA);
+ bytes2->CopyBytes("abcdefg");
+ msg2.AddAttribute(std::move(bytes2));
+
+ rtc::ByteBufferWriter out;
+ EXPECT_TRUE(msg.Write(&out));
+ EXPECT_EQ(size, out.Length());
+ size_t len1 = out.Length();
+ rtc::ByteBufferReader read_buf(out);
+ std::string outstring;
+ read_buf.ReadString(&outstring, len1);
+ EXPECT_EQ(0, memcmp(outstring.c_str(), input, len1));
+
+ rtc::ByteBufferWriter out2;
+ EXPECT_TRUE(msg2.Write(&out2));
+ EXPECT_EQ(size, out2.Length());
+ size_t len2 = out2.Length();
+ rtc::ByteBufferReader read_buf2(out2);
+ std::string outstring2;
+ read_buf2.ReadString(&outstring2, len2);
+ EXPECT_EQ(0, memcmp(outstring2.c_str(), input, len2));
+}
+
+// Test that we can remove attribute from a message.
+TEST_F(StunTest, RemoveAttribute) {
+ StunMessage msg;
+
+ // Removing something that does exist should return nullptr.
+ EXPECT_EQ(msg.RemoveAttribute(STUN_ATTR_USERNAME), nullptr);
+
+ {
+ auto attr = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
+ attr->CopyBytes("kes", sizeof("kes"));
+ msg.AddAttribute(std::move(attr));
+ }
+
+ size_t len = msg.length();
+ {
+ auto attr = msg.RemoveAttribute(STUN_ATTR_USERNAME);
+ ASSERT_NE(attr, nullptr);
+ EXPECT_EQ(attr->type(), STUN_ATTR_USERNAME);
+ EXPECT_STREQ("kes",
+ static_cast<StunByteStringAttribute*>(attr.get())->bytes());
+ EXPECT_LT(msg.length(), len);
+ }
+
+ // Now add same attribute type twice.
+ {
+ auto attr = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
+ attr->CopyBytes("kes", sizeof("kes"));
+ msg.AddAttribute(std::move(attr));
+ }
+
+ {
+ auto attr = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
+ attr->CopyBytes("kenta", sizeof("kenta"));
+ msg.AddAttribute(std::move(attr));
+ }
+
+ // Remove should remove the last added occurrence.
+ {
+ auto attr = msg.RemoveAttribute(STUN_ATTR_USERNAME);
+ ASSERT_NE(attr, nullptr);
+ EXPECT_EQ(attr->type(), STUN_ATTR_USERNAME);
+ EXPECT_STREQ("kenta",
+ static_cast<StunByteStringAttribute*>(attr.get())->bytes());
+ }
+
+ // Remove should remove the last added occurrence.
+ {
+ auto attr = msg.RemoveAttribute(STUN_ATTR_USERNAME);
+ ASSERT_NE(attr, nullptr);
+ EXPECT_EQ(attr->type(), STUN_ATTR_USERNAME);
+ EXPECT_STREQ("kes",
+ static_cast<StunByteStringAttribute*>(attr.get())->bytes());
+ }
+
+ // Removing something that does exist should return nullptr.
+ EXPECT_EQ(msg.RemoveAttribute(STUN_ATTR_USERNAME), nullptr);
+}
+
+// Test that we can remove attribute from a message.
+TEST_F(StunTest, ClearAttributes) {
+ StunMessage msg;
+
+ auto attr = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
+ attr->CopyBytes("kes", sizeof("kes"));
+ msg.AddAttribute(std::move(attr));
+ size_t len = msg.length();
+
+ msg.ClearAttributes();
+ EXPECT_EQ(msg.length(), len - /* 3 + 1 byte padding + header */ 8);
+ EXPECT_EQ(nullptr, msg.GetByteString(STUN_ATTR_USERNAME));
+}
+
+// Test CopyStunAttribute
+TEST_F(StunTest, CopyAttribute) {
+ rtc::ByteBufferWriter buf;
+ rtc::ByteBufferWriter* buffer_ptrs[] = {&buf, nullptr};
+ // Test both with and without supplied ByteBufferWriter.
+ for (auto buffer_ptr : buffer_ptrs) {
+ { // Test StunByteStringAttribute.
+ auto attr = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
+ attr->CopyBytes("kes", sizeof("kes"));
+
+ auto copy = CopyStunAttribute(*attr.get(), buffer_ptr);
+ ASSERT_EQ(copy->value_type(), STUN_VALUE_BYTE_STRING);
+ EXPECT_STREQ("kes",
+ static_cast<StunByteStringAttribute*>(copy.get())->bytes());
+ }
+
+ { // Test StunAddressAttribute.
+ rtc::IPAddress test_ip(kIPv6TestAddress2);
+ auto addr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
+ rtc::SocketAddress test_addr(test_ip, kTestMessagePort2);
+ addr->SetAddress(test_addr);
+ CheckStunAddressAttribute(addr.get(), STUN_ADDRESS_IPV6,
+ kTestMessagePort2, test_ip);
+
+ auto copy = CopyStunAttribute(*addr.get(), buffer_ptr);
+ ASSERT_EQ(copy->value_type(), STUN_VALUE_ADDRESS);
+ CheckStunAddressAttribute(static_cast<StunAddressAttribute*>(copy.get()),
+ STUN_ADDRESS_IPV6, kTestMessagePort2, test_ip);
+ }
+
+ { // Test StunAddressAttribute.
+ rtc::IPAddress test_ip(kIPv6TestAddress2);
+ auto addr = StunAttribute::CreateAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
+ rtc::SocketAddress test_addr(test_ip, kTestMessagePort2);
+ addr->SetAddress(test_addr);
+ CheckStunAddressAttribute(addr.get(), STUN_ADDRESS_IPV6,
+ kTestMessagePort2, test_ip);
+
+ auto copy = CopyStunAttribute(*addr.get(), buffer_ptr);
+ ASSERT_EQ(copy->value_type(), STUN_VALUE_ADDRESS);
+ CheckStunAddressAttribute(static_cast<StunAddressAttribute*>(copy.get()),
+ STUN_ADDRESS_IPV6, kTestMessagePort2, test_ip);
+ }
+ }
+}
+
+// Test Clone
+TEST_F(StunTest, Clone) {
+ IceMessage msg(0, "0123456789ab");
+ {
+ auto errorcode = StunAttribute::CreateErrorCode();
+ errorcode->SetCode(kTestErrorCode);
+ errorcode->SetReason(kTestErrorReason);
+ msg.AddAttribute(std::move(errorcode));
+ }
+ {
+ auto bytes2 = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
+ bytes2->CopyBytes("abcdefghijkl");
+ msg.AddAttribute(std::move(bytes2));
+ }
+ {
+ auto uval2 = StunAttribute::CreateUInt32(STUN_ATTR_RETRANSMIT_COUNT);
+ uval2->SetValue(11);
+ msg.AddAttribute(std::move(uval2));
+ }
+ {
+ auto addr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
+ addr->SetIP(rtc::IPAddress(kIPv6TestAddress1));
+ addr->SetPort(kTestMessagePort1);
+ msg.AddAttribute(std::move(addr));
+ }
+ auto copy = msg.Clone();
+ ASSERT_NE(nullptr, copy.get());
+
+ rtc::ByteBufferWriter out1;
+ EXPECT_TRUE(msg.Write(&out1));
+ rtc::ByteBufferWriter out2;
+ EXPECT_TRUE(copy->Write(&out2));
+
+ ASSERT_EQ(out1.Length(), out2.Length());
+ EXPECT_EQ(0, memcmp(out1.Data(), out2.Data(), out1.Length()));
+}
+
+// Test EqualAttributes
+TEST_F(StunTest, EqualAttributes) {
+ IceMessage msg;
+ {
+ auto errorcode = StunAttribute::CreateErrorCode();
+ errorcode->SetCode(kTestErrorCode);
+ errorcode->SetReason(kTestErrorReason);
+ msg.AddAttribute(std::move(errorcode));
+ }
+ {
+ auto bytes2 = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
+ bytes2->CopyBytes("abcdefghijkl");
+ msg.AddAttribute(std::move(bytes2));
+ }
+ {
+ auto uval2 = StunAttribute::CreateUInt32(STUN_ATTR_RETRANSMIT_COUNT);
+ uval2->SetValue(11);
+ msg.AddAttribute(std::move(uval2));
+ }
+ {
+ auto addr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
+ addr->SetIP(rtc::IPAddress(kIPv6TestAddress1));
+ addr->SetPort(kTestMessagePort1);
+ msg.AddAttribute(std::move(addr));
+ }
+ auto copy = msg.Clone();
+ ASSERT_NE(nullptr, copy.get());
+
+ EXPECT_TRUE(copy->EqualAttributes(&msg, [](int type) { return true; }));
+
+ {
+ auto attr = StunAttribute::CreateByteString(STUN_ATTR_NONCE);
+ attr->CopyBytes("keso");
+ msg.AddAttribute(std::move(attr));
+ EXPECT_FALSE(copy->EqualAttributes(&msg, [](int type) { return true; }));
+ EXPECT_TRUE(copy->EqualAttributes(
+ &msg, [](int type) { return type != STUN_ATTR_NONCE; }));
+ }
+
+ {
+ auto attr = StunAttribute::CreateByteString(STUN_ATTR_NONCE);
+ attr->CopyBytes("keso");
+ copy->AddAttribute(std::move(attr));
+ EXPECT_TRUE(copy->EqualAttributes(&msg, [](int type) { return true; }));
+ }
+ {
+ copy->RemoveAttribute(STUN_ATTR_NONCE);
+ auto attr = StunAttribute::CreateByteString(STUN_ATTR_NONCE);
+ attr->CopyBytes("kent");
+ copy->AddAttribute(std::move(attr));
+ EXPECT_FALSE(copy->EqualAttributes(&msg, [](int type) { return true; }));
+ EXPECT_TRUE(copy->EqualAttributes(
+ &msg, [](int type) { return type != STUN_ATTR_NONCE; }));
+ }
+
+ {
+ msg.RemoveAttribute(STUN_ATTR_NONCE);
+ EXPECT_FALSE(copy->EqualAttributes(&msg, [](int type) { return true; }));
+ EXPECT_TRUE(copy->EqualAttributes(
+ &msg, [](int type) { return type != STUN_ATTR_NONCE; }));
+ }
+}
+
+TEST_F(StunTest, ReduceTransactionIdIsHostOrderIndependent) {
+ const std::string transaction_id = "abcdefghijkl";
+ StunMessage message(0, transaction_id);
+ uint32_t reduced_transaction_id = message.reduced_transaction_id();
+ EXPECT_EQ(reduced_transaction_id, 1835954016u);
+}
+
+TEST_F(StunTest, GoogMiscInfo) {
+ StunMessage msg(STUN_BINDING_REQUEST, "ABCDEFGHIJKL");
+ const size_t size =
+ /* msg header */ 20 +
+ /* attr header */ 4 +
+ /* 3 * 2 rounded to multiple of 4 */ 8;
+ auto list =
+ StunAttribute::CreateUInt16ListAttribute(STUN_ATTR_GOOG_MISC_INFO);
+ list->AddTypeAtIndex(0, 0x1U);
+ list->AddTypeAtIndex(3, 0x1000U);
+ list->AddTypeAtIndex(2, 0xAB0CU);
+ msg.AddAttribute(std::move(list));
+ CheckStunHeader(msg, STUN_BINDING_REQUEST, (size - 20));
+
+ rtc::ByteBufferWriter out;
+ EXPECT_TRUE(msg.Write(&out));
+ ASSERT_EQ(size, out.Length());
+
+ size_t read_size = ReadStunMessageTestCase(
+ &msg, reinterpret_cast<const unsigned char*>(out.Data()), out.Length());
+ ASSERT_EQ(read_size + 20, size);
+ CheckStunHeader(msg, STUN_BINDING_REQUEST, read_size);
+ const StunUInt16ListAttribute* types =
+ msg.GetUInt16List(STUN_ATTR_GOOG_MISC_INFO);
+ ASSERT_TRUE(types != NULL);
+ EXPECT_EQ(4U, types->Size());
+ EXPECT_EQ(0x1U, types->GetType(0));
+ EXPECT_EQ(0x0U, types->GetType(1));
+ EXPECT_EQ(0x1000U, types->GetType(3));
+ EXPECT_EQ(0xAB0CU, types->GetType(2));
+}
+
+TEST_F(StunTest, IsStunMethod) {
+ int methods[] = {STUN_BINDING_REQUEST};
+ EXPECT_TRUE(StunMessage::IsStunMethod(
+ methods, reinterpret_cast<const char*>(kRfc5769SampleRequest),
+ sizeof(kRfc5769SampleRequest)));
+}
+
+TEST_F(StunTest, SizeRestrictionOnAttributes) {
+ StunMessage msg(STUN_BINDING_REQUEST, "ABCDEFGHIJKL");
+ auto long_username = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
+ std::string long_string(509, 'x');
+ long_username->CopyBytes(long_string.c_str(), long_string.size());
+ msg.AddAttribute(std::move(long_username));
+ rtc::ByteBufferWriter out;
+ ASSERT_FALSE(msg.Write(&out));
+}
+
+TEST_F(StunTest, ValidateMessageIntegrityWithParser) {
+ webrtc::metrics::Reset(); // Ensure counters start from zero.
+ // Try the messages from RFC 5769.
+ StunMessage message;
+ rtc::ByteBufferReader reader(
+ reinterpret_cast<const char*>(kRfc5769SampleRequest),
+ sizeof(kRfc5769SampleRequest));
+ EXPECT_TRUE(message.Read(&reader));
+ EXPECT_EQ(message.ValidateMessageIntegrity(kRfc5769SampleMsgPassword),
+ StunMessage::IntegrityStatus::kIntegrityOk);
+ EXPECT_EQ(webrtc::metrics::NumEvents(
+ "WebRTC.Stun.Integrity.Request",
+ static_cast<int>(StunMessage::IntegrityStatus::kIntegrityOk)),
+ 1);
+ EXPECT_EQ(message.RevalidateMessageIntegrity("Invalid password"),
+ StunMessage::IntegrityStatus::kIntegrityBad);
+ EXPECT_EQ(webrtc::metrics::NumEvents(
+ "WebRTC.Stun.Integrity.Request",
+ static_cast<int>(StunMessage::IntegrityStatus::kIntegrityBad)),
+ 1);
+ EXPECT_EQ(webrtc::metrics::NumSamples("WebRTC.Stun.Integrity.Request"), 2);
+}
+
+} // namespace cricket
diff --git a/third_party/libwebrtc/api/transport/test/create_feedback_generator.cc b/third_party/libwebrtc/api/transport/test/create_feedback_generator.cc
new file mode 100644
index 0000000000..7c83823ce4
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/test/create_feedback_generator.cc
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/transport/test/create_feedback_generator.h"
+
+#include <memory>
+
+#include "test/network/feedback_generator.h"
+
+namespace webrtc {
+
+std::unique_ptr<FeedbackGenerator> CreateFeedbackGenerator(
+ FeedbackGenerator::Config confg) {
+ return std::make_unique<FeedbackGeneratorImpl>(confg);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/transport/test/create_feedback_generator.h b/third_party/libwebrtc/api/transport/test/create_feedback_generator.h
new file mode 100644
index 0000000000..a1a2226496
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/test/create_feedback_generator.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_TRANSPORT_TEST_CREATE_FEEDBACK_GENERATOR_H_
+#define API_TRANSPORT_TEST_CREATE_FEEDBACK_GENERATOR_H_
+
+#include <memory>
+
+#include "api/transport/test/feedback_generator_interface.h"
+
+namespace webrtc {
+std::unique_ptr<FeedbackGenerator> CreateFeedbackGenerator(
+ FeedbackGenerator::Config confg);
+} // namespace webrtc
+#endif // API_TRANSPORT_TEST_CREATE_FEEDBACK_GENERATOR_H_
diff --git a/third_party/libwebrtc/api/transport/test/feedback_generator_interface.h b/third_party/libwebrtc/api/transport/test/feedback_generator_interface.h
new file mode 100644
index 0000000000..6e5118cbf4
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/test/feedback_generator_interface.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_TRANSPORT_TEST_FEEDBACK_GENERATOR_INTERFACE_H_
+#define API_TRANSPORT_TEST_FEEDBACK_GENERATOR_INTERFACE_H_
+
+#include <vector>
+
+#include "api/test/simulated_network.h"
+#include "api/transport/network_types.h"
+
+namespace webrtc {
+class FeedbackGenerator {
+ public:
+ struct Config {
+ BuiltInNetworkBehaviorConfig send_link;
+ BuiltInNetworkBehaviorConfig return_link;
+ TimeDelta feedback_interval = TimeDelta::Millis(50);
+ DataSize feedback_packet_size = DataSize::Bytes(20);
+ };
+ virtual ~FeedbackGenerator() = default;
+ virtual Timestamp Now() = 0;
+ virtual void Sleep(TimeDelta duration) = 0;
+ virtual void SendPacket(size_t size) = 0;
+ virtual std::vector<TransportPacketsFeedback> PopFeedback() = 0;
+ virtual void SetSendConfig(BuiltInNetworkBehaviorConfig config) = 0;
+ virtual void SetReturnConfig(BuiltInNetworkBehaviorConfig config) = 0;
+ virtual void SetSendLinkCapacity(DataRate capacity) = 0;
+};
+} // namespace webrtc
+#endif // API_TRANSPORT_TEST_FEEDBACK_GENERATOR_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/transport/test/mock_network_control.h b/third_party/libwebrtc/api/transport/test/mock_network_control.h
new file mode 100644
index 0000000000..f613004fb7
--- /dev/null
+++ b/third_party/libwebrtc/api/transport/test/mock_network_control.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TRANSPORT_TEST_MOCK_NETWORK_CONTROL_H_
+#define API_TRANSPORT_TEST_MOCK_NETWORK_CONTROL_H_
+
+#include "api/transport/network_control.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockNetworkStateEstimator : public NetworkStateEstimator {
+ public:
+ MOCK_METHOD(absl::optional<NetworkStateEstimate>,
+ GetCurrentEstimate,
+ (),
+ (override));
+ MOCK_METHOD(void,
+ OnTransportPacketsFeedback,
+ (const TransportPacketsFeedback&),
+ (override));
+ MOCK_METHOD(void, OnReceivedPacket, (const PacketResult&), (override));
+ MOCK_METHOD(void, OnRouteChange, (const NetworkRouteChange&), (override));
+};
+
+} // namespace webrtc
+
+#endif // API_TRANSPORT_TEST_MOCK_NETWORK_CONTROL_H_
diff --git a/third_party/libwebrtc/api/transport_api_gn/moz.build b/third_party/libwebrtc/api/transport_api_gn/moz.build
new file mode 100644
index 0000000000..5335c2c519
--- /dev/null
+++ b/third_party/libwebrtc/api/transport_api_gn/moz.build
@@ -0,0 +1,217 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/call/transport.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("transport_api_gn")
diff --git a/third_party/libwebrtc/api/turn_customizer.h b/third_party/libwebrtc/api/turn_customizer.h
new file mode 100644
index 0000000000..8d569b36d2
--- /dev/null
+++ b/third_party/libwebrtc/api/turn_customizer.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2017 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_TURN_CUSTOMIZER_H_
+#define API_TURN_CUSTOMIZER_H_
+
+#include <stdlib.h>
+
+#include "api/transport/stun.h"
+
+namespace cricket {
+class PortInterface;
+} // namespace cricket
+
+namespace webrtc {
+
+class TurnCustomizer {
+ public:
+ // This is called before a TURN message is sent.
+ // This could be used to add implementation specific attributes to a request.
+ virtual void MaybeModifyOutgoingStunMessage(
+ cricket::PortInterface* port,
+ cricket::StunMessage* message) = 0;
+
+ // TURN can send data using channel data messages or Send indication.
+ // This method should return false if `data` should be sent using
+ // a Send indication instead of a ChannelData message, even if a
+ // channel is bound.
+ virtual bool AllowChannelData(cricket::PortInterface* port,
+ const void* data,
+ size_t size,
+ bool payload) = 0;
+
+ virtual ~TurnCustomizer() {}
+};
+
+} // namespace webrtc
+
+#endif // API_TURN_CUSTOMIZER_H_
diff --git a/third_party/libwebrtc/api/uma_metrics.h b/third_party/libwebrtc/api/uma_metrics.h
new file mode 100644
index 0000000000..a63159e849
--- /dev/null
+++ b/third_party/libwebrtc/api/uma_metrics.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This file contains enums related to Chrome UMA histograms. See
+// https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md#requirements
+// for requirements when adding or changing metrics.
+
+#ifndef API_UMA_METRICS_H_
+#define API_UMA_METRICS_H_
+
+namespace webrtc {
+
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum PeerConnectionAddressFamilyCounter {
+ kPeerConnection_IPv4 = 0,
+ kPeerConnection_IPv6 = 1,
+ kBestConnections_IPv4 = 2,
+ kBestConnections_IPv6 = 3,
+ kPeerConnectionAddressFamilyCounter_Max
+};
+
+// This enum defines types for UMA samples, which will have a range.
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum PeerConnectionMetricsName {
+ kNetworkInterfaces_IPv4 = 0, // Number of IPv4 interfaces.
+ kNetworkInterfaces_IPv6 = 1, // Number of IPv6 interfaces.
+ kTimeToConnect = 2, // In milliseconds.
+ kLocalCandidates_IPv4 = 3, // Number of IPv4 local candidates.
+ kLocalCandidates_IPv6 = 4, // Number of IPv6 local candidates.
+ kPeerConnectionMetricsName_Max
+};
+
+// The IceCandidatePairType has the format of
+// <local_candidate_type>_<remote_candidate_type>. It is recorded based on the
+// type of candidate pair used when the PeerConnection first goes to a completed
+// state. When BUNDLE is enabled, only the first transport gets recorded.
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum IceCandidatePairType {
+ // HostHost is deprecated. It was replaced with the set of types at the bottom
+ // to report private or public host IP address.
+ kIceCandidatePairHostHost = 0,
+ kIceCandidatePairHostSrflx = 1,
+ kIceCandidatePairHostRelay = 2,
+ kIceCandidatePairHostPrflx = 3,
+ kIceCandidatePairSrflxHost = 4,
+ kIceCandidatePairSrflxSrflx = 5,
+ kIceCandidatePairSrflxRelay = 6,
+ kIceCandidatePairSrflxPrflx = 7,
+ kIceCandidatePairRelayHost = 8,
+ kIceCandidatePairRelaySrflx = 9,
+ kIceCandidatePairRelayRelay = 10,
+ kIceCandidatePairRelayPrflx = 11,
+ kIceCandidatePairPrflxHost = 12,
+ kIceCandidatePairPrflxSrflx = 13,
+ kIceCandidatePairPrflxRelay = 14,
+
+ // The following 9 types tell whether local and remote hosts have hostname,
+ // private or public IP addresses.
+ kIceCandidatePairHostPrivateHostPrivate = 15,
+ kIceCandidatePairHostPrivateHostPublic = 16,
+ kIceCandidatePairHostPublicHostPrivate = 17,
+ kIceCandidatePairHostPublicHostPublic = 18,
+ kIceCandidatePairHostNameHostName = 19,
+ kIceCandidatePairHostNameHostPrivate = 20,
+ kIceCandidatePairHostNameHostPublic = 21,
+ kIceCandidatePairHostPrivateHostName = 22,
+ kIceCandidatePairHostPublicHostName = 23,
+ kIceCandidatePairMax
+};
+
+// The difference between PeerConnectionEnumCounter and
+// PeerConnectionMetricsName is that the "EnumCounter" is only counting the
+// occurrences of events, while "Name" has a value associated with it which is
+// used to form a histogram.
+
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum KeyExchangeProtocolMedia {
+ kEnumCounterKeyProtocolMediaTypeDtlsAudio = 0,
+ kEnumCounterKeyProtocolMediaTypeDtlsVideo = 1,
+ kEnumCounterKeyProtocolMediaTypeDtlsData = 2,
+ kEnumCounterKeyProtocolMediaTypeSdesAudio = 3,
+ kEnumCounterKeyProtocolMediaTypeSdesVideo = 4,
+ kEnumCounterKeyProtocolMediaTypeSdesData = 5,
+ kEnumCounterKeyProtocolMediaTypeMax
+};
+
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum SdpSemanticRequested {
+ kSdpSemanticRequestDefault = 0,
+ kSdpSemanticRequestPlanB = 1,
+ kSdpSemanticRequestUnifiedPlan = 2,
+ kSdpSemanticRequestMax
+};
+
+// Metric for counting the outcome of adding an ICE candidate
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum AddIceCandidateResult {
+ kAddIceCandidateSuccess = 0,
+ kAddIceCandidateFailClosed = 1,
+ kAddIceCandidateFailNoRemoteDescription = 2,
+ kAddIceCandidateFailNullCandidate = 3,
+ kAddIceCandidateFailNotValid = 4,
+ kAddIceCandidateFailNotReady = 5,
+ kAddIceCandidateFailInAddition = 6,
+ kAddIceCandidateFailNotUsable = 7,
+ kAddIceCandidateMax
+};
+
+// Metric for recording which api surface was used to enable simulcast.
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum SimulcastApiVersion {
+ kSimulcastApiVersionNone = 0,
+ kSimulcastApiVersionLegacy = 1,
+ kSimulcastApiVersionSpecCompliant = 2,
+ kSimulcastApiVersionMax
+};
+
+// Metrics for reporting usage of BUNDLE.
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum BundleUsage {
+ // There are no m-lines in the SDP, only a session description.
+ kBundleUsageEmpty = 0,
+ // Only a data channel is negotiated but BUNDLE is not negotiated.
+ kBundleUsageNoBundleDatachannelOnly = 1,
+ // BUNDLE is not negotiated and there is at most one m-line per media type,
+ kBundleUsageNoBundleSimple = 2,
+ // BUNDLE is not negotiated and there are multiple m-lines per media type,
+ kBundleUsageNoBundleComplex = 3,
+ // Only a data channel is negotiated and BUNDLE is negotiated.
+ kBundleUsageBundleDatachannelOnly = 4,
+ // BUNDLE is negotiated but there is at most one m-line per media type,
+ kBundleUsageBundleSimple = 5,
+ // BUNDLE is negotiated and there are multiple m-lines per media type,
+ kBundleUsageBundleComplex = 6,
+ // Legacy plan-b metrics.
+ kBundleUsageNoBundlePlanB = 7,
+ kBundleUsageBundlePlanB = 8,
+ kBundleUsageMax
+};
+
+// Metrics for reporting configured BUNDLE policy, mapping directly to
+// https://w3c.github.io/webrtc-pc/#rtcbundlepolicy-enum
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum BundlePolicyUsage {
+ kBundlePolicyUsageBalanced = 0,
+ kBundlePolicyUsageMaxBundle = 1,
+ kBundlePolicyUsageMaxCompat = 2,
+ kBundlePolicyUsageMax
+};
+
+// Metrics for provisional answers as described in
+// https://datatracker.ietf.org/doc/html/rfc8829#section-4.1.10.1
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum ProvisionalAnswerUsage {
+ kProvisionalAnswerNotUsed = 0,
+ kProvisionalAnswerLocal = 1,
+ kProvisionalAnswerRemote = 2,
+ kProvisionalAnswerMax
+};
+
+// Metrics for RTCRtpMuxPolicy. The only defined value is
+// https://w3c.github.io/webrtc-pc/#rtcrtcpmuxpolicy-enum
+// "require" but there is a legacy option "negotiate" which
+// was removed from the spec.
+enum RtcpMuxPolicyUsage {
+ kRtcpMuxPolicyUsageRequire = 0,
+ kRtcpMuxPolicyUsageNegotiate = 1,
+ kRtcpMuxPolicyUsageMax
+};
+
+// When adding new metrics please consider using the style described in
+// https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md#usage
+// instead of the legacy enums used above.
+
+} // namespace webrtc
+
+#endif // API_UMA_METRICS_H_
diff --git a/third_party/libwebrtc/api/units/BUILD.gn b/third_party/libwebrtc/api/units/BUILD.gn
new file mode 100644
index 0000000000..45cdcd3097
--- /dev/null
+++ b/third_party/libwebrtc/api/units/BUILD.gn
@@ -0,0 +1,111 @@
+# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../webrtc.gni")
+
+rtc_library("data_rate") {
+ visibility = [ "*" ]
+ sources = [
+ "data_rate.cc",
+ "data_rate.h",
+ ]
+
+ deps = [
+ ":data_size",
+ ":frequency",
+ ":time_delta",
+ "..:array_view",
+ "../../rtc_base:checks",
+ "../../rtc_base:stringutils",
+ "../../rtc_base/units:unit_base",
+ ]
+}
+
+rtc_library("data_size") {
+ visibility = [ "*" ]
+ sources = [
+ "data_size.cc",
+ "data_size.h",
+ ]
+
+ deps = [
+ "..:array_view",
+ "../../rtc_base:checks",
+ "../../rtc_base:stringutils",
+ "../../rtc_base/units:unit_base",
+ ]
+}
+
+rtc_library("time_delta") {
+ visibility = [ "*" ]
+ sources = [
+ "time_delta.cc",
+ "time_delta.h",
+ ]
+
+ deps = [
+ "..:array_view",
+ "../../rtc_base:checks",
+ "../../rtc_base:stringutils",
+ "../../rtc_base/units:unit_base",
+ ]
+}
+
+rtc_library("frequency") {
+ visibility = [ "*" ]
+ sources = [
+ "frequency.cc",
+ "frequency.h",
+ ]
+
+ deps = [
+ ":time_delta",
+ "..:array_view",
+ "../../rtc_base:checks",
+ "../../rtc_base:stringutils",
+ "../../rtc_base/units:unit_base",
+ ]
+}
+
+rtc_library("timestamp") {
+ visibility = [ "*" ]
+ sources = [
+ "timestamp.cc",
+ "timestamp.h",
+ ]
+
+ deps = [
+ ":time_delta",
+ "..:array_view",
+ "../../rtc_base:checks",
+ "../../rtc_base:stringutils",
+ "../../rtc_base/units:unit_base",
+ ]
+}
+
+if (rtc_include_tests) {
+ rtc_library("units_unittests") {
+ testonly = true
+ sources = [
+ "data_rate_unittest.cc",
+ "data_size_unittest.cc",
+ "frequency_unittest.cc",
+ "time_delta_unittest.cc",
+ "timestamp_unittest.cc",
+ ]
+ deps = [
+ ":data_rate",
+ ":data_size",
+ ":frequency",
+ ":time_delta",
+ ":timestamp",
+ "../../rtc_base:logging",
+ "../../test:test_support",
+ ]
+ }
+}
diff --git a/third_party/libwebrtc/api/units/OWNERS b/third_party/libwebrtc/api/units/OWNERS
new file mode 100644
index 0000000000..53e076b20b
--- /dev/null
+++ b/third_party/libwebrtc/api/units/OWNERS
@@ -0,0 +1 @@
+srte@webrtc.org
diff --git a/third_party/libwebrtc/api/units/data_rate.cc b/third_party/libwebrtc/api/units/data_rate.cc
new file mode 100644
index 0000000000..f9586c5f40
--- /dev/null
+++ b/third_party/libwebrtc/api/units/data_rate.cc
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/units/data_rate.h"
+
+#include "api/array_view.h"
+#include "rtc_base/strings/string_builder.h"
+
+namespace webrtc {
+
+std::string ToString(DataRate value) {
+ char buf[64];
+ rtc::SimpleStringBuilder sb(buf);
+ if (value.IsPlusInfinity()) {
+ sb << "+inf bps";
+ } else if (value.IsMinusInfinity()) {
+ sb << "-inf bps";
+ } else {
+ if (value.bps() == 0 || value.bps() % 1000 != 0) {
+ sb << value.bps() << " bps";
+ } else {
+ sb << value.kbps() << " kbps";
+ }
+ }
+ return sb.str();
+}
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/units/data_rate.h b/third_party/libwebrtc/api/units/data_rate.h
new file mode 100644
index 0000000000..d813c61156
--- /dev/null
+++ b/third_party/libwebrtc/api/units/data_rate.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_UNITS_DATA_RATE_H_
+#define API_UNITS_DATA_RATE_H_
+
+#ifdef WEBRTC_UNIT_TEST
+#include <ostream> // no-presubmit-check TODO(webrtc:8982)
+#endif // WEBRTC_UNIT_TEST
+
+#include <limits>
+#include <string>
+#include <type_traits>
+
+#include "api/units/data_size.h"
+#include "api/units/frequency.h"
+#include "api/units/time_delta.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/units/unit_base.h" // IWYU pragma: export
+
+namespace webrtc {
+// DataRate is a class that represents a given data rate. This can be used to
+// represent bandwidth, encoding bitrate, etc. The internal storage is bits per
+// second (bps).
+class DataRate final : public rtc_units_impl::RelativeUnit<DataRate> {
+ public:
+ template <typename T>
+ static constexpr DataRate BitsPerSec(T value) {
+ static_assert(std::is_arithmetic<T>::value, "");
+ return FromValue(value);
+ }
+ template <typename T>
+ static constexpr DataRate BytesPerSec(T value) {
+ static_assert(std::is_arithmetic<T>::value, "");
+ return FromFraction(8, value);
+ }
+ template <typename T>
+ static constexpr DataRate KilobitsPerSec(T value) {
+ static_assert(std::is_arithmetic<T>::value, "");
+ return FromFraction(1000, value);
+ }
+ static constexpr DataRate Infinity() { return PlusInfinity(); }
+
+ DataRate() = delete;
+
+ template <typename T = int64_t>
+ constexpr T bps() const {
+ return ToValue<T>();
+ }
+ template <typename T = int64_t>
+ constexpr T bytes_per_sec() const {
+ return ToFraction<8, T>();
+ }
+ template <typename T = int64_t>
+ constexpr T kbps() const {
+ return ToFraction<1000, T>();
+ }
+ constexpr int64_t bps_or(int64_t fallback_value) const {
+ return ToValueOr(fallback_value);
+ }
+ constexpr int64_t kbps_or(int64_t fallback_value) const {
+ return ToFractionOr<1000>(fallback_value);
+ }
+
+ private:
+ // Bits per second used internally to simplify debugging by making the value
+ // more recognizable.
+ friend class rtc_units_impl::UnitBase<DataRate>;
+ using RelativeUnit::RelativeUnit;
+ static constexpr bool one_sided = true;
+};
+
+namespace data_rate_impl {
+inline constexpr int64_t Microbits(const DataSize& size) {
+ constexpr int64_t kMaxBeforeConversion =
+ std::numeric_limits<int64_t>::max() / 8000000;
+ RTC_DCHECK_LE(size.bytes(), kMaxBeforeConversion)
+ << "size is too large to be expressed in microbits";
+ return size.bytes() * 8000000;
+}
+
+inline constexpr int64_t MillibytePerSec(const DataRate& size) {
+ constexpr int64_t kMaxBeforeConversion =
+ std::numeric_limits<int64_t>::max() / (1000 / 8);
+ RTC_DCHECK_LE(size.bps(), kMaxBeforeConversion)
+ << "rate is too large to be expressed in microbytes per second";
+ return size.bps() * (1000 / 8);
+}
+} // namespace data_rate_impl
+
+inline constexpr DataRate operator/(const DataSize size,
+ const TimeDelta duration) {
+ return DataRate::BitsPerSec(data_rate_impl::Microbits(size) / duration.us());
+}
+inline constexpr TimeDelta operator/(const DataSize size, const DataRate rate) {
+ return TimeDelta::Micros(data_rate_impl::Microbits(size) / rate.bps());
+}
+inline constexpr DataSize operator*(const DataRate rate,
+ const TimeDelta duration) {
+ int64_t microbits = rate.bps() * duration.us();
+ return DataSize::Bytes((microbits + 4000000) / 8000000);
+}
+inline constexpr DataSize operator*(const TimeDelta duration,
+ const DataRate rate) {
+ return rate * duration;
+}
+
+inline constexpr DataSize operator/(const DataRate rate,
+ const Frequency frequency) {
+ int64_t millihertz = frequency.millihertz<int64_t>();
+ // Note that the value is truncated here reather than rounded, potentially
+ // introducing an error of .5 bytes if rounding were expected.
+ return DataSize::Bytes(data_rate_impl::MillibytePerSec(rate) / millihertz);
+}
+inline constexpr Frequency operator/(const DataRate rate, const DataSize size) {
+ return Frequency::MilliHertz(data_rate_impl::MillibytePerSec(rate) /
+ size.bytes());
+}
+inline constexpr DataRate operator*(const DataSize size,
+ const Frequency frequency) {
+ RTC_DCHECK(frequency.IsZero() ||
+ size.bytes() <= std::numeric_limits<int64_t>::max() / 8 /
+ frequency.millihertz<int64_t>());
+ int64_t millibits_per_second =
+ size.bytes() * 8 * frequency.millihertz<int64_t>();
+ return DataRate::BitsPerSec((millibits_per_second + 500) / 1000);
+}
+inline constexpr DataRate operator*(const Frequency frequency,
+ const DataSize size) {
+ return size * frequency;
+}
+
+std::string ToString(DataRate value);
+inline std::string ToLogString(DataRate value) {
+ return ToString(value);
+}
+
+#ifdef WEBRTC_UNIT_TEST
+inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982)
+ std::ostream& stream, // no-presubmit-check TODO(webrtc:8982)
+ DataRate value) {
+ return stream << ToString(value);
+}
+#endif // WEBRTC_UNIT_TEST
+
+} // namespace webrtc
+
+#endif // API_UNITS_DATA_RATE_H_
diff --git a/third_party/libwebrtc/api/units/data_rate_gn/moz.build b/third_party/libwebrtc/api/units/data_rate_gn/moz.build
new file mode 100644
index 0000000000..de76b8e11c
--- /dev/null
+++ b/third_party/libwebrtc/api/units/data_rate_gn/moz.build
@@ -0,0 +1,221 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/units/data_rate.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("data_rate_gn")
diff --git a/third_party/libwebrtc/api/units/data_rate_unittest.cc b/third_party/libwebrtc/api/units/data_rate_unittest.cc
new file mode 100644
index 0000000000..f77b3702d4
--- /dev/null
+++ b/third_party/libwebrtc/api/units/data_rate_unittest.cc
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/units/data_rate.h"
+
+#include "rtc_base/logging.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace test {
+
+TEST(DataRateTest, CompilesWithChecksAndLogs) {
+ DataRate a = DataRate::KilobitsPerSec(300);
+ DataRate b = DataRate::KilobitsPerSec(210);
+ RTC_CHECK_GT(a, b);
+ RTC_LOG(LS_INFO) << a;
+}
+
+TEST(DataRateTest, ConstExpr) {
+ constexpr int64_t kValue = 12345;
+ constexpr DataRate kDataRateZero = DataRate::Zero();
+ constexpr DataRate kDataRateInf = DataRate::Infinity();
+ static_assert(kDataRateZero.IsZero(), "");
+ static_assert(kDataRateInf.IsInfinite(), "");
+ static_assert(kDataRateInf.bps_or(-1) == -1, "");
+ static_assert(kDataRateInf > kDataRateZero, "");
+
+ constexpr DataRate kDataRateBps = DataRate::BitsPerSec(kValue);
+ constexpr DataRate kDataRateKbps = DataRate::KilobitsPerSec(kValue);
+ static_assert(kDataRateBps.bps<double>() == kValue, "");
+ static_assert(kDataRateBps.bps_or(0) == kValue, "");
+ static_assert(kDataRateKbps.kbps_or(0) == kValue, "");
+}
+
+TEST(DataRateTest, GetBackSameValues) {
+ const int64_t kValue = 123 * 8;
+ EXPECT_EQ(DataRate::BitsPerSec(kValue).bps(), kValue);
+ EXPECT_EQ(DataRate::KilobitsPerSec(kValue).kbps(), kValue);
+}
+
+TEST(DataRateTest, GetDifferentPrefix) {
+ const int64_t kValue = 123 * 8000;
+ EXPECT_EQ(DataRate::BitsPerSec(kValue).kbps(), kValue / 1000);
+}
+
+TEST(DataRateTest, IdentityChecks) {
+ const int64_t kValue = 3000;
+ EXPECT_TRUE(DataRate::Zero().IsZero());
+ EXPECT_FALSE(DataRate::BitsPerSec(kValue).IsZero());
+
+ EXPECT_TRUE(DataRate::Infinity().IsInfinite());
+ EXPECT_FALSE(DataRate::Zero().IsInfinite());
+ EXPECT_FALSE(DataRate::BitsPerSec(kValue).IsInfinite());
+
+ EXPECT_FALSE(DataRate::Infinity().IsFinite());
+ EXPECT_TRUE(DataRate::BitsPerSec(kValue).IsFinite());
+ EXPECT_TRUE(DataRate::Zero().IsFinite());
+}
+
+TEST(DataRateTest, ComparisonOperators) {
+ const int64_t kSmall = 450;
+ const int64_t kLarge = 451;
+ const DataRate small = DataRate::BitsPerSec(kSmall);
+ const DataRate large = DataRate::BitsPerSec(kLarge);
+
+ EXPECT_EQ(DataRate::Zero(), DataRate::BitsPerSec(0));
+ EXPECT_EQ(DataRate::Infinity(), DataRate::Infinity());
+ EXPECT_EQ(small, small);
+ EXPECT_LE(small, small);
+ EXPECT_GE(small, small);
+ EXPECT_NE(small, large);
+ EXPECT_LE(small, large);
+ EXPECT_LT(small, large);
+ EXPECT_GE(large, small);
+ EXPECT_GT(large, small);
+ EXPECT_LT(DataRate::Zero(), small);
+ EXPECT_GT(DataRate::Infinity(), large);
+}
+
+TEST(DataRateTest, ConvertsToAndFromDouble) {
+ const int64_t kValue = 128;
+ const double kDoubleValue = static_cast<double>(kValue);
+ const double kDoubleKbps = kValue * 1e-3;
+ const double kFloatKbps = static_cast<float>(kDoubleKbps);
+
+ EXPECT_EQ(DataRate::BitsPerSec(kValue).bps<double>(), kDoubleValue);
+ EXPECT_EQ(DataRate::BitsPerSec(kValue).kbps<double>(), kDoubleKbps);
+ EXPECT_EQ(DataRate::BitsPerSec(kValue).kbps<float>(), kFloatKbps);
+ EXPECT_EQ(DataRate::BitsPerSec(kDoubleValue).bps(), kValue);
+ EXPECT_EQ(DataRate::KilobitsPerSec(kDoubleKbps).bps(), kValue);
+
+ const double kInfinity = std::numeric_limits<double>::infinity();
+ EXPECT_EQ(DataRate::Infinity().bps<double>(), kInfinity);
+ EXPECT_TRUE(DataRate::BitsPerSec(kInfinity).IsInfinite());
+ EXPECT_TRUE(DataRate::KilobitsPerSec(kInfinity).IsInfinite());
+}
+TEST(DataRateTest, Clamping) {
+ const DataRate upper = DataRate::KilobitsPerSec(800);
+ const DataRate lower = DataRate::KilobitsPerSec(100);
+ const DataRate under = DataRate::KilobitsPerSec(100);
+ const DataRate inside = DataRate::KilobitsPerSec(500);
+ const DataRate over = DataRate::KilobitsPerSec(1000);
+ EXPECT_EQ(under.Clamped(lower, upper), lower);
+ EXPECT_EQ(inside.Clamped(lower, upper), inside);
+ EXPECT_EQ(over.Clamped(lower, upper), upper);
+
+ DataRate mutable_rate = lower;
+ mutable_rate.Clamp(lower, upper);
+ EXPECT_EQ(mutable_rate, lower);
+ mutable_rate = inside;
+ mutable_rate.Clamp(lower, upper);
+ EXPECT_EQ(mutable_rate, inside);
+ mutable_rate = over;
+ mutable_rate.Clamp(lower, upper);
+ EXPECT_EQ(mutable_rate, upper);
+}
+
+TEST(DataRateTest, MathOperations) {
+ const int64_t kValueA = 450;
+ const int64_t kValueB = 267;
+ const DataRate rate_a = DataRate::BitsPerSec(kValueA);
+ const DataRate rate_b = DataRate::BitsPerSec(kValueB);
+ const int32_t kInt32Value = 123;
+ const double kFloatValue = 123.0;
+
+ EXPECT_EQ((rate_a + rate_b).bps(), kValueA + kValueB);
+ EXPECT_EQ((rate_a - rate_b).bps(), kValueA - kValueB);
+
+ EXPECT_EQ((rate_a * kValueB).bps(), kValueA * kValueB);
+ EXPECT_EQ((rate_a * kInt32Value).bps(), kValueA * kInt32Value);
+ EXPECT_EQ((rate_a * kFloatValue).bps(), kValueA * kFloatValue);
+
+ EXPECT_EQ(rate_a / rate_b, static_cast<double>(kValueA) / kValueB);
+
+ EXPECT_EQ((rate_a / 10).bps(), kValueA / 10);
+ EXPECT_NEAR((rate_a / 0.5).bps(), kValueA * 2, 1);
+
+ DataRate mutable_rate = DataRate::BitsPerSec(kValueA);
+ mutable_rate += rate_b;
+ EXPECT_EQ(mutable_rate.bps(), kValueA + kValueB);
+ mutable_rate -= rate_a;
+ EXPECT_EQ(mutable_rate.bps(), kValueB);
+}
+
+TEST(UnitConversionTest, DataRateAndDataSizeAndTimeDelta) {
+ const int64_t kSeconds = 5;
+ const int64_t kBitsPerSecond = 440;
+ const int64_t kBytes = 44000;
+ const TimeDelta delta_a = TimeDelta::Seconds(kSeconds);
+ const DataRate rate_b = DataRate::BitsPerSec(kBitsPerSecond);
+ const DataSize size_c = DataSize::Bytes(kBytes);
+ EXPECT_EQ((delta_a * rate_b).bytes(), kSeconds * kBitsPerSecond / 8);
+ EXPECT_EQ((rate_b * delta_a).bytes(), kSeconds * kBitsPerSecond / 8);
+ EXPECT_EQ((size_c / delta_a).bps(), kBytes * 8 / kSeconds);
+ EXPECT_EQ((size_c / rate_b).seconds(), kBytes * 8 / kBitsPerSecond);
+}
+
+TEST(UnitConversionTest, DataRateAndDataSizeAndFrequency) {
+ const int64_t kHertz = 30;
+ const int64_t kBitsPerSecond = 96000;
+ const int64_t kBytes = 1200;
+ const Frequency freq_a = Frequency::Hertz(kHertz);
+ const DataRate rate_b = DataRate::BitsPerSec(kBitsPerSecond);
+ const DataSize size_c = DataSize::Bytes(kBytes);
+ EXPECT_EQ((freq_a * size_c).bps(), kHertz * kBytes * 8);
+ EXPECT_EQ((size_c * freq_a).bps(), kHertz * kBytes * 8);
+ EXPECT_EQ((rate_b / size_c).hertz<int64_t>(), kBitsPerSecond / kBytes / 8);
+ EXPECT_EQ((rate_b / freq_a).bytes(), kBitsPerSecond / kHertz / 8);
+}
+
+TEST(UnitConversionDeathTest, DivisionFailsOnLargeSize) {
+ // Note that the failure is expected since the current implementation is
+ // implementated in a way that does not support division of large sizes. If
+ // the implementation is changed, this test can safely be removed.
+ const int64_t kJustSmallEnoughForDivision =
+ std::numeric_limits<int64_t>::max() / 8000000;
+ const DataSize large_size = DataSize::Bytes(kJustSmallEnoughForDivision);
+ const DataRate data_rate = DataRate::KilobitsPerSec(100);
+ const TimeDelta time_delta = TimeDelta::Millis(100);
+ EXPECT_TRUE((large_size / data_rate).IsFinite());
+ EXPECT_TRUE((large_size / time_delta).IsFinite());
+#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) && RTC_DCHECK_IS_ON
+ const int64_t kToolargeForDivision = kJustSmallEnoughForDivision + 1;
+ const DataSize too_large_size = DataSize::Bytes(kToolargeForDivision);
+ EXPECT_DEATH(too_large_size / data_rate, "");
+ EXPECT_DEATH(too_large_size / time_delta, "");
+#endif // GTEST_HAS_DEATH_TEST && !!defined(WEBRTC_ANDROID) && RTC_DCHECK_IS_ON
+}
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/units/data_size.cc b/third_party/libwebrtc/api/units/data_size.cc
new file mode 100644
index 0000000000..45487dfd83
--- /dev/null
+++ b/third_party/libwebrtc/api/units/data_size.cc
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/units/data_size.h"
+
+#include "api/array_view.h"
+#include "rtc_base/strings/string_builder.h"
+
+namespace webrtc {
+
+std::string ToString(DataSize value) {
+ char buf[64];
+ rtc::SimpleStringBuilder sb(buf);
+ if (value.IsPlusInfinity()) {
+ sb << "+inf bytes";
+ } else if (value.IsMinusInfinity()) {
+ sb << "-inf bytes";
+ } else {
+ sb << value.bytes() << " bytes";
+ }
+ return sb.str();
+}
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/units/data_size.h b/third_party/libwebrtc/api/units/data_size.h
new file mode 100644
index 0000000000..9df6434fb9
--- /dev/null
+++ b/third_party/libwebrtc/api/units/data_size.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_UNITS_DATA_SIZE_H_
+#define API_UNITS_DATA_SIZE_H_
+
+#ifdef WEBRTC_UNIT_TEST
+#include <ostream> // no-presubmit-check TODO(webrtc:8982)
+#endif // WEBRTC_UNIT_TEST
+
+#include <string>
+#include <type_traits>
+
+#include "rtc_base/units/unit_base.h" // IWYU pragma: export
+
+namespace webrtc {
+// DataSize is a class represeting a count of bytes.
+class DataSize final : public rtc_units_impl::RelativeUnit<DataSize> {
+ public:
+ template <typename T>
+ static constexpr DataSize Bytes(T value) {
+ static_assert(std::is_arithmetic<T>::value, "");
+ return FromValue(value);
+ }
+ static constexpr DataSize Infinity() { return PlusInfinity(); }
+
+ DataSize() = delete;
+
+ template <typename T = int64_t>
+ constexpr T bytes() const {
+ return ToValue<T>();
+ }
+
+ constexpr int64_t bytes_or(int64_t fallback_value) const {
+ return ToValueOr(fallback_value);
+ }
+
+ private:
+ friend class rtc_units_impl::UnitBase<DataSize>;
+ using RelativeUnit::RelativeUnit;
+ static constexpr bool one_sided = true;
+};
+
+std::string ToString(DataSize value);
+inline std::string ToLogString(DataSize value) {
+ return ToString(value);
+}
+
+#ifdef WEBRTC_UNIT_TEST
+inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982)
+ std::ostream& stream, // no-presubmit-check TODO(webrtc:8982)
+ DataSize value) {
+ return stream << ToString(value);
+}
+#endif // WEBRTC_UNIT_TEST
+
+} // namespace webrtc
+
+#endif // API_UNITS_DATA_SIZE_H_
diff --git a/third_party/libwebrtc/api/units/data_size_gn/moz.build b/third_party/libwebrtc/api/units/data_size_gn/moz.build
new file mode 100644
index 0000000000..dc54ce4f15
--- /dev/null
+++ b/third_party/libwebrtc/api/units/data_size_gn/moz.build
@@ -0,0 +1,221 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/units/data_size.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("data_size_gn")
diff --git a/third_party/libwebrtc/api/units/data_size_unittest.cc b/third_party/libwebrtc/api/units/data_size_unittest.cc
new file mode 100644
index 0000000000..eb8d98c1f0
--- /dev/null
+++ b/third_party/libwebrtc/api/units/data_size_unittest.cc
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/units/data_size.h"
+
+#include <limits>
+
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace test {
+
+TEST(DataSizeTest, ConstExpr) {
+ constexpr int64_t kValue = 12345;
+ constexpr DataSize kDataSizeZero = DataSize::Zero();
+ constexpr DataSize kDataSizeInf = DataSize::Infinity();
+ static_assert(kDataSizeZero.IsZero(), "");
+ static_assert(kDataSizeInf.IsInfinite(), "");
+ static_assert(kDataSizeInf.bytes_or(-1) == -1, "");
+ static_assert(kDataSizeInf > kDataSizeZero, "");
+
+ constexpr DataSize kDataSize = DataSize::Bytes(kValue);
+ static_assert(kDataSize.bytes_or(-1) == kValue, "");
+
+ EXPECT_EQ(kDataSize.bytes(), kValue);
+}
+
+TEST(DataSizeTest, GetBackSameValues) {
+ const int64_t kValue = 123 * 8;
+ EXPECT_EQ(DataSize::Bytes(kValue).bytes(), kValue);
+}
+
+TEST(DataSizeTest, IdentityChecks) {
+ const int64_t kValue = 3000;
+ EXPECT_TRUE(DataSize::Zero().IsZero());
+ EXPECT_FALSE(DataSize::Bytes(kValue).IsZero());
+
+ EXPECT_TRUE(DataSize::Infinity().IsInfinite());
+ EXPECT_FALSE(DataSize::Zero().IsInfinite());
+ EXPECT_FALSE(DataSize::Bytes(kValue).IsInfinite());
+
+ EXPECT_FALSE(DataSize::Infinity().IsFinite());
+ EXPECT_TRUE(DataSize::Bytes(kValue).IsFinite());
+ EXPECT_TRUE(DataSize::Zero().IsFinite());
+}
+
+TEST(DataSizeTest, ComparisonOperators) {
+ const int64_t kSmall = 450;
+ const int64_t kLarge = 451;
+ const DataSize small = DataSize::Bytes(kSmall);
+ const DataSize large = DataSize::Bytes(kLarge);
+
+ EXPECT_EQ(DataSize::Zero(), DataSize::Bytes(0));
+ EXPECT_EQ(DataSize::Infinity(), DataSize::Infinity());
+ EXPECT_EQ(small, small);
+ EXPECT_LE(small, small);
+ EXPECT_GE(small, small);
+ EXPECT_NE(small, large);
+ EXPECT_LE(small, large);
+ EXPECT_LT(small, large);
+ EXPECT_GE(large, small);
+ EXPECT_GT(large, small);
+ EXPECT_LT(DataSize::Zero(), small);
+ EXPECT_GT(DataSize::Infinity(), large);
+}
+
+TEST(DataSizeTest, ConvertsToAndFromDouble) {
+ const int64_t kValue = 128;
+ const double kDoubleValue = static_cast<double>(kValue);
+
+ EXPECT_EQ(DataSize::Bytes(kValue).bytes<double>(), kDoubleValue);
+ EXPECT_EQ(DataSize::Bytes(kDoubleValue).bytes(), kValue);
+
+ const double kInfinity = std::numeric_limits<double>::infinity();
+ EXPECT_EQ(DataSize::Infinity().bytes<double>(), kInfinity);
+ EXPECT_TRUE(DataSize::Bytes(kInfinity).IsInfinite());
+}
+
+TEST(DataSizeTest, MathOperations) {
+ const int64_t kValueA = 450;
+ const int64_t kValueB = 267;
+ const DataSize size_a = DataSize::Bytes(kValueA);
+ const DataSize size_b = DataSize::Bytes(kValueB);
+ EXPECT_EQ((size_a + size_b).bytes(), kValueA + kValueB);
+ EXPECT_EQ((size_a - size_b).bytes(), kValueA - kValueB);
+
+ const int32_t kInt32Value = 123;
+ const double kFloatValue = 123.0;
+ EXPECT_EQ((size_a * kValueB).bytes(), kValueA * kValueB);
+ EXPECT_EQ((size_a * kInt32Value).bytes(), kValueA * kInt32Value);
+ EXPECT_EQ((size_a * kFloatValue).bytes(), kValueA * kFloatValue);
+
+ EXPECT_EQ((size_a / 10).bytes(), kValueA / 10);
+ EXPECT_EQ(size_a / size_b, static_cast<double>(kValueA) / kValueB);
+
+ DataSize mutable_size = DataSize::Bytes(kValueA);
+ mutable_size += size_b;
+ EXPECT_EQ(mutable_size.bytes(), kValueA + kValueB);
+ mutable_size -= size_a;
+ EXPECT_EQ(mutable_size.bytes(), kValueB);
+}
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/units/frequency.cc b/third_party/libwebrtc/api/units/frequency.cc
new file mode 100644
index 0000000000..2d938a2814
--- /dev/null
+++ b/third_party/libwebrtc/api/units/frequency.cc
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/units/frequency.h"
+
+#include "rtc_base/strings/string_builder.h"
+
+namespace webrtc {
+std::string ToString(Frequency value) {
+ char buf[64];
+ rtc::SimpleStringBuilder sb(buf);
+ if (value.IsPlusInfinity()) {
+ sb << "+inf Hz";
+ } else if (value.IsMinusInfinity()) {
+ sb << "-inf Hz";
+ } else if (value.millihertz<int64_t>() % 1000 != 0) {
+ sb.AppendFormat("%.3f Hz", value.hertz<double>());
+ } else {
+ sb << value.hertz<int64_t>() << " Hz";
+ }
+ return sb.str();
+}
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/units/frequency.h b/third_party/libwebrtc/api/units/frequency.h
new file mode 100644
index 0000000000..06081e4c0d
--- /dev/null
+++ b/third_party/libwebrtc/api/units/frequency.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_UNITS_FREQUENCY_H_
+#define API_UNITS_FREQUENCY_H_
+
+#ifdef WEBRTC_UNIT_TEST
+#include <ostream> // no-presubmit-check TODO(webrtc:8982)
+#endif // WEBRTC_UNIT_TEST
+
+#include <cstdlib>
+#include <limits>
+#include <string>
+#include <type_traits>
+
+#include "api/units/time_delta.h"
+#include "rtc_base/units/unit_base.h" // IWYU pragma: export
+
+namespace webrtc {
+
+class Frequency final : public rtc_units_impl::RelativeUnit<Frequency> {
+ public:
+ template <typename T>
+ static constexpr Frequency MilliHertz(T value) {
+ static_assert(std::is_arithmetic<T>::value, "");
+ return FromValue(value);
+ }
+ template <typename T>
+ static constexpr Frequency Hertz(T value) {
+ static_assert(std::is_arithmetic<T>::value, "");
+ return FromFraction(1'000, value);
+ }
+ template <typename T>
+ static constexpr Frequency KiloHertz(T value) {
+ static_assert(std::is_arithmetic<T>::value, "");
+ return FromFraction(1'000'000, value);
+ }
+
+ Frequency() = delete;
+
+ template <typename T = int64_t>
+ constexpr T hertz() const {
+ return ToFraction<1000, T>();
+ }
+ template <typename T = int64_t>
+ constexpr T millihertz() const {
+ return ToValue<T>();
+ }
+
+ private:
+ friend class rtc_units_impl::UnitBase<Frequency>;
+ using RelativeUnit::RelativeUnit;
+ static constexpr bool one_sided = true;
+};
+
+inline constexpr Frequency operator/(int64_t nominator,
+ const TimeDelta& interval) {
+ constexpr int64_t kKiloPerMicro = 1000 * 1000000;
+ RTC_DCHECK_LE(nominator, std::numeric_limits<int64_t>::max() / kKiloPerMicro);
+ RTC_CHECK(interval.IsFinite());
+ RTC_CHECK(!interval.IsZero());
+ return Frequency::MilliHertz(nominator * kKiloPerMicro / interval.us());
+}
+
+inline constexpr TimeDelta operator/(int64_t nominator,
+ const Frequency& frequency) {
+ constexpr int64_t kMegaPerMilli = 1000000 * 1000;
+ RTC_DCHECK_LE(nominator, std::numeric_limits<int64_t>::max() / kMegaPerMilli);
+ RTC_CHECK(frequency.IsFinite());
+ RTC_CHECK(!frequency.IsZero());
+ return TimeDelta::Micros(nominator * kMegaPerMilli / frequency.millihertz());
+}
+
+inline constexpr double operator*(Frequency frequency, TimeDelta time_delta) {
+ return frequency.hertz<double>() * time_delta.seconds<double>();
+}
+inline constexpr double operator*(TimeDelta time_delta, Frequency frequency) {
+ return frequency * time_delta;
+}
+
+std::string ToString(Frequency value);
+inline std::string ToLogString(Frequency value) {
+ return ToString(value);
+}
+
+#ifdef WEBRTC_UNIT_TEST
+inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982)
+ std::ostream& stream, // no-presubmit-check TODO(webrtc:8982)
+ Frequency value) {
+ return stream << ToString(value);
+}
+#endif // WEBRTC_UNIT_TEST
+
+} // namespace webrtc
+#endif // API_UNITS_FREQUENCY_H_
diff --git a/third_party/libwebrtc/api/units/frequency_gn/moz.build b/third_party/libwebrtc/api/units/frequency_gn/moz.build
new file mode 100644
index 0000000000..3c84c283b8
--- /dev/null
+++ b/third_party/libwebrtc/api/units/frequency_gn/moz.build
@@ -0,0 +1,221 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/units/frequency.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("frequency_gn")
diff --git a/third_party/libwebrtc/api/units/frequency_unittest.cc b/third_party/libwebrtc/api/units/frequency_unittest.cc
new file mode 100644
index 0000000000..1260c2107d
--- /dev/null
+++ b/third_party/libwebrtc/api/units/frequency_unittest.cc
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/units/frequency.h"
+
+#include <limits>
+
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace test {
+TEST(FrequencyTest, ConstExpr) {
+ constexpr Frequency kFrequencyZero = Frequency::Zero();
+ constexpr Frequency kFrequencyPlusInf = Frequency::PlusInfinity();
+ constexpr Frequency kFrequencyMinusInf = Frequency::MinusInfinity();
+ static_assert(kFrequencyZero.IsZero(), "");
+ static_assert(kFrequencyPlusInf.IsPlusInfinity(), "");
+ static_assert(kFrequencyMinusInf.IsMinusInfinity(), "");
+
+ static_assert(kFrequencyPlusInf > kFrequencyZero, "");
+}
+
+TEST(FrequencyTest, GetBackSameValues) {
+ const int64_t kValue = 31;
+ EXPECT_EQ(Frequency::Hertz(kValue).hertz<int64_t>(), kValue);
+ EXPECT_EQ(Frequency::Zero().hertz<int64_t>(), 0);
+}
+
+TEST(FrequencyTest, GetDifferentPrefix) {
+ const int64_t kValue = 30000;
+ EXPECT_EQ(Frequency::MilliHertz(kValue).hertz<int64_t>(), kValue / 1000);
+ EXPECT_EQ(Frequency::Hertz(kValue).millihertz(), kValue * 1000);
+ EXPECT_EQ(Frequency::KiloHertz(kValue).hertz(), kValue * 1000);
+}
+
+TEST(FrequencyTest, IdentityChecks) {
+ const int64_t kValue = 31;
+ EXPECT_TRUE(Frequency::Zero().IsZero());
+ EXPECT_FALSE(Frequency::Hertz(kValue).IsZero());
+
+ EXPECT_TRUE(Frequency::PlusInfinity().IsInfinite());
+ EXPECT_TRUE(Frequency::MinusInfinity().IsInfinite());
+ EXPECT_FALSE(Frequency::Zero().IsInfinite());
+ EXPECT_FALSE(Frequency::Hertz(kValue).IsInfinite());
+
+ EXPECT_FALSE(Frequency::PlusInfinity().IsFinite());
+ EXPECT_FALSE(Frequency::MinusInfinity().IsFinite());
+ EXPECT_TRUE(Frequency::Hertz(kValue).IsFinite());
+ EXPECT_TRUE(Frequency::Zero().IsFinite());
+
+ EXPECT_TRUE(Frequency::PlusInfinity().IsPlusInfinity());
+ EXPECT_FALSE(Frequency::MinusInfinity().IsPlusInfinity());
+
+ EXPECT_TRUE(Frequency::MinusInfinity().IsMinusInfinity());
+ EXPECT_FALSE(Frequency::PlusInfinity().IsMinusInfinity());
+}
+
+TEST(FrequencyTest, ComparisonOperators) {
+ const int64_t kSmall = 42;
+ const int64_t kLarge = 45;
+ const Frequency small = Frequency::Hertz(kSmall);
+ const Frequency large = Frequency::Hertz(kLarge);
+
+ EXPECT_EQ(Frequency::Zero(), Frequency::Hertz(0));
+ EXPECT_EQ(Frequency::PlusInfinity(), Frequency::PlusInfinity());
+ EXPECT_EQ(small, Frequency::Hertz(kSmall));
+ EXPECT_LE(small, Frequency::Hertz(kSmall));
+ EXPECT_GE(small, Frequency::Hertz(kSmall));
+ EXPECT_NE(small, Frequency::Hertz(kLarge));
+ EXPECT_LE(small, Frequency::Hertz(kLarge));
+ EXPECT_LT(small, Frequency::Hertz(kLarge));
+ EXPECT_GE(large, Frequency::Hertz(kSmall));
+ EXPECT_GT(large, Frequency::Hertz(kSmall));
+ EXPECT_LT(Frequency::Zero(), small);
+
+ EXPECT_GT(Frequency::PlusInfinity(), large);
+ EXPECT_LT(Frequency::MinusInfinity(), Frequency::Zero());
+}
+
+TEST(FrequencyTest, Clamping) {
+ const Frequency upper = Frequency::Hertz(800);
+ const Frequency lower = Frequency::Hertz(100);
+ const Frequency under = Frequency::Hertz(100);
+ const Frequency inside = Frequency::Hertz(500);
+ const Frequency over = Frequency::Hertz(1000);
+ EXPECT_EQ(under.Clamped(lower, upper), lower);
+ EXPECT_EQ(inside.Clamped(lower, upper), inside);
+ EXPECT_EQ(over.Clamped(lower, upper), upper);
+
+ Frequency mutable_frequency = lower;
+ mutable_frequency.Clamp(lower, upper);
+ EXPECT_EQ(mutable_frequency, lower);
+ mutable_frequency = inside;
+ mutable_frequency.Clamp(lower, upper);
+ EXPECT_EQ(mutable_frequency, inside);
+ mutable_frequency = over;
+ mutable_frequency.Clamp(lower, upper);
+ EXPECT_EQ(mutable_frequency, upper);
+}
+
+TEST(FrequencyTest, MathOperations) {
+ const int64_t kValueA = 457;
+ const int64_t kValueB = 260;
+ const Frequency frequency_a = Frequency::Hertz(kValueA);
+ const Frequency frequency_b = Frequency::Hertz(kValueB);
+ EXPECT_EQ((frequency_a + frequency_b).hertz<int64_t>(), kValueA + kValueB);
+ EXPECT_EQ((frequency_a - frequency_b).hertz<int64_t>(), kValueA - kValueB);
+
+ EXPECT_EQ((Frequency::Hertz(kValueA) * kValueB).hertz<int64_t>(),
+ kValueA * kValueB);
+
+ EXPECT_EQ((frequency_b / 10).hertz<int64_t>(), kValueB / 10);
+ EXPECT_EQ(frequency_b / frequency_a, static_cast<double>(kValueB) / kValueA);
+
+ Frequency mutable_frequency = Frequency::Hertz(kValueA);
+ mutable_frequency += Frequency::Hertz(kValueB);
+ EXPECT_EQ(mutable_frequency, Frequency::Hertz(kValueA + kValueB));
+ mutable_frequency -= Frequency::Hertz(kValueB);
+ EXPECT_EQ(mutable_frequency, Frequency::Hertz(kValueA));
+}
+TEST(FrequencyTest, Rounding) {
+ const Frequency freq_high = Frequency::Hertz(23.976);
+ EXPECT_EQ(freq_high.hertz(), 24);
+ EXPECT_EQ(freq_high.RoundDownTo(Frequency::Hertz(1)), Frequency::Hertz(23));
+ EXPECT_EQ(freq_high.RoundTo(Frequency::Hertz(1)), Frequency::Hertz(24));
+ EXPECT_EQ(freq_high.RoundUpTo(Frequency::Hertz(1)), Frequency::Hertz(24));
+
+ const Frequency freq_low = Frequency::Hertz(23.4);
+ EXPECT_EQ(freq_low.hertz(), 23);
+ EXPECT_EQ(freq_low.RoundDownTo(Frequency::Hertz(1)), Frequency::Hertz(23));
+ EXPECT_EQ(freq_low.RoundTo(Frequency::Hertz(1)), Frequency::Hertz(23));
+ EXPECT_EQ(freq_low.RoundUpTo(Frequency::Hertz(1)), Frequency::Hertz(24));
+}
+
+TEST(FrequencyTest, InfinityOperations) {
+ const double kValue = 267;
+ const Frequency finite = Frequency::Hertz(kValue);
+ EXPECT_TRUE((Frequency::PlusInfinity() + finite).IsPlusInfinity());
+ EXPECT_TRUE((Frequency::PlusInfinity() - finite).IsPlusInfinity());
+ EXPECT_TRUE((finite + Frequency::PlusInfinity()).IsPlusInfinity());
+ EXPECT_TRUE((finite - Frequency::MinusInfinity()).IsPlusInfinity());
+
+ EXPECT_TRUE((Frequency::MinusInfinity() + finite).IsMinusInfinity());
+ EXPECT_TRUE((Frequency::MinusInfinity() - finite).IsMinusInfinity());
+ EXPECT_TRUE((finite + Frequency::MinusInfinity()).IsMinusInfinity());
+ EXPECT_TRUE((finite - Frequency::PlusInfinity()).IsMinusInfinity());
+}
+
+TEST(UnitConversionTest, TimeDeltaAndFrequency) {
+ EXPECT_EQ(1 / Frequency::Hertz(50), TimeDelta::Millis(20));
+ EXPECT_EQ(1 / TimeDelta::Millis(20), Frequency::Hertz(50));
+ EXPECT_EQ(Frequency::KiloHertz(200) * TimeDelta::Millis(2), 400.0);
+}
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/units/time_delta.cc b/third_party/libwebrtc/api/units/time_delta.cc
new file mode 100644
index 0000000000..31bf3e0106
--- /dev/null
+++ b/third_party/libwebrtc/api/units/time_delta.cc
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/units/time_delta.h"
+
+#include "api/array_view.h"
+#include "rtc_base/strings/string_builder.h"
+
+namespace webrtc {
+
+std::string ToString(TimeDelta value) {
+ char buf[64];
+ rtc::SimpleStringBuilder sb(buf);
+ if (value.IsPlusInfinity()) {
+ sb << "+inf ms";
+ } else if (value.IsMinusInfinity()) {
+ sb << "-inf ms";
+ } else {
+ if (value.us() == 0 || (value.us() % 1000) != 0)
+ sb << value.us() << " us";
+ else if (value.ms() % 1000 != 0)
+ sb << value.ms() << " ms";
+ else
+ sb << value.seconds() << " s";
+ }
+ return sb.str();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/units/time_delta.h b/third_party/libwebrtc/api/units/time_delta.h
new file mode 100644
index 0000000000..5981e32dce
--- /dev/null
+++ b/third_party/libwebrtc/api/units/time_delta.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_UNITS_TIME_DELTA_H_
+#define API_UNITS_TIME_DELTA_H_
+
+#ifdef WEBRTC_UNIT_TEST
+#include <ostream> // no-presubmit-check TODO(webrtc:8982)
+#endif // WEBRTC_UNIT_TEST
+
+#include <cstdlib>
+#include <string>
+#include <type_traits>
+
+#include "rtc_base/units/unit_base.h" // IWYU pragma: export
+
+namespace webrtc {
+
+// TimeDelta represents the difference between two timestamps. Commonly this can
+// be a duration. However since two Timestamps are not guaranteed to have the
+// same epoch (they might come from different computers, making exact
+// synchronisation infeasible), the duration covered by a TimeDelta can be
+// undefined. To simplify usage, it can be constructed and converted to
+// different units, specifically seconds (s), milliseconds (ms) and
+// microseconds (us).
+class TimeDelta final : public rtc_units_impl::RelativeUnit<TimeDelta> {
+ public:
+ template <typename T>
+ static constexpr TimeDelta Minutes(T value) {
+ static_assert(std::is_arithmetic<T>::value, "");
+ return Seconds(value * 60);
+ }
+ template <typename T>
+ static constexpr TimeDelta Seconds(T value) {
+ static_assert(std::is_arithmetic<T>::value, "");
+ return FromFraction(1'000'000, value);
+ }
+ template <typename T>
+ static constexpr TimeDelta Millis(T value) {
+ static_assert(std::is_arithmetic<T>::value, "");
+ return FromFraction(1'000, value);
+ }
+ template <typename T>
+ static constexpr TimeDelta Micros(T value) {
+ static_assert(std::is_arithmetic<T>::value, "");
+ return FromValue(value);
+ }
+
+ TimeDelta() = delete;
+
+ template <typename T = int64_t>
+ constexpr T seconds() const {
+ return ToFraction<1000000, T>();
+ }
+ template <typename T = int64_t>
+ constexpr T ms() const {
+ return ToFraction<1000, T>();
+ }
+ template <typename T = int64_t>
+ constexpr T us() const {
+ return ToValue<T>();
+ }
+ template <typename T = int64_t>
+ constexpr T ns() const {
+ return ToMultiple<1000, T>();
+ }
+
+ constexpr int64_t seconds_or(int64_t fallback_value) const {
+ return ToFractionOr<1000000>(fallback_value);
+ }
+ constexpr int64_t ms_or(int64_t fallback_value) const {
+ return ToFractionOr<1000>(fallback_value);
+ }
+ constexpr int64_t us_or(int64_t fallback_value) const {
+ return ToValueOr(fallback_value);
+ }
+
+ constexpr TimeDelta Abs() const {
+ return us() < 0 ? TimeDelta::Micros(-us()) : *this;
+ }
+
+ private:
+ friend class rtc_units_impl::UnitBase<TimeDelta>;
+ using RelativeUnit::RelativeUnit;
+ static constexpr bool one_sided = false;
+};
+
+std::string ToString(TimeDelta value);
+inline std::string ToLogString(TimeDelta value) {
+ return ToString(value);
+}
+
+#ifdef WEBRTC_UNIT_TEST
+inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982)
+ std::ostream& stream, // no-presubmit-check TODO(webrtc:8982)
+ TimeDelta value) {
+ return stream << ToString(value);
+}
+#endif // WEBRTC_UNIT_TEST
+
+} // namespace webrtc
+
+#endif // API_UNITS_TIME_DELTA_H_
diff --git a/third_party/libwebrtc/api/units/time_delta_gn/moz.build b/third_party/libwebrtc/api/units/time_delta_gn/moz.build
new file mode 100644
index 0000000000..3fe57620d8
--- /dev/null
+++ b/third_party/libwebrtc/api/units/time_delta_gn/moz.build
@@ -0,0 +1,221 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/units/time_delta.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("time_delta_gn")
diff --git a/third_party/libwebrtc/api/units/time_delta_unittest.cc b/third_party/libwebrtc/api/units/time_delta_unittest.cc
new file mode 100644
index 0000000000..51a7aa233a
--- /dev/null
+++ b/third_party/libwebrtc/api/units/time_delta_unittest.cc
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/units/time_delta.h"
+
+#include <limits>
+
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace test {
+TEST(TimeDeltaTest, ConstExpr) {
+ constexpr int64_t kValue = -12345;
+ constexpr TimeDelta kTimeDeltaZero = TimeDelta::Zero();
+ constexpr TimeDelta kTimeDeltaPlusInf = TimeDelta::PlusInfinity();
+ constexpr TimeDelta kTimeDeltaMinusInf = TimeDelta::MinusInfinity();
+ static_assert(kTimeDeltaZero.IsZero(), "");
+ static_assert(kTimeDeltaPlusInf.IsPlusInfinity(), "");
+ static_assert(kTimeDeltaMinusInf.IsMinusInfinity(), "");
+ static_assert(kTimeDeltaPlusInf.ms_or(-1) == -1, "");
+
+ static_assert(kTimeDeltaPlusInf > kTimeDeltaZero, "");
+
+ constexpr TimeDelta kTimeDeltaMinutes = TimeDelta::Minutes(kValue);
+ constexpr TimeDelta kTimeDeltaSeconds = TimeDelta::Seconds(kValue);
+ constexpr TimeDelta kTimeDeltaMs = TimeDelta::Millis(kValue);
+ constexpr TimeDelta kTimeDeltaUs = TimeDelta::Micros(kValue);
+
+ static_assert(kTimeDeltaMinutes.seconds_or(0) == kValue * 60, "");
+ static_assert(kTimeDeltaSeconds.seconds_or(0) == kValue, "");
+ static_assert(kTimeDeltaMs.ms_or(0) == kValue, "");
+ static_assert(kTimeDeltaUs.us_or(0) == kValue, "");
+}
+
+TEST(TimeDeltaTest, GetBackSameValues) {
+ const int64_t kValue = 499;
+ for (int sign = -1; sign <= 1; ++sign) {
+ int64_t value = kValue * sign;
+ EXPECT_EQ(TimeDelta::Millis(value).ms(), value);
+ EXPECT_EQ(TimeDelta::Micros(value).us(), value);
+ EXPECT_EQ(TimeDelta::Seconds(value).seconds(), value);
+ EXPECT_EQ(TimeDelta::Seconds(value).seconds(), value);
+ }
+ EXPECT_EQ(TimeDelta::Zero().us(), 0);
+}
+
+TEST(TimeDeltaTest, GetDifferentPrefix) {
+ const int64_t kValue = 3000000;
+ EXPECT_EQ(TimeDelta::Micros(kValue).seconds(), kValue / 1000000);
+ EXPECT_EQ(TimeDelta::Millis(kValue).seconds(), kValue / 1000);
+ EXPECT_EQ(TimeDelta::Micros(kValue).ms(), kValue / 1000);
+ EXPECT_EQ(TimeDelta::Minutes(kValue / 60).seconds(), kValue);
+
+ EXPECT_EQ(TimeDelta::Millis(kValue).us(), kValue * 1000);
+ EXPECT_EQ(TimeDelta::Seconds(kValue).ms(), kValue * 1000);
+ EXPECT_EQ(TimeDelta::Seconds(kValue).us(), kValue * 1000000);
+ EXPECT_EQ(TimeDelta::Minutes(kValue / 60).seconds(), kValue);
+}
+
+TEST(TimeDeltaTest, IdentityChecks) {
+ const int64_t kValue = 3000;
+ EXPECT_TRUE(TimeDelta::Zero().IsZero());
+ EXPECT_FALSE(TimeDelta::Millis(kValue).IsZero());
+
+ EXPECT_TRUE(TimeDelta::PlusInfinity().IsInfinite());
+ EXPECT_TRUE(TimeDelta::MinusInfinity().IsInfinite());
+ EXPECT_FALSE(TimeDelta::Zero().IsInfinite());
+ EXPECT_FALSE(TimeDelta::Millis(-kValue).IsInfinite());
+ EXPECT_FALSE(TimeDelta::Millis(kValue).IsInfinite());
+
+ EXPECT_FALSE(TimeDelta::PlusInfinity().IsFinite());
+ EXPECT_FALSE(TimeDelta::MinusInfinity().IsFinite());
+ EXPECT_TRUE(TimeDelta::Millis(-kValue).IsFinite());
+ EXPECT_TRUE(TimeDelta::Millis(kValue).IsFinite());
+ EXPECT_TRUE(TimeDelta::Zero().IsFinite());
+
+ EXPECT_TRUE(TimeDelta::PlusInfinity().IsPlusInfinity());
+ EXPECT_FALSE(TimeDelta::MinusInfinity().IsPlusInfinity());
+
+ EXPECT_TRUE(TimeDelta::MinusInfinity().IsMinusInfinity());
+ EXPECT_FALSE(TimeDelta::PlusInfinity().IsMinusInfinity());
+}
+
+TEST(TimeDeltaTest, ComparisonOperators) {
+ const int64_t kSmall = 450;
+ const int64_t kLarge = 451;
+ const TimeDelta small = TimeDelta::Millis(kSmall);
+ const TimeDelta large = TimeDelta::Millis(kLarge);
+
+ EXPECT_EQ(TimeDelta::Zero(), TimeDelta::Millis(0));
+ EXPECT_EQ(TimeDelta::PlusInfinity(), TimeDelta::PlusInfinity());
+ EXPECT_EQ(small, TimeDelta::Millis(kSmall));
+ EXPECT_LE(small, TimeDelta::Millis(kSmall));
+ EXPECT_GE(small, TimeDelta::Millis(kSmall));
+ EXPECT_NE(small, TimeDelta::Millis(kLarge));
+ EXPECT_LE(small, TimeDelta::Millis(kLarge));
+ EXPECT_LT(small, TimeDelta::Millis(kLarge));
+ EXPECT_GE(large, TimeDelta::Millis(kSmall));
+ EXPECT_GT(large, TimeDelta::Millis(kSmall));
+ EXPECT_LT(TimeDelta::Zero(), small);
+ EXPECT_GT(TimeDelta::Zero(), TimeDelta::Millis(-kSmall));
+ EXPECT_GT(TimeDelta::Zero(), TimeDelta::Millis(-kSmall));
+
+ EXPECT_GT(TimeDelta::PlusInfinity(), large);
+ EXPECT_LT(TimeDelta::MinusInfinity(), TimeDelta::Zero());
+}
+
+TEST(TimeDeltaTest, Clamping) {
+ const TimeDelta upper = TimeDelta::Millis(800);
+ const TimeDelta lower = TimeDelta::Millis(100);
+ const TimeDelta under = TimeDelta::Millis(100);
+ const TimeDelta inside = TimeDelta::Millis(500);
+ const TimeDelta over = TimeDelta::Millis(1000);
+ EXPECT_EQ(under.Clamped(lower, upper), lower);
+ EXPECT_EQ(inside.Clamped(lower, upper), inside);
+ EXPECT_EQ(over.Clamped(lower, upper), upper);
+
+ TimeDelta mutable_delta = lower;
+ mutable_delta.Clamp(lower, upper);
+ EXPECT_EQ(mutable_delta, lower);
+ mutable_delta = inside;
+ mutable_delta.Clamp(lower, upper);
+ EXPECT_EQ(mutable_delta, inside);
+ mutable_delta = over;
+ mutable_delta.Clamp(lower, upper);
+ EXPECT_EQ(mutable_delta, upper);
+}
+
+TEST(TimeDeltaTest, CanBeInititializedFromLargeInt) {
+ const int kMaxInt = std::numeric_limits<int>::max();
+ EXPECT_EQ(TimeDelta::Seconds(kMaxInt).us(),
+ static_cast<int64_t>(kMaxInt) * 1000000);
+ EXPECT_EQ(TimeDelta::Millis(kMaxInt).us(),
+ static_cast<int64_t>(kMaxInt) * 1000);
+}
+
+TEST(TimeDeltaTest, ConvertsToAndFromDouble) {
+ const int64_t kMicros = 17017;
+ const double kNanosDouble = kMicros * 1e3;
+ const double kMicrosDouble = kMicros;
+ const double kMillisDouble = kMicros * 1e-3;
+ const double kSecondsDouble = kMillisDouble * 1e-3;
+
+ EXPECT_EQ(TimeDelta::Micros(kMicros).seconds<double>(), kSecondsDouble);
+ EXPECT_EQ(TimeDelta::Seconds(kSecondsDouble).us(), kMicros);
+
+ EXPECT_EQ(TimeDelta::Micros(kMicros).ms<double>(), kMillisDouble);
+ EXPECT_EQ(TimeDelta::Millis(kMillisDouble).us(), kMicros);
+
+ EXPECT_EQ(TimeDelta::Micros(kMicros).us<double>(), kMicrosDouble);
+ EXPECT_EQ(TimeDelta::Micros(kMicrosDouble).us(), kMicros);
+
+ EXPECT_NEAR(TimeDelta::Micros(kMicros).ns<double>(), kNanosDouble, 1);
+
+ const double kPlusInfinity = std::numeric_limits<double>::infinity();
+ const double kMinusInfinity = -kPlusInfinity;
+
+ EXPECT_EQ(TimeDelta::PlusInfinity().seconds<double>(), kPlusInfinity);
+ EXPECT_EQ(TimeDelta::MinusInfinity().seconds<double>(), kMinusInfinity);
+ EXPECT_EQ(TimeDelta::PlusInfinity().ms<double>(), kPlusInfinity);
+ EXPECT_EQ(TimeDelta::MinusInfinity().ms<double>(), kMinusInfinity);
+ EXPECT_EQ(TimeDelta::PlusInfinity().us<double>(), kPlusInfinity);
+ EXPECT_EQ(TimeDelta::MinusInfinity().us<double>(), kMinusInfinity);
+ EXPECT_EQ(TimeDelta::PlusInfinity().ns<double>(), kPlusInfinity);
+ EXPECT_EQ(TimeDelta::MinusInfinity().ns<double>(), kMinusInfinity);
+
+ EXPECT_TRUE(TimeDelta::Seconds(kPlusInfinity).IsPlusInfinity());
+ EXPECT_TRUE(TimeDelta::Seconds(kMinusInfinity).IsMinusInfinity());
+ EXPECT_TRUE(TimeDelta::Millis(kPlusInfinity).IsPlusInfinity());
+ EXPECT_TRUE(TimeDelta::Millis(kMinusInfinity).IsMinusInfinity());
+ EXPECT_TRUE(TimeDelta::Micros(kPlusInfinity).IsPlusInfinity());
+ EXPECT_TRUE(TimeDelta::Micros(kMinusInfinity).IsMinusInfinity());
+}
+
+TEST(TimeDeltaTest, MathOperations) {
+ const int64_t kValueA = 267;
+ const int64_t kValueB = 450;
+ const TimeDelta delta_a = TimeDelta::Millis(kValueA);
+ const TimeDelta delta_b = TimeDelta::Millis(kValueB);
+ EXPECT_EQ((delta_a + delta_b).ms(), kValueA + kValueB);
+ EXPECT_EQ((delta_a - delta_b).ms(), kValueA - kValueB);
+
+ EXPECT_EQ((delta_b / 10).ms(), kValueB / 10);
+ EXPECT_EQ(delta_b / delta_a, static_cast<double>(kValueB) / kValueA);
+
+ EXPECT_EQ(TimeDelta::Micros(-kValueA).Abs().us(), kValueA);
+ EXPECT_EQ(TimeDelta::Micros(kValueA).Abs().us(), kValueA);
+
+ TimeDelta mutable_delta = TimeDelta::Millis(kValueA);
+ mutable_delta += TimeDelta::Millis(kValueB);
+ EXPECT_EQ(mutable_delta, TimeDelta::Millis(kValueA + kValueB));
+ mutable_delta -= TimeDelta::Millis(kValueB);
+ EXPECT_EQ(mutable_delta, TimeDelta::Millis(kValueA));
+}
+
+TEST(TimeDeltaTest, MultiplyByScalar) {
+ const TimeDelta kValue = TimeDelta::Micros(267);
+ const int64_t kInt64 = 450;
+ const int32_t kInt32 = 123;
+ const size_t kUnsignedInt = 125;
+ const double kFloat = 123.0;
+
+ EXPECT_EQ((kValue * kInt64).us(), kValue.us() * kInt64);
+ EXPECT_EQ(kValue * kInt64, kInt64 * kValue);
+
+ EXPECT_EQ((kValue * kInt32).us(), kValue.us() * kInt32);
+ EXPECT_EQ(kValue * kInt32, kInt32 * kValue);
+
+ EXPECT_EQ((kValue * kUnsignedInt).us(), kValue.us() * int64_t{kUnsignedInt});
+ EXPECT_EQ(kValue * kUnsignedInt, kUnsignedInt * kValue);
+
+ EXPECT_DOUBLE_EQ((kValue * kFloat).us(), kValue.us() * kFloat);
+ EXPECT_EQ(kValue * kFloat, kFloat * kValue);
+}
+
+TEST(TimeDeltaTest, InfinityOperations) {
+ const int64_t kValue = 267;
+ const TimeDelta finite = TimeDelta::Millis(kValue);
+ EXPECT_TRUE((TimeDelta::PlusInfinity() + finite).IsPlusInfinity());
+ EXPECT_TRUE((TimeDelta::PlusInfinity() - finite).IsPlusInfinity());
+ EXPECT_TRUE((finite + TimeDelta::PlusInfinity()).IsPlusInfinity());
+ EXPECT_TRUE((finite - TimeDelta::MinusInfinity()).IsPlusInfinity());
+
+ EXPECT_TRUE((TimeDelta::MinusInfinity() + finite).IsMinusInfinity());
+ EXPECT_TRUE((TimeDelta::MinusInfinity() - finite).IsMinusInfinity());
+ EXPECT_TRUE((finite + TimeDelta::MinusInfinity()).IsMinusInfinity());
+ EXPECT_TRUE((finite - TimeDelta::PlusInfinity()).IsMinusInfinity());
+}
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/units/timestamp.cc b/third_party/libwebrtc/api/units/timestamp.cc
new file mode 100644
index 0000000000..fc4f419596
--- /dev/null
+++ b/third_party/libwebrtc/api/units/timestamp.cc
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/units/timestamp.h"
+
+#include "api/array_view.h"
+#include "rtc_base/strings/string_builder.h"
+
+namespace webrtc {
+std::string ToString(Timestamp value) {
+ char buf[64];
+ rtc::SimpleStringBuilder sb(buf);
+ if (value.IsPlusInfinity()) {
+ sb << "+inf ms";
+ } else if (value.IsMinusInfinity()) {
+ sb << "-inf ms";
+ } else {
+ if (value.us() == 0 || (value.us() % 1000) != 0)
+ sb << value.us() << " us";
+ else if (value.ms() % 1000 != 0)
+ sb << value.ms() << " ms";
+ else
+ sb << value.seconds() << " s";
+ }
+ return sb.str();
+}
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/units/timestamp.h b/third_party/libwebrtc/api/units/timestamp.h
new file mode 100644
index 0000000000..8aabe05cad
--- /dev/null
+++ b/third_party/libwebrtc/api/units/timestamp.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_UNITS_TIMESTAMP_H_
+#define API_UNITS_TIMESTAMP_H_
+
+#ifdef WEBRTC_UNIT_TEST
+#include <ostream> // no-presubmit-check TODO(webrtc:8982)
+#endif // WEBRTC_UNIT_TEST
+
+#include <string>
+#include <type_traits>
+
+#include "api/units/time_delta.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/units/unit_base.h" // IWYU pragma: export
+
+namespace webrtc {
+// Timestamp represents the time that has passed since some unspecified epoch.
+// The epoch is assumed to be before any represented timestamps, this means that
+// negative values are not valid. The most notable feature is that the
+// difference of two Timestamps results in a TimeDelta.
+class Timestamp final : public rtc_units_impl::UnitBase<Timestamp> {
+ public:
+ template <typename T>
+ static constexpr Timestamp Seconds(T value) {
+ static_assert(std::is_arithmetic<T>::value, "");
+ return FromFraction(1'000'000, value);
+ }
+ template <typename T>
+ static constexpr Timestamp Millis(T value) {
+ static_assert(std::is_arithmetic<T>::value, "");
+ return FromFraction(1'000, value);
+ }
+ template <typename T>
+ static constexpr Timestamp Micros(T value) {
+ static_assert(std::is_arithmetic<T>::value, "");
+ return FromValue(value);
+ }
+
+ Timestamp() = delete;
+
+ template <typename T = int64_t>
+ constexpr T seconds() const {
+ return ToFraction<1000000, T>();
+ }
+ template <typename T = int64_t>
+ constexpr T ms() const {
+ return ToFraction<1000, T>();
+ }
+ template <typename T = int64_t>
+ constexpr T us() const {
+ return ToValue<T>();
+ }
+
+ constexpr int64_t seconds_or(int64_t fallback_value) const {
+ return ToFractionOr<1000000>(fallback_value);
+ }
+ constexpr int64_t ms_or(int64_t fallback_value) const {
+ return ToFractionOr<1000>(fallback_value);
+ }
+ constexpr int64_t us_or(int64_t fallback_value) const {
+ return ToValueOr(fallback_value);
+ }
+
+ constexpr Timestamp operator+(const TimeDelta delta) const {
+ if (IsPlusInfinity() || delta.IsPlusInfinity()) {
+ RTC_DCHECK(!IsMinusInfinity());
+ RTC_DCHECK(!delta.IsMinusInfinity());
+ return PlusInfinity();
+ } else if (IsMinusInfinity() || delta.IsMinusInfinity()) {
+ RTC_DCHECK(!IsPlusInfinity());
+ RTC_DCHECK(!delta.IsPlusInfinity());
+ return MinusInfinity();
+ }
+ return Timestamp::Micros(us() + delta.us());
+ }
+ constexpr Timestamp operator-(const TimeDelta delta) const {
+ if (IsPlusInfinity() || delta.IsMinusInfinity()) {
+ RTC_DCHECK(!IsMinusInfinity());
+ RTC_DCHECK(!delta.IsPlusInfinity());
+ return PlusInfinity();
+ } else if (IsMinusInfinity() || delta.IsPlusInfinity()) {
+ RTC_DCHECK(!IsPlusInfinity());
+ RTC_DCHECK(!delta.IsMinusInfinity());
+ return MinusInfinity();
+ }
+ return Timestamp::Micros(us() - delta.us());
+ }
+ constexpr TimeDelta operator-(const Timestamp other) const {
+ if (IsPlusInfinity() || other.IsMinusInfinity()) {
+ RTC_DCHECK(!IsMinusInfinity());
+ RTC_DCHECK(!other.IsPlusInfinity());
+ return TimeDelta::PlusInfinity();
+ } else if (IsMinusInfinity() || other.IsPlusInfinity()) {
+ RTC_DCHECK(!IsPlusInfinity());
+ RTC_DCHECK(!other.IsMinusInfinity());
+ return TimeDelta::MinusInfinity();
+ }
+ return TimeDelta::Micros(us() - other.us());
+ }
+ constexpr Timestamp& operator-=(const TimeDelta delta) {
+ *this = *this - delta;
+ return *this;
+ }
+ constexpr Timestamp& operator+=(const TimeDelta delta) {
+ *this = *this + delta;
+ return *this;
+ }
+
+ private:
+ friend class rtc_units_impl::UnitBase<Timestamp>;
+ using UnitBase::UnitBase;
+ static constexpr bool one_sided = true;
+};
+
+std::string ToString(Timestamp value);
+inline std::string ToLogString(Timestamp value) {
+ return ToString(value);
+}
+
+#ifdef WEBRTC_UNIT_TEST
+inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982)
+ std::ostream& stream, // no-presubmit-check TODO(webrtc:8982)
+ Timestamp value) {
+ return stream << ToString(value);
+}
+#endif // WEBRTC_UNIT_TEST
+
+} // namespace webrtc
+
+#endif // API_UNITS_TIMESTAMP_H_
diff --git a/third_party/libwebrtc/api/units/timestamp_gn/moz.build b/third_party/libwebrtc/api/units/timestamp_gn/moz.build
new file mode 100644
index 0000000000..a869cbcd71
--- /dev/null
+++ b/third_party/libwebrtc/api/units/timestamp_gn/moz.build
@@ -0,0 +1,221 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/units/timestamp.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("timestamp_gn")
diff --git a/third_party/libwebrtc/api/units/timestamp_unittest.cc b/third_party/libwebrtc/api/units/timestamp_unittest.cc
new file mode 100644
index 0000000000..43b2985d43
--- /dev/null
+++ b/third_party/libwebrtc/api/units/timestamp_unittest.cc
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <limits>
+
+#include "api/units/timestamp.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace test {
+TEST(TimestampTest, ConstExpr) {
+ constexpr int64_t kValue = 12345;
+ constexpr Timestamp kTimestampInf = Timestamp::PlusInfinity();
+ static_assert(kTimestampInf.IsInfinite(), "");
+ static_assert(kTimestampInf.ms_or(-1) == -1, "");
+
+ constexpr Timestamp kTimestampSeconds = Timestamp::Seconds(kValue);
+ constexpr Timestamp kTimestampMs = Timestamp::Millis(kValue);
+ constexpr Timestamp kTimestampUs = Timestamp::Micros(kValue);
+
+ static_assert(kTimestampSeconds.seconds_or(0) == kValue, "");
+ static_assert(kTimestampMs.ms_or(0) == kValue, "");
+ static_assert(kTimestampUs.us_or(0) == kValue, "");
+
+ static_assert(kTimestampMs > kTimestampUs, "");
+
+ EXPECT_EQ(kTimestampSeconds.seconds(), kValue);
+ EXPECT_EQ(kTimestampMs.ms(), kValue);
+ EXPECT_EQ(kTimestampUs.us(), kValue);
+}
+
+TEST(TimestampTest, GetBackSameValues) {
+ const int64_t kValue = 499;
+ EXPECT_EQ(Timestamp::Millis(kValue).ms(), kValue);
+ EXPECT_EQ(Timestamp::Micros(kValue).us(), kValue);
+ EXPECT_EQ(Timestamp::Seconds(kValue).seconds(), kValue);
+}
+
+TEST(TimestampTest, GetDifferentPrefix) {
+ const int64_t kValue = 3000000;
+ EXPECT_EQ(Timestamp::Micros(kValue).seconds(), kValue / 1000000);
+ EXPECT_EQ(Timestamp::Millis(kValue).seconds(), kValue / 1000);
+ EXPECT_EQ(Timestamp::Micros(kValue).ms(), kValue / 1000);
+
+ EXPECT_EQ(Timestamp::Millis(kValue).us(), kValue * 1000);
+ EXPECT_EQ(Timestamp::Seconds(kValue).ms(), kValue * 1000);
+ EXPECT_EQ(Timestamp::Seconds(kValue).us(), kValue * 1000000);
+}
+
+TEST(TimestampTest, IdentityChecks) {
+ const int64_t kValue = 3000;
+
+ EXPECT_TRUE(Timestamp::PlusInfinity().IsInfinite());
+ EXPECT_TRUE(Timestamp::MinusInfinity().IsInfinite());
+ EXPECT_FALSE(Timestamp::Millis(kValue).IsInfinite());
+
+ EXPECT_FALSE(Timestamp::PlusInfinity().IsFinite());
+ EXPECT_FALSE(Timestamp::MinusInfinity().IsFinite());
+ EXPECT_TRUE(Timestamp::Millis(kValue).IsFinite());
+
+ EXPECT_TRUE(Timestamp::PlusInfinity().IsPlusInfinity());
+ EXPECT_FALSE(Timestamp::MinusInfinity().IsPlusInfinity());
+
+ EXPECT_TRUE(Timestamp::MinusInfinity().IsMinusInfinity());
+ EXPECT_FALSE(Timestamp::PlusInfinity().IsMinusInfinity());
+}
+
+TEST(TimestampTest, ComparisonOperators) {
+ const int64_t kSmall = 450;
+ const int64_t kLarge = 451;
+
+ EXPECT_EQ(Timestamp::PlusInfinity(), Timestamp::PlusInfinity());
+ EXPECT_GE(Timestamp::PlusInfinity(), Timestamp::PlusInfinity());
+ EXPECT_GT(Timestamp::PlusInfinity(), Timestamp::Millis(kLarge));
+ EXPECT_EQ(Timestamp::Millis(kSmall), Timestamp::Millis(kSmall));
+ EXPECT_LE(Timestamp::Millis(kSmall), Timestamp::Millis(kSmall));
+ EXPECT_GE(Timestamp::Millis(kSmall), Timestamp::Millis(kSmall));
+ EXPECT_NE(Timestamp::Millis(kSmall), Timestamp::Millis(kLarge));
+ EXPECT_LE(Timestamp::Millis(kSmall), Timestamp::Millis(kLarge));
+ EXPECT_LT(Timestamp::Millis(kSmall), Timestamp::Millis(kLarge));
+ EXPECT_GE(Timestamp::Millis(kLarge), Timestamp::Millis(kSmall));
+ EXPECT_GT(Timestamp::Millis(kLarge), Timestamp::Millis(kSmall));
+}
+
+TEST(TimestampTest, CanBeInititializedFromLargeInt) {
+ const int kMaxInt = std::numeric_limits<int>::max();
+ EXPECT_EQ(Timestamp::Seconds(kMaxInt).us(),
+ static_cast<int64_t>(kMaxInt) * 1000000);
+ EXPECT_EQ(Timestamp::Millis(kMaxInt).us(),
+ static_cast<int64_t>(kMaxInt) * 1000);
+}
+
+TEST(TimestampTest, ConvertsToAndFromDouble) {
+ const int64_t kMicros = 17017;
+ const double kMicrosDouble = kMicros;
+ const double kMillisDouble = kMicros * 1e-3;
+ const double kSecondsDouble = kMillisDouble * 1e-3;
+
+ EXPECT_EQ(Timestamp::Micros(kMicros).seconds<double>(), kSecondsDouble);
+ EXPECT_EQ(Timestamp::Seconds(kSecondsDouble).us(), kMicros);
+
+ EXPECT_EQ(Timestamp::Micros(kMicros).ms<double>(), kMillisDouble);
+ EXPECT_EQ(Timestamp::Millis(kMillisDouble).us(), kMicros);
+
+ EXPECT_EQ(Timestamp::Micros(kMicros).us<double>(), kMicrosDouble);
+ EXPECT_EQ(Timestamp::Micros(kMicrosDouble).us(), kMicros);
+
+ const double kPlusInfinity = std::numeric_limits<double>::infinity();
+ const double kMinusInfinity = -kPlusInfinity;
+
+ EXPECT_EQ(Timestamp::PlusInfinity().seconds<double>(), kPlusInfinity);
+ EXPECT_EQ(Timestamp::MinusInfinity().seconds<double>(), kMinusInfinity);
+ EXPECT_EQ(Timestamp::PlusInfinity().ms<double>(), kPlusInfinity);
+ EXPECT_EQ(Timestamp::MinusInfinity().ms<double>(), kMinusInfinity);
+ EXPECT_EQ(Timestamp::PlusInfinity().us<double>(), kPlusInfinity);
+ EXPECT_EQ(Timestamp::MinusInfinity().us<double>(), kMinusInfinity);
+
+ EXPECT_TRUE(Timestamp::Seconds(kPlusInfinity).IsPlusInfinity());
+ EXPECT_TRUE(Timestamp::Seconds(kMinusInfinity).IsMinusInfinity());
+ EXPECT_TRUE(Timestamp::Millis(kPlusInfinity).IsPlusInfinity());
+ EXPECT_TRUE(Timestamp::Millis(kMinusInfinity).IsMinusInfinity());
+ EXPECT_TRUE(Timestamp::Micros(kPlusInfinity).IsPlusInfinity());
+ EXPECT_TRUE(Timestamp::Micros(kMinusInfinity).IsMinusInfinity());
+}
+
+TEST(UnitConversionTest, TimestampAndTimeDeltaMath) {
+ const int64_t kValueA = 267;
+ const int64_t kValueB = 450;
+ const Timestamp time_a = Timestamp::Millis(kValueA);
+ const Timestamp time_b = Timestamp::Millis(kValueB);
+ const TimeDelta delta_a = TimeDelta::Millis(kValueA);
+ const TimeDelta delta_b = TimeDelta::Millis(kValueB);
+
+ EXPECT_EQ((time_a - time_b), TimeDelta::Millis(kValueA - kValueB));
+ EXPECT_EQ((time_b - delta_a), Timestamp::Millis(kValueB - kValueA));
+ EXPECT_EQ((time_b + delta_a), Timestamp::Millis(kValueB + kValueA));
+
+ Timestamp mutable_time = time_a;
+ mutable_time += delta_b;
+ EXPECT_EQ(mutable_time, time_a + delta_b);
+ mutable_time -= delta_b;
+ EXPECT_EQ(mutable_time, time_a);
+}
+
+TEST(UnitConversionTest, InfinityOperations) {
+ const int64_t kValue = 267;
+ const Timestamp finite_time = Timestamp::Millis(kValue);
+ const TimeDelta finite_delta = TimeDelta::Millis(kValue);
+ EXPECT_TRUE((Timestamp::PlusInfinity() + finite_delta).IsInfinite());
+ EXPECT_TRUE((Timestamp::PlusInfinity() - finite_delta).IsInfinite());
+ EXPECT_TRUE((finite_time + TimeDelta::PlusInfinity()).IsInfinite());
+ EXPECT_TRUE((finite_time - TimeDelta::MinusInfinity()).IsInfinite());
+}
+} // namespace test
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/BUILD.gn b/third_party/libwebrtc/api/video/BUILD.gn
new file mode 100644
index 0000000000..5d1aa2a1a3
--- /dev/null
+++ b/third_party/libwebrtc/api/video/BUILD.gn
@@ -0,0 +1,421 @@
+# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../webrtc.gni")
+if (is_android) {
+ import("//build/config/android/config.gni")
+ import("//build/config/android/rules.gni")
+}
+
+rtc_library("video_rtp_headers") {
+ visibility = [ "*" ]
+ sources = [
+ "color_space.cc",
+ "color_space.h",
+ "hdr_metadata.cc",
+ "hdr_metadata.h",
+ "video_content_type.cc",
+ "video_content_type.h",
+ "video_rotation.h",
+ "video_timing.cc",
+ "video_timing.h",
+ ]
+
+ deps = [
+ "..:array_view",
+ "../../rtc_base:logging",
+ "../../rtc_base:safe_conversions",
+ "../../rtc_base:stringutils",
+ "../../rtc_base/system:rtc_export",
+ "../units:data_rate",
+ "../units:time_delta",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/container:inlined_vector",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
+rtc_library("video_frame") {
+ visibility = [ "*" ]
+ sources = [
+ "i420_buffer.cc",
+ "i420_buffer.h",
+ "i422_buffer.cc",
+ "i422_buffer.h",
+ "i444_buffer.cc",
+ "i444_buffer.h",
+ "nv12_buffer.cc",
+ "nv12_buffer.h",
+ "video_codec_type.h",
+ "video_frame.cc",
+ "video_frame.h",
+ "video_frame_buffer.cc",
+ "video_frame_buffer.h",
+ "video_sink_interface.h",
+ "video_source_interface.cc",
+ "video_source_interface.h",
+ ]
+
+ deps = [
+ ":video_rtp_headers",
+ "..:array_view",
+ "..:make_ref_counted",
+ "..:rtp_packet_info",
+ "..:scoped_refptr",
+ "..:video_track_source_constraints",
+ "../../rtc_base:checks",
+ "../../rtc_base:refcount",
+ "../../rtc_base:timeutils",
+ "../../rtc_base/memory:aligned_malloc",
+ "../../rtc_base/system:rtc_export",
+ "//third_party/libyuv",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+if (is_android) {
+ java_cpp_enum("video_frame_enums") {
+ sources = [ "video_frame_buffer.h" ]
+ }
+}
+
+rtc_library("video_frame_i010") {
+ visibility = [ "*" ]
+ sources = [
+ "i010_buffer.cc",
+ "i010_buffer.h",
+ "i210_buffer.cc",
+ "i210_buffer.h",
+ "i410_buffer.cc",
+ "i410_buffer.h",
+ ]
+ deps = [
+ ":video_frame",
+ ":video_rtp_headers",
+ "..:make_ref_counted",
+ "..:scoped_refptr",
+ "../../rtc_base:checks",
+ "../../rtc_base:refcount",
+ "../../rtc_base/memory:aligned_malloc",
+ "//third_party/libyuv",
+ ]
+}
+
+rtc_source_set("recordable_encoded_frame") {
+ visibility = [ "*" ]
+ sources = [ "recordable_encoded_frame.h" ]
+
+ deps = [
+ ":encoded_image",
+ ":video_frame",
+ ":video_rtp_headers",
+ "..:array_view",
+ "..:make_ref_counted",
+ "..:scoped_refptr",
+ "../units:timestamp",
+ ]
+}
+
+rtc_source_set("video_frame_type") {
+ visibility = [ "*" ]
+ sources = [ "video_frame_type.h" ]
+}
+
+rtc_source_set("render_resolution") {
+ visibility = [ "*" ]
+ public = [ "render_resolution.h" ]
+}
+
+rtc_source_set("resolution") {
+ visibility = [ "*" ]
+ public = [ "resolution.h" ]
+}
+
+rtc_library("encoded_image") {
+ visibility = [ "*" ]
+ sources = [
+ "encoded_image.cc",
+ "encoded_image.h",
+ ]
+ deps = [
+ ":video_codec_constants",
+ ":video_frame",
+ ":video_frame_type",
+ ":video_rtp_headers",
+ "..:refcountedbase",
+ "..:rtp_packet_info",
+ "..:scoped_refptr",
+ "../../rtc_base:checks",
+ "../../rtc_base:refcount",
+ "../../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_library("encoded_frame") {
+ visibility = [ "*" ]
+ sources = [
+ "encoded_frame.cc",
+ "encoded_frame.h",
+ ]
+
+ deps = [
+ "../../modules/video_coding:encoded_frame",
+ "../units:timestamp",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_library("rtp_video_frame_assembler") {
+ visibility = [ "*" ]
+ sources = [
+ "rtp_video_frame_assembler.cc",
+ "rtp_video_frame_assembler.h",
+ ]
+
+ deps = [
+ ":encoded_frame",
+ "../../modules/rtp_rtcp:rtp_rtcp",
+ "../../modules/rtp_rtcp:rtp_rtcp_format",
+ "../../modules/video_coding:packet_buffer",
+ "../../modules/video_coding:video_coding",
+ "../../rtc_base:logging",
+ "../../rtc_base:rtc_numerics",
+ ]
+
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/container:inlined_vector",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
+rtc_library("rtp_video_frame_assembler_unittests") {
+ testonly = true
+ sources = [ "rtp_video_frame_assembler_unittests.cc" ]
+
+ deps = [
+ ":rtp_video_frame_assembler",
+ "..:array_view",
+ "../../modules/rtp_rtcp:rtp_packetizer_av1_test_helper",
+ "../../modules/rtp_rtcp:rtp_rtcp",
+ "../../modules/rtp_rtcp:rtp_rtcp_format",
+ "../../test:test_support",
+ ]
+}
+
+rtc_source_set("video_codec_constants") {
+ visibility = [ "*" ]
+ sources = [ "video_codec_constants.h" ]
+ deps = []
+}
+
+rtc_library("video_bitrate_allocation") {
+ visibility = [ "*" ]
+ sources = [
+ "video_bitrate_allocation.cc",
+ "video_bitrate_allocation.h",
+ ]
+ deps = [
+ ":video_codec_constants",
+ "../../rtc_base:checks",
+ "../../rtc_base:safe_conversions",
+ "../../rtc_base:stringutils",
+ "../../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_source_set("video_layers_allocation") {
+ visibility = [ "*" ]
+ sources = [ "video_layers_allocation.h" ]
+ deps = [ "../units:data_rate" ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/container:inlined_vector" ]
+}
+
+rtc_library("video_bitrate_allocator") {
+ visibility = [ "*" ]
+ sources = [
+ "video_bitrate_allocator.cc",
+ "video_bitrate_allocator.h",
+ ]
+ deps = [
+ ":video_bitrate_allocation",
+ "../units:data_rate",
+ ]
+}
+
+rtc_source_set("video_bitrate_allocator_factory") {
+ visibility = [ "*" ]
+ sources = [ "video_bitrate_allocator_factory.h" ]
+ deps = [
+ ":video_bitrate_allocator",
+ "../video_codecs:video_codecs_api",
+ ]
+}
+
+rtc_source_set("video_stream_decoder") {
+ visibility = [ "*" ]
+ sources = [ "video_stream_decoder.h" ]
+
+ deps = [
+ ":encoded_frame",
+ ":video_frame",
+ ":video_rtp_headers",
+ "../task_queue",
+ "../units:time_delta",
+ "../video_codecs:video_codecs_api",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_library("video_stream_decoder_create") {
+ visibility = [ "*" ]
+ sources = [
+ "video_stream_decoder_create.cc",
+ "video_stream_decoder_create.h",
+ ]
+
+ deps = [
+ ":video_stream_decoder",
+ "../../api:field_trials_view",
+ "../../video:video_stream_decoder_impl",
+ "../task_queue",
+ "../video_codecs:video_codecs_api",
+ ]
+}
+
+rtc_library("video_adaptation") {
+ visibility = [ "*" ]
+ sources = [
+ "video_adaptation_counters.cc",
+ "video_adaptation_counters.h",
+ "video_adaptation_reason.h",
+ ]
+
+ deps = [
+ "../../rtc_base:checks",
+ "../../rtc_base:stringutils",
+ ]
+}
+
+rtc_source_set("video_stream_encoder") {
+ visibility = [ "*" ]
+ sources = [ "video_stream_encoder_settings.h" ]
+
+ deps = [
+ ":video_adaptation",
+ ":video_bitrate_allocation",
+ ":video_bitrate_allocator",
+ ":video_bitrate_allocator_factory",
+ ":video_codec_constants",
+ ":video_frame",
+ ":video_layers_allocation",
+ "..:rtp_parameters",
+ "..:scoped_refptr",
+ "../:fec_controller_api",
+ "../:rtp_parameters",
+ "../adaptation:resource_adaptation_api",
+ "../units:data_rate",
+ "../video_codecs:video_codecs_api",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_source_set("video_frame_metadata") {
+ visibility = [ "*" ]
+ sources = [
+ "video_frame_metadata.cc",
+ "video_frame_metadata.h",
+ ]
+ deps = [
+ ":video_frame",
+ ":video_frame_type",
+ ":video_rtp_headers",
+ "..:array_view",
+ "../../modules/video_coding:codec_globals_headers",
+ "../../rtc_base/system:rtc_export",
+ "../transport/rtp:dependency_descriptor",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/container:inlined_vector",
+ "//third_party/abseil-cpp/absl/types:optional",
+ "//third_party/abseil-cpp/absl/types:variant",
+ ]
+}
+
+rtc_library("builtin_video_bitrate_allocator_factory") {
+ visibility = [ "*" ]
+ sources = [
+ "builtin_video_bitrate_allocator_factory.cc",
+ "builtin_video_bitrate_allocator_factory.h",
+ ]
+
+ deps = [
+ ":video_bitrate_allocation",
+ ":video_bitrate_allocator",
+ ":video_bitrate_allocator_factory",
+ "../../api:scoped_refptr",
+ "../../media:rtc_media_base",
+ "../../modules/video_coding:video_coding_utility",
+ "../../modules/video_coding/svc:svc_rate_allocator",
+ "../video_codecs:video_codecs_api",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/base:core_headers" ]
+}
+
+rtc_library("frame_buffer") {
+ visibility = [ "*" ]
+ sources = [
+ "frame_buffer.cc",
+ "frame_buffer.h",
+ ]
+ deps = [
+ "../../api:field_trials_view",
+ "../../api/units:timestamp",
+ "../../api/video:encoded_frame",
+ "../../modules/video_coding:video_coding_utility",
+ "../../rtc_base:logging",
+ "../../rtc_base:rtc_numerics",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/algorithm:container",
+ "//third_party/abseil-cpp/absl/container:inlined_vector",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
+rtc_library("frame_buffer_unittest") {
+ testonly = true
+ sources = [ "frame_buffer_unittest.cc" ]
+
+ deps = [
+ ":frame_buffer",
+ "../../api/video:encoded_frame",
+ "../../test:fake_encoded_frame",
+ "../../test:field_trial",
+ "../../test:scoped_key_value_config",
+ "../../test:test_support",
+ ]
+}
+
+if (rtc_include_tests) {
+ rtc_library("video_unittests") {
+ testonly = true
+ sources = [ "video_stream_decoder_create_unittest.cc" ]
+ deps = [
+ ":video_frame_metadata",
+ ":video_frame_type",
+ ":video_stream_decoder_create",
+ "../../modules/rtp_rtcp:rtp_video_header",
+ "../../test:test_support",
+ "../task_queue:default_task_queue_factory",
+ "../video_codecs:builtin_video_decoder_factory",
+ ]
+ }
+}
diff --git a/third_party/libwebrtc/api/video/DEPS b/third_party/libwebrtc/api/video/DEPS
new file mode 100644
index 0000000000..c84299f943
--- /dev/null
+++ b/third_party/libwebrtc/api/video/DEPS
@@ -0,0 +1,77 @@
+specific_include_rules = {
+ # Until the new VideoStreamDecoder is implemented the current decoding
+ # pipeline will be used, and therefore EncodedFrame needs to inherit
+ # VCMEncodedFrame.
+ "encoded_frame.h": [
+ "+modules/video_coding/encoded_frame.h",
+ ],
+
+ "encoded_image\.h" : [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "i010_buffer\.h": [
+ "+rtc_base/memory/aligned_malloc.h",
+ ],
+
+ "i210_buffer\.h": [
+ "+rtc_base/memory/aligned_malloc.h",
+ ],
+
+ "i410_buffer\.h": [
+ "+rtc_base/memory/aligned_malloc.h",
+ ],
+
+ "i420_buffer\.h": [
+ "+rtc_base/memory/aligned_malloc.h",
+ ],
+
+ "i422_buffer\.h": [
+ "+rtc_base/memory/aligned_malloc.h",
+ ],
+
+ "i444_buffer\.h": [
+ "+rtc_base/memory/aligned_malloc.h",
+ ],
+
+ "nv12_buffer\.h": [
+ "+rtc_base/memory/aligned_malloc.h",
+ ],
+
+ "recordable_encoded_frame\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "video_frame\.h": [
+ ],
+
+ "video_frame_buffer\.h": [
+ "+rtc_base/ref_count.h",
+ ],
+
+ "video_frame_metadata\.h": [
+ "+modules/video_coding/codecs/h264/include/h264_globals.h",
+ "+modules/video_coding/codecs/vp8/include/vp8_globals.h",
+ "+modules/video_coding/codecs/vp9/include/vp9_globals.h",
+ ],
+
+ "video_stream_decoder_create.cc": [
+ "+video/video_stream_decoder_impl.h",
+ ],
+
+ "video_stream_encoder_create.cc": [
+ "+video/video_stream_encoder.h",
+ ],
+
+ "rtp_video_frame_assembler.h": [
+ "+modules/rtp_rtcp/source/rtp_packet_received.h",
+ ],
+
+ "frame_buffer.h": [
+ "+modules/video_coding/utility/decoded_frames_history.h",
+ ],
+
+ "video_frame_matchers\.h": [
+ "+test/gmock.h",
+ ],
+}
diff --git a/third_party/libwebrtc/api/video/OWNERS b/third_party/libwebrtc/api/video/OWNERS
new file mode 100644
index 0000000000..49b62f3780
--- /dev/null
+++ b/third_party/libwebrtc/api/video/OWNERS
@@ -0,0 +1,5 @@
+brandtr@webrtc.org
+magjed@webrtc.org
+philipel@webrtc.org
+
+per-file video_timing.h=ilnik@webrtc.org
diff --git a/third_party/libwebrtc/api/video/builtin_video_bitrate_allocator_factory.cc b/third_party/libwebrtc/api/video/builtin_video_bitrate_allocator_factory.cc
new file mode 100644
index 0000000000..4c24a0e75d
--- /dev/null
+++ b/third_party/libwebrtc/api/video/builtin_video_bitrate_allocator_factory.cc
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/builtin_video_bitrate_allocator_factory.h"
+
+#include <memory>
+
+#include "absl/base/macros.h"
+#include "api/video/video_bitrate_allocator.h"
+#include "api/video_codecs/video_codec.h"
+#include "modules/video_coding/svc/svc_rate_allocator.h"
+#include "modules/video_coding/utility/simulcast_rate_allocator.h"
+
+namespace webrtc {
+
+namespace {
+
+class BuiltinVideoBitrateAllocatorFactory
+ : public VideoBitrateAllocatorFactory {
+ public:
+ BuiltinVideoBitrateAllocatorFactory() = default;
+ ~BuiltinVideoBitrateAllocatorFactory() override = default;
+
+ std::unique_ptr<VideoBitrateAllocator> CreateVideoBitrateAllocator(
+ const VideoCodec& codec) override {
+ switch (codec.codecType) {
+ case kVideoCodecAV1:
+ case kVideoCodecVP9:
+ return std::make_unique<SvcRateAllocator>(codec);
+ default:
+ return std::make_unique<SimulcastRateAllocator>(codec);
+ }
+ }
+};
+
+} // namespace
+
+std::unique_ptr<VideoBitrateAllocatorFactory>
+CreateBuiltinVideoBitrateAllocatorFactory() {
+ return std::make_unique<BuiltinVideoBitrateAllocatorFactory>();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/builtin_video_bitrate_allocator_factory.h b/third_party/libwebrtc/api/video/builtin_video_bitrate_allocator_factory.h
new file mode 100644
index 0000000000..ac880a0863
--- /dev/null
+++ b/third_party/libwebrtc/api/video/builtin_video_bitrate_allocator_factory.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_BUILTIN_VIDEO_BITRATE_ALLOCATOR_FACTORY_H_
+#define API_VIDEO_BUILTIN_VIDEO_BITRATE_ALLOCATOR_FACTORY_H_
+
+#include <memory>
+
+#include "api/video/video_bitrate_allocator_factory.h"
+
+namespace webrtc {
+
+std::unique_ptr<VideoBitrateAllocatorFactory>
+CreateBuiltinVideoBitrateAllocatorFactory();
+
+} // namespace webrtc
+
+#endif // API_VIDEO_BUILTIN_VIDEO_BITRATE_ALLOCATOR_FACTORY_H_
diff --git a/third_party/libwebrtc/api/video/builtin_video_bitrate_allocator_factory_gn/moz.build b/third_party/libwebrtc/api/video/builtin_video_bitrate_allocator_factory_gn/moz.build
new file mode 100644
index 0000000000..40823f2355
--- /dev/null
+++ b/third_party/libwebrtc/api/video/builtin_video_bitrate_allocator_factory_gn/moz.build
@@ -0,0 +1,233 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/video/builtin_video_bitrate_allocator_factory.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "GLESv2",
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "rt"
+ ]
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "crypt32",
+ "iphlpapi",
+ "secur32",
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("builtin_video_bitrate_allocator_factory_gn")
diff --git a/third_party/libwebrtc/api/video/color_space.cc b/third_party/libwebrtc/api/video/color_space.cc
new file mode 100644
index 0000000000..a0cd32edb2
--- /dev/null
+++ b/third_party/libwebrtc/api/video/color_space.cc
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/color_space.h"
+
+namespace webrtc {
+namespace {
+// Try to convert `enum_value` into the enum class T. `enum_bitmask` is created
+// by the funciton below. Returns true if conversion was successful, false
+// otherwise.
+template <typename T>
+bool SetFromUint8(uint8_t enum_value, uint64_t enum_bitmask, T* out) {
+ if ((enum_value < 64) && ((enum_bitmask >> enum_value) & 1)) {
+ *out = static_cast<T>(enum_value);
+ return true;
+ }
+ return false;
+}
+
+// This function serves as an assert for the constexpr function below. It's on
+// purpose not declared as constexpr so that it causes a build problem if enum
+// values of 64 or above are used. The bitmask and the code generating it would
+// have to be extended if the standard is updated to include enum values >= 64.
+int EnumMustBeLessThan64() {
+ return -1;
+}
+
+template <typename T, size_t N>
+constexpr int MakeMask(const int index, const int length, T (&values)[N]) {
+ return length > 1
+ ? (MakeMask(index, 1, values) +
+ MakeMask(index + 1, length - 1, values))
+ : (static_cast<uint8_t>(values[index]) < 64
+ ? (uint64_t{1} << static_cast<uint8_t>(values[index]))
+ : EnumMustBeLessThan64());
+}
+
+// Create a bitmask where each bit corresponds to one potential enum value.
+// `values` should be an array listing all possible enum values. The bit is set
+// to one if the corresponding enum exists. Only works for enums with values
+// less than 64.
+template <typename T, size_t N>
+constexpr uint64_t CreateEnumBitmask(T (&values)[N]) {
+ return MakeMask(0, N, values);
+}
+
+bool SetChromaSitingFromUint8(uint8_t enum_value,
+ ColorSpace::ChromaSiting* chroma_siting) {
+ constexpr ColorSpace::ChromaSiting kChromaSitings[] = {
+ ColorSpace::ChromaSiting::kUnspecified,
+ ColorSpace::ChromaSiting::kCollocated, ColorSpace::ChromaSiting::kHalf};
+ constexpr uint64_t enum_bitmask = CreateEnumBitmask(kChromaSitings);
+
+ return SetFromUint8(enum_value, enum_bitmask, chroma_siting);
+}
+
+} // namespace
+
+ColorSpace::ColorSpace() = default;
+ColorSpace::ColorSpace(const ColorSpace& other) = default;
+ColorSpace::ColorSpace(ColorSpace&& other) = default;
+ColorSpace& ColorSpace::operator=(const ColorSpace& other) = default;
+
+ColorSpace::ColorSpace(PrimaryID primaries,
+ TransferID transfer,
+ MatrixID matrix,
+ RangeID range)
+ : ColorSpace(primaries,
+ transfer,
+ matrix,
+ range,
+ ChromaSiting::kUnspecified,
+ ChromaSiting::kUnspecified,
+ nullptr) {}
+
+ColorSpace::ColorSpace(PrimaryID primaries,
+ TransferID transfer,
+ MatrixID matrix,
+ RangeID range,
+ ChromaSiting chroma_siting_horz,
+ ChromaSiting chroma_siting_vert,
+ const HdrMetadata* hdr_metadata)
+ : primaries_(primaries),
+ transfer_(transfer),
+ matrix_(matrix),
+ range_(range),
+ chroma_siting_horizontal_(chroma_siting_horz),
+ chroma_siting_vertical_(chroma_siting_vert),
+ hdr_metadata_(hdr_metadata ? absl::make_optional(*hdr_metadata)
+ : absl::nullopt) {}
+
+ColorSpace::PrimaryID ColorSpace::primaries() const {
+ return primaries_;
+}
+
+ColorSpace::TransferID ColorSpace::transfer() const {
+ return transfer_;
+}
+
+ColorSpace::MatrixID ColorSpace::matrix() const {
+ return matrix_;
+}
+
+ColorSpace::RangeID ColorSpace::range() const {
+ return range_;
+}
+
+ColorSpace::ChromaSiting ColorSpace::chroma_siting_horizontal() const {
+ return chroma_siting_horizontal_;
+}
+
+ColorSpace::ChromaSiting ColorSpace::chroma_siting_vertical() const {
+ return chroma_siting_vertical_;
+}
+
+const HdrMetadata* ColorSpace::hdr_metadata() const {
+ return hdr_metadata_ ? &*hdr_metadata_ : nullptr;
+}
+
+bool ColorSpace::set_primaries_from_uint8(uint8_t enum_value) {
+ constexpr PrimaryID kPrimaryIds[] = {
+ PrimaryID::kBT709, PrimaryID::kUnspecified, PrimaryID::kBT470M,
+ PrimaryID::kBT470BG, PrimaryID::kSMPTE170M, PrimaryID::kSMPTE240M,
+ PrimaryID::kFILM, PrimaryID::kBT2020, PrimaryID::kSMPTEST428,
+ PrimaryID::kSMPTEST431, PrimaryID::kSMPTEST432, PrimaryID::kJEDECP22};
+ constexpr uint64_t enum_bitmask = CreateEnumBitmask(kPrimaryIds);
+
+ return SetFromUint8(enum_value, enum_bitmask, &primaries_);
+}
+
+bool ColorSpace::set_transfer_from_uint8(uint8_t enum_value) {
+ constexpr TransferID kTransferIds[] = {
+ TransferID::kBT709, TransferID::kUnspecified,
+ TransferID::kGAMMA22, TransferID::kGAMMA28,
+ TransferID::kSMPTE170M, TransferID::kSMPTE240M,
+ TransferID::kLINEAR, TransferID::kLOG,
+ TransferID::kLOG_SQRT, TransferID::kIEC61966_2_4,
+ TransferID::kBT1361_ECG, TransferID::kIEC61966_2_1,
+ TransferID::kBT2020_10, TransferID::kBT2020_12,
+ TransferID::kSMPTEST2084, TransferID::kSMPTEST428,
+ TransferID::kARIB_STD_B67};
+ constexpr uint64_t enum_bitmask = CreateEnumBitmask(kTransferIds);
+
+ return SetFromUint8(enum_value, enum_bitmask, &transfer_);
+}
+
+bool ColorSpace::set_matrix_from_uint8(uint8_t enum_value) {
+ constexpr MatrixID kMatrixIds[] = {
+ MatrixID::kRGB, MatrixID::kBT709, MatrixID::kUnspecified,
+ MatrixID::kFCC, MatrixID::kBT470BG, MatrixID::kSMPTE170M,
+ MatrixID::kSMPTE240M, MatrixID::kYCOCG, MatrixID::kBT2020_NCL,
+ MatrixID::kBT2020_CL, MatrixID::kSMPTE2085, MatrixID::kCDNCLS,
+ MatrixID::kCDCLS, MatrixID::kBT2100_ICTCP};
+ constexpr uint64_t enum_bitmask = CreateEnumBitmask(kMatrixIds);
+
+ return SetFromUint8(enum_value, enum_bitmask, &matrix_);
+}
+
+bool ColorSpace::set_range_from_uint8(uint8_t enum_value) {
+ constexpr RangeID kRangeIds[] = {RangeID::kInvalid, RangeID::kLimited,
+ RangeID::kFull, RangeID::kDerived};
+ constexpr uint64_t enum_bitmask = CreateEnumBitmask(kRangeIds);
+
+ return SetFromUint8(enum_value, enum_bitmask, &range_);
+}
+
+bool ColorSpace::set_chroma_siting_horizontal_from_uint8(uint8_t enum_value) {
+ return SetChromaSitingFromUint8(enum_value, &chroma_siting_horizontal_);
+}
+
+bool ColorSpace::set_chroma_siting_vertical_from_uint8(uint8_t enum_value) {
+ return SetChromaSitingFromUint8(enum_value, &chroma_siting_vertical_);
+}
+
+void ColorSpace::set_hdr_metadata(const HdrMetadata* hdr_metadata) {
+ hdr_metadata_ =
+ hdr_metadata ? absl::make_optional(*hdr_metadata) : absl::nullopt;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/color_space.h b/third_party/libwebrtc/api/video/color_space.h
new file mode 100644
index 0000000000..a7ad86b016
--- /dev/null
+++ b/third_party/libwebrtc/api/video/color_space.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_COLOR_SPACE_H_
+#define API_VIDEO_COLOR_SPACE_H_
+
+#include <stdint.h>
+
+#include "absl/types/optional.h"
+#include "api/video/hdr_metadata.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// This class represents color information as specified in T-REC H.273,
+// available from https://www.itu.int/rec/T-REC-H.273.
+//
+// WebRTC's supported codecs:
+// - VP9 supports color profiles, see VP9 Bitstream & Decoding Process
+// Specification Version 0.6 Section 7.2.2 "Color config semantics" available
+// from https://www.webmproject.org.
+// - VP8 only supports BT.601, see
+// https://tools.ietf.org/html/rfc6386#section-9.2
+// - H264 uses the exact same representation as T-REC H.273. See T-REC-H.264
+// E.2.1, "VUI parameters semantics", available from
+// https://www.itu.int/rec/T-REC-H.264.
+
+class RTC_EXPORT ColorSpace {
+ public:
+ enum class PrimaryID : uint8_t {
+ // The indices are equal to the values specified in T-REC H.273 Table 2.
+ kBT709 = 1,
+ kUnspecified = 2,
+ kBT470M = 4,
+ kBT470BG = 5,
+ kSMPTE170M = 6, // Identical to BT601
+ kSMPTE240M = 7,
+ kFILM = 8,
+ kBT2020 = 9,
+ kSMPTEST428 = 10,
+ kSMPTEST431 = 11,
+ kSMPTEST432 = 12,
+ kJEDECP22 = 22, // Identical to EBU3213-E
+ // When adding/removing entries here, please make sure to do the
+ // corresponding change to kPrimaryIds.
+ };
+
+ enum class TransferID : uint8_t {
+ // The indices are equal to the values specified in T-REC H.273 Table 3.
+ kBT709 = 1,
+ kUnspecified = 2,
+ kGAMMA22 = 4,
+ kGAMMA28 = 5,
+ kSMPTE170M = 6,
+ kSMPTE240M = 7,
+ kLINEAR = 8,
+ kLOG = 9,
+ kLOG_SQRT = 10,
+ kIEC61966_2_4 = 11,
+ kBT1361_ECG = 12,
+ kIEC61966_2_1 = 13,
+ kBT2020_10 = 14,
+ kBT2020_12 = 15,
+ kSMPTEST2084 = 16,
+ kSMPTEST428 = 17,
+ kARIB_STD_B67 = 18,
+ // When adding/removing entries here, please make sure to do the
+ // corresponding change to kTransferIds.
+ };
+
+ enum class MatrixID : uint8_t {
+ // The indices are equal to the values specified in T-REC H.273 Table 4.
+ kRGB = 0,
+ kBT709 = 1,
+ kUnspecified = 2,
+ kFCC = 4,
+ kBT470BG = 5,
+ kSMPTE170M = 6,
+ kSMPTE240M = 7,
+ kYCOCG = 8,
+ kBT2020_NCL = 9,
+ kBT2020_CL = 10,
+ kSMPTE2085 = 11,
+ kCDNCLS = 12,
+ kCDCLS = 13,
+ kBT2100_ICTCP = 14,
+ // When adding/removing entries here, please make sure to do the
+ // corresponding change to kMatrixIds.
+ };
+
+ enum class RangeID {
+ // The indices are equal to the values specified at
+ // https://www.webmproject.org/docs/container/#colour for the element Range.
+ kInvalid = 0,
+ // Limited Rec. 709 color range with RGB values ranging from 16 to 235.
+ kLimited = 1,
+ // Full RGB color range with RGB valees from 0 to 255.
+ kFull = 2,
+ // Range is defined by MatrixCoefficients/TransferCharacteristics.
+ kDerived = 3,
+ // When adding/removing entries here, please make sure to do the
+ // corresponding change to kRangeIds.
+ };
+
+ enum class ChromaSiting {
+ // Chroma siting specifies how chroma is subsampled relative to the luma
+ // samples in a YUV video frame.
+ // The indices are equal to the values specified at
+ // https://www.webmproject.org/docs/container/#colour for the element
+ // ChromaSitingVert and ChromaSitingHorz.
+ kUnspecified = 0,
+ kCollocated = 1,
+ kHalf = 2,
+ // When adding/removing entries here, please make sure to do the
+ // corresponding change to kChromaSitings.
+ };
+
+ ColorSpace();
+ ColorSpace(const ColorSpace& other);
+ ColorSpace(ColorSpace&& other);
+ ColorSpace& operator=(const ColorSpace& other);
+ ColorSpace(PrimaryID primaries,
+ TransferID transfer,
+ MatrixID matrix,
+ RangeID range);
+ ColorSpace(PrimaryID primaries,
+ TransferID transfer,
+ MatrixID matrix,
+ RangeID range,
+ ChromaSiting chroma_siting_horizontal,
+ ChromaSiting chroma_siting_vertical,
+ const HdrMetadata* hdr_metadata);
+ friend bool operator==(const ColorSpace& lhs, const ColorSpace& rhs) {
+ return lhs.primaries_ == rhs.primaries_ && lhs.transfer_ == rhs.transfer_ &&
+ lhs.matrix_ == rhs.matrix_ && lhs.range_ == rhs.range_ &&
+ lhs.chroma_siting_horizontal_ == rhs.chroma_siting_horizontal_ &&
+ lhs.chroma_siting_vertical_ == rhs.chroma_siting_vertical_ &&
+ lhs.hdr_metadata_ == rhs.hdr_metadata_;
+ }
+ friend bool operator!=(const ColorSpace& lhs, const ColorSpace& rhs) {
+ return !(lhs == rhs);
+ }
+
+ PrimaryID primaries() const;
+ TransferID transfer() const;
+ MatrixID matrix() const;
+ RangeID range() const;
+ ChromaSiting chroma_siting_horizontal() const;
+ ChromaSiting chroma_siting_vertical() const;
+ const HdrMetadata* hdr_metadata() const;
+
+ bool set_primaries_from_uint8(uint8_t enum_value);
+ bool set_transfer_from_uint8(uint8_t enum_value);
+ bool set_matrix_from_uint8(uint8_t enum_value);
+ bool set_range_from_uint8(uint8_t enum_value);
+ bool set_chroma_siting_horizontal_from_uint8(uint8_t enum_value);
+ bool set_chroma_siting_vertical_from_uint8(uint8_t enum_value);
+ void set_hdr_metadata(const HdrMetadata* hdr_metadata);
+
+ private:
+ PrimaryID primaries_ = PrimaryID::kUnspecified;
+ TransferID transfer_ = TransferID::kUnspecified;
+ MatrixID matrix_ = MatrixID::kUnspecified;
+ RangeID range_ = RangeID::kInvalid;
+ ChromaSiting chroma_siting_horizontal_ = ChromaSiting::kUnspecified;
+ ChromaSiting chroma_siting_vertical_ = ChromaSiting::kUnspecified;
+ absl::optional<HdrMetadata> hdr_metadata_;
+};
+
+} // namespace webrtc
+#endif // API_VIDEO_COLOR_SPACE_H_
diff --git a/third_party/libwebrtc/api/video/encoded_frame.cc b/third_party/libwebrtc/api/video/encoded_frame.cc
new file mode 100644
index 0000000000..c5e2abbbb4
--- /dev/null
+++ b/third_party/libwebrtc/api/video/encoded_frame.cc
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/encoded_frame.h"
+
+#include "absl/types/optional.h"
+
+namespace webrtc {
+
+absl::optional<Timestamp> EncodedFrame::ReceivedTimestamp() const {
+ return ReceivedTime() >= 0
+ ? absl::make_optional(Timestamp::Millis(ReceivedTime()))
+ : absl::nullopt;
+}
+
+absl::optional<Timestamp> EncodedFrame::RenderTimestamp() const {
+ return RenderTimeMs() >= 0
+ ? absl::make_optional(Timestamp::Millis(RenderTimeMs()))
+ : absl::nullopt;
+}
+
+bool EncodedFrame::delayed_by_retransmission() const {
+ return false;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/encoded_frame.h b/third_party/libwebrtc/api/video/encoded_frame.h
new file mode 100644
index 0000000000..66aee227bb
--- /dev/null
+++ b/third_party/libwebrtc/api/video/encoded_frame.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_ENCODED_FRAME_H_
+#define API_VIDEO_ENCODED_FRAME_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "absl/types/optional.h"
+#include "api/units/timestamp.h"
+#include "modules/video_coding/encoded_frame.h"
+
+namespace webrtc {
+
+// TODO(philipel): Remove webrtc::VCMEncodedFrame inheritance.
+// TODO(philipel): Move transport specific info out of EncodedFrame.
+// NOTE: This class is still under development and may change without notice.
+class EncodedFrame : public webrtc::VCMEncodedFrame {
+ public:
+ static const uint8_t kMaxFrameReferences = 5;
+
+ EncodedFrame() = default;
+ EncodedFrame(const EncodedFrame&) = default;
+ virtual ~EncodedFrame() {}
+
+ // When this frame was received.
+ // TODO(bugs.webrtc.org/13756): Use Timestamp instead of int.
+ virtual int64_t ReceivedTime() const = 0;
+ // Returns a Timestamp from `ReceivedTime`, or nullopt if there is no receive
+ // time.
+ absl::optional<webrtc::Timestamp> ReceivedTimestamp() const;
+
+ // When this frame should be rendered.
+ // TODO(bugs.webrtc.org/13756): Use Timestamp instead of int.
+ virtual int64_t RenderTime() const = 0;
+ // Returns a Timestamp from `RenderTime`, or nullopt if there is no
+ // render time.
+ absl::optional<webrtc::Timestamp> RenderTimestamp() const;
+
+ // This information is currently needed by the timing calculation class.
+ // TODO(philipel): Remove this function when a new timing class has
+ // been implemented.
+ virtual bool delayed_by_retransmission() const;
+
+ bool is_keyframe() const { return num_references == 0; }
+
+ void SetId(int64_t id) { id_ = id; }
+ int64_t Id() const { return id_; }
+
+ // TODO(philipel): Add simple modify/access functions to prevent adding too
+ // many `references`.
+ size_t num_references = 0;
+ int64_t references[kMaxFrameReferences];
+ // Is this subframe the last one in the superframe (In RTP stream that would
+ // mean that the last packet has a marker bit set).
+ bool is_last_spatial_layer = true;
+
+ private:
+ // The ID of the frame is determined from RTP level information. The IDs are
+ // used to describe order and dependencies between frames.
+ int64_t id_ = -1;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_ENCODED_FRAME_H_
diff --git a/third_party/libwebrtc/api/video/encoded_frame_gn/moz.build b/third_party/libwebrtc/api/video/encoded_frame_gn/moz.build
new file mode 100644
index 0000000000..f5aee8c8e8
--- /dev/null
+++ b/third_party/libwebrtc/api/video/encoded_frame_gn/moz.build
@@ -0,0 +1,232 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/video/encoded_frame.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "rt"
+ ]
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "crypt32",
+ "iphlpapi",
+ "secur32",
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("encoded_frame_gn")
diff --git a/third_party/libwebrtc/api/video/encoded_image.cc b/third_party/libwebrtc/api/video/encoded_image.cc
new file mode 100644
index 0000000000..ff61994dee
--- /dev/null
+++ b/third_party/libwebrtc/api/video/encoded_image.cc
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/encoded_image.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+namespace webrtc {
+
+EncodedImageBuffer::EncodedImageBuffer(size_t size) : size_(size) {
+ buffer_ = static_cast<uint8_t*>(malloc(size));
+}
+
+EncodedImageBuffer::EncodedImageBuffer(const uint8_t* data, size_t size)
+ : EncodedImageBuffer(size) {
+ memcpy(buffer_, data, size);
+}
+
+EncodedImageBuffer::~EncodedImageBuffer() {
+ free(buffer_);
+}
+
+// static
+rtc::scoped_refptr<EncodedImageBuffer> EncodedImageBuffer::Create(size_t size) {
+ return rtc::make_ref_counted<EncodedImageBuffer>(size);
+}
+// static
+rtc::scoped_refptr<EncodedImageBuffer> EncodedImageBuffer::Create(
+ const uint8_t* data,
+ size_t size) {
+ return rtc::make_ref_counted<EncodedImageBuffer>(data, size);
+}
+
+const uint8_t* EncodedImageBuffer::data() const {
+ return buffer_;
+}
+uint8_t* EncodedImageBuffer::data() {
+ return buffer_;
+}
+size_t EncodedImageBuffer::size() const {
+ return size_;
+}
+
+void EncodedImageBuffer::Realloc(size_t size) {
+ // Calling realloc with size == 0 is equivalent to free, and returns nullptr.
+ // Which is confusing on systems where malloc(0) doesn't return a nullptr.
+ // More specifically, it breaks expectations of
+ // VCMSessionInfo::UpdateDataPointers.
+ RTC_DCHECK(size > 0);
+ buffer_ = static_cast<uint8_t*>(realloc(buffer_, size));
+ size_ = size;
+}
+
+EncodedImage::EncodedImage() = default;
+
+EncodedImage::EncodedImage(EncodedImage&&) = default;
+EncodedImage::EncodedImage(const EncodedImage&) = default;
+
+EncodedImage::~EncodedImage() = default;
+
+EncodedImage& EncodedImage::operator=(EncodedImage&&) = default;
+EncodedImage& EncodedImage::operator=(const EncodedImage&) = default;
+
+void EncodedImage::SetEncodeTime(int64_t encode_start_ms,
+ int64_t encode_finish_ms) {
+ timing_.encode_start_ms = encode_start_ms;
+ timing_.encode_finish_ms = encode_finish_ms;
+}
+
+absl::optional<size_t> EncodedImage::SpatialLayerFrameSize(
+ int spatial_index) const {
+ RTC_DCHECK_GE(spatial_index, 0);
+ RTC_DCHECK_LE(spatial_index, spatial_index_.value_or(0));
+
+ auto it = spatial_layer_frame_size_bytes_.find(spatial_index);
+ if (it == spatial_layer_frame_size_bytes_.end()) {
+ return absl::nullopt;
+ }
+
+ return it->second;
+}
+
+void EncodedImage::SetSpatialLayerFrameSize(int spatial_index,
+ size_t size_bytes) {
+ RTC_DCHECK_GE(spatial_index, 0);
+ RTC_DCHECK_LE(spatial_index, spatial_index_.value_or(0));
+ RTC_DCHECK_GE(size_bytes, 0);
+ spatial_layer_frame_size_bytes_[spatial_index] = size_bytes;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/encoded_image.h b/third_party/libwebrtc/api/video/encoded_image.h
new file mode 100644
index 0000000000..dae790c46c
--- /dev/null
+++ b/third_party/libwebrtc/api/video/encoded_image.h
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_ENCODED_IMAGE_H_
+#define API_VIDEO_ENCODED_IMAGE_H_
+
+#include <stdint.h>
+
+#include <map>
+#include <utility>
+
+#include "absl/types/optional.h"
+#include "api/rtp_packet_infos.h"
+#include "api/scoped_refptr.h"
+#include "api/video/color_space.h"
+#include "api/video/video_codec_constants.h"
+#include "api/video/video_content_type.h"
+#include "api/video/video_frame_type.h"
+#include "api/video/video_rotation.h"
+#include "api/video/video_timing.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/ref_count.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Abstract interface for buffer storage. Intended to support buffers owned by
+// external encoders with special release requirements, e.g, java encoders with
+// releaseOutputBuffer.
+class EncodedImageBufferInterface : public rtc::RefCountInterface {
+ public:
+ virtual const uint8_t* data() const = 0;
+ // TODO(bugs.webrtc.org/9378): Make interface essentially read-only, delete
+ // this non-const data method.
+ virtual uint8_t* data() = 0;
+ virtual size_t size() const = 0;
+};
+
+// Basic implementation of EncodedImageBufferInterface.
+class RTC_EXPORT EncodedImageBuffer : public EncodedImageBufferInterface {
+ public:
+ static rtc::scoped_refptr<EncodedImageBuffer> Create() { return Create(0); }
+ static rtc::scoped_refptr<EncodedImageBuffer> Create(size_t size);
+ static rtc::scoped_refptr<EncodedImageBuffer> Create(const uint8_t* data,
+ size_t size);
+
+ const uint8_t* data() const override;
+ uint8_t* data() override;
+ size_t size() const override;
+ void Realloc(size_t t);
+
+ protected:
+ explicit EncodedImageBuffer(size_t size);
+ EncodedImageBuffer(const uint8_t* data, size_t size);
+ ~EncodedImageBuffer();
+
+ size_t size_;
+ uint8_t* buffer_;
+};
+
+// TODO(bug.webrtc.org/9378): This is a legacy api class, which is slowly being
+// cleaned up. Direct use of its members is strongly discouraged.
+class RTC_EXPORT EncodedImage {
+ public:
+ EncodedImage();
+ EncodedImage(EncodedImage&&);
+ EncodedImage(const EncodedImage&);
+
+ ~EncodedImage();
+
+ EncodedImage& operator=(EncodedImage&&);
+ EncodedImage& operator=(const EncodedImage&);
+
+ // TODO(bugs.webrtc.org/9378): Change style to timestamp(), set_timestamp(),
+ // for consistency with the VideoFrame class. Set frame timestamp (90kHz).
+ void SetTimestamp(uint32_t timestamp) { timestamp_rtp_ = timestamp; }
+
+ // Get frame timestamp (90kHz).
+ uint32_t Timestamp() const { return timestamp_rtp_; }
+
+ void SetEncodeTime(int64_t encode_start_ms, int64_t encode_finish_ms);
+
+ int64_t NtpTimeMs() const { return ntp_time_ms_; }
+
+ absl::optional<int> SpatialIndex() const { return spatial_index_; }
+ void SetSpatialIndex(absl::optional<int> spatial_index) {
+ RTC_DCHECK_GE(spatial_index.value_or(0), 0);
+ RTC_DCHECK_LT(spatial_index.value_or(0), kMaxSpatialLayers);
+ spatial_index_ = spatial_index;
+ }
+
+ absl::optional<int> TemporalIndex() const { return temporal_index_; }
+ void SetTemporalIndex(absl::optional<int> temporal_index) {
+ RTC_DCHECK_GE(temporal_index_.value_or(0), 0);
+ RTC_DCHECK_LT(temporal_index_.value_or(0), kMaxTemporalStreams);
+ temporal_index_ = temporal_index;
+ }
+
+ // These methods can be used to set/get size of subframe with spatial index
+ // `spatial_index` on encoded frames that consist of multiple spatial layers.
+ absl::optional<size_t> SpatialLayerFrameSize(int spatial_index) const;
+ void SetSpatialLayerFrameSize(int spatial_index, size_t size_bytes);
+
+ const webrtc::ColorSpace* ColorSpace() const {
+ return color_space_ ? &*color_space_ : nullptr;
+ }
+ void SetColorSpace(const absl::optional<webrtc::ColorSpace>& color_space) {
+ color_space_ = color_space;
+ }
+
+ // These methods along with the private member video_frame_tracking_id_ are
+ // meant for media quality testing purpose only.
+ absl::optional<uint16_t> VideoFrameTrackingId() const {
+ return video_frame_tracking_id_;
+ }
+ void SetVideoFrameTrackingId(absl::optional<uint16_t> tracking_id) {
+ video_frame_tracking_id_ = tracking_id;
+ }
+
+ const RtpPacketInfos& PacketInfos() const { return packet_infos_; }
+ void SetPacketInfos(RtpPacketInfos packet_infos) {
+ packet_infos_ = std::move(packet_infos);
+ }
+
+ bool RetransmissionAllowed() const { return retransmission_allowed_; }
+ void SetRetransmissionAllowed(bool retransmission_allowed) {
+ retransmission_allowed_ = retransmission_allowed;
+ }
+
+ size_t size() const { return size_; }
+ void set_size(size_t new_size) {
+ // Allow set_size(0) even if we have no buffer.
+ RTC_DCHECK_LE(new_size, new_size == 0 ? 0 : capacity());
+ size_ = new_size;
+ }
+
+ void SetEncodedData(
+ rtc::scoped_refptr<EncodedImageBufferInterface> encoded_data) {
+ encoded_data_ = encoded_data;
+ size_ = encoded_data->size();
+ }
+
+ void ClearEncodedData() {
+ encoded_data_ = nullptr;
+ size_ = 0;
+ }
+
+ rtc::scoped_refptr<EncodedImageBufferInterface> GetEncodedData() const {
+ return encoded_data_;
+ }
+
+ const uint8_t* data() const {
+ return encoded_data_ ? encoded_data_->data() : nullptr;
+ }
+
+ // Returns whether the encoded image can be considered to be of target
+ // quality.
+ bool IsAtTargetQuality() const { return at_target_quality_; }
+
+ // Sets that the encoded image can be considered to be of target quality to
+ // true or false.
+ void SetAtTargetQuality(bool at_target_quality) {
+ at_target_quality_ = at_target_quality;
+ }
+
+ uint32_t _encodedWidth = 0;
+ uint32_t _encodedHeight = 0;
+ // NTP time of the capture time in local timebase in milliseconds.
+ // TODO(minyue): make this member private.
+ int64_t ntp_time_ms_ = 0;
+ int64_t capture_time_ms_ = 0;
+ VideoFrameType _frameType = VideoFrameType::kVideoFrameDelta;
+ VideoRotation rotation_ = kVideoRotation_0;
+ VideoContentType content_type_ = VideoContentType::UNSPECIFIED;
+ int qp_ = -1; // Quantizer value.
+
+ // When an application indicates non-zero values here, it is taken as an
+ // indication that all future frames will be constrained with those limits
+ // until the application indicates a change again.
+ VideoPlayoutDelay playout_delay_;
+
+ struct Timing {
+ uint8_t flags = VideoSendTiming::kInvalid;
+ int64_t encode_start_ms = 0;
+ int64_t encode_finish_ms = 0;
+ int64_t packetization_finish_ms = 0;
+ int64_t pacer_exit_ms = 0;
+ int64_t network_timestamp_ms = 0;
+ int64_t network2_timestamp_ms = 0;
+ int64_t receive_start_ms = 0;
+ int64_t receive_finish_ms = 0;
+ } timing_;
+
+ private:
+ size_t capacity() const { return encoded_data_ ? encoded_data_->size() : 0; }
+
+ rtc::scoped_refptr<EncodedImageBufferInterface> encoded_data_;
+ size_t size_ = 0; // Size of encoded frame data.
+ uint32_t timestamp_rtp_ = 0;
+ absl::optional<int> spatial_index_;
+ absl::optional<int> temporal_index_;
+ std::map<int, size_t> spatial_layer_frame_size_bytes_;
+ absl::optional<webrtc::ColorSpace> color_space_;
+ // This field is meant for media quality testing purpose only. When enabled it
+ // carries the webrtc::VideoFrame id field from the sender to the receiver.
+ absl::optional<uint16_t> video_frame_tracking_id_;
+ // Information about packets used to assemble this video frame. This is needed
+ // by `SourceTracker` when the frame is delivered to the RTCRtpReceiver's
+ // MediaStreamTrack, in order to implement getContributingSources(). See:
+ // https://w3c.github.io/webrtc-pc/#dom-rtcrtpreceiver-getcontributingsources
+ RtpPacketInfos packet_infos_;
+ bool retransmission_allowed_ = true;
+ // True if the encoded image can be considered to be of target quality.
+ bool at_target_quality_ = false;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_ENCODED_IMAGE_H_
diff --git a/third_party/libwebrtc/api/video/encoded_image_gn/moz.build b/third_party/libwebrtc/api/video/encoded_image_gn/moz.build
new file mode 100644
index 0000000000..aebcf21b37
--- /dev/null
+++ b/third_party/libwebrtc/api/video/encoded_image_gn/moz.build
@@ -0,0 +1,225 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/video/encoded_image.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("encoded_image_gn")
diff --git a/third_party/libwebrtc/api/video/frame_buffer.cc b/third_party/libwebrtc/api/video/frame_buffer.cc
new file mode 100644
index 0000000000..f5d93f5f76
--- /dev/null
+++ b/third_party/libwebrtc/api/video/frame_buffer.cc
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/frame_buffer.h"
+
+#include <algorithm>
+
+#include "absl/algorithm/container.h"
+#include "absl/container/inlined_vector.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/numerics/sequence_number_util.h"
+#include "rtc_base/trace_event.h"
+
+namespace webrtc {
+namespace {
+bool ValidReferences(const EncodedFrame& frame) {
+ // All references must point backwards, and duplicates are not allowed.
+ for (size_t i = 0; i < frame.num_references; ++i) {
+ if (frame.references[i] >= frame.Id())
+ return false;
+
+ for (size_t j = i + 1; j < frame.num_references; ++j) {
+ if (frame.references[i] == frame.references[j])
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// Since FrameBuffer::FrameInfo is private it can't be used in the function
+// signature, hence the FrameIteratorT type.
+template <typename FrameIteratorT>
+rtc::ArrayView<const int64_t> GetReferences(const FrameIteratorT& it) {
+ return {it->second.encoded_frame->references,
+ std::min<size_t>(it->second.encoded_frame->num_references,
+ EncodedFrame::kMaxFrameReferences)};
+}
+
+template <typename FrameIteratorT>
+int64_t GetFrameId(const FrameIteratorT& it) {
+ return it->first;
+}
+
+template <typename FrameIteratorT>
+uint32_t GetTimestamp(const FrameIteratorT& it) {
+ return it->second.encoded_frame->Timestamp();
+}
+
+template <typename FrameIteratorT>
+bool IsLastFrameInTemporalUnit(const FrameIteratorT& it) {
+ return it->second.encoded_frame->is_last_spatial_layer;
+}
+} // namespace
+
+FrameBuffer::FrameBuffer(int max_size,
+ int max_decode_history,
+ const FieldTrialsView& field_trials)
+ : legacy_frame_id_jump_behavior_(
+ !field_trials.IsDisabled("WebRTC-LegacyFrameIdJumpBehavior")),
+ max_size_(max_size),
+ decoded_frame_history_(max_decode_history) {}
+
+bool FrameBuffer::InsertFrame(std::unique_ptr<EncodedFrame> frame) {
+ const uint32_t ssrc =
+ frame->PacketInfos().empty() ? 0 : frame->PacketInfos()[0].ssrc();
+ if (!ValidReferences(*frame)) {
+ TRACE_EVENT2("webrtc",
+ "FrameBuffer::InsertFrame Frame dropped (Invalid references)",
+ "remote_ssrc", ssrc, "frame_id", frame->Id());
+ RTC_DLOG(LS_WARNING) << "Frame " << frame->Id()
+ << " has invalid references, dropping frame.";
+ return false;
+ }
+
+ if (frame->Id() <= decoded_frame_history_.GetLastDecodedFrameId()) {
+ if (legacy_frame_id_jump_behavior_ && frame->is_keyframe() &&
+ AheadOf(frame->Timestamp(),
+ *decoded_frame_history_.GetLastDecodedFrameTimestamp())) {
+ TRACE_EVENT2("webrtc",
+ "FrameBuffer::InsertFrame Frames dropped (OOO + PicId jump)",
+ "remote_ssrc", ssrc, "frame_id", frame->Id());
+ RTC_DLOG(LS_WARNING)
+ << "Keyframe " << frame->Id()
+ << " has newer timestamp but older picture id, clearing buffer.";
+ Clear();
+ } else {
+ // Already decoded past this frame.
+ TRACE_EVENT2("webrtc",
+ "FrameBuffer::InsertFrame Frame dropped (Out of order)",
+ "remote_ssrc", ssrc, "frame_id", frame->Id());
+ return false;
+ }
+ }
+
+ if (frames_.size() == max_size_) {
+ if (frame->is_keyframe()) {
+ TRACE_EVENT2("webrtc",
+ "FrameBuffer::InsertFrame Frames dropped (KF + Full buffer)",
+ "remote_ssrc", ssrc, "frame_id", frame->Id());
+ RTC_DLOG(LS_WARNING) << "Keyframe " << frame->Id()
+ << " inserted into full buffer, clearing buffer.";
+ Clear();
+ } else {
+ // No space for this frame.
+ TRACE_EVENT2("webrtc",
+ "FrameBuffer::InsertFrame Frame dropped (Full buffer)",
+ "remote_ssrc", ssrc, "frame_id", frame->Id());
+ return false;
+ }
+ }
+
+ const int64_t frame_id = frame->Id();
+ auto insert_res = frames_.emplace(frame_id, FrameInfo{std::move(frame)});
+ if (!insert_res.second) {
+ // Frame has already been inserted.
+ return false;
+ }
+
+ if (frames_.size() == max_size_) {
+ RTC_DLOG(LS_WARNING) << "Frame " << frame_id
+ << " inserted, buffer is now full.";
+ }
+
+ PropagateContinuity(insert_res.first);
+ FindNextAndLastDecodableTemporalUnit();
+ return true;
+}
+
+absl::InlinedVector<std::unique_ptr<EncodedFrame>, 4>
+FrameBuffer::ExtractNextDecodableTemporalUnit() {
+ absl::InlinedVector<std::unique_ptr<EncodedFrame>, 4> res;
+ if (!next_decodable_temporal_unit_) {
+ return res;
+ }
+
+ auto end_it = std::next(next_decodable_temporal_unit_->last_frame);
+ for (auto it = next_decodable_temporal_unit_->first_frame; it != end_it;
+ ++it) {
+ decoded_frame_history_.InsertDecoded(GetFrameId(it), GetTimestamp(it));
+ res.push_back(std::move(it->second.encoded_frame));
+ }
+
+ DropNextDecodableTemporalUnit();
+ return res;
+}
+
+void FrameBuffer::DropNextDecodableTemporalUnit() {
+ if (!next_decodable_temporal_unit_) {
+ return;
+ }
+
+ auto end_it = std::next(next_decodable_temporal_unit_->last_frame);
+
+ UpdateDroppedFramesAndDiscardedPackets(frames_.begin(), end_it);
+
+ frames_.erase(frames_.begin(), end_it);
+ FindNextAndLastDecodableTemporalUnit();
+}
+
+void FrameBuffer::UpdateDroppedFramesAndDiscardedPackets(FrameIterator begin_it,
+ FrameIterator end_it) {
+ uint32_t dropped_ssrc = 0;
+ int64_t dropped_frame_id = 0;
+ unsigned int num_discarded_packets = 0;
+ unsigned int num_dropped_frames =
+ std::count_if(begin_it, end_it, [&](const auto& f) {
+ if (f.second.encoded_frame) {
+ const auto& packetInfos = f.second.encoded_frame->PacketInfos();
+ dropped_frame_id = f.first;
+ if (!packetInfos.empty()) {
+ dropped_ssrc = packetInfos[0].ssrc();
+ }
+ num_discarded_packets += packetInfos.size();
+ }
+ return f.second.encoded_frame != nullptr;
+ });
+
+ if (num_dropped_frames > 0) {
+ TRACE_EVENT2("webrtc", "FrameBuffer Dropping Old Frames", "remote_ssrc",
+ dropped_ssrc, "frame_id", dropped_frame_id);
+ }
+ if (num_discarded_packets > 0) {
+ TRACE_EVENT2("webrtc", "FrameBuffer Discarding Old Packets", "remote_ssrc",
+ dropped_ssrc, "frame_id", dropped_frame_id);
+ }
+
+ num_dropped_frames_ += num_dropped_frames;
+ num_discarded_packets_ += num_discarded_packets;
+}
+
+absl::optional<int64_t> FrameBuffer::LastContinuousFrameId() const {
+ return last_continuous_frame_id_;
+}
+
+absl::optional<int64_t> FrameBuffer::LastContinuousTemporalUnitFrameId() const {
+ return last_continuous_temporal_unit_frame_id_;
+}
+
+absl::optional<FrameBuffer::DecodabilityInfo>
+FrameBuffer::DecodableTemporalUnitsInfo() const {
+ return decodable_temporal_units_info_;
+}
+
+int FrameBuffer::GetTotalNumberOfContinuousTemporalUnits() const {
+ return num_continuous_temporal_units_;
+}
+int FrameBuffer::GetTotalNumberOfDroppedFrames() const {
+ return num_dropped_frames_;
+}
+int FrameBuffer::GetTotalNumberOfDiscardedPackets() const {
+ return num_discarded_packets_;
+}
+
+size_t FrameBuffer::CurrentSize() const {
+ return frames_.size();
+}
+
+bool FrameBuffer::IsContinuous(const FrameIterator& it) const {
+ for (int64_t reference : GetReferences(it)) {
+ if (decoded_frame_history_.WasDecoded(reference)) {
+ continue;
+ }
+
+ auto reference_frame_it = frames_.find(reference);
+ if (reference_frame_it != frames_.end() &&
+ reference_frame_it->second.continuous) {
+ continue;
+ }
+
+ return false;
+ }
+
+ return true;
+}
+
+void FrameBuffer::PropagateContinuity(const FrameIterator& frame_it) {
+ for (auto it = frame_it; it != frames_.end(); ++it) {
+ if (!it->second.continuous) {
+ if (IsContinuous(it)) {
+ it->second.continuous = true;
+ if (last_continuous_frame_id_ < GetFrameId(it)) {
+ last_continuous_frame_id_ = GetFrameId(it);
+ }
+ if (IsLastFrameInTemporalUnit(it)) {
+ num_continuous_temporal_units_++;
+ if (last_continuous_temporal_unit_frame_id_ < GetFrameId(it)) {
+ last_continuous_temporal_unit_frame_id_ = GetFrameId(it);
+ }
+ }
+ }
+ }
+ }
+}
+
+void FrameBuffer::FindNextAndLastDecodableTemporalUnit() {
+ next_decodable_temporal_unit_.reset();
+ decodable_temporal_units_info_.reset();
+
+ if (!last_continuous_temporal_unit_frame_id_) {
+ return;
+ }
+
+ FrameIterator first_frame_it = frames_.begin();
+ FrameIterator last_frame_it = frames_.begin();
+ absl::InlinedVector<int64_t, 4> frames_in_temporal_unit;
+ uint32_t last_decodable_temporal_unit_timestamp;
+ for (auto frame_it = frames_.begin(); frame_it != frames_.end();) {
+ if (GetFrameId(frame_it) > *last_continuous_temporal_unit_frame_id_) {
+ break;
+ }
+
+ if (GetTimestamp(frame_it) != GetTimestamp(first_frame_it)) {
+ frames_in_temporal_unit.clear();
+ first_frame_it = frame_it;
+ }
+
+ frames_in_temporal_unit.push_back(GetFrameId(frame_it));
+
+ last_frame_it = frame_it++;
+
+ if (IsLastFrameInTemporalUnit(last_frame_it)) {
+ bool temporal_unit_decodable = true;
+ for (auto it = first_frame_it; it != frame_it && temporal_unit_decodable;
+ ++it) {
+ for (int64_t reference : GetReferences(it)) {
+ if (!decoded_frame_history_.WasDecoded(reference) &&
+ !absl::c_linear_search(frames_in_temporal_unit, reference)) {
+ // A frame in the temporal unit has a non-decoded reference outside
+ // the temporal unit, so it's not yet ready to be decoded.
+ temporal_unit_decodable = false;
+ break;
+ }
+ }
+ }
+
+ if (temporal_unit_decodable) {
+ if (!next_decodable_temporal_unit_) {
+ next_decodable_temporal_unit_ = {first_frame_it, last_frame_it};
+ }
+
+ last_decodable_temporal_unit_timestamp = GetTimestamp(first_frame_it);
+ }
+ }
+ }
+
+ if (next_decodable_temporal_unit_) {
+ decodable_temporal_units_info_ = {
+ .next_rtp_timestamp =
+ GetTimestamp(next_decodable_temporal_unit_->first_frame),
+ .last_rtp_timestamp = last_decodable_temporal_unit_timestamp};
+ }
+}
+
+void FrameBuffer::Clear() {
+ UpdateDroppedFramesAndDiscardedPackets(frames_.begin(), frames_.end());
+ frames_.clear();
+ next_decodable_temporal_unit_.reset();
+ decodable_temporal_units_info_.reset();
+ last_continuous_frame_id_.reset();
+ last_continuous_temporal_unit_frame_id_.reset();
+ decoded_frame_history_.Clear();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/frame_buffer.h b/third_party/libwebrtc/api/video/frame_buffer.h
new file mode 100644
index 0000000000..81fd12da58
--- /dev/null
+++ b/third_party/libwebrtc/api/video/frame_buffer.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_FRAME_BUFFER_H_
+#define API_VIDEO_FRAME_BUFFER_H_
+
+#include <map>
+#include <memory>
+#include <utility>
+
+#include "absl/container/inlined_vector.h"
+#include "absl/types/optional.h"
+#include "api/field_trials_view.h"
+#include "api/video/encoded_frame.h"
+#include "modules/video_coding/utility/decoded_frames_history.h"
+
+namespace webrtc {
+// The high level idea of the FrameBuffer is to order frames received from the
+// network into a decodable stream. Frames are order by frame ID, and grouped
+// into temporal units by timestamp. A temporal unit is decodable after all
+// referenced frames outside the unit has been decoded, and a temporal unit is
+// continuous if all referenced frames are directly or indirectly decodable.
+// The FrameBuffer is thread-unsafe.
+class FrameBuffer {
+ public:
+ struct DecodabilityInfo {
+ uint32_t next_rtp_timestamp;
+ uint32_t last_rtp_timestamp;
+ };
+
+ // The `max_size` determines the maximum number of frames the buffer will
+ // store, and max_decode_history determines how far back (by frame ID) the
+ // buffer will store if a frame was decoded or not.
+ FrameBuffer(int max_size,
+ int max_decode_history,
+ // TODO(hta): remove field trials!
+ const FieldTrialsView& field_trials);
+ FrameBuffer(const FrameBuffer&) = delete;
+ FrameBuffer& operator=(const FrameBuffer&) = delete;
+ ~FrameBuffer() = default;
+
+ // Inserted frames may only reference backwards, and must have no duplicate
+ // references. Frame insertion will fail if `frame` is a duplicate, has
+ // already been decoded, invalid, or if the buffer is full and the frame is
+ // not a keyframe. Returns true if the frame was successfully inserted.
+ bool InsertFrame(std::unique_ptr<EncodedFrame> frame);
+
+ // Mark all frames belonging to the next decodable temporal unit as decoded
+ // and returns them.
+ absl::InlinedVector<std::unique_ptr<EncodedFrame>, 4>
+ ExtractNextDecodableTemporalUnit();
+
+ // Drop all frames in the next decodable unit.
+ void DropNextDecodableTemporalUnit();
+
+ absl::optional<int64_t> LastContinuousFrameId() const;
+ absl::optional<int64_t> LastContinuousTemporalUnitFrameId() const;
+ absl::optional<DecodabilityInfo> DecodableTemporalUnitsInfo() const;
+
+ int GetTotalNumberOfContinuousTemporalUnits() const;
+ int GetTotalNumberOfDroppedFrames() const;
+ int GetTotalNumberOfDiscardedPackets() const;
+ size_t CurrentSize() const;
+
+ private:
+ struct FrameInfo {
+ std::unique_ptr<EncodedFrame> encoded_frame;
+ bool continuous = false;
+ };
+
+ using FrameMap = std::map<int64_t, FrameInfo>;
+ using FrameIterator = FrameMap::iterator;
+
+ struct TemporalUnit {
+ // Both first and last are inclusive.
+ FrameIterator first_frame;
+ FrameIterator last_frame;
+ };
+
+ bool IsContinuous(const FrameIterator& it) const;
+ void PropagateContinuity(const FrameIterator& frame_it);
+ void FindNextAndLastDecodableTemporalUnit();
+ void Clear();
+ void UpdateDroppedFramesAndDiscardedPackets(FrameIterator begin_it,
+ FrameIterator end_it);
+
+ const bool legacy_frame_id_jump_behavior_;
+ const size_t max_size_;
+ FrameMap frames_;
+ absl::optional<TemporalUnit> next_decodable_temporal_unit_;
+ absl::optional<DecodabilityInfo> decodable_temporal_units_info_;
+ absl::optional<int64_t> last_continuous_frame_id_;
+ absl::optional<int64_t> last_continuous_temporal_unit_frame_id_;
+ video_coding::DecodedFramesHistory decoded_frame_history_;
+
+ int num_continuous_temporal_units_ = 0;
+ int num_dropped_frames_ = 0;
+ int num_discarded_packets_ = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_FRAME_BUFFER_H_
diff --git a/third_party/libwebrtc/api/video/frame_buffer_gn/moz.build b/third_party/libwebrtc/api/video/frame_buffer_gn/moz.build
new file mode 100644
index 0000000000..b4c504524c
--- /dev/null
+++ b/third_party/libwebrtc/api/video/frame_buffer_gn/moz.build
@@ -0,0 +1,232 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/video/frame_buffer.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "rt"
+ ]
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "crypt32",
+ "iphlpapi",
+ "secur32",
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("frame_buffer_gn")
diff --git a/third_party/libwebrtc/api/video/frame_buffer_unittest.cc b/third_party/libwebrtc/api/video/frame_buffer_unittest.cc
new file mode 100644
index 0000000000..92e2f67540
--- /dev/null
+++ b/third_party/libwebrtc/api/video/frame_buffer_unittest.cc
@@ -0,0 +1,393 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/video/frame_buffer.h"
+
+#include <vector>
+
+#include "api/video/encoded_frame.h"
+#include "test/fake_encoded_frame.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+#include "test/scoped_key_value_config.h"
+
+namespace webrtc {
+namespace {
+
+using ::testing::ElementsAre;
+using ::testing::Eq;
+using ::testing::IsEmpty;
+using ::testing::Matches;
+
+MATCHER_P(FrameWithId, id, "") {
+ return Matches(Eq(id))(arg->Id());
+}
+
+TEST(FrameBuffer3Test, RejectInvalidRefs) {
+ test::ScopedKeyValueConfig field_trials;
+ FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
+ field_trials);
+ // Ref must be less than the id of this frame.
+ EXPECT_FALSE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(0).Id(0).Refs({0}).AsLast().Build()));
+ EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(absl::nullopt));
+
+ // Duplicate ids are also invalid.
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
+ EXPECT_FALSE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(20).Id(2).Refs({1, 1}).AsLast().Build()));
+ EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(1));
+}
+
+TEST(FrameBuffer3Test, LastContinuousUpdatesOnInsertedFrames) {
+ test::ScopedKeyValueConfig field_trials;
+ FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
+ field_trials);
+ EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(absl::nullopt));
+ EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));
+
+ EXPECT_TRUE(
+ buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).Build()));
+ EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(1));
+ EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));
+
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(10).Id(2).Refs({1}).AsLast().Build()));
+ EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(2));
+ EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(2));
+}
+
+TEST(FrameBuffer3Test, LastContinuousFrameReordering) {
+ test::ScopedKeyValueConfig field_trials;
+ FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
+ field_trials);
+
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(30).Id(3).Refs({2}).AsLast().Build()));
+ EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(1));
+
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()));
+ EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(3));
+}
+
+TEST(FrameBuffer3Test, LastContinuousTemporalUnit) {
+ test::ScopedKeyValueConfig field_trials;
+ FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
+ field_trials);
+
+ EXPECT_TRUE(
+ buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).Build()));
+ EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(10).Id(2).Refs({1}).AsLast().Build()));
+ EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(2));
+}
+
+TEST(FrameBuffer3Test, LastContinuousTemporalUnitReordering) {
+ test::ScopedKeyValueConfig field_trials;
+ FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
+ field_trials);
+
+ EXPECT_TRUE(
+ buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(20).Id(3).Refs({1}).Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(20).Id(4).Refs({2, 3}).AsLast().Build()));
+ EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));
+
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(10).Id(2).Refs({1}).AsLast().Build()));
+ EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(4));
+}
+
+TEST(FrameBuffer3Test, NextDecodable) {
+ test::ScopedKeyValueConfig field_trials;
+ FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
+ field_trials);
+
+ EXPECT_THAT(buffer.DecodableTemporalUnitsInfo(), Eq(absl::nullopt));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
+ EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->next_rtp_timestamp, Eq(10U));
+}
+
+TEST(FrameBuffer3Test, AdvanceNextDecodableOnExtraction) {
+ test::ScopedKeyValueConfig field_trials;
+ FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
+ field_trials);
+
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(20).Id(2).AsLast().Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(30).Id(3).Refs({2}).AsLast().Build()));
+ EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->next_rtp_timestamp, Eq(10U));
+
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
+ ElementsAre(FrameWithId(1)));
+ EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->next_rtp_timestamp, Eq(20U));
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
+ ElementsAre(FrameWithId(2)));
+ EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->next_rtp_timestamp, Eq(30U));
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
+ ElementsAre(FrameWithId(3)));
+}
+
+TEST(FrameBuffer3Test, AdvanceLastDecodableOnExtraction) {
+ test::ScopedKeyValueConfig field_trials;
+ FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
+ field_trials);
+
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(30).Id(3).Refs({1}).AsLast().Build()));
+ EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->last_rtp_timestamp, Eq(10U));
+
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
+ ElementsAre(FrameWithId(1)));
+ EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->last_rtp_timestamp, Eq(30U));
+}
+
+TEST(FrameBuffer3Test, FrameUpdatesNextDecodable) {
+ test::ScopedKeyValueConfig field_trials;
+ FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
+ field_trials);
+
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(20).Id(2).AsLast().Build()));
+ EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->next_rtp_timestamp, Eq(20U));
+
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
+ EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->next_rtp_timestamp, Eq(10U));
+}
+
+TEST(FrameBuffer3Test, KeyframeClearsFullBuffer) {
+ test::ScopedKeyValueConfig field_trials;
+ FrameBuffer buffer(/*max_frame_slots=*/5, /*max_decode_history=*/10,
+ field_trials);
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(30).Id(3).Refs({2}).AsLast().Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(40).Id(4).Refs({3}).AsLast().Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(50).Id(5).Refs({4}).AsLast().Build()));
+ EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(5));
+
+ // Frame buffer is full
+ EXPECT_FALSE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(60).Id(6).Refs({5}).AsLast().Build()));
+ EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(5));
+
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(70).Id(7).AsLast().Build()));
+ EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(7));
+}
+
+TEST(FrameBuffer3Test, DropNextDecodableTemporalUnit) {
+ test::ScopedKeyValueConfig field_trials;
+ FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
+ field_trials);
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(30).Id(3).Refs({1}).AsLast().Build()));
+
+ buffer.ExtractNextDecodableTemporalUnit();
+ buffer.DropNextDecodableTemporalUnit();
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
+ ElementsAre(FrameWithId(3)));
+}
+
+TEST(FrameBuffer3Test, OldFramesAreIgnored) {
+ test::ScopedKeyValueConfig field_trials;
+ FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
+ field_trials);
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()));
+
+ buffer.ExtractNextDecodableTemporalUnit();
+ buffer.ExtractNextDecodableTemporalUnit();
+
+ EXPECT_FALSE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
+ EXPECT_FALSE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(30).Id(3).Refs({1}).AsLast().Build()));
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
+ ElementsAre(FrameWithId(3)));
+}
+
+TEST(FrameBuffer3Test, ReturnFullTemporalUnitKSVC) {
+ test::ScopedKeyValueConfig field_trials;
+ FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
+ field_trials);
+ EXPECT_TRUE(
+ buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(10).Id(2).Refs({1}).Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(10).Id(3).Refs({2}).AsLast().Build()));
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
+ ElementsAre(FrameWithId(1), FrameWithId(2), FrameWithId(3)));
+
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(20).Id(4).Refs({3}).AsLast().Build()));
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
+ ElementsAre(FrameWithId(4)));
+}
+
+TEST(FrameBuffer3Test, InterleavedStream) {
+ test::ScopedKeyValueConfig field_trials;
+ FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
+ field_trials);
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(30).Id(3).Refs({1}).AsLast().Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(40).Id(4).Refs({2}).AsLast().Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(50).Id(5).Refs({3}).AsLast().Build()));
+
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
+ ElementsAre(FrameWithId(1)));
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
+ ElementsAre(FrameWithId(2)));
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
+ ElementsAre(FrameWithId(3)));
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
+ ElementsAre(FrameWithId(4)));
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
+ ElementsAre(FrameWithId(5)));
+
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(70).Id(7).Refs({5}).AsLast().Build()));
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
+ ElementsAre(FrameWithId(7)));
+ EXPECT_FALSE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(60).Id(6).Refs({4}).AsLast().Build()));
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), IsEmpty());
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(90).Id(9).Refs({7}).AsLast().Build()));
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
+ ElementsAre(FrameWithId(9)));
+}
+
+TEST(FrameBuffer3Test, LegacyFrameIdJumpBehavior) {
+ {
+ test::ScopedKeyValueConfig field_trials(
+ "WebRTC-LegacyFrameIdJumpBehavior/Disabled/");
+ FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
+ field_trials);
+
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(20).Id(3).AsLast().Build()));
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
+ ElementsAre(FrameWithId(3)));
+ EXPECT_FALSE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(30).Id(2).AsLast().Build()));
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), IsEmpty());
+ }
+
+ {
+ // WebRTC-LegacyFrameIdJumpBehavior is disabled by default.
+ test::ScopedKeyValueConfig field_trials;
+ FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
+ field_trials);
+
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(20).Id(3).AsLast().Build()));
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
+ ElementsAre(FrameWithId(3)));
+ EXPECT_FALSE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(30).Id(2).Refs({1}).AsLast().Build()));
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), IsEmpty());
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(40).Id(1).AsLast().Build()));
+ EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
+ ElementsAre(FrameWithId(1)));
+ }
+}
+
+TEST(FrameBuffer3Test, TotalNumberOfContinuousTemporalUnits) {
+ test::ScopedKeyValueConfig field_trials;
+ FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
+ field_trials);
+ EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(0));
+
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
+ EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(1));
+
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).Build()));
+ EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(1));
+
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(40).Id(4).Refs({2}).Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(40).Id(5).Refs({3, 4}).AsLast().Build()));
+ EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(1));
+
+ // Reordered
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(20).Id(3).Refs({2}).AsLast().Build()));
+ EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(3));
+}
+
+TEST(FrameBuffer3Test, TotalNumberOfDroppedFrames) {
+ test::ScopedKeyValueConfig field_trials;
+ FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
+ field_trials);
+ EXPECT_THAT(buffer.GetTotalNumberOfDroppedFrames(), Eq(0));
+
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(20).Id(3).Refs({2}).AsLast().Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(40).Id(4).Refs({1}).Build()));
+ EXPECT_TRUE(buffer.InsertFrame(
+ test::FakeFrameBuilder().Time(40).Id(5).Refs({4}).AsLast().Build()));
+
+ buffer.ExtractNextDecodableTemporalUnit();
+ EXPECT_THAT(buffer.GetTotalNumberOfDroppedFrames(), Eq(0));
+
+ buffer.DropNextDecodableTemporalUnit();
+ EXPECT_THAT(buffer.GetTotalNumberOfDroppedFrames(), Eq(2));
+
+ buffer.ExtractNextDecodableTemporalUnit();
+ EXPECT_THAT(buffer.GetTotalNumberOfDroppedFrames(), Eq(2));
+}
+
+} // namespace
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/hdr_metadata.cc b/third_party/libwebrtc/api/video/hdr_metadata.cc
new file mode 100644
index 0000000000..e2a669c98a
--- /dev/null
+++ b/third_party/libwebrtc/api/video/hdr_metadata.cc
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/hdr_metadata.h"
+
+namespace webrtc {
+
+HdrMasteringMetadata::Chromaticity::Chromaticity() = default;
+
+HdrMasteringMetadata::HdrMasteringMetadata() = default;
+
+HdrMetadata::HdrMetadata() = default;
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/hdr_metadata.h b/third_party/libwebrtc/api/video/hdr_metadata.h
new file mode 100644
index 0000000000..e9001a2c80
--- /dev/null
+++ b/third_party/libwebrtc/api/video/hdr_metadata.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_HDR_METADATA_H_
+#define API_VIDEO_HDR_METADATA_H_
+
+namespace webrtc {
+
+// SMPTE ST 2086 mastering metadata,
+// see https://ieeexplore.ieee.org/document/8353899.
+struct HdrMasteringMetadata {
+ struct Chromaticity {
+ Chromaticity();
+
+ bool operator==(const Chromaticity& rhs) const {
+ return x == rhs.x && y == rhs.y;
+ }
+
+ bool Validate() const {
+ return x >= 0.0 && x <= 1.0 && y >= 0.0 && y <= 1.0;
+ }
+
+ // xy chromaticity coordinates must be calculated as specified in ISO
+ // 11664-3:2012 Section 7, and must be specified with four decimal places.
+ // The x coordinate should be in the range [0.0001, 0.7400] and the y
+ // coordinate should be in the range [0.0001, 0.8400]. Valid range [0.0000,
+ // 1.0000].
+ float x = 0.0f;
+ float y = 0.0f;
+ };
+
+ HdrMasteringMetadata();
+
+ bool operator==(const HdrMasteringMetadata& rhs) const {
+ return ((primary_r == rhs.primary_r) && (primary_g == rhs.primary_g) &&
+ (primary_b == rhs.primary_b) && (white_point == rhs.white_point) &&
+ (luminance_max == rhs.luminance_max) &&
+ (luminance_min == rhs.luminance_min));
+ }
+
+ bool Validate() const {
+ return luminance_max >= 0.0 && luminance_max <= 20000.0 &&
+ luminance_min >= 0.0 && luminance_min <= 5.0 &&
+ primary_r.Validate() && primary_g.Validate() &&
+ primary_b.Validate() && white_point.Validate();
+ }
+
+ // The nominal primaries of the mastering display.
+ Chromaticity primary_r;
+ Chromaticity primary_g;
+ Chromaticity primary_b;
+
+ // The nominal chromaticity of the white point of the mastering display.
+ Chromaticity white_point;
+
+ // The nominal maximum display luminance of the mastering display. Specified
+ // in the unit candela/m2. The value should be in the range [5, 10000] with
+ // zero decimal places. Valid range [0, 20000].
+ float luminance_max = 0.0f;
+
+ // The nominal minimum display luminance of the mastering display. Specified
+ // in the unit candela/m2. The value should be in the range [0.0001, 5.0000]
+ // with four decimal places. Valid range [0.0000, 5.0000].
+ float luminance_min = 0.0f;
+};
+
+// High dynamic range (HDR) metadata common for HDR10 and WebM/VP9-based HDR
+// formats. This struct replicates the HDRMetadata struct defined in
+// https://cs.chromium.org/chromium/src/media/base/hdr_metadata.h
+struct HdrMetadata {
+ HdrMetadata();
+
+ bool operator==(const HdrMetadata& rhs) const {
+ return (
+ (max_content_light_level == rhs.max_content_light_level) &&
+ (max_frame_average_light_level == rhs.max_frame_average_light_level) &&
+ (mastering_metadata == rhs.mastering_metadata));
+ }
+
+ bool Validate() const {
+ return max_content_light_level >= 0 && max_content_light_level <= 20000 &&
+ max_frame_average_light_level >= 0 &&
+ max_frame_average_light_level <= 20000 &&
+ mastering_metadata.Validate();
+ }
+
+ HdrMasteringMetadata mastering_metadata;
+ // Max content light level (CLL), i.e. maximum brightness level present in the
+ // stream, in nits. 1 nit = 1 candela/m2. Valid range [0, 20000].
+ int max_content_light_level = 0;
+ // Max frame-average light level (FALL), i.e. maximum average brightness of
+ // the brightest frame in the stream, in nits. Valid range [0, 20000].
+ int max_frame_average_light_level = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_HDR_METADATA_H_
diff --git a/third_party/libwebrtc/api/video/i010_buffer.cc b/third_party/libwebrtc/api/video/i010_buffer.cc
new file mode 100644
index 0000000000..d78e854eb9
--- /dev/null
+++ b/third_party/libwebrtc/api/video/i010_buffer.cc
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/video/i010_buffer.h"
+
+#include <utility>
+
+#include "api/make_ref_counted.h"
+#include "api/video/i420_buffer.h"
+#include "rtc_base/checks.h"
+#include "third_party/libyuv/include/libyuv/convert.h"
+#include "third_party/libyuv/include/libyuv/scale.h"
+
+// Aligning pointer to 64 bytes for improved performance, e.g. use SIMD.
+static const int kBufferAlignment = 64;
+static const int kBytesPerPixel = 2;
+
+namespace webrtc {
+
+namespace {
+
+int I010DataSize(int height, int stride_y, int stride_u, int stride_v) {
+ return kBytesPerPixel *
+ (stride_y * height + (stride_u + stride_v) * ((height + 1) / 2));
+}
+
+} // namespace
+
+I010Buffer::I010Buffer(int width,
+ int height,
+ int stride_y,
+ int stride_u,
+ int stride_v)
+ : width_(width),
+ height_(height),
+ stride_y_(stride_y),
+ stride_u_(stride_u),
+ stride_v_(stride_v),
+ data_(static_cast<uint16_t*>(
+ AlignedMalloc(I010DataSize(height, stride_y, stride_u, stride_v),
+ kBufferAlignment))) {
+ RTC_DCHECK_GT(width, 0);
+ RTC_DCHECK_GT(height, 0);
+ RTC_DCHECK_GE(stride_y, width);
+ RTC_DCHECK_GE(stride_u, (width + 1) / 2);
+ RTC_DCHECK_GE(stride_v, (width + 1) / 2);
+}
+
+I010Buffer::~I010Buffer() {}
+
+// static
+rtc::scoped_refptr<I010Buffer> I010Buffer::Create(int width, int height) {
+ return rtc::make_ref_counted<I010Buffer>(width, height, width,
+ (width + 1) / 2, (width + 1) / 2);
+}
+
+// static
+rtc::scoped_refptr<I010Buffer> I010Buffer::Copy(
+ const I010BufferInterface& source) {
+ const int width = source.width();
+ const int height = source.height();
+ rtc::scoped_refptr<I010Buffer> buffer = Create(width, height);
+ int res = libyuv::I010Copy(
+ source.DataY(), source.StrideY(), source.DataU(), source.StrideU(),
+ source.DataV(), source.StrideV(), buffer->MutableDataY(),
+ buffer->StrideY(), buffer->MutableDataU(), buffer->StrideU(),
+ buffer->MutableDataV(), buffer->StrideV(), width, height);
+ RTC_DCHECK_EQ(res, 0);
+
+ return buffer;
+}
+
+// static
+rtc::scoped_refptr<I010Buffer> I010Buffer::Copy(
+ const I420BufferInterface& source) {
+ const int width = source.width();
+ const int height = source.height();
+ rtc::scoped_refptr<I010Buffer> buffer = Create(width, height);
+ int res = libyuv::I420ToI010(
+ source.DataY(), source.StrideY(), source.DataU(), source.StrideU(),
+ source.DataV(), source.StrideV(), buffer->MutableDataY(),
+ buffer->StrideY(), buffer->MutableDataU(), buffer->StrideU(),
+ buffer->MutableDataV(), buffer->StrideV(), width, height);
+ RTC_DCHECK_EQ(res, 0);
+
+ return buffer;
+}
+
+// static
+rtc::scoped_refptr<I010Buffer> I010Buffer::Rotate(
+ const I010BufferInterface& src,
+ VideoRotation rotation) {
+ if (rotation == webrtc::kVideoRotation_0)
+ return Copy(src);
+
+ RTC_CHECK(src.DataY());
+ RTC_CHECK(src.DataU());
+ RTC_CHECK(src.DataV());
+ int rotated_width = src.width();
+ int rotated_height = src.height();
+ if (rotation == webrtc::kVideoRotation_90 ||
+ rotation == webrtc::kVideoRotation_270) {
+ std::swap(rotated_width, rotated_height);
+ }
+
+ rtc::scoped_refptr<webrtc::I010Buffer> buffer =
+ Create(rotated_width, rotated_height);
+
+ int res = libyuv::I010Rotate(
+ src.DataY(), src.StrideY(), src.DataU(), src.StrideU(), src.DataV(),
+ src.StrideV(), buffer->MutableDataY(), buffer->StrideY(),
+ buffer->MutableDataU(), buffer->StrideU(), buffer->MutableDataV(),
+ buffer->StrideV(), src.width(), src.height(),
+ static_cast<libyuv::RotationMode>(rotation));
+ RTC_DCHECK_EQ(res, 0);
+
+ return buffer;
+}
+
+rtc::scoped_refptr<I420BufferInterface> I010Buffer::ToI420() {
+ rtc::scoped_refptr<I420Buffer> i420_buffer =
+ I420Buffer::Create(width(), height());
+ int res = libyuv::I010ToI420(
+ DataY(), StrideY(), DataU(), StrideU(), DataV(), StrideV(),
+ i420_buffer->MutableDataY(), i420_buffer->StrideY(),
+ i420_buffer->MutableDataU(), i420_buffer->StrideU(),
+ i420_buffer->MutableDataV(), i420_buffer->StrideV(), width(), height());
+ RTC_DCHECK_EQ(res, 0);
+
+ return i420_buffer;
+}
+
+int I010Buffer::width() const {
+ return width_;
+}
+
+int I010Buffer::height() const {
+ return height_;
+}
+
+const uint16_t* I010Buffer::DataY() const {
+ return data_.get();
+}
+const uint16_t* I010Buffer::DataU() const {
+ return data_.get() + stride_y_ * height_;
+}
+const uint16_t* I010Buffer::DataV() const {
+ return data_.get() + stride_y_ * height_ + stride_u_ * ((height_ + 1) / 2);
+}
+
+int I010Buffer::StrideY() const {
+ return stride_y_;
+}
+int I010Buffer::StrideU() const {
+ return stride_u_;
+}
+int I010Buffer::StrideV() const {
+ return stride_v_;
+}
+
+uint16_t* I010Buffer::MutableDataY() {
+ return const_cast<uint16_t*>(DataY());
+}
+uint16_t* I010Buffer::MutableDataU() {
+ return const_cast<uint16_t*>(DataU());
+}
+uint16_t* I010Buffer::MutableDataV() {
+ return const_cast<uint16_t*>(DataV());
+}
+
+void I010Buffer::CropAndScaleFrom(const I010BufferInterface& src,
+ int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height) {
+ RTC_CHECK_LE(crop_width, src.width());
+ RTC_CHECK_LE(crop_height, src.height());
+ RTC_CHECK_LE(crop_width + offset_x, src.width());
+ RTC_CHECK_LE(crop_height + offset_y, src.height());
+ RTC_CHECK_GE(offset_x, 0);
+ RTC_CHECK_GE(offset_y, 0);
+
+ // Make sure offset is even so that u/v plane becomes aligned.
+ const int uv_offset_x = offset_x / 2;
+ const int uv_offset_y = offset_y / 2;
+ offset_x = uv_offset_x * 2;
+ offset_y = uv_offset_y * 2;
+
+ const uint16_t* y_plane = src.DataY() + src.StrideY() * offset_y + offset_x;
+ const uint16_t* u_plane =
+ src.DataU() + src.StrideU() * uv_offset_y + uv_offset_x;
+ const uint16_t* v_plane =
+ src.DataV() + src.StrideV() * uv_offset_y + uv_offset_x;
+ int res = libyuv::I420Scale_16(
+ y_plane, src.StrideY(), u_plane, src.StrideU(), v_plane, src.StrideV(),
+ crop_width, crop_height, MutableDataY(), StrideY(), MutableDataU(),
+ StrideU(), MutableDataV(), StrideV(), width(), height(),
+ libyuv::kFilterBox);
+
+ RTC_DCHECK_EQ(res, 0);
+}
+
+void I010Buffer::ScaleFrom(const I010BufferInterface& src) {
+ CropAndScaleFrom(src, 0, 0, src.width(), src.height());
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/i010_buffer.h b/third_party/libwebrtc/api/video/i010_buffer.h
new file mode 100644
index 0000000000..11e0879fec
--- /dev/null
+++ b/third_party/libwebrtc/api/video/i010_buffer.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_I010_BUFFER_H_
+#define API_VIDEO_I010_BUFFER_H_
+
+#include <stdint.h>
+
+#include <memory>
+
+#include "api/scoped_refptr.h"
+#include "api/video/video_frame_buffer.h"
+#include "api/video/video_rotation.h"
+#include "rtc_base/memory/aligned_malloc.h"
+
+namespace webrtc {
+
+// Plain I010 buffer in standard memory.
+class I010Buffer : public I010BufferInterface {
+ public:
+ // Create a new buffer.
+ static rtc::scoped_refptr<I010Buffer> Create(int width, int height);
+
+ // Create a new buffer and copy the pixel data.
+ static rtc::scoped_refptr<I010Buffer> Copy(const I010BufferInterface& buffer);
+
+ // Convert and put I420 buffer into a new buffer.
+ static rtc::scoped_refptr<I010Buffer> Copy(const I420BufferInterface& buffer);
+
+ // Return a rotated copy of `src`.
+ static rtc::scoped_refptr<I010Buffer> Rotate(const I010BufferInterface& src,
+ VideoRotation rotation);
+
+ // VideoFrameBuffer implementation.
+ rtc::scoped_refptr<I420BufferInterface> ToI420() override;
+
+ // PlanarYuv16BBuffer implementation.
+ int width() const override;
+ int height() const override;
+ const uint16_t* DataY() const override;
+ const uint16_t* DataU() const override;
+ const uint16_t* DataV() const override;
+ int StrideY() const override;
+ int StrideU() const override;
+ int StrideV() const override;
+
+ uint16_t* MutableDataY();
+ uint16_t* MutableDataU();
+ uint16_t* MutableDataV();
+
+ // Scale the cropped area of `src` to the size of `this` buffer, and
+ // write the result into `this`.
+ void CropAndScaleFrom(const I010BufferInterface& src,
+ int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height);
+
+ // Scale all of `src` to the size of `this` buffer, with no cropping.
+ void ScaleFrom(const I010BufferInterface& src);
+
+ protected:
+ I010Buffer(int width, int height, int stride_y, int stride_u, int stride_v);
+ ~I010Buffer() override;
+
+ private:
+ const int width_;
+ const int height_;
+ const int stride_y_;
+ const int stride_u_;
+ const int stride_v_;
+ const std::unique_ptr<uint16_t, AlignedFreeDeleter> data_;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_I010_BUFFER_H_
diff --git a/third_party/libwebrtc/api/video/i210_buffer.cc b/third_party/libwebrtc/api/video/i210_buffer.cc
new file mode 100644
index 0000000000..c83c8a0c0b
--- /dev/null
+++ b/third_party/libwebrtc/api/video/i210_buffer.cc
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/video/i210_buffer.h"
+
+#include <utility>
+
+#include "api/make_ref_counted.h"
+#include "api/video/i420_buffer.h"
+#include "api/video/i422_buffer.h"
+#include "rtc_base/checks.h"
+#include "third_party/libyuv/include/libyuv/convert.h"
+#include "third_party/libyuv/include/libyuv/scale.h"
+
+// Aligning pointer to 64 bytes for improved performance, e.g. use SIMD.
+static const int kBufferAlignment = 64;
+static const int kBytesPerPixel = 2;
+
+namespace webrtc {
+
+namespace {
+
+int I210DataSize(int height, int stride_y, int stride_u, int stride_v) {
+ return kBytesPerPixel *
+ (stride_y * height + stride_u * height + stride_v * height);
+}
+
+} // namespace
+
+I210Buffer::I210Buffer(int width,
+ int height,
+ int stride_y,
+ int stride_u,
+ int stride_v)
+ : width_(width),
+ height_(height),
+ stride_y_(stride_y),
+ stride_u_(stride_u),
+ stride_v_(stride_v),
+ data_(static_cast<uint16_t*>(
+ AlignedMalloc(I210DataSize(height, stride_y, stride_u, stride_v),
+ kBufferAlignment))) {
+ RTC_DCHECK_GT(width, 0);
+ RTC_DCHECK_GT(height, 0);
+ RTC_DCHECK_GE(stride_y, width);
+ RTC_DCHECK_GE(stride_u, (width + 1) / 2);
+ RTC_DCHECK_GE(stride_v, (width + 1) / 2);
+}
+
+I210Buffer::~I210Buffer() {}
+
+// static
+rtc::scoped_refptr<I210Buffer> I210Buffer::Create(int width, int height) {
+ return rtc::make_ref_counted<I210Buffer>(width, height, width,
+ (width + 1) / 2, (width + 1) / 2);
+}
+
+// static
+rtc::scoped_refptr<I210Buffer> I210Buffer::Copy(
+ const I210BufferInterface& source) {
+ const int width = source.width();
+ const int height = source.height();
+ rtc::scoped_refptr<I210Buffer> buffer = Create(width, height);
+ RTC_CHECK_EQ(
+ 0, libyuv::I210Copy(
+ source.DataY(), source.StrideY(), source.DataU(), source.StrideU(),
+ source.DataV(), source.StrideV(), buffer->MutableDataY(),
+ buffer->StrideY(), buffer->MutableDataU(), buffer->StrideU(),
+ buffer->MutableDataV(), buffer->StrideV(), width, height));
+ return buffer;
+}
+
+// static
+rtc::scoped_refptr<I210Buffer> I210Buffer::Copy(
+ const I420BufferInterface& source) {
+ const int width = source.width();
+ const int height = source.height();
+ auto i422buffer = I422Buffer::Copy(source);
+ rtc::scoped_refptr<I210Buffer> buffer = Create(width, height);
+ RTC_CHECK_EQ(0, libyuv::I422ToI210(i422buffer->DataY(), i422buffer->StrideY(),
+ i422buffer->DataU(), i422buffer->StrideU(),
+ i422buffer->DataV(), i422buffer->StrideV(),
+ buffer->MutableDataY(), buffer->StrideY(),
+ buffer->MutableDataU(), buffer->StrideU(),
+ buffer->MutableDataV(), buffer->StrideV(),
+ width, height));
+ return buffer;
+}
+
+// static
+rtc::scoped_refptr<I210Buffer> I210Buffer::Rotate(
+ const I210BufferInterface& src,
+ VideoRotation rotation) {
+ RTC_CHECK(src.DataY());
+ RTC_CHECK(src.DataU());
+ RTC_CHECK(src.DataV());
+
+ int rotated_width = src.width();
+ int rotated_height = src.height();
+ if (rotation == webrtc::kVideoRotation_90 ||
+ rotation == webrtc::kVideoRotation_270) {
+ std::swap(rotated_width, rotated_height);
+ }
+
+ rtc::scoped_refptr<webrtc::I210Buffer> buffer =
+ I210Buffer::Create(rotated_width, rotated_height);
+
+ RTC_CHECK_EQ(0,
+ libyuv::I210Rotate(
+ src.DataY(), src.StrideY(), src.DataU(), src.StrideU(),
+ src.DataV(), src.StrideV(), buffer->MutableDataY(),
+ buffer->StrideY(), buffer->MutableDataU(), buffer->StrideU(),
+ buffer->MutableDataV(), buffer->StrideV(), src.width(),
+ src.height(), static_cast<libyuv::RotationMode>(rotation)));
+
+ return buffer;
+}
+
+rtc::scoped_refptr<I420BufferInterface> I210Buffer::ToI420() {
+ rtc::scoped_refptr<I420Buffer> i420_buffer =
+ I420Buffer::Create(width(), height());
+ libyuv::I210ToI420(DataY(), StrideY(), DataU(), StrideU(), DataV(), StrideV(),
+ i420_buffer->MutableDataY(), i420_buffer->StrideY(),
+ i420_buffer->MutableDataU(), i420_buffer->StrideU(),
+ i420_buffer->MutableDataV(), i420_buffer->StrideV(),
+ width(), height());
+ return i420_buffer;
+}
+
+int I210Buffer::width() const {
+ return width_;
+}
+
+int I210Buffer::height() const {
+ return height_;
+}
+
+const uint16_t* I210Buffer::DataY() const {
+ return data_.get();
+}
+const uint16_t* I210Buffer::DataU() const {
+ return data_.get() + stride_y_ * height_;
+}
+const uint16_t* I210Buffer::DataV() const {
+ return data_.get() + stride_y_ * height_ + stride_u_ * height_;
+}
+
+int I210Buffer::StrideY() const {
+ return stride_y_;
+}
+int I210Buffer::StrideU() const {
+ return stride_u_;
+}
+int I210Buffer::StrideV() const {
+ return stride_v_;
+}
+
+uint16_t* I210Buffer::MutableDataY() {
+ return const_cast<uint16_t*>(DataY());
+}
+uint16_t* I210Buffer::MutableDataU() {
+ return const_cast<uint16_t*>(DataU());
+}
+uint16_t* I210Buffer::MutableDataV() {
+ return const_cast<uint16_t*>(DataV());
+}
+
+void I210Buffer::CropAndScaleFrom(const I210BufferInterface& src,
+ int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height) {
+ RTC_CHECK_LE(crop_width, src.width());
+ RTC_CHECK_LE(crop_height, src.height());
+ RTC_CHECK_LE(crop_width + offset_x, src.width());
+ RTC_CHECK_LE(crop_height + offset_y, src.height());
+ RTC_CHECK_GE(offset_x, 0);
+ RTC_CHECK_GE(offset_y, 0);
+ RTC_CHECK_GE(crop_width, 0);
+ RTC_CHECK_GE(crop_height, 0);
+
+ // Make sure offset is even so that u/v plane becomes aligned.
+ const int uv_offset_x = offset_x / 2;
+ const int uv_offset_y = offset_y;
+ offset_x = uv_offset_x * 2;
+
+ const uint16_t* y_plane = src.DataY() + src.StrideY() * offset_y + offset_x;
+ const uint16_t* u_plane =
+ src.DataU() + src.StrideU() * uv_offset_y + uv_offset_x;
+ const uint16_t* v_plane =
+ src.DataV() + src.StrideV() * uv_offset_y + uv_offset_x;
+ int res = libyuv::I422Scale_16(
+ y_plane, src.StrideY(), u_plane, src.StrideU(), v_plane, src.StrideV(),
+ crop_width, crop_height, MutableDataY(), StrideY(), MutableDataU(),
+ StrideU(), MutableDataV(), StrideV(), width(), height(),
+ libyuv::kFilterBox);
+
+ RTC_DCHECK_EQ(res, 0);
+}
+
+void I210Buffer::ScaleFrom(const I210BufferInterface& src) {
+ CropAndScaleFrom(src, 0, 0, src.width(), src.height());
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/i210_buffer.h b/third_party/libwebrtc/api/video/i210_buffer.h
new file mode 100644
index 0000000000..e3b6452b95
--- /dev/null
+++ b/third_party/libwebrtc/api/video/i210_buffer.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_I210_BUFFER_H_
+#define API_VIDEO_I210_BUFFER_H_
+
+#include <stdint.h>
+
+#include <memory>
+
+#include "api/scoped_refptr.h"
+#include "api/video/video_frame_buffer.h"
+#include "api/video/video_rotation.h"
+#include "rtc_base/memory/aligned_malloc.h"
+
+namespace webrtc {
+
+// Plain I210 (yuv 422 planar 10 bits) buffer in standard memory.
+class I210Buffer : public I210BufferInterface {
+ public:
+ // Create a new buffer.
+ static rtc::scoped_refptr<I210Buffer> Create(int width, int height);
+
+ // Create a new buffer and copy the pixel data.
+ static rtc::scoped_refptr<I210Buffer> Copy(const I210BufferInterface& buffer);
+
+ // Convert and put I420 buffer into a new buffer.
+ static rtc::scoped_refptr<I210Buffer> Copy(const I420BufferInterface& buffer);
+
+ // Return a rotated copy of `src`.
+ static rtc::scoped_refptr<I210Buffer> Rotate(const I210BufferInterface& src,
+ VideoRotation rotation);
+
+ // VideoFrameBuffer implementation.
+ rtc::scoped_refptr<I420BufferInterface> ToI420() override;
+
+ // PlanarYuv16BBuffer implementation.
+ int width() const override;
+ int height() const override;
+ const uint16_t* DataY() const override;
+ const uint16_t* DataU() const override;
+ const uint16_t* DataV() const override;
+ int StrideY() const override;
+ int StrideU() const override;
+ int StrideV() const override;
+
+ uint16_t* MutableDataY();
+ uint16_t* MutableDataU();
+ uint16_t* MutableDataV();
+
+ // Scale the cropped area of `src` to the size of `this` buffer, and
+ // write the result into `this`.
+ void CropAndScaleFrom(const I210BufferInterface& src,
+ int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height);
+
+ // Scale all of `src` to the size of `this` buffer, with no cropping.
+ void ScaleFrom(const I210BufferInterface& src);
+
+ protected:
+ I210Buffer(int width, int height, int stride_y, int stride_u, int stride_v);
+ ~I210Buffer() override;
+
+ private:
+ const int width_;
+ const int height_;
+ const int stride_y_;
+ const int stride_u_;
+ const int stride_v_;
+ const std::unique_ptr<uint16_t, AlignedFreeDeleter> data_;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_I210_BUFFER_H_
diff --git a/third_party/libwebrtc/api/video/i410_buffer.cc b/third_party/libwebrtc/api/video/i410_buffer.cc
new file mode 100644
index 0000000000..1b0d4fdb5c
--- /dev/null
+++ b/third_party/libwebrtc/api/video/i410_buffer.cc
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2023 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/video/i410_buffer.h"
+
+#include <string.h>
+
+#include <algorithm>
+#include <utility>
+
+#include "api/make_ref_counted.h"
+#include "api/video/i420_buffer.h"
+#include "rtc_base/checks.h"
+#include "third_party/libyuv/include/libyuv/convert.h"
+#include "third_party/libyuv/include/libyuv/planar_functions.h"
+#include "third_party/libyuv/include/libyuv/scale.h"
+
+// Aligning pointer to 64 bytes for improved performance, e.g. use SIMD.
+static const int kBufferAlignment = 64;
+static const int kBytesPerPixel = 2;
+
+namespace webrtc {
+
+namespace {
+
+int I410DataSize(int height, int stride_y, int stride_u, int stride_v) {
+ return kBytesPerPixel *
+ (stride_y * height + stride_u * height + stride_v * height);
+}
+
+} // namespace
+
+I410Buffer::I410Buffer(int width, int height)
+ : I410Buffer(width, height, width, width, width) {}
+
+I410Buffer::I410Buffer(int width,
+ int height,
+ int stride_y,
+ int stride_u,
+ int stride_v)
+ : width_(width),
+ height_(height),
+ stride_y_(stride_y),
+ stride_u_(stride_u),
+ stride_v_(stride_v),
+ data_(static_cast<uint16_t*>(
+ AlignedMalloc(I410DataSize(height, stride_y, stride_u, stride_v),
+ kBufferAlignment))) {
+ RTC_DCHECK_GT(width, 0);
+ RTC_DCHECK_GT(height, 0);
+ RTC_DCHECK_GE(stride_y, width);
+ RTC_DCHECK_GE(stride_u, width);
+ RTC_DCHECK_GE(stride_v, width);
+}
+
+I410Buffer::~I410Buffer() {}
+
+// static
+rtc::scoped_refptr<I410Buffer> I410Buffer::Create(int width, int height) {
+ return rtc::make_ref_counted<I410Buffer>(width, height);
+}
+
+// static
+rtc::scoped_refptr<I410Buffer> I410Buffer::Create(int width,
+ int height,
+ int stride_y,
+ int stride_u,
+ int stride_v) {
+ return rtc::make_ref_counted<I410Buffer>(width, height, stride_y, stride_u,
+ stride_v);
+}
+
+// static
+rtc::scoped_refptr<I410Buffer> I410Buffer::Copy(
+ const I410BufferInterface& source) {
+ return Copy(source.width(), source.height(), source.DataY(), source.StrideY(),
+ source.DataU(), source.StrideU(), source.DataV(),
+ source.StrideV());
+}
+
+// static
+rtc::scoped_refptr<I410Buffer> I410Buffer::Copy(int width,
+ int height,
+ const uint16_t* data_y,
+ int stride_y,
+ const uint16_t* data_u,
+ int stride_u,
+ const uint16_t* data_v,
+ int stride_v) {
+ // Note: May use different strides than the input data.
+ rtc::scoped_refptr<I410Buffer> buffer = Create(width, height);
+ int res = libyuv::I410Copy(data_y, stride_y, data_u, stride_u, data_v,
+ stride_v, buffer->MutableDataY(),
+ buffer->StrideY(), buffer->MutableDataU(),
+ buffer->StrideU(), buffer->MutableDataV(),
+ buffer->StrideV(), width, height);
+ RTC_DCHECK_EQ(res, 0);
+
+ return buffer;
+}
+
+// static
+rtc::scoped_refptr<I410Buffer> I410Buffer::Rotate(
+ const I410BufferInterface& src,
+ VideoRotation rotation) {
+ RTC_CHECK(src.DataY());
+ RTC_CHECK(src.DataU());
+ RTC_CHECK(src.DataV());
+
+ int rotated_width = src.width();
+ int rotated_height = src.height();
+ if (rotation == webrtc::kVideoRotation_90 ||
+ rotation == webrtc::kVideoRotation_270) {
+ std::swap(rotated_width, rotated_height);
+ }
+
+ rtc::scoped_refptr<webrtc::I410Buffer> buffer =
+ I410Buffer::Create(rotated_width, rotated_height);
+
+ int res = libyuv::I410Rotate(
+ src.DataY(), src.StrideY(), src.DataU(), src.StrideU(), src.DataV(),
+ src.StrideV(), buffer->MutableDataY(), buffer->StrideY(),
+ buffer->MutableDataU(), buffer->StrideU(), buffer->MutableDataV(),
+ buffer->StrideV(), src.width(), src.height(),
+ static_cast<libyuv::RotationMode>(rotation));
+ RTC_DCHECK_EQ(res, 0);
+
+ return buffer;
+}
+
+rtc::scoped_refptr<I420BufferInterface> I410Buffer::ToI420() {
+ rtc::scoped_refptr<I420Buffer> i420_buffer =
+ I420Buffer::Create(width(), height());
+ int res = libyuv::I410ToI420(
+ DataY(), StrideY(), DataU(), StrideU(), DataV(), StrideV(),
+ i420_buffer->MutableDataY(), i420_buffer->StrideY(),
+ i420_buffer->MutableDataU(), i420_buffer->StrideU(),
+ i420_buffer->MutableDataV(), i420_buffer->StrideV(), width(), height());
+ RTC_DCHECK_EQ(res, 0);
+
+ return i420_buffer;
+}
+
+void I410Buffer::InitializeData() {
+ memset(data_.get(), 0,
+ I410DataSize(height_, stride_y_, stride_u_, stride_v_));
+}
+
+int I410Buffer::width() const {
+ return width_;
+}
+
+int I410Buffer::height() const {
+ return height_;
+}
+
+const uint16_t* I410Buffer::DataY() const {
+ return data_.get();
+}
+const uint16_t* I410Buffer::DataU() const {
+ return data_.get() + stride_y_ * height_;
+}
+const uint16_t* I410Buffer::DataV() const {
+ return data_.get() + stride_y_ * height_ + stride_u_ * height_;
+}
+
+int I410Buffer::StrideY() const {
+ return stride_y_;
+}
+int I410Buffer::StrideU() const {
+ return stride_u_;
+}
+int I410Buffer::StrideV() const {
+ return stride_v_;
+}
+
+uint16_t* I410Buffer::MutableDataY() {
+ return const_cast<uint16_t*>(DataY());
+}
+uint16_t* I410Buffer::MutableDataU() {
+ return const_cast<uint16_t*>(DataU());
+}
+uint16_t* I410Buffer::MutableDataV() {
+ return const_cast<uint16_t*>(DataV());
+}
+
+void I410Buffer::CropAndScaleFrom(const I410BufferInterface& src,
+ int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height) {
+ RTC_CHECK_LE(crop_width, src.width());
+ RTC_CHECK_LE(crop_height, src.height());
+ RTC_CHECK_LE(crop_width + offset_x, src.width());
+ RTC_CHECK_LE(crop_height + offset_y, src.height());
+ RTC_CHECK_GE(offset_x, 0);
+ RTC_CHECK_GE(offset_y, 0);
+
+ const uint16_t* y_plane = src.DataY() + src.StrideY() * offset_y + offset_x;
+ const uint16_t* u_plane = src.DataU() + src.StrideU() * offset_y + offset_x;
+ const uint16_t* v_plane = src.DataV() + src.StrideV() * offset_y + offset_x;
+ int res = libyuv::I444Scale_16(
+ y_plane, src.StrideY(), u_plane, src.StrideU(), v_plane, src.StrideV(),
+ crop_width, crop_height, MutableDataY(), StrideY(), MutableDataU(),
+ StrideU(), MutableDataV(), StrideV(), width(), height(),
+ libyuv::kFilterBox);
+
+ RTC_DCHECK_EQ(res, 0);
+}
+
+void I410Buffer::ScaleFrom(const I410BufferInterface& src) {
+ CropAndScaleFrom(src, 0, 0, src.width(), src.height());
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/i410_buffer.h b/third_party/libwebrtc/api/video/i410_buffer.h
new file mode 100644
index 0000000000..1c0cd86c12
--- /dev/null
+++ b/third_party/libwebrtc/api/video/i410_buffer.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2023 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_I410_BUFFER_H_
+#define API_VIDEO_I410_BUFFER_H_
+
+#include <stdint.h>
+
+#include <memory>
+
+#include "api/scoped_refptr.h"
+#include "api/video/video_frame_buffer.h"
+#include "api/video/video_rotation.h"
+#include "rtc_base/memory/aligned_malloc.h"
+
+namespace webrtc {
+
+// Plain I410 (yuv 444 planar 10 bits) buffer in standard memory.
+class RTC_EXPORT I410Buffer : public I410BufferInterface {
+ public:
+ static rtc::scoped_refptr<I410Buffer> Create(int width, int height);
+ static rtc::scoped_refptr<I410Buffer> Create(int width,
+ int height,
+ int stride_y,
+ int stride_u,
+ int stride_v);
+
+ // Create a new buffer and copy the pixel data.
+ static rtc::scoped_refptr<I410Buffer> Copy(const I410BufferInterface& buffer);
+
+ static rtc::scoped_refptr<I410Buffer> Copy(int width,
+ int height,
+ const uint16_t* data_y,
+ int stride_y,
+ const uint16_t* data_u,
+ int stride_u,
+ const uint16_t* data_v,
+ int stride_v);
+
+ // Returns a rotated copy of |src|.
+ static rtc::scoped_refptr<I410Buffer> Rotate(const I410BufferInterface& src,
+ VideoRotation rotation);
+
+ rtc::scoped_refptr<I420BufferInterface> ToI420() final;
+ const I420BufferInterface* GetI420() const final { return nullptr; }
+
+ // Sets all three planes to all zeros. Used to work around for
+ // quirks in memory checkers
+ // (https://bugs.chromium.org/p/libyuv/issues/detail?id=377) and
+ // ffmpeg (http://crbug.com/390941).
+ // TODO(https://crbug.com/390941): Deprecated. Should be deleted if/when those
+ // issues are resolved in a better way. Or in the mean time, use SetBlack.
+ void InitializeData();
+
+ int width() const override;
+ int height() const override;
+ const uint16_t* DataY() const override;
+ const uint16_t* DataU() const override;
+ const uint16_t* DataV() const override;
+
+ int StrideY() const override;
+ int StrideU() const override;
+ int StrideV() const override;
+
+ uint16_t* MutableDataY();
+ uint16_t* MutableDataU();
+ uint16_t* MutableDataV();
+
+ // Scale the cropped area of |src| to the size of |this| buffer, and
+ // write the result into |this|.
+ void CropAndScaleFrom(const I410BufferInterface& src,
+ int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height);
+
+ // Scale all of `src` to the size of `this` buffer, with no cropping.
+ void ScaleFrom(const I410BufferInterface& src);
+
+ protected:
+ I410Buffer(int width, int height);
+ I410Buffer(int width, int height, int stride_y, int stride_u, int stride_v);
+
+ ~I410Buffer() override;
+
+ private:
+ const int width_;
+ const int height_;
+ const int stride_y_;
+ const int stride_u_;
+ const int stride_v_;
+ const std::unique_ptr<uint16_t, AlignedFreeDeleter> data_;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_I410_BUFFER_H_
diff --git a/third_party/libwebrtc/api/video/i420_buffer.cc b/third_party/libwebrtc/api/video/i420_buffer.cc
new file mode 100644
index 0000000000..bf7fc06ee9
--- /dev/null
+++ b/third_party/libwebrtc/api/video/i420_buffer.cc
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/video/i420_buffer.h"
+
+#include <string.h>
+
+#include <algorithm>
+#include <utility>
+
+#include "api/make_ref_counted.h"
+#include "rtc_base/checks.h"
+#include "third_party/libyuv/include/libyuv/convert.h"
+#include "third_party/libyuv/include/libyuv/planar_functions.h"
+#include "third_party/libyuv/include/libyuv/scale.h"
+
+// Aligning pointer to 64 bytes for improved performance, e.g. use SIMD.
+static const int kBufferAlignment = 64;
+
+namespace webrtc {
+
+namespace {
+
+int I420DataSize(int height, int stride_y, int stride_u, int stride_v) {
+ return stride_y * height + (stride_u + stride_v) * ((height + 1) / 2);
+}
+
+} // namespace
+
+I420Buffer::I420Buffer(int width, int height)
+ : I420Buffer(width, height, width, (width + 1) / 2, (width + 1) / 2) {}
+
+I420Buffer::I420Buffer(int width,
+ int height,
+ int stride_y,
+ int stride_u,
+ int stride_v)
+ : width_(width),
+ height_(height),
+ stride_y_(stride_y),
+ stride_u_(stride_u),
+ stride_v_(stride_v),
+ data_(static_cast<uint8_t*>(
+ AlignedMalloc(I420DataSize(height, stride_y, stride_u, stride_v),
+ kBufferAlignment))) {
+ RTC_DCHECK_GT(width, 0);
+ RTC_DCHECK_GT(height, 0);
+ RTC_DCHECK_GE(stride_y, width);
+ RTC_DCHECK_GE(stride_u, (width + 1) / 2);
+ RTC_DCHECK_GE(stride_v, (width + 1) / 2);
+}
+
+I420Buffer::~I420Buffer() {}
+
+// static
+rtc::scoped_refptr<I420Buffer> I420Buffer::Create(int width, int height) {
+ return rtc::make_ref_counted<I420Buffer>(width, height);
+}
+
+// static
+rtc::scoped_refptr<I420Buffer> I420Buffer::Create(int width,
+ int height,
+ int stride_y,
+ int stride_u,
+ int stride_v) {
+ return rtc::make_ref_counted<I420Buffer>(width, height, stride_y, stride_u,
+ stride_v);
+}
+
+// static
+rtc::scoped_refptr<I420Buffer> I420Buffer::Copy(
+ const I420BufferInterface& source) {
+ return Copy(source.width(), source.height(), source.DataY(), source.StrideY(),
+ source.DataU(), source.StrideU(), source.DataV(),
+ source.StrideV());
+}
+
+// static
+rtc::scoped_refptr<I420Buffer> I420Buffer::Copy(int width,
+ int height,
+ const uint8_t* data_y,
+ int stride_y,
+ const uint8_t* data_u,
+ int stride_u,
+ const uint8_t* data_v,
+ int stride_v) {
+ // Note: May use different strides than the input data.
+ rtc::scoped_refptr<I420Buffer> buffer = Create(width, height);
+ RTC_CHECK_EQ(0, libyuv::I420Copy(data_y, stride_y, data_u, stride_u, data_v,
+ stride_v, buffer->MutableDataY(),
+ buffer->StrideY(), buffer->MutableDataU(),
+ buffer->StrideU(), buffer->MutableDataV(),
+ buffer->StrideV(), width, height));
+ return buffer;
+}
+
+// static
+rtc::scoped_refptr<I420Buffer> I420Buffer::Rotate(
+ const I420BufferInterface& src,
+ VideoRotation rotation) {
+ RTC_CHECK(src.DataY());
+ RTC_CHECK(src.DataU());
+ RTC_CHECK(src.DataV());
+
+ int rotated_width = src.width();
+ int rotated_height = src.height();
+ if (rotation == webrtc::kVideoRotation_90 ||
+ rotation == webrtc::kVideoRotation_270) {
+ std::swap(rotated_width, rotated_height);
+ }
+
+ rtc::scoped_refptr<webrtc::I420Buffer> buffer =
+ I420Buffer::Create(rotated_width, rotated_height);
+
+ RTC_CHECK_EQ(0,
+ libyuv::I420Rotate(
+ src.DataY(), src.StrideY(), src.DataU(), src.StrideU(),
+ src.DataV(), src.StrideV(), buffer->MutableDataY(),
+ buffer->StrideY(), buffer->MutableDataU(), buffer->StrideU(),
+ buffer->MutableDataV(), buffer->StrideV(), src.width(),
+ src.height(), static_cast<libyuv::RotationMode>(rotation)));
+
+ return buffer;
+}
+
+void I420Buffer::InitializeData() {
+ memset(data_.get(), 0,
+ I420DataSize(height_, stride_y_, stride_u_, stride_v_));
+}
+
+int I420Buffer::width() const {
+ return width_;
+}
+
+int I420Buffer::height() const {
+ return height_;
+}
+
+const uint8_t* I420Buffer::DataY() const {
+ return data_.get();
+}
+const uint8_t* I420Buffer::DataU() const {
+ return data_.get() + stride_y_ * height_;
+}
+const uint8_t* I420Buffer::DataV() const {
+ return data_.get() + stride_y_ * height_ + stride_u_ * ((height_ + 1) / 2);
+}
+
+int I420Buffer::StrideY() const {
+ return stride_y_;
+}
+int I420Buffer::StrideU() const {
+ return stride_u_;
+}
+int I420Buffer::StrideV() const {
+ return stride_v_;
+}
+
+uint8_t* I420Buffer::MutableDataY() {
+ return const_cast<uint8_t*>(DataY());
+}
+uint8_t* I420Buffer::MutableDataU() {
+ return const_cast<uint8_t*>(DataU());
+}
+uint8_t* I420Buffer::MutableDataV() {
+ return const_cast<uint8_t*>(DataV());
+}
+
+// static
+void I420Buffer::SetBlack(I420Buffer* buffer) {
+ RTC_CHECK(libyuv::I420Rect(buffer->MutableDataY(), buffer->StrideY(),
+ buffer->MutableDataU(), buffer->StrideU(),
+ buffer->MutableDataV(), buffer->StrideV(), 0, 0,
+ buffer->width(), buffer->height(), 0, 128,
+ 128) == 0);
+}
+
+void I420Buffer::CropAndScaleFrom(const I420BufferInterface& src,
+ int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height) {
+ RTC_CHECK_LE(crop_width, src.width());
+ RTC_CHECK_LE(crop_height, src.height());
+ RTC_CHECK_LE(crop_width + offset_x, src.width());
+ RTC_CHECK_LE(crop_height + offset_y, src.height());
+ RTC_CHECK_GE(offset_x, 0);
+ RTC_CHECK_GE(offset_y, 0);
+
+ // Make sure offset is even so that u/v plane becomes aligned.
+ const int uv_offset_x = offset_x / 2;
+ const int uv_offset_y = offset_y / 2;
+ offset_x = uv_offset_x * 2;
+ offset_y = uv_offset_y * 2;
+
+ const uint8_t* y_plane = src.DataY() + src.StrideY() * offset_y + offset_x;
+ const uint8_t* u_plane =
+ src.DataU() + src.StrideU() * uv_offset_y + uv_offset_x;
+ const uint8_t* v_plane =
+ src.DataV() + src.StrideV() * uv_offset_y + uv_offset_x;
+ int res =
+ libyuv::I420Scale(y_plane, src.StrideY(), u_plane, src.StrideU(), v_plane,
+ src.StrideV(), crop_width, crop_height, MutableDataY(),
+ StrideY(), MutableDataU(), StrideU(), MutableDataV(),
+ StrideV(), width(), height(), libyuv::kFilterBox);
+
+ RTC_DCHECK_EQ(res, 0);
+}
+
+void I420Buffer::CropAndScaleFrom(const I420BufferInterface& src) {
+ const int crop_width =
+ height() > 0 ? std::min(src.width(), width() * src.height() / height())
+ : src.width();
+ const int crop_height =
+ width() > 0 ? std::min(src.height(), height() * src.width() / width())
+ : src.height();
+
+ CropAndScaleFrom(src, (src.width() - crop_width) / 2,
+ (src.height() - crop_height) / 2, crop_width, crop_height);
+}
+
+void I420Buffer::ScaleFrom(const I420BufferInterface& src) {
+ CropAndScaleFrom(src, 0, 0, src.width(), src.height());
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/i420_buffer.h b/third_party/libwebrtc/api/video/i420_buffer.h
new file mode 100644
index 0000000000..b337489657
--- /dev/null
+++ b/third_party/libwebrtc/api/video/i420_buffer.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_I420_BUFFER_H_
+#define API_VIDEO_I420_BUFFER_H_
+
+#include <stdint.h>
+
+#include <memory>
+
+#include "api/scoped_refptr.h"
+#include "api/video/video_frame_buffer.h"
+#include "api/video/video_rotation.h"
+#include "rtc_base/memory/aligned_malloc.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Plain I420 buffer in standard memory.
+class RTC_EXPORT I420Buffer : public I420BufferInterface {
+ public:
+ static rtc::scoped_refptr<I420Buffer> Create(int width, int height);
+ static rtc::scoped_refptr<I420Buffer> Create(int width,
+ int height,
+ int stride_y,
+ int stride_u,
+ int stride_v);
+
+ // Create a new buffer and copy the pixel data.
+ static rtc::scoped_refptr<I420Buffer> Copy(const I420BufferInterface& buffer);
+ // Deprecated.
+ static rtc::scoped_refptr<I420Buffer> Copy(const VideoFrameBuffer& buffer) {
+ return Copy(*buffer.GetI420());
+ }
+
+ static rtc::scoped_refptr<I420Buffer> Copy(int width,
+ int height,
+ const uint8_t* data_y,
+ int stride_y,
+ const uint8_t* data_u,
+ int stride_u,
+ const uint8_t* data_v,
+ int stride_v);
+
+ // Returns a rotated copy of `src`.
+ static rtc::scoped_refptr<I420Buffer> Rotate(const I420BufferInterface& src,
+ VideoRotation rotation);
+ // Deprecated.
+ static rtc::scoped_refptr<I420Buffer> Rotate(const VideoFrameBuffer& src,
+ VideoRotation rotation) {
+ return Rotate(*src.GetI420(), rotation);
+ }
+
+ // Sets the buffer to all black.
+ static void SetBlack(I420Buffer* buffer);
+
+ // Sets all three planes to all zeros. Used to work around for
+ // quirks in memory checkers
+ // (https://bugs.chromium.org/p/libyuv/issues/detail?id=377) and
+ // ffmpeg (http://crbug.com/390941).
+ // TODO(https://crbug.com/390941): Deprecated. Should be deleted if/when those
+ // issues are resolved in a better way. Or in the mean time, use SetBlack.
+ void InitializeData();
+
+ int width() const override;
+ int height() const override;
+ const uint8_t* DataY() const override;
+ const uint8_t* DataU() const override;
+ const uint8_t* DataV() const override;
+
+ int StrideY() const override;
+ int StrideU() const override;
+ int StrideV() const override;
+
+ uint8_t* MutableDataY();
+ uint8_t* MutableDataU();
+ uint8_t* MutableDataV();
+
+ // Scale the cropped area of `src` to the size of `this` buffer, and
+ // write the result into `this`.
+ void CropAndScaleFrom(const I420BufferInterface& src,
+ int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height);
+
+ // The common case of a center crop, when needed to adjust the
+ // aspect ratio without distorting the image.
+ void CropAndScaleFrom(const I420BufferInterface& src);
+
+ // Scale all of `src` to the size of `this` buffer, with no cropping.
+ void ScaleFrom(const I420BufferInterface& src);
+
+ protected:
+ I420Buffer(int width, int height);
+ I420Buffer(int width, int height, int stride_y, int stride_u, int stride_v);
+
+ ~I420Buffer() override;
+
+ private:
+ const int width_;
+ const int height_;
+ const int stride_y_;
+ const int stride_u_;
+ const int stride_v_;
+ const std::unique_ptr<uint8_t, AlignedFreeDeleter> data_;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_I420_BUFFER_H_
diff --git a/third_party/libwebrtc/api/video/i422_buffer.cc b/third_party/libwebrtc/api/video/i422_buffer.cc
new file mode 100644
index 0000000000..fddc1b57fd
--- /dev/null
+++ b/third_party/libwebrtc/api/video/i422_buffer.cc
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/video/i422_buffer.h"
+
+#include <string.h>
+
+#include <algorithm>
+#include <utility>
+
+#include "api/make_ref_counted.h"
+#include "api/video/i420_buffer.h"
+#include "rtc_base/checks.h"
+#include "third_party/libyuv/include/libyuv/convert.h"
+#include "third_party/libyuv/include/libyuv/planar_functions.h"
+#include "third_party/libyuv/include/libyuv/scale.h"
+
+// Aligning pointer to 64 bytes for improved performance, e.g. use SIMD.
+static const int kBufferAlignment = 64;
+
+namespace webrtc {
+
+namespace {
+
+int I422DataSize(int height, int stride_y, int stride_u, int stride_v) {
+ return stride_y * height + stride_u * height + stride_v * height;
+}
+} // namespace
+
+I422Buffer::I422Buffer(int width, int height)
+ : I422Buffer(width, height, width, (width + 1) / 2, (width + 1) / 2) {}
+
+I422Buffer::I422Buffer(int width,
+ int height,
+ int stride_y,
+ int stride_u,
+ int stride_v)
+ : width_(width),
+ height_(height),
+ stride_y_(stride_y),
+ stride_u_(stride_u),
+ stride_v_(stride_v),
+ data_(static_cast<uint8_t*>(
+ AlignedMalloc(I422DataSize(height, stride_y, stride_u, stride_v),
+ kBufferAlignment))) {
+ RTC_DCHECK_GT(width, 0);
+ RTC_DCHECK_GT(height, 0);
+ RTC_DCHECK_GE(stride_y, width);
+ RTC_DCHECK_GE(stride_u, (width + 1) / 2);
+ RTC_DCHECK_GE(stride_v, (width + 1) / 2);
+}
+
+I422Buffer::~I422Buffer() {}
+
+// static
+rtc::scoped_refptr<I422Buffer> I422Buffer::Create(int width, int height) {
+ return rtc::make_ref_counted<I422Buffer>(width, height);
+}
+
+// static
+rtc::scoped_refptr<I422Buffer> I422Buffer::Create(int width,
+ int height,
+ int stride_y,
+ int stride_u,
+ int stride_v) {
+ return rtc::make_ref_counted<I422Buffer>(width, height, stride_y, stride_u,
+ stride_v);
+}
+
+// static
+rtc::scoped_refptr<I422Buffer> I422Buffer::Copy(
+ const I422BufferInterface& source) {
+ return Copy(source.width(), source.height(), source.DataY(), source.StrideY(),
+ source.DataU(), source.StrideU(), source.DataV(),
+ source.StrideV());
+}
+
+// static
+rtc::scoped_refptr<I422Buffer> I422Buffer::Copy(
+ const I420BufferInterface& source) {
+ const int width = source.width();
+ const int height = source.height();
+ rtc::scoped_refptr<I422Buffer> buffer = Create(width, height);
+ int res = libyuv::I420ToI422(
+ source.DataY(), source.StrideY(), source.DataU(), source.StrideU(),
+ source.DataV(), source.StrideV(), buffer->MutableDataY(),
+ buffer->StrideY(), buffer->MutableDataU(), buffer->StrideU(),
+ buffer->MutableDataV(), buffer->StrideV(), width, height);
+ RTC_DCHECK_EQ(res, 0);
+
+ return buffer;
+}
+
+// static
+rtc::scoped_refptr<I422Buffer> I422Buffer::Copy(int width,
+ int height,
+ const uint8_t* data_y,
+ int stride_y,
+ const uint8_t* data_u,
+ int stride_u,
+ const uint8_t* data_v,
+ int stride_v) {
+ // Note: May use different strides than the input data.
+ rtc::scoped_refptr<I422Buffer> buffer = Create(width, height);
+ int res = libyuv::I422Copy(data_y, stride_y, data_u, stride_u, data_v,
+ stride_v, buffer->MutableDataY(),
+ buffer->StrideY(), buffer->MutableDataU(),
+ buffer->StrideU(), buffer->MutableDataV(),
+ buffer->StrideV(), width, height);
+ RTC_DCHECK_EQ(res, 0);
+
+ return buffer;
+}
+
+// static
+rtc::scoped_refptr<I422Buffer> I422Buffer::Rotate(
+ const I422BufferInterface& src,
+ VideoRotation rotation) {
+ RTC_CHECK(src.DataY());
+ RTC_CHECK(src.DataU());
+ RTC_CHECK(src.DataV());
+
+ int rotated_width = src.width();
+ int rotated_height = src.height();
+ if (rotation == webrtc::kVideoRotation_90 ||
+ rotation == webrtc::kVideoRotation_270) {
+ std::swap(rotated_width, rotated_height);
+ }
+
+ rtc::scoped_refptr<webrtc::I422Buffer> buffer =
+ I422Buffer::Create(rotated_width, rotated_height);
+
+ int res = libyuv::I422Rotate(
+ src.DataY(), src.StrideY(), src.DataU(), src.StrideU(), src.DataV(),
+ src.StrideV(), buffer->MutableDataY(), buffer->StrideY(),
+ buffer->MutableDataU(), buffer->StrideU(), buffer->MutableDataV(),
+ buffer->StrideV(), src.width(), src.height(),
+ static_cast<libyuv::RotationMode>(rotation));
+ RTC_DCHECK_EQ(res, 0);
+
+ return buffer;
+}
+
+rtc::scoped_refptr<I420BufferInterface> I422Buffer::ToI420() {
+ rtc::scoped_refptr<I420Buffer> i420_buffer =
+ I420Buffer::Create(width(), height());
+ int res = libyuv::I422ToI420(
+ DataY(), StrideY(), DataU(), StrideU(), DataV(), StrideV(),
+ i420_buffer->MutableDataY(), i420_buffer->StrideY(),
+ i420_buffer->MutableDataU(), i420_buffer->StrideU(),
+ i420_buffer->MutableDataV(), i420_buffer->StrideV(), width(), height());
+ RTC_DCHECK_EQ(res, 0);
+
+ return i420_buffer;
+}
+
+void I422Buffer::InitializeData() {
+ memset(data_.get(), 0,
+ I422DataSize(height_, stride_y_, stride_u_, stride_v_));
+}
+
+int I422Buffer::width() const {
+ return width_;
+}
+
+int I422Buffer::height() const {
+ return height_;
+}
+
+const uint8_t* I422Buffer::DataY() const {
+ return data_.get();
+}
+const uint8_t* I422Buffer::DataU() const {
+ return data_.get() + stride_y_ * height_;
+}
+const uint8_t* I422Buffer::DataV() const {
+ return data_.get() + stride_y_ * height_ + stride_u_ * height_;
+}
+
+int I422Buffer::StrideY() const {
+ return stride_y_;
+}
+int I422Buffer::StrideU() const {
+ return stride_u_;
+}
+int I422Buffer::StrideV() const {
+ return stride_v_;
+}
+
+uint8_t* I422Buffer::MutableDataY() {
+ return const_cast<uint8_t*>(DataY());
+}
+uint8_t* I422Buffer::MutableDataU() {
+ return const_cast<uint8_t*>(DataU());
+}
+uint8_t* I422Buffer::MutableDataV() {
+ return const_cast<uint8_t*>(DataV());
+}
+
+void I422Buffer::CropAndScaleFrom(const I422BufferInterface& src,
+ int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height) {
+ RTC_CHECK_LE(crop_width, src.width());
+ RTC_CHECK_LE(crop_height, src.height());
+ RTC_CHECK_LE(crop_width + offset_x, src.width());
+ RTC_CHECK_LE(crop_height + offset_y, src.height());
+ RTC_CHECK_GE(offset_x, 0);
+ RTC_CHECK_GE(offset_y, 0);
+
+ // Make sure offset is even so that u/v plane becomes aligned.
+ const int uv_offset_x = offset_x / 2;
+ const int uv_offset_y = offset_y;
+ offset_x = uv_offset_x * 2;
+
+ const uint8_t* y_plane = src.DataY() + src.StrideY() * offset_y + offset_x;
+ const uint8_t* u_plane =
+ src.DataU() + src.StrideU() * uv_offset_y + uv_offset_x;
+ const uint8_t* v_plane =
+ src.DataV() + src.StrideV() * uv_offset_y + uv_offset_x;
+
+ int res =
+ libyuv::I422Scale(y_plane, src.StrideY(), u_plane, src.StrideU(), v_plane,
+ src.StrideV(), crop_width, crop_height, MutableDataY(),
+ StrideY(), MutableDataU(), StrideU(), MutableDataV(),
+ StrideV(), width(), height(), libyuv::kFilterBox);
+ RTC_DCHECK_EQ(res, 0);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/i422_buffer.h b/third_party/libwebrtc/api/video/i422_buffer.h
new file mode 100644
index 0000000000..600b4ecea7
--- /dev/null
+++ b/third_party/libwebrtc/api/video/i422_buffer.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_I422_BUFFER_H_
+#define API_VIDEO_I422_BUFFER_H_
+
+#include <stdint.h>
+
+#include <memory>
+
+#include "api/scoped_refptr.h"
+#include "api/video/video_frame_buffer.h"
+#include "api/video/video_rotation.h"
+#include "rtc_base/memory/aligned_malloc.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Plain I422 buffer in standard memory.
+class RTC_EXPORT I422Buffer : public I422BufferInterface {
+ public:
+ static rtc::scoped_refptr<I422Buffer> Create(int width, int height);
+ static rtc::scoped_refptr<I422Buffer> Create(int width,
+ int height,
+ int stride_y,
+ int stride_u,
+ int stride_v);
+
+ // Create a new buffer and copy the pixel data.
+ static rtc::scoped_refptr<I422Buffer> Copy(const I422BufferInterface& buffer);
+ /// Convert and put I420 buffer into a new buffer.
+ static rtc::scoped_refptr<I422Buffer> Copy(const I420BufferInterface& buffer);
+
+ static rtc::scoped_refptr<I422Buffer> Copy(int width,
+ int height,
+ const uint8_t* data_y,
+ int stride_y,
+ const uint8_t* data_u,
+ int stride_u,
+ const uint8_t* data_v,
+ int stride_v);
+
+ // Returns a rotated copy of `src`.
+ static rtc::scoped_refptr<I422Buffer> Rotate(const I422BufferInterface& src,
+ VideoRotation rotation);
+
+ rtc::scoped_refptr<I420BufferInterface> ToI420() final;
+ const I420BufferInterface* GetI420() const final { return nullptr; }
+
+ // Sets the buffer to all black.
+ static void SetBlack(I422Buffer* buffer);
+
+ // Sets all three planes to all zeros. Used to work around for
+ // quirks in memory checkers
+ // (https://bugs.chromium.org/p/libyuv/issues/detail?id=377) and
+ // ffmpeg (http://crbug.com/390941).
+ // TODO(https://crbug.com/390941): Deprecated. Should be deleted if/when those
+ // issues are resolved in a better way. Or in the mean time, use SetBlack.
+ void InitializeData();
+
+ int width() const override;
+ int height() const override;
+ const uint8_t* DataY() const override;
+ const uint8_t* DataU() const override;
+ const uint8_t* DataV() const override;
+
+ int StrideY() const override;
+ int StrideU() const override;
+ int StrideV() const override;
+
+ uint8_t* MutableDataY();
+ uint8_t* MutableDataU();
+ uint8_t* MutableDataV();
+
+ // Scale the cropped area of `src` to the size of `this` buffer, and
+ // write the result into `this`.
+ void CropAndScaleFrom(const I422BufferInterface& src,
+ int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height);
+
+ // The common case of a center crop, when needed to adjust the
+ // aspect ratio without distorting the image.
+ void CropAndScaleFrom(const I422BufferInterface& src);
+
+ // Scale all of `src` to the size of `this` buffer, with no cropping.
+ void ScaleFrom(const I422BufferInterface& src);
+
+ protected:
+ I422Buffer(int width, int height);
+ I422Buffer(int width, int height, int stride_y, int stride_u, int stride_v);
+
+ ~I422Buffer() override;
+
+ private:
+ const int width_;
+ const int height_;
+ const int stride_y_;
+ const int stride_u_;
+ const int stride_v_;
+ const std::unique_ptr<uint8_t, AlignedFreeDeleter> data_;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_I422_BUFFER_H_
diff --git a/third_party/libwebrtc/api/video/i444_buffer.cc b/third_party/libwebrtc/api/video/i444_buffer.cc
new file mode 100644
index 0000000000..98e892308f
--- /dev/null
+++ b/third_party/libwebrtc/api/video/i444_buffer.cc
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "api/video/i444_buffer.h"
+
+#include <string.h>
+
+#include <algorithm>
+#include <utility>
+
+#include "api/make_ref_counted.h"
+#include "api/video/i420_buffer.h"
+#include "rtc_base/checks.h"
+#include "third_party/libyuv/include/libyuv/convert.h"
+#include "third_party/libyuv/include/libyuv/planar_functions.h"
+#include "third_party/libyuv/include/libyuv/scale.h"
+
+// Aligning pointer to 64 bytes for improved performance, e.g. use SIMD.
+static const int kBufferAlignment = 64;
+
+namespace webrtc {
+
+namespace {
+
+int I444DataSize(int height, int stride_y, int stride_u, int stride_v) {
+ return stride_y * height + stride_u * height + stride_v * height;
+}
+
+} // namespace
+
+I444Buffer::I444Buffer(int width, int height)
+ : I444Buffer(width, height, width, (width), (width)) {}
+
+I444Buffer::I444Buffer(int width,
+ int height,
+ int stride_y,
+ int stride_u,
+ int stride_v)
+ : width_(width),
+ height_(height),
+ stride_y_(stride_y),
+ stride_u_(stride_u),
+ stride_v_(stride_v),
+ data_(static_cast<uint8_t*>(
+ AlignedMalloc(I444DataSize(height, stride_y, stride_u, stride_v),
+ kBufferAlignment))) {
+ RTC_DCHECK_GT(width, 0);
+ RTC_DCHECK_GT(height, 0);
+ RTC_DCHECK_GE(stride_y, width);
+ RTC_DCHECK_GE(stride_u, (width));
+ RTC_DCHECK_GE(stride_v, (width));
+}
+
+I444Buffer::~I444Buffer() {}
+
+// static
+rtc::scoped_refptr<I444Buffer> I444Buffer::Create(int width, int height) {
+ return rtc::make_ref_counted<I444Buffer>(width, height);
+}
+
+// static
+rtc::scoped_refptr<I444Buffer> I444Buffer::Create(int width,
+ int height,
+ int stride_y,
+ int stride_u,
+ int stride_v) {
+ return rtc::make_ref_counted<I444Buffer>(width, height, stride_y, stride_u,
+ stride_v);
+}
+
+// static
+rtc::scoped_refptr<I444Buffer> I444Buffer::Copy(
+ const I444BufferInterface& source) {
+ return Copy(source.width(), source.height(), source.DataY(), source.StrideY(),
+ source.DataU(), source.StrideU(), source.DataV(),
+ source.StrideV());
+}
+
+// static
+rtc::scoped_refptr<I444Buffer> I444Buffer::Copy(int width,
+ int height,
+ const uint8_t* data_y,
+ int stride_y,
+ const uint8_t* data_u,
+ int stride_u,
+ const uint8_t* data_v,
+ int stride_v) {
+ // Note: May use different strides than the input data.
+ rtc::scoped_refptr<I444Buffer> buffer = Create(width, height);
+ RTC_CHECK_EQ(0, libyuv::I444Copy(data_y, stride_y, data_u, stride_u, data_v,
+ stride_v, buffer->MutableDataY(),
+ buffer->StrideY(), buffer->MutableDataU(),
+ buffer->StrideU(), buffer->MutableDataV(),
+ buffer->StrideV(), width, height));
+ return buffer;
+}
+
+// static
+rtc::scoped_refptr<I444Buffer> I444Buffer::Rotate(
+ const I444BufferInterface& src,
+ VideoRotation rotation) {
+ RTC_CHECK(src.DataY());
+ RTC_CHECK(src.DataU());
+ RTC_CHECK(src.DataV());
+
+ int rotated_width = src.width();
+ int rotated_height = src.height();
+ if (rotation == webrtc::kVideoRotation_90 ||
+ rotation == webrtc::kVideoRotation_270) {
+ std::swap(rotated_width, rotated_height);
+ }
+
+ rtc::scoped_refptr<webrtc::I444Buffer> buffer =
+ I444Buffer::Create(rotated_width, rotated_height);
+
+ RTC_CHECK_EQ(0,
+ libyuv::I444Rotate(
+ src.DataY(), src.StrideY(), src.DataU(), src.StrideU(),
+ src.DataV(), src.StrideV(), buffer->MutableDataY(),
+ buffer->StrideY(), buffer->MutableDataU(), buffer->StrideU(),
+ buffer->MutableDataV(), buffer->StrideV(), src.width(),
+ src.height(), static_cast<libyuv::RotationMode>(rotation)));
+
+ return buffer;
+}
+
+rtc::scoped_refptr<I420BufferInterface> I444Buffer::ToI420() {
+ rtc::scoped_refptr<I420Buffer> i420_buffer =
+ I420Buffer::Create(width(), height());
+ libyuv::I444ToI420(DataY(), StrideY(), DataU(), StrideU(), DataV(), StrideV(),
+ i420_buffer->MutableDataY(), i420_buffer->StrideY(),
+ i420_buffer->MutableDataU(), i420_buffer->StrideU(),
+ i420_buffer->MutableDataV(), i420_buffer->StrideV(),
+ width(), height());
+ return i420_buffer;
+}
+
+void I444Buffer::InitializeData() {
+ memset(data_.get(), 0,
+ I444DataSize(height_, stride_y_, stride_u_, stride_v_));
+}
+
+int I444Buffer::width() const {
+ return width_;
+}
+
+int I444Buffer::height() const {
+ return height_;
+}
+
+const uint8_t* I444Buffer::DataY() const {
+ return data_.get();
+}
+const uint8_t* I444Buffer::DataU() const {
+ return data_.get() + stride_y_ * height_;
+}
+const uint8_t* I444Buffer::DataV() const {
+ return data_.get() + stride_y_ * height_ + stride_u_ * ((height_));
+}
+
+int I444Buffer::StrideY() const {
+ return stride_y_;
+}
+int I444Buffer::StrideU() const {
+ return stride_u_;
+}
+int I444Buffer::StrideV() const {
+ return stride_v_;
+}
+
+uint8_t* I444Buffer::MutableDataY() {
+ return const_cast<uint8_t*>(DataY());
+}
+uint8_t* I444Buffer::MutableDataU() {
+ return const_cast<uint8_t*>(DataU());
+}
+uint8_t* I444Buffer::MutableDataV() {
+ return const_cast<uint8_t*>(DataV());
+}
+
+void I444Buffer::CropAndScaleFrom(const I444BufferInterface& src,
+ int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height) {
+ RTC_CHECK_LE(crop_width, src.width());
+ RTC_CHECK_LE(crop_height, src.height());
+ RTC_CHECK_LE(crop_width + offset_x, src.width());
+ RTC_CHECK_LE(crop_height + offset_y, src.height());
+ RTC_CHECK_GE(offset_x, 0);
+ RTC_CHECK_GE(offset_y, 0);
+
+ const uint8_t* y_plane = src.DataY() + src.StrideY() * offset_y + offset_x;
+ const uint8_t* u_plane = src.DataU() + src.StrideU() * offset_y + offset_x;
+ const uint8_t* v_plane = src.DataV() + src.StrideV() * offset_y + offset_x;
+ int res =
+ libyuv::I444Scale(y_plane, src.StrideY(), u_plane, src.StrideU(), v_plane,
+ src.StrideV(), crop_width, crop_height, MutableDataY(),
+ StrideY(), MutableDataU(), StrideU(), MutableDataV(),
+ StrideV(), width(), height(), libyuv::kFilterBox);
+
+ RTC_DCHECK_EQ(res, 0);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/i444_buffer.h b/third_party/libwebrtc/api/video/i444_buffer.h
new file mode 100644
index 0000000000..f1e3f63114
--- /dev/null
+++ b/third_party/libwebrtc/api/video/i444_buffer.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_I444_BUFFER_H_
+#define API_VIDEO_I444_BUFFER_H_
+
+#include <stdint.h>
+
+#include <memory>
+
+#include "api/scoped_refptr.h"
+#include "api/video/video_frame_buffer.h"
+#include "api/video/video_rotation.h"
+#include "rtc_base/memory/aligned_malloc.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Plain I444 buffer in standard memory.
+// I444 represents an image with in YUV format withouth any chroma subsampling.
+// https://en.wikipedia.org/wiki/Chroma_subsampling#4:4:4
+class RTC_EXPORT I444Buffer : public I444BufferInterface {
+ public:
+ static rtc::scoped_refptr<I444Buffer> Create(int width, int height);
+ static rtc::scoped_refptr<I444Buffer> Create(int width,
+ int height,
+ int stride_y,
+ int stride_u,
+ int stride_v);
+
+ // Create a new buffer and copy the pixel data.
+ static rtc::scoped_refptr<I444Buffer> Copy(const I444BufferInterface& buffer);
+
+ static rtc::scoped_refptr<I444Buffer> Copy(int width,
+ int height,
+ const uint8_t* data_y,
+ int stride_y,
+ const uint8_t* data_u,
+ int stride_u,
+ const uint8_t* data_v,
+ int stride_v);
+
+ // Returns a rotated copy of |src|.
+ static rtc::scoped_refptr<I444Buffer> Rotate(const I444BufferInterface& src,
+ VideoRotation rotation);
+
+ rtc::scoped_refptr<I420BufferInterface> ToI420() final;
+ const I420BufferInterface* GetI420() const final { return nullptr; }
+
+ // Sets all three planes to all zeros. Used to work around for
+ // quirks in memory checkers
+ // (https://bugs.chromium.org/p/libyuv/issues/detail?id=377) and
+ // ffmpeg (http://crbug.com/390941).
+ // TODO(https://crbug.com/390941): Deprecated. Should be deleted if/when those
+ // issues are resolved in a better way. Or in the mean time, use SetBlack.
+ void InitializeData();
+
+ int width() const override;
+ int height() const override;
+ const uint8_t* DataY() const override;
+ const uint8_t* DataU() const override;
+ const uint8_t* DataV() const override;
+
+ int StrideY() const override;
+ int StrideU() const override;
+ int StrideV() const override;
+
+ uint8_t* MutableDataY();
+ uint8_t* MutableDataU();
+ uint8_t* MutableDataV();
+
+ // Scale the cropped area of |src| to the size of |this| buffer, and
+ // write the result into |this|.
+ void CropAndScaleFrom(const I444BufferInterface& src,
+ int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height);
+
+ protected:
+ I444Buffer(int width, int height);
+ I444Buffer(int width, int height, int stride_y, int stride_u, int stride_v);
+
+ ~I444Buffer() override;
+
+ private:
+ const int width_;
+ const int height_;
+ const int stride_y_;
+ const int stride_u_;
+ const int stride_v_;
+ const std::unique_ptr<uint8_t, AlignedFreeDeleter> data_;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_I444_BUFFER_H_
diff --git a/third_party/libwebrtc/api/video/nv12_buffer.cc b/third_party/libwebrtc/api/video/nv12_buffer.cc
new file mode 100644
index 0000000000..ca9dcd8677
--- /dev/null
+++ b/third_party/libwebrtc/api/video/nv12_buffer.cc
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/nv12_buffer.h"
+
+#include "api/make_ref_counted.h"
+#include "api/video/i420_buffer.h"
+#include "rtc_base/checks.h"
+#include "third_party/libyuv/include/libyuv/convert.h"
+#include "third_party/libyuv/include/libyuv/scale.h"
+
+namespace webrtc {
+
+namespace {
+
+static const int kBufferAlignment = 64;
+
+int NV12DataSize(int height, int stride_y, int stride_uv) {
+ return stride_y * height + stride_uv * ((height + 1) / 2);
+}
+
+} // namespace
+
+NV12Buffer::NV12Buffer(int width, int height)
+ : NV12Buffer(width, height, width, width + width % 2) {}
+
+NV12Buffer::NV12Buffer(int width, int height, int stride_y, int stride_uv)
+ : width_(width),
+ height_(height),
+ stride_y_(stride_y),
+ stride_uv_(stride_uv),
+ data_(static_cast<uint8_t*>(
+ AlignedMalloc(NV12DataSize(height_, stride_y_, stride_uv),
+ kBufferAlignment))) {
+ RTC_DCHECK_GT(width, 0);
+ RTC_DCHECK_GT(height, 0);
+ RTC_DCHECK_GE(stride_y, width);
+ RTC_DCHECK_GE(stride_uv, (width + width % 2));
+}
+
+NV12Buffer::~NV12Buffer() = default;
+
+// static
+rtc::scoped_refptr<NV12Buffer> NV12Buffer::Create(int width, int height) {
+ return rtc::make_ref_counted<NV12Buffer>(width, height);
+}
+
+// static
+rtc::scoped_refptr<NV12Buffer> NV12Buffer::Create(int width,
+ int height,
+ int stride_y,
+ int stride_uv) {
+ return rtc::make_ref_counted<NV12Buffer>(width, height, stride_y, stride_uv);
+}
+
+// static
+rtc::scoped_refptr<NV12Buffer> NV12Buffer::Copy(
+ const I420BufferInterface& i420_buffer) {
+ rtc::scoped_refptr<NV12Buffer> buffer =
+ NV12Buffer::Create(i420_buffer.width(), i420_buffer.height());
+ libyuv::I420ToNV12(
+ i420_buffer.DataY(), i420_buffer.StrideY(), i420_buffer.DataU(),
+ i420_buffer.StrideU(), i420_buffer.DataV(), i420_buffer.StrideV(),
+ buffer->MutableDataY(), buffer->StrideY(), buffer->MutableDataUV(),
+ buffer->StrideUV(), buffer->width(), buffer->height());
+ return buffer;
+}
+
+rtc::scoped_refptr<I420BufferInterface> NV12Buffer::ToI420() {
+ rtc::scoped_refptr<I420Buffer> i420_buffer =
+ I420Buffer::Create(width(), height());
+ libyuv::NV12ToI420(DataY(), StrideY(), DataUV(), StrideUV(),
+ i420_buffer->MutableDataY(), i420_buffer->StrideY(),
+ i420_buffer->MutableDataU(), i420_buffer->StrideU(),
+ i420_buffer->MutableDataV(), i420_buffer->StrideV(),
+ width(), height());
+ return i420_buffer;
+}
+
+int NV12Buffer::width() const {
+ return width_;
+}
+int NV12Buffer::height() const {
+ return height_;
+}
+
+int NV12Buffer::StrideY() const {
+ return stride_y_;
+}
+int NV12Buffer::StrideUV() const {
+ return stride_uv_;
+}
+
+const uint8_t* NV12Buffer::DataY() const {
+ return data_.get();
+}
+
+const uint8_t* NV12Buffer::DataUV() const {
+ return data_.get() + UVOffset();
+}
+
+uint8_t* NV12Buffer::MutableDataY() {
+ return data_.get();
+}
+
+uint8_t* NV12Buffer::MutableDataUV() {
+ return data_.get() + UVOffset();
+}
+
+size_t NV12Buffer::UVOffset() const {
+ return stride_y_ * height_;
+}
+
+void NV12Buffer::InitializeData() {
+ memset(data_.get(), 0, NV12DataSize(height_, stride_y_, stride_uv_));
+}
+
+void NV12Buffer::CropAndScaleFrom(const NV12BufferInterface& src,
+ int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height) {
+ RTC_CHECK_LE(crop_width, src.width());
+ RTC_CHECK_LE(crop_height, src.height());
+ RTC_CHECK_LE(crop_width + offset_x, src.width());
+ RTC_CHECK_LE(crop_height + offset_y, src.height());
+ RTC_CHECK_GE(offset_x, 0);
+ RTC_CHECK_GE(offset_y, 0);
+
+ // Make sure offset is even so that u/v plane becomes aligned.
+ const int uv_offset_x = offset_x / 2;
+ const int uv_offset_y = offset_y / 2;
+ offset_x = uv_offset_x * 2;
+ offset_y = uv_offset_y * 2;
+
+ const uint8_t* y_plane = src.DataY() + src.StrideY() * offset_y + offset_x;
+ const uint8_t* uv_plane =
+ src.DataUV() + src.StrideUV() * uv_offset_y + uv_offset_x * 2;
+
+ int res = libyuv::NV12Scale(y_plane, src.StrideY(), uv_plane, src.StrideUV(),
+ crop_width, crop_height, MutableDataY(),
+ StrideY(), MutableDataUV(), StrideUV(), width(),
+ height(), libyuv::kFilterBox);
+
+ RTC_DCHECK_EQ(res, 0);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/nv12_buffer.h b/third_party/libwebrtc/api/video/nv12_buffer.h
new file mode 100644
index 0000000000..46a85f82e1
--- /dev/null
+++ b/third_party/libwebrtc/api/video/nv12_buffer.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_NV12_BUFFER_H_
+#define API_VIDEO_NV12_BUFFER_H_
+
+#include <memory>
+#include <utility>
+
+#include "api/scoped_refptr.h"
+#include "api/video/video_frame_buffer.h"
+#include "rtc_base/memory/aligned_malloc.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// NV12 is a biplanar encoding format, with full-resolution Y and
+// half-resolution interleved UV. More information can be found at
+// http://msdn.microsoft.com/library/windows/desktop/dd206750.aspx#nv12.
+class RTC_EXPORT NV12Buffer : public NV12BufferInterface {
+ public:
+ static rtc::scoped_refptr<NV12Buffer> Create(int width, int height);
+ static rtc::scoped_refptr<NV12Buffer> Create(int width,
+ int height,
+ int stride_y,
+ int stride_uv);
+ static rtc::scoped_refptr<NV12Buffer> Copy(
+ const I420BufferInterface& i420_buffer);
+
+ rtc::scoped_refptr<I420BufferInterface> ToI420() override;
+
+ int width() const override;
+ int height() const override;
+
+ int StrideY() const override;
+ int StrideUV() const override;
+
+ const uint8_t* DataY() const override;
+ const uint8_t* DataUV() const override;
+
+ uint8_t* MutableDataY();
+ uint8_t* MutableDataUV();
+
+ // Sets all three planes to all zeros. Used to work around for
+ // quirks in memory checkers
+ // (https://bugs.chromium.org/p/libyuv/issues/detail?id=377) and
+ // ffmpeg (http://crbug.com/390941).
+ // TODO(https://crbug.com/390941): Deprecated. Should be deleted if/when those
+ // issues are resolved in a better way. Or in the mean time, use SetBlack.
+ void InitializeData();
+
+ // Scale the cropped area of `src` to the size of `this` buffer, and
+ // write the result into `this`.
+ void CropAndScaleFrom(const NV12BufferInterface& src,
+ int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height);
+
+ protected:
+ NV12Buffer(int width, int height);
+ NV12Buffer(int width, int height, int stride_y, int stride_uv);
+
+ ~NV12Buffer() override;
+
+ private:
+ size_t UVOffset() const;
+
+ const int width_;
+ const int height_;
+ const int stride_y_;
+ const int stride_uv_;
+ const std::unique_ptr<uint8_t, AlignedFreeDeleter> data_;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_NV12_BUFFER_H_
diff --git a/third_party/libwebrtc/api/video/recordable_encoded_frame.h b/third_party/libwebrtc/api/video/recordable_encoded_frame.h
new file mode 100644
index 0000000000..47ea23f119
--- /dev/null
+++ b/third_party/libwebrtc/api/video/recordable_encoded_frame.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_RECORDABLE_ENCODED_FRAME_H_
+#define API_VIDEO_RECORDABLE_ENCODED_FRAME_H_
+
+#include "api/array_view.h"
+#include "api/scoped_refptr.h"
+#include "api/units/timestamp.h"
+#include "api/video/color_space.h"
+#include "api/video/encoded_image.h"
+#include "api/video/video_codec_type.h"
+
+namespace webrtc {
+
+// Interface for accessing recordable elements of an encoded frame.
+class RecordableEncodedFrame {
+ public:
+ // Encoded resolution in pixels
+ // TODO(bugs.webrtc.org/12114) : remove in favor of Resolution.
+ struct EncodedResolution {
+ bool empty() const { return width == 0 && height == 0; }
+
+ unsigned width = 0;
+ unsigned height = 0;
+ };
+
+ virtual ~RecordableEncodedFrame() = default;
+
+ // Provides access to encoded data
+ virtual rtc::scoped_refptr<const EncodedImageBufferInterface> encoded_buffer()
+ const = 0;
+
+ // Optionally returns the colorspace of the encoded frame. This can differ
+ // from the eventually decoded frame's colorspace.
+ virtual absl::optional<webrtc::ColorSpace> color_space() const = 0;
+
+ // Returns the codec of the encoded frame
+ virtual VideoCodecType codec() const = 0;
+
+ // Returns whether the encoded frame is a key frame
+ virtual bool is_key_frame() const = 0;
+
+ // Returns the frame's encoded resolution. May be 0x0 if the frame
+ // doesn't contain resolution information
+ virtual EncodedResolution resolution() const = 0;
+
+ // Returns the computed render time
+ virtual Timestamp render_time() const = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_RECORDABLE_ENCODED_FRAME_H_
diff --git a/third_party/libwebrtc/api/video/recordable_encoded_frame_gn/moz.build b/third_party/libwebrtc/api/video/recordable_encoded_frame_gn/moz.build
new file mode 100644
index 0000000000..af294ef3ca
--- /dev/null
+++ b/third_party/libwebrtc/api/video/recordable_encoded_frame_gn/moz.build
@@ -0,0 +1,209 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("recordable_encoded_frame_gn")
diff --git a/third_party/libwebrtc/api/video/render_resolution.h b/third_party/libwebrtc/api/video/render_resolution.h
new file mode 100644
index 0000000000..fcf4f122d6
--- /dev/null
+++ b/third_party/libwebrtc/api/video/render_resolution.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_RENDER_RESOLUTION_H_
+#define API_VIDEO_RENDER_RESOLUTION_H_
+
+namespace webrtc {
+
+// TODO(bugs.webrtc.org/12114) : remove in favor of Resolution.
+class RenderResolution {
+ public:
+ constexpr RenderResolution() = default;
+ constexpr RenderResolution(int width, int height)
+ : width_(width), height_(height) {}
+ RenderResolution(const RenderResolution&) = default;
+ RenderResolution& operator=(const RenderResolution&) = default;
+
+ friend bool operator==(const RenderResolution& lhs,
+ const RenderResolution& rhs) {
+ return lhs.width_ == rhs.width_ && lhs.height_ == rhs.height_;
+ }
+ friend bool operator!=(const RenderResolution& lhs,
+ const RenderResolution& rhs) {
+ return !(lhs == rhs);
+ }
+
+ constexpr bool Valid() const { return width_ > 0 && height_ > 0; }
+
+ constexpr int Width() const { return width_; }
+ constexpr int Height() const { return height_; }
+
+ private:
+ int width_ = 0;
+ int height_ = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_RENDER_RESOLUTION_H_
diff --git a/third_party/libwebrtc/api/video/render_resolution_gn/moz.build b/third_party/libwebrtc/api/video/render_resolution_gn/moz.build
new file mode 100644
index 0000000000..5f97a983f8
--- /dev/null
+++ b/third_party/libwebrtc/api/video/render_resolution_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("render_resolution_gn")
diff --git a/third_party/libwebrtc/api/video/resolution.h b/third_party/libwebrtc/api/video/resolution.h
new file mode 100644
index 0000000000..11ffef0b03
--- /dev/null
+++ b/third_party/libwebrtc/api/video/resolution.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_RESOLUTION_H_
+#define API_VIDEO_RESOLUTION_H_
+
+#include <utility>
+
+namespace webrtc {
+
+// A struct representing a video resolution in pixels.
+struct Resolution {
+ int width = 0;
+ int height = 0;
+
+ // Helper methods.
+ int PixelCount() const { return width * height; }
+ std::pair<int, int> ToPair() const { return std::make_pair(width, height); }
+};
+
+inline bool operator==(const Resolution& lhs, const Resolution& rhs) {
+ return lhs.width == rhs.width && lhs.height == rhs.height;
+}
+
+inline bool operator!=(const Resolution& lhs, const Resolution& rhs) {
+ return !(lhs == rhs);
+}
+
+} // namespace webrtc
+
+#endif // API_VIDEO_RESOLUTION_H_
diff --git a/third_party/libwebrtc/api/video/resolution_gn/moz.build b/third_party/libwebrtc/api/video/resolution_gn/moz.build
new file mode 100644
index 0000000000..deafa478dd
--- /dev/null
+++ b/third_party/libwebrtc/api/video/resolution_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("resolution_gn")
diff --git a/third_party/libwebrtc/api/video/rtp_video_frame_assembler.cc b/third_party/libwebrtc/api/video/rtp_video_frame_assembler.cc
new file mode 100644
index 0000000000..b748534f3f
--- /dev/null
+++ b/third_party/libwebrtc/api/video/rtp_video_frame_assembler.cc
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/rtp_video_frame_assembler.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "absl/container/inlined_vector.h"
+#include "absl/types/optional.h"
+#include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h"
+#include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h"
+#include "modules/rtp_rtcp/source/rtp_packet_received.h"
+#include "modules/rtp_rtcp/source/video_rtp_depacketizer_av1.h"
+#include "modules/rtp_rtcp/source/video_rtp_depacketizer_generic.h"
+#include "modules/rtp_rtcp/source/video_rtp_depacketizer_h264.h"
+#include "modules/rtp_rtcp/source/video_rtp_depacketizer_raw.h"
+#include "modules/rtp_rtcp/source/video_rtp_depacketizer_vp8.h"
+#include "modules/rtp_rtcp/source/video_rtp_depacketizer_vp9.h"
+#include "modules/video_coding/frame_object.h"
+#include "modules/video_coding/packet_buffer.h"
+#include "modules/video_coding/rtp_frame_reference_finder.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/numerics/sequence_number_unwrapper.h"
+
+namespace webrtc {
+namespace {
+std::unique_ptr<VideoRtpDepacketizer> CreateDepacketizer(
+ RtpVideoFrameAssembler::PayloadFormat payload_format) {
+ switch (payload_format) {
+ case RtpVideoFrameAssembler::kRaw:
+ return std::make_unique<VideoRtpDepacketizerRaw>();
+ case RtpVideoFrameAssembler::kH264:
+ return std::make_unique<VideoRtpDepacketizerH264>();
+ case RtpVideoFrameAssembler::kVp8:
+ return std::make_unique<VideoRtpDepacketizerVp8>();
+ case RtpVideoFrameAssembler::kVp9:
+ return std::make_unique<VideoRtpDepacketizerVp9>();
+ case RtpVideoFrameAssembler::kAv1:
+ return std::make_unique<VideoRtpDepacketizerAv1>();
+ case RtpVideoFrameAssembler::kGeneric:
+ return std::make_unique<VideoRtpDepacketizerGeneric>();
+ }
+ RTC_DCHECK_NOTREACHED();
+ return nullptr;
+}
+} // namespace
+
+class RtpVideoFrameAssembler::Impl {
+ public:
+ explicit Impl(std::unique_ptr<VideoRtpDepacketizer> depacketizer);
+ ~Impl() = default;
+
+ FrameVector InsertPacket(const RtpPacketReceived& packet);
+
+ private:
+ using RtpFrameVector =
+ absl::InlinedVector<std::unique_ptr<RtpFrameObject>, 3>;
+
+ RtpFrameVector AssembleFrames(
+ video_coding::PacketBuffer::InsertResult insert_result);
+ FrameVector FindReferences(RtpFrameVector frames);
+ FrameVector UpdateWithPadding(uint16_t seq_num);
+ bool ParseDependenciesDescriptorExtension(const RtpPacketReceived& rtp_packet,
+ RTPVideoHeader& video_header);
+ bool ParseGenericDescriptorExtension(const RtpPacketReceived& rtp_packet,
+ RTPVideoHeader& video_header);
+ void ClearOldData(uint16_t incoming_seq_num);
+
+ std::unique_ptr<FrameDependencyStructure> video_structure_;
+ SeqNumUnwrapper<uint16_t> frame_id_unwrapper_;
+ absl::optional<int64_t> video_structure_frame_id_;
+ std::unique_ptr<VideoRtpDepacketizer> depacketizer_;
+ video_coding::PacketBuffer packet_buffer_;
+ RtpFrameReferenceFinder reference_finder_;
+};
+
+RtpVideoFrameAssembler::Impl::Impl(
+ std::unique_ptr<VideoRtpDepacketizer> depacketizer)
+ : depacketizer_(std::move(depacketizer)),
+ packet_buffer_(/*start_buffer_size=*/2048, /*max_buffer_size=*/2048) {}
+
+RtpVideoFrameAssembler::FrameVector RtpVideoFrameAssembler::Impl::InsertPacket(
+ const RtpPacketReceived& rtp_packet) {
+ if (rtp_packet.payload_size() == 0) {
+ ClearOldData(rtp_packet.SequenceNumber());
+ return UpdateWithPadding(rtp_packet.SequenceNumber());
+ }
+
+ absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload =
+ depacketizer_->Parse(rtp_packet.PayloadBuffer());
+
+ if (parsed_payload == absl::nullopt) {
+ return {};
+ }
+
+ if (rtp_packet.HasExtension<RtpDependencyDescriptorExtension>()) {
+ if (!ParseDependenciesDescriptorExtension(rtp_packet,
+ parsed_payload->video_header)) {
+ return {};
+ }
+ } else if (rtp_packet.HasExtension<RtpGenericFrameDescriptorExtension00>()) {
+ if (!ParseGenericDescriptorExtension(rtp_packet,
+ parsed_payload->video_header)) {
+ return {};
+ }
+ }
+
+ parsed_payload->video_header.is_last_packet_in_frame |= rtp_packet.Marker();
+
+ auto packet = std::make_unique<video_coding::PacketBuffer::Packet>(
+ rtp_packet, parsed_payload->video_header);
+ packet->video_payload = std::move(parsed_payload->video_payload);
+
+ ClearOldData(rtp_packet.SequenceNumber());
+ return FindReferences(
+ AssembleFrames(packet_buffer_.InsertPacket(std::move(packet))));
+}
+
+void RtpVideoFrameAssembler::Impl::ClearOldData(uint16_t incoming_seq_num) {
+ constexpr uint16_t kOldSeqNumThreshold = 2000;
+ uint16_t old_seq_num = incoming_seq_num - kOldSeqNumThreshold;
+ packet_buffer_.ClearTo(old_seq_num);
+ reference_finder_.ClearTo(old_seq_num);
+}
+
+RtpVideoFrameAssembler::Impl::RtpFrameVector
+RtpVideoFrameAssembler::Impl::AssembleFrames(
+ video_coding::PacketBuffer::InsertResult insert_result) {
+ video_coding::PacketBuffer::Packet* first_packet = nullptr;
+ std::vector<rtc::ArrayView<const uint8_t>> payloads;
+ RtpFrameVector result;
+
+ for (auto& packet : insert_result.packets) {
+ if (packet->is_first_packet_in_frame()) {
+ first_packet = packet.get();
+ payloads.clear();
+ }
+ payloads.emplace_back(packet->video_payload);
+
+ if (packet->is_last_packet_in_frame()) {
+ rtc::scoped_refptr<EncodedImageBuffer> bitstream =
+ depacketizer_->AssembleFrame(payloads);
+
+ if (!bitstream) {
+ continue;
+ }
+
+ const video_coding::PacketBuffer::Packet& last_packet = *packet;
+ result.push_back(std::make_unique<RtpFrameObject>(
+ first_packet->seq_num, //
+ last_packet.seq_num, //
+ last_packet.marker_bit, //
+ /*times_nacked=*/0, //
+ /*first_packet_received_time=*/0, //
+ /*last_packet_received_time=*/0, //
+ first_packet->timestamp, //
+ /*ntp_time_ms=*/0, //
+ /*timing=*/VideoSendTiming(), //
+ first_packet->payload_type, //
+ first_packet->codec(), //
+ last_packet.video_header.rotation, //
+ last_packet.video_header.content_type, //
+ first_packet->video_header, //
+ last_packet.video_header.color_space, //
+ /*packet_infos=*/RtpPacketInfos(), //
+ std::move(bitstream)));
+ }
+ }
+
+ return result;
+}
+
+RtpVideoFrameAssembler::FrameVector
+RtpVideoFrameAssembler::Impl::FindReferences(RtpFrameVector frames) {
+ FrameVector res;
+ for (auto& frame : frames) {
+ auto complete_frames = reference_finder_.ManageFrame(std::move(frame));
+ for (std::unique_ptr<RtpFrameObject>& complete_frame : complete_frames) {
+ uint16_t rtp_seq_num_start = complete_frame->first_seq_num();
+ uint16_t rtp_seq_num_end = complete_frame->last_seq_num();
+ res.emplace_back(rtp_seq_num_start, rtp_seq_num_end,
+ std::move(complete_frame));
+ }
+ }
+ return res;
+}
+
+RtpVideoFrameAssembler::FrameVector
+RtpVideoFrameAssembler::Impl::UpdateWithPadding(uint16_t seq_num) {
+ auto res =
+ FindReferences(AssembleFrames(packet_buffer_.InsertPadding(seq_num)));
+ auto ref_finder_update = reference_finder_.PaddingReceived(seq_num);
+
+ for (std::unique_ptr<RtpFrameObject>& complete_frame : ref_finder_update) {
+ uint16_t rtp_seq_num_start = complete_frame->first_seq_num();
+ uint16_t rtp_seq_num_end = complete_frame->last_seq_num();
+ res.emplace_back(rtp_seq_num_start, rtp_seq_num_end,
+ std::move(complete_frame));
+ }
+
+ return res;
+}
+
+bool RtpVideoFrameAssembler::Impl::ParseDependenciesDescriptorExtension(
+ const RtpPacketReceived& rtp_packet,
+ RTPVideoHeader& video_header) {
+ webrtc::DependencyDescriptor dependency_descriptor;
+
+ if (!rtp_packet.GetExtension<RtpDependencyDescriptorExtension>(
+ video_structure_.get(), &dependency_descriptor)) {
+ // Descriptor is either malformed, or the template referenced is not in
+ // the `video_structure_` currently being held.
+ // TODO(bugs.webrtc.org/10342): Improve packet reordering behavior.
+ RTC_LOG(LS_WARNING) << "ssrc: " << rtp_packet.Ssrc()
+ << " Failed to parse dependency descriptor.";
+ return false;
+ }
+
+ if (dependency_descriptor.attached_structure != nullptr &&
+ !dependency_descriptor.first_packet_in_frame) {
+ RTC_LOG(LS_WARNING) << "ssrc: " << rtp_packet.Ssrc()
+ << "Invalid dependency descriptor: structure "
+ "attached to non first packet of a frame.";
+ return false;
+ }
+
+ video_header.is_first_packet_in_frame =
+ dependency_descriptor.first_packet_in_frame;
+ video_header.is_last_packet_in_frame =
+ dependency_descriptor.last_packet_in_frame;
+
+ int64_t frame_id =
+ frame_id_unwrapper_.Unwrap(dependency_descriptor.frame_number);
+ auto& generic_descriptor_info = video_header.generic.emplace();
+ generic_descriptor_info.frame_id = frame_id;
+ generic_descriptor_info.spatial_index =
+ dependency_descriptor.frame_dependencies.spatial_id;
+ generic_descriptor_info.temporal_index =
+ dependency_descriptor.frame_dependencies.temporal_id;
+
+ for (int fdiff : dependency_descriptor.frame_dependencies.frame_diffs) {
+ generic_descriptor_info.dependencies.push_back(frame_id - fdiff);
+ }
+ for (int cdiff : dependency_descriptor.frame_dependencies.chain_diffs) {
+ generic_descriptor_info.chain_diffs.push_back(frame_id - cdiff);
+ }
+ generic_descriptor_info.decode_target_indications =
+ dependency_descriptor.frame_dependencies.decode_target_indications;
+ if (dependency_descriptor.resolution) {
+ video_header.width = dependency_descriptor.resolution->Width();
+ video_header.height = dependency_descriptor.resolution->Height();
+ }
+ if (dependency_descriptor.active_decode_targets_bitmask.has_value()) {
+ generic_descriptor_info.active_decode_targets =
+ *dependency_descriptor.active_decode_targets_bitmask;
+ }
+
+ // FrameDependencyStructure is sent in the dependency descriptor of the first
+ // packet of a key frame and is required to parse all subsequent packets until
+ // the next key frame.
+ if (dependency_descriptor.attached_structure) {
+ RTC_DCHECK(dependency_descriptor.first_packet_in_frame);
+ if (video_structure_frame_id_ > frame_id) {
+ RTC_LOG(LS_WARNING)
+ << "Arrived key frame with id " << frame_id << " and structure id "
+ << dependency_descriptor.attached_structure->structure_id
+ << " is older than the latest received key frame with id "
+ << *video_structure_frame_id_ << " and structure id "
+ << video_structure_->structure_id;
+ return false;
+ }
+ video_structure_ = std::move(dependency_descriptor.attached_structure);
+ video_structure_frame_id_ = frame_id;
+ video_header.frame_type = VideoFrameType::kVideoFrameKey;
+ } else {
+ video_header.frame_type = VideoFrameType::kVideoFrameDelta;
+ }
+ return true;
+}
+
+bool RtpVideoFrameAssembler::Impl::ParseGenericDescriptorExtension(
+ const RtpPacketReceived& rtp_packet,
+ RTPVideoHeader& video_header) {
+ RtpGenericFrameDescriptor generic_frame_descriptor;
+ if (!rtp_packet.GetExtension<RtpGenericFrameDescriptorExtension00>(
+ &generic_frame_descriptor)) {
+ return false;
+ }
+
+ video_header.is_first_packet_in_frame =
+ generic_frame_descriptor.FirstPacketInSubFrame();
+ video_header.is_last_packet_in_frame =
+ generic_frame_descriptor.LastPacketInSubFrame();
+
+ if (generic_frame_descriptor.FirstPacketInSubFrame()) {
+ video_header.frame_type =
+ generic_frame_descriptor.FrameDependenciesDiffs().empty()
+ ? VideoFrameType::kVideoFrameKey
+ : VideoFrameType::kVideoFrameDelta;
+
+ auto& generic_descriptor_info = video_header.generic.emplace();
+ int64_t frame_id =
+ frame_id_unwrapper_.Unwrap(generic_frame_descriptor.FrameId());
+ generic_descriptor_info.frame_id = frame_id;
+ generic_descriptor_info.spatial_index =
+ generic_frame_descriptor.SpatialLayer();
+ generic_descriptor_info.temporal_index =
+ generic_frame_descriptor.TemporalLayer();
+ for (uint16_t fdiff : generic_frame_descriptor.FrameDependenciesDiffs()) {
+ generic_descriptor_info.dependencies.push_back(frame_id - fdiff);
+ }
+ }
+ video_header.width = generic_frame_descriptor.Width();
+ video_header.height = generic_frame_descriptor.Height();
+ return true;
+}
+
+RtpVideoFrameAssembler::RtpVideoFrameAssembler(PayloadFormat payload_format)
+ : impl_(std::make_unique<Impl>(CreateDepacketizer(payload_format))) {}
+
+RtpVideoFrameAssembler::~RtpVideoFrameAssembler() = default;
+
+RtpVideoFrameAssembler::FrameVector RtpVideoFrameAssembler::InsertPacket(
+ const RtpPacketReceived& packet) {
+ return impl_->InsertPacket(packet);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/rtp_video_frame_assembler.h b/third_party/libwebrtc/api/video/rtp_video_frame_assembler.h
new file mode 100644
index 0000000000..83162cb818
--- /dev/null
+++ b/third_party/libwebrtc/api/video/rtp_video_frame_assembler.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_RTP_VIDEO_FRAME_ASSEMBLER_H_
+#define API_VIDEO_RTP_VIDEO_FRAME_ASSEMBLER_H_
+
+#include <cstdint>
+#include <memory>
+#include <utility>
+
+#include "absl/container/inlined_vector.h"
+#include "api/video/encoded_frame.h"
+#include "modules/rtp_rtcp/source/rtp_packet_received.h"
+
+namespace webrtc {
+// The RtpVideoFrameAssembler takes RtpPacketReceived and assembles them into
+// complete frames. A frame is considered complete when all packets of the frame
+// has been received, the bitstream data has successfully extracted, an ID has
+// been assigned, and all dependencies are known. Frame IDs are strictly
+// monotonic in decode order, dependencies are expressed as frame IDs.
+class RtpVideoFrameAssembler {
+ public:
+ // The RtpVideoFrameAssembler should return "RTP frames", but for now there
+ // is no good class for this purpose. For now return an EncodedFrame bundled
+ // with some minimal RTP information.
+ class AssembledFrame {
+ public:
+ AssembledFrame(uint16_t rtp_seq_num_start,
+ uint16_t rtp_seq_num_end,
+ std::unique_ptr<EncodedFrame> frame)
+ : rtp_seq_num_start_(rtp_seq_num_start),
+ rtp_seq_num_end_(rtp_seq_num_end),
+ frame_(std::move(frame)) {}
+
+ uint16_t RtpSeqNumStart() const { return rtp_seq_num_start_; }
+ uint16_t RtpSeqNumEnd() const { return rtp_seq_num_end_; }
+ std::unique_ptr<EncodedFrame> ExtractFrame() { return std::move(frame_); }
+
+ private:
+ uint16_t rtp_seq_num_start_;
+ uint16_t rtp_seq_num_end_;
+ std::unique_ptr<EncodedFrame> frame_;
+ };
+
+ // FrameVector is just a vector-like type of std::unique_ptr<EncodedFrame>.
+ // The vector type may change without notice.
+ using FrameVector = absl::InlinedVector<AssembledFrame, 3>;
+ enum PayloadFormat { kRaw, kH264, kVp8, kVp9, kAv1, kGeneric };
+
+ explicit RtpVideoFrameAssembler(PayloadFormat payload_format);
+ RtpVideoFrameAssembler(const RtpVideoFrameAssembler& other) = delete;
+ RtpVideoFrameAssembler& operator=(const RtpVideoFrameAssembler& other) =
+ delete;
+ ~RtpVideoFrameAssembler();
+
+ // Typically when a packet is inserted zero or one frame is completed. In the
+ // case of RTP packets being inserted out of order then sometime multiple
+ // frames could be completed from a single packet, hence the 'FrameVector'
+ // return type.
+ FrameVector InsertPacket(const RtpPacketReceived& packet);
+
+ private:
+ class Impl;
+ std::unique_ptr<Impl> impl_;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_RTP_VIDEO_FRAME_ASSEMBLER_H_
diff --git a/third_party/libwebrtc/api/video/rtp_video_frame_assembler_unittests.cc b/third_party/libwebrtc/api/video/rtp_video_frame_assembler_unittests.cc
new file mode 100644
index 0000000000..82defb8399
--- /dev/null
+++ b/third_party/libwebrtc/api/video/rtp_video_frame_assembler_unittests.cc
@@ -0,0 +1,583 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <vector>
+
+#include "api/array_view.h"
+#include "api/video/rtp_video_frame_assembler.h"
+#include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h"
+#include "modules/rtp_rtcp/source/rtp_format.h"
+#include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h"
+#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
+#include "modules/rtp_rtcp/source/rtp_packetizer_av1_test_helper.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace {
+
+using ::testing::ElementsAreArray;
+using ::testing::Eq;
+using ::testing::IsEmpty;
+using ::testing::Matches;
+using ::testing::SizeIs;
+using ::testing::UnorderedElementsAre;
+using ::testing::UnorderedElementsAreArray;
+using PayloadFormat = RtpVideoFrameAssembler::PayloadFormat;
+
+class PacketBuilder {
+ public:
+ explicit PacketBuilder(PayloadFormat format)
+ : format_(format), packet_to_send_(&extension_manager_) {}
+
+ PacketBuilder& WithSeqNum(uint16_t seq_num) {
+ seq_num_ = seq_num;
+ return *this;
+ }
+
+ PacketBuilder& WithPayload(rtc::ArrayView<const uint8_t> payload) {
+ payload_.assign(payload.begin(), payload.end());
+ return *this;
+ }
+
+ PacketBuilder& WithVideoHeader(const RTPVideoHeader& video_header) {
+ video_header_ = video_header;
+ return *this;
+ }
+
+ template <typename T, typename... Args>
+ PacketBuilder& WithExtension(int id, const Args&... args) {
+ extension_manager_.Register<T>(id);
+ packet_to_send_.IdentifyExtensions(extension_manager_);
+ packet_to_send_.SetExtension<T>(std::forward<const Args>(args)...);
+ return *this;
+ }
+
+ RtpPacketReceived Build() {
+ auto packetizer =
+ RtpPacketizer::Create(GetVideoCodecType(), payload_, {}, video_header_);
+ packetizer->NextPacket(&packet_to_send_);
+ packet_to_send_.SetSequenceNumber(seq_num_);
+
+ RtpPacketReceived received(&extension_manager_);
+ received.Parse(packet_to_send_.Buffer());
+ return received;
+ }
+
+ private:
+ absl::optional<VideoCodecType> GetVideoCodecType() {
+ switch (format_) {
+ case PayloadFormat::kRaw: {
+ return absl::nullopt;
+ }
+ case PayloadFormat::kH264: {
+ return kVideoCodecH264;
+ }
+ case PayloadFormat::kVp8: {
+ return kVideoCodecVP8;
+ }
+ case PayloadFormat::kVp9: {
+ return kVideoCodecVP9;
+ }
+ case PayloadFormat::kAv1: {
+ return kVideoCodecAV1;
+ }
+ case PayloadFormat::kGeneric: {
+ return kVideoCodecGeneric;
+ }
+ }
+ RTC_DCHECK_NOTREACHED();
+ return absl::nullopt;
+ }
+
+ const RtpVideoFrameAssembler::PayloadFormat format_;
+ uint16_t seq_num_ = 0;
+ std::vector<uint8_t> payload_;
+ RTPVideoHeader video_header_;
+ RtpPacketReceived::ExtensionManager extension_manager_;
+ RtpPacketToSend packet_to_send_;
+};
+
+RtpPacketReceived PaddingPacket(uint16_t seq_num) {
+ RtpPacketReceived padding_packet;
+ padding_packet.SetSequenceNumber(seq_num);
+ padding_packet.SetPadding(224);
+ return padding_packet;
+}
+
+void AppendFrames(RtpVideoFrameAssembler::FrameVector from,
+ RtpVideoFrameAssembler::FrameVector& to) {
+ to.insert(to.end(), std::make_move_iterator(from.begin()),
+ std::make_move_iterator(from.end()));
+}
+
+rtc::ArrayView<int64_t> References(const std::unique_ptr<EncodedFrame>& frame) {
+ return rtc::MakeArrayView(frame->references, frame->num_references);
+}
+
+rtc::ArrayView<uint8_t> Payload(const std::unique_ptr<EncodedFrame>& frame) {
+ return rtc::ArrayView<uint8_t>(*frame->GetEncodedData());
+}
+
+TEST(RtpVideoFrameAssembler, Vp8Packetization) {
+ RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kVp8);
+
+ // When sending VP8 over RTP parts of the payload is actually inspected at the
+ // RTP level. It just so happen that the initial 'V' sets the keyframe bit
+ // (0x01) to the correct value.
+ uint8_t kKeyframePayload[] = "Vp8Keyframe";
+ ASSERT_EQ(kKeyframePayload[0] & 0x01, 0);
+
+ uint8_t kDeltaframePayload[] = "SomeFrame";
+ ASSERT_EQ(kDeltaframePayload[0] & 0x01, 1);
+
+ RtpVideoFrameAssembler::FrameVector frames;
+
+ RTPVideoHeader video_header;
+ auto& vp8_header =
+ video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
+
+ vp8_header.pictureId = 10;
+ vp8_header.tl0PicIdx = 0;
+ AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kVp8)
+ .WithPayload(kKeyframePayload)
+ .WithVideoHeader(video_header)
+ .Build()),
+ frames);
+
+ vp8_header.pictureId = 11;
+ vp8_header.tl0PicIdx = 1;
+ AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kVp8)
+ .WithPayload(kDeltaframePayload)
+ .WithVideoHeader(video_header)
+ .Build()),
+ frames);
+
+ ASSERT_THAT(frames, SizeIs(2));
+
+ auto first_frame = frames[0].ExtractFrame();
+ EXPECT_THAT(first_frame->Id(), Eq(10));
+ EXPECT_THAT(References(first_frame), IsEmpty());
+ EXPECT_THAT(Payload(first_frame), ElementsAreArray(kKeyframePayload));
+
+ auto second_frame = frames[1].ExtractFrame();
+ EXPECT_THAT(second_frame->Id(), Eq(11));
+ EXPECT_THAT(References(second_frame), UnorderedElementsAre(10));
+ EXPECT_THAT(Payload(second_frame), ElementsAreArray(kDeltaframePayload));
+}
+
+TEST(RtpVideoFrameAssembler, Vp9Packetization) {
+ RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kVp9);
+ RtpVideoFrameAssembler::FrameVector frames;
+
+ uint8_t kPayload[] = "SomePayload";
+
+ RTPVideoHeader video_header;
+ auto& vp9_header =
+ video_header.video_type_header.emplace<RTPVideoHeaderVP9>();
+ vp9_header.InitRTPVideoHeaderVP9();
+
+ vp9_header.picture_id = 10;
+ vp9_header.tl0_pic_idx = 0;
+ AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kVp9)
+ .WithPayload(kPayload)
+ .WithVideoHeader(video_header)
+ .Build()),
+ frames);
+
+ vp9_header.picture_id = 11;
+ vp9_header.tl0_pic_idx = 1;
+ vp9_header.inter_pic_predicted = true;
+ AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kVp9)
+ .WithPayload(kPayload)
+ .WithVideoHeader(video_header)
+ .Build()),
+ frames);
+
+ ASSERT_THAT(frames, SizeIs(2));
+
+ auto first_frame = frames[0].ExtractFrame();
+ EXPECT_THAT(first_frame->Id(), Eq(10));
+ EXPECT_THAT(Payload(first_frame), ElementsAreArray(kPayload));
+ EXPECT_THAT(References(first_frame), IsEmpty());
+
+ auto second_frame = frames[1].ExtractFrame();
+ EXPECT_THAT(second_frame->Id(), Eq(11));
+ EXPECT_THAT(Payload(second_frame), ElementsAreArray(kPayload));
+ EXPECT_THAT(References(second_frame), UnorderedElementsAre(10));
+}
+
+TEST(RtpVideoFrameAssembler, Av1Packetization) {
+ RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kAv1);
+ RtpVideoFrameAssembler::FrameVector frames;
+
+ auto kKeyframePayload =
+ BuildAv1Frame({Av1Obu(kAv1ObuTypeSequenceHeader).WithPayload({1, 2, 3}),
+ Av1Obu(kAv1ObuTypeFrame).WithPayload({4, 5, 6})});
+
+ auto kDeltaframePayload =
+ BuildAv1Frame({Av1Obu(kAv1ObuTypeFrame).WithPayload({7, 8, 9})});
+
+ RTPVideoHeader video_header;
+
+ video_header.frame_type = VideoFrameType::kVideoFrameKey;
+ AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kAv1)
+ .WithPayload(kKeyframePayload)
+ .WithVideoHeader(video_header)
+ .WithSeqNum(20)
+ .Build()),
+ frames);
+
+ AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kAv1)
+ .WithPayload(kDeltaframePayload)
+ .WithSeqNum(21)
+ .Build()),
+ frames);
+
+ ASSERT_THAT(frames, SizeIs(2));
+
+ auto first_frame = frames[0].ExtractFrame();
+ EXPECT_THAT(first_frame->Id(), Eq(20));
+ EXPECT_THAT(Payload(first_frame), ElementsAreArray(kKeyframePayload));
+ EXPECT_THAT(References(first_frame), IsEmpty());
+
+ auto second_frame = frames[1].ExtractFrame();
+ EXPECT_THAT(second_frame->Id(), Eq(21));
+ EXPECT_THAT(Payload(second_frame), ElementsAreArray(kDeltaframePayload));
+ EXPECT_THAT(References(second_frame), UnorderedElementsAre(20));
+}
+
+TEST(RtpVideoFrameAssembler, RawPacketizationDependencyDescriptorExtension) {
+ RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kRaw);
+ RtpVideoFrameAssembler::FrameVector frames;
+ uint8_t kPayload[] = "SomePayload";
+
+ FrameDependencyStructure dependency_structure;
+ dependency_structure.num_decode_targets = 1;
+ dependency_structure.num_chains = 1;
+ dependency_structure.decode_target_protected_by_chain.push_back(0);
+ dependency_structure.templates.push_back(
+ FrameDependencyTemplate().S(0).T(0).Dtis("S").ChainDiffs({0}));
+ dependency_structure.templates.push_back(
+ FrameDependencyTemplate().S(0).T(0).Dtis("S").ChainDiffs({10}).FrameDiffs(
+ {10}));
+
+ DependencyDescriptor dependency_descriptor;
+
+ dependency_descriptor.frame_number = 10;
+ dependency_descriptor.frame_dependencies = dependency_structure.templates[0];
+ dependency_descriptor.attached_structure =
+ std::make_unique<FrameDependencyStructure>(dependency_structure);
+ AppendFrames(assembler.InsertPacket(
+ PacketBuilder(PayloadFormat::kRaw)
+ .WithPayload(kPayload)
+ .WithExtension<RtpDependencyDescriptorExtension>(
+ 1, dependency_structure, dependency_descriptor)
+ .Build()),
+ frames);
+
+ dependency_descriptor.frame_number = 20;
+ dependency_descriptor.frame_dependencies = dependency_structure.templates[1];
+ dependency_descriptor.attached_structure.reset();
+ AppendFrames(assembler.InsertPacket(
+ PacketBuilder(PayloadFormat::kRaw)
+ .WithPayload(kPayload)
+ .WithExtension<RtpDependencyDescriptorExtension>(
+ 1, dependency_structure, dependency_descriptor)
+ .Build()),
+ frames);
+
+ ASSERT_THAT(frames, SizeIs(2));
+
+ auto first_frame = frames[0].ExtractFrame();
+ EXPECT_THAT(first_frame->Id(), Eq(10));
+ EXPECT_THAT(Payload(first_frame), ElementsAreArray(kPayload));
+ EXPECT_THAT(References(first_frame), IsEmpty());
+
+ auto second_frame = frames[1].ExtractFrame();
+ EXPECT_THAT(second_frame->Id(), Eq(20));
+ EXPECT_THAT(Payload(second_frame), ElementsAreArray(kPayload));
+ EXPECT_THAT(References(second_frame), UnorderedElementsAre(10));
+}
+
+TEST(RtpVideoFrameAssembler, RawPacketizationGenericDescriptor00Extension) {
+ RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kRaw);
+ RtpVideoFrameAssembler::FrameVector frames;
+ uint8_t kPayload[] = "SomePayload";
+
+ RtpGenericFrameDescriptor generic;
+
+ generic.SetFirstPacketInSubFrame(true);
+ generic.SetLastPacketInSubFrame(true);
+ generic.SetFrameId(100);
+ AppendFrames(
+ assembler.InsertPacket(
+ PacketBuilder(PayloadFormat::kRaw)
+ .WithPayload(kPayload)
+ .WithExtension<RtpGenericFrameDescriptorExtension00>(1, generic)
+ .Build()),
+ frames);
+
+ generic.SetFrameId(102);
+ generic.AddFrameDependencyDiff(2);
+ AppendFrames(
+ assembler.InsertPacket(
+ PacketBuilder(PayloadFormat::kRaw)
+ .WithPayload(kPayload)
+ .WithExtension<RtpGenericFrameDescriptorExtension00>(1, generic)
+ .Build()),
+ frames);
+
+ ASSERT_THAT(frames, SizeIs(2));
+
+ auto first_frame = frames[0].ExtractFrame();
+ EXPECT_THAT(first_frame->Id(), Eq(100));
+ EXPECT_THAT(Payload(first_frame), ElementsAreArray(kPayload));
+ EXPECT_THAT(References(first_frame), IsEmpty());
+
+ auto second_frame = frames[1].ExtractFrame();
+ EXPECT_THAT(second_frame->Id(), Eq(102));
+ EXPECT_THAT(Payload(second_frame), ElementsAreArray(kPayload));
+ EXPECT_THAT(References(second_frame), UnorderedElementsAre(100));
+}
+
+TEST(RtpVideoFrameAssembler, RawPacketizationGenericPayloadDescriptor) {
+ RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kGeneric);
+ RtpVideoFrameAssembler::FrameVector frames;
+ uint8_t kPayload[] = "SomePayload";
+
+ RTPVideoHeader video_header;
+
+ video_header.frame_type = VideoFrameType::kVideoFrameKey;
+ AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric)
+ .WithPayload(kPayload)
+ .WithVideoHeader(video_header)
+ .WithSeqNum(123)
+ .Build()),
+ frames);
+
+ video_header.frame_type = VideoFrameType::kVideoFrameDelta;
+ AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric)
+ .WithPayload(kPayload)
+ .WithVideoHeader(video_header)
+ .WithSeqNum(124)
+ .Build()),
+ frames);
+
+ ASSERT_THAT(frames, SizeIs(2));
+
+ auto first_frame = frames[0].ExtractFrame();
+ EXPECT_THAT(first_frame->Id(), Eq(123));
+ EXPECT_THAT(Payload(first_frame), ElementsAreArray(kPayload));
+ EXPECT_THAT(References(first_frame), IsEmpty());
+
+ auto second_frame = frames[1].ExtractFrame();
+ EXPECT_THAT(second_frame->Id(), Eq(124));
+ EXPECT_THAT(Payload(second_frame), ElementsAreArray(kPayload));
+ EXPECT_THAT(References(second_frame), UnorderedElementsAre(123));
+}
+
+TEST(RtpVideoFrameAssembler, Padding) {
+ RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kGeneric);
+ RtpVideoFrameAssembler::FrameVector frames;
+ uint8_t kPayload[] = "SomePayload";
+
+ RTPVideoHeader video_header;
+
+ video_header.frame_type = VideoFrameType::kVideoFrameKey;
+ AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric)
+ .WithPayload(kPayload)
+ .WithVideoHeader(video_header)
+ .WithSeqNum(123)
+ .Build()),
+ frames);
+
+ video_header.frame_type = VideoFrameType::kVideoFrameDelta;
+ AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric)
+ .WithPayload(kPayload)
+ .WithVideoHeader(video_header)
+ .WithSeqNum(125)
+ .Build()),
+ frames);
+
+ ASSERT_THAT(frames, SizeIs(1));
+ auto first_frame = frames[0].ExtractFrame();
+ EXPECT_THAT(first_frame->Id(), Eq(123));
+ EXPECT_THAT(Payload(first_frame), ElementsAreArray(kPayload));
+ EXPECT_THAT(References(first_frame), IsEmpty());
+
+ AppendFrames(assembler.InsertPacket(PaddingPacket(/*seq_num=*/124)), frames);
+
+ ASSERT_THAT(frames, SizeIs(2));
+ auto second_frame = frames[1].ExtractFrame();
+ EXPECT_THAT(second_frame->Id(), Eq(125));
+ EXPECT_THAT(Payload(second_frame), ElementsAreArray(kPayload));
+ EXPECT_THAT(References(second_frame), UnorderedElementsAre(123));
+}
+
+TEST(RtpVideoFrameAssembler, ClearOldPackets) {
+ RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kGeneric);
+
+ // If we don't have a payload the packet will be counted as a padding packet.
+ uint8_t kPayload[] = "DontCare";
+
+ RTPVideoHeader video_header;
+ video_header.frame_type = VideoFrameType::kVideoFrameKey;
+ EXPECT_THAT(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric)
+ .WithPayload(kPayload)
+ .WithVideoHeader(video_header)
+ .WithSeqNum(0)
+ .Build()),
+ SizeIs(1));
+
+ EXPECT_THAT(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric)
+ .WithPayload(kPayload)
+ .WithVideoHeader(video_header)
+ .WithSeqNum(2000)
+ .Build()),
+ SizeIs(1));
+
+ EXPECT_THAT(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric)
+ .WithPayload(kPayload)
+ .WithVideoHeader(video_header)
+ .WithSeqNum(0)
+ .Build()),
+ SizeIs(0));
+
+ EXPECT_THAT(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric)
+ .WithPayload(kPayload)
+ .WithVideoHeader(video_header)
+ .WithSeqNum(1)
+ .Build()),
+ SizeIs(1));
+}
+
+TEST(RtpVideoFrameAssembler, ClearOldPacketsWithPadding) {
+ RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kGeneric);
+ uint8_t kPayload[] = "DontCare";
+
+ RTPVideoHeader video_header;
+ video_header.frame_type = VideoFrameType::kVideoFrameKey;
+ EXPECT_THAT(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric)
+ .WithPayload(kPayload)
+ .WithVideoHeader(video_header)
+ .WithSeqNum(0)
+ .Build()),
+ SizeIs(1));
+
+ EXPECT_THAT(assembler.InsertPacket(PaddingPacket(/*seq_num=*/2000)),
+ SizeIs(0));
+
+ EXPECT_THAT(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric)
+ .WithPayload(kPayload)
+ .WithVideoHeader(video_header)
+ .WithSeqNum(0)
+ .Build()),
+ SizeIs(0));
+
+ EXPECT_THAT(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric)
+ .WithPayload(kPayload)
+ .WithVideoHeader(video_header)
+ .WithSeqNum(1)
+ .Build()),
+ SizeIs(1));
+}
+
+TEST(RtpVideoFrameAssembler, SeqNumStartAndSeqNumEndSet) {
+ RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kGeneric);
+ RtpVideoFrameAssembler::FrameVector frames;
+ uint8_t kPayload[] =
+ "Some payload that will get split into two when packetized.";
+
+ RTPVideoHeader video_header;
+ video_header.frame_type = VideoFrameType::kVideoFrameKey;
+ RtpPacketizer::PayloadSizeLimits limits;
+ limits.max_payload_len = sizeof(kPayload) - 1;
+
+ auto packetizer =
+ RtpPacketizer::Create(kVideoCodecGeneric, kPayload, limits, video_header);
+ ASSERT_THAT(packetizer->NumPackets(), Eq(2U));
+
+ RtpPacketReceived::ExtensionManager extension_manager;
+ {
+ RtpPacketToSend send_packet(&extension_manager);
+ packetizer->NextPacket(&send_packet);
+ send_packet.SetSequenceNumber(123);
+ RtpPacketReceived received_packet(&extension_manager);
+ received_packet.Parse(send_packet.Buffer());
+ assembler.InsertPacket(received_packet);
+ }
+
+ {
+ RtpPacketToSend send_packet(&extension_manager);
+ packetizer->NextPacket(&send_packet);
+ send_packet.SetSequenceNumber(124);
+ RtpPacketReceived received_packet(&extension_manager);
+ received_packet.Parse(send_packet.Buffer());
+ AppendFrames(assembler.InsertPacket(received_packet), frames);
+ }
+
+ ASSERT_THAT(frames, SizeIs(1));
+ EXPECT_THAT(frames[0].RtpSeqNumStart(), Eq(123));
+ EXPECT_THAT(frames[0].RtpSeqNumEnd(), Eq(124));
+}
+
+TEST(RtpVideoFrameAssembler, SeqNumStartAndSeqNumEndSetWhenPaddingReceived) {
+ RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kGeneric);
+ RtpVideoFrameAssembler::FrameVector frames;
+ uint8_t kPayload[] =
+ "Some payload that will get split into two when packetized.";
+
+ RTPVideoHeader video_header;
+ video_header.frame_type = VideoFrameType::kVideoFrameKey;
+
+ EXPECT_THAT(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric)
+ .WithPayload(kPayload)
+ .WithVideoHeader(video_header)
+ .WithSeqNum(121)
+ .Build()),
+ SizeIs(1));
+
+ video_header.frame_type = VideoFrameType::kVideoFrameDelta;
+ RtpPacketReceived::ExtensionManager extension_manager;
+ RtpPacketizer::PayloadSizeLimits limits;
+ limits.max_payload_len = sizeof(kPayload) - 1;
+
+ auto packetizer =
+ RtpPacketizer::Create(kVideoCodecGeneric, kPayload, limits, video_header);
+ ASSERT_THAT(packetizer->NumPackets(), Eq(2U));
+
+ {
+ RtpPacketToSend send_packet(&extension_manager);
+ packetizer->NextPacket(&send_packet);
+ send_packet.SetSequenceNumber(123);
+ RtpPacketReceived received_packet(&extension_manager);
+ received_packet.Parse(send_packet.Buffer());
+ assembler.InsertPacket(received_packet);
+ }
+
+ {
+ RtpPacketToSend send_packet(&extension_manager);
+ packetizer->NextPacket(&send_packet);
+ send_packet.SetSequenceNumber(124);
+ RtpPacketReceived received_packet(&extension_manager);
+ received_packet.Parse(send_packet.Buffer());
+ assembler.InsertPacket(received_packet);
+ }
+
+ AppendFrames(assembler.InsertPacket(PaddingPacket(/*seq_num=*/122)), frames);
+
+ ASSERT_THAT(frames, SizeIs(1));
+ EXPECT_THAT(frames[0].RtpSeqNumStart(), Eq(123));
+ EXPECT_THAT(frames[0].RtpSeqNumEnd(), Eq(124));
+}
+
+} // namespace
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/test/BUILD.gn b/third_party/libwebrtc/api/video/test/BUILD.gn
new file mode 100644
index 0000000000..60ec4b852f
--- /dev/null
+++ b/third_party/libwebrtc/api/video/test/BUILD.gn
@@ -0,0 +1,56 @@
+# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+
+rtc_library("rtc_api_video_unittests") {
+ testonly = true
+ sources = [
+ "color_space_unittest.cc",
+ "i210_buffer_unittest.cc",
+ "i410_buffer_unittest.cc",
+ "i422_buffer_unittest.cc",
+ "i444_buffer_unittest.cc",
+ "nv12_buffer_unittest.cc",
+ "video_adaptation_counters_unittest.cc",
+ "video_bitrate_allocation_unittest.cc",
+ ]
+ deps = [
+ "..:video_adaptation",
+ "..:video_bitrate_allocation",
+ "..:video_frame",
+ "..:video_frame_i010",
+ "..:video_rtp_headers",
+ "../../../test:frame_utils",
+ "../../../test:test_support",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_source_set("mock_recordable_encoded_frame") {
+ testonly = true
+ visibility = [ "*" ]
+ sources = [ "mock_recordable_encoded_frame.h" ]
+
+ deps = [
+ "..:recordable_encoded_frame",
+ "../../../test:test_support",
+ ]
+}
+
+rtc_source_set("video_frame_matchers") {
+ testonly = true
+ visibility = [ "*" ]
+ sources = [ "video_frame_matchers.h" ]
+
+ deps = [
+ "..:video_frame",
+ "../..:rtp_packet_info",
+ "../../../test:test_support",
+ ]
+}
diff --git a/third_party/libwebrtc/api/video/test/color_space_unittest.cc b/third_party/libwebrtc/api/video/test/color_space_unittest.cc
new file mode 100644
index 0000000000..1d8b3a87f6
--- /dev/null
+++ b/third_party/libwebrtc/api/video/test/color_space_unittest.cc
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/color_space.h"
+
+#include <stdint.h>
+
+#include "test/gtest.h"
+
+namespace webrtc {
+TEST(ColorSpace, TestSettingPrimariesFromUint8) {
+ ColorSpace color_space;
+ EXPECT_TRUE(color_space.set_primaries_from_uint8(
+ static_cast<uint8_t>(ColorSpace::PrimaryID::kBT470BG)));
+ EXPECT_EQ(ColorSpace::PrimaryID::kBT470BG, color_space.primaries());
+ EXPECT_FALSE(color_space.set_primaries_from_uint8(3));
+ EXPECT_FALSE(color_space.set_primaries_from_uint8(23));
+ EXPECT_FALSE(color_space.set_primaries_from_uint8(64));
+}
+
+TEST(ColorSpace, TestSettingTransferFromUint8) {
+ ColorSpace color_space;
+ EXPECT_TRUE(color_space.set_transfer_from_uint8(
+ static_cast<uint8_t>(ColorSpace::TransferID::kBT2020_10)));
+ EXPECT_EQ(ColorSpace::TransferID::kBT2020_10, color_space.transfer());
+ EXPECT_FALSE(color_space.set_transfer_from_uint8(3));
+ EXPECT_FALSE(color_space.set_transfer_from_uint8(19));
+ EXPECT_FALSE(color_space.set_transfer_from_uint8(128));
+}
+
+TEST(ColorSpace, TestSettingMatrixFromUint8) {
+ ColorSpace color_space;
+ EXPECT_TRUE(color_space.set_matrix_from_uint8(
+ static_cast<uint8_t>(ColorSpace::MatrixID::kCDNCLS)));
+ EXPECT_EQ(ColorSpace::MatrixID::kCDNCLS, color_space.matrix());
+ EXPECT_FALSE(color_space.set_matrix_from_uint8(3));
+ EXPECT_FALSE(color_space.set_matrix_from_uint8(15));
+ EXPECT_FALSE(color_space.set_matrix_from_uint8(255));
+}
+
+TEST(ColorSpace, TestSettingRangeFromUint8) {
+ ColorSpace color_space;
+ EXPECT_TRUE(color_space.set_range_from_uint8(
+ static_cast<uint8_t>(ColorSpace::RangeID::kFull)));
+ EXPECT_EQ(ColorSpace::RangeID::kFull, color_space.range());
+ EXPECT_FALSE(color_space.set_range_from_uint8(4));
+}
+
+TEST(ColorSpace, TestSettingChromaSitingHorizontalFromUint8) {
+ ColorSpace color_space;
+ EXPECT_TRUE(color_space.set_chroma_siting_horizontal_from_uint8(
+ static_cast<uint8_t>(ColorSpace::ChromaSiting::kCollocated)));
+ EXPECT_EQ(ColorSpace::ChromaSiting::kCollocated,
+ color_space.chroma_siting_horizontal());
+ EXPECT_FALSE(color_space.set_chroma_siting_horizontal_from_uint8(3));
+}
+
+TEST(ColorSpace, TestSettingChromaSitingVerticalFromUint8) {
+ ColorSpace color_space;
+ EXPECT_TRUE(color_space.set_chroma_siting_vertical_from_uint8(
+ static_cast<uint8_t>(ColorSpace::ChromaSiting::kHalf)));
+ EXPECT_EQ(ColorSpace::ChromaSiting::kHalf,
+ color_space.chroma_siting_vertical());
+ EXPECT_FALSE(color_space.set_chroma_siting_vertical_from_uint8(3));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/test/i210_buffer_unittest.cc b/third_party/libwebrtc/api/video/test/i210_buffer_unittest.cc
new file mode 100644
index 0000000000..aaa231b6d2
--- /dev/null
+++ b/third_party/libwebrtc/api/video/test/i210_buffer_unittest.cc
@@ -0,0 +1,126 @@
+
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/i210_buffer.h"
+
+#include "api/video/i420_buffer.h"
+#include "test/frame_utils.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+namespace {
+
+int GetY(rtc::scoped_refptr<I210BufferInterface> buf, int col, int row) {
+ return buf->DataY()[row * buf->StrideY() + col];
+}
+
+int GetU(rtc::scoped_refptr<I210BufferInterface> buf, int col, int row) {
+ return buf->DataU()[row * buf->StrideU() + col];
+}
+
+int GetV(rtc::scoped_refptr<I210BufferInterface> buf, int col, int row) {
+ return buf->DataV()[row * buf->StrideV() + col];
+}
+
+void FillI210Buffer(rtc::scoped_refptr<I210Buffer> buf) {
+ const uint16_t Y = 4;
+ const uint16_t U = 8;
+ const uint16_t V = 16;
+ for (int row = 0; row < buf->height(); ++row) {
+ for (int col = 0; col < buf->width(); ++col) {
+ buf->MutableDataY()[row * buf->StrideY() + col] = Y;
+ }
+ }
+ for (int row = 0; row < buf->ChromaHeight(); ++row) {
+ for (int col = 0; col < buf->ChromaWidth(); ++col) {
+ buf->MutableDataU()[row * buf->StrideU() + col] = U;
+ buf->MutableDataV()[row * buf->StrideV() + col] = V;
+ }
+ }
+}
+
+} // namespace
+
+TEST(I210BufferTest, InitialData) {
+ constexpr int stride = 3;
+ constexpr int halfstride = (stride + 1) >> 1;
+ constexpr int width = 3;
+ constexpr int halfwidth = (width + 1) >> 1;
+ constexpr int height = 3;
+
+ rtc::scoped_refptr<I210Buffer> i210_buffer(I210Buffer::Create(width, height));
+ EXPECT_EQ(width, i210_buffer->width());
+ EXPECT_EQ(height, i210_buffer->height());
+ EXPECT_EQ(stride, i210_buffer->StrideY());
+ EXPECT_EQ(halfstride, i210_buffer->StrideU());
+ EXPECT_EQ(halfstride, i210_buffer->StrideV());
+ EXPECT_EQ(halfwidth, i210_buffer->ChromaWidth());
+ EXPECT_EQ(height, i210_buffer->ChromaHeight());
+}
+
+TEST(I210BufferTest, ReadPixels) {
+ constexpr int width = 3;
+ constexpr int halfwidth = (width + 1) >> 1;
+ constexpr int height = 3;
+
+ rtc::scoped_refptr<I210Buffer> i210_buffer(I210Buffer::Create(width, height));
+ // Y = 4, U = 8, V = 16.
+ FillI210Buffer(i210_buffer);
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < width; col++) {
+ EXPECT_EQ(4, GetY(i210_buffer, col, row));
+ }
+ }
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < halfwidth; col++) {
+ EXPECT_EQ(8, GetU(i210_buffer, col, row));
+ EXPECT_EQ(16, GetV(i210_buffer, col, row));
+ }
+ }
+}
+
+TEST(I210BufferTest, ToI420) {
+ constexpr int width = 3;
+ constexpr int halfwidth = (width + 1) >> 1;
+ constexpr int height = 3;
+ constexpr int size = width * height;
+ constexpr int quartersize = (width + 1) / 2 * (height + 1) / 2;
+ rtc::scoped_refptr<I420Buffer> reference(I420Buffer::Create(width, height));
+ memset(reference->MutableDataY(), 1, size);
+ memset(reference->MutableDataU(), 2, quartersize);
+ memset(reference->MutableDataV(), 4, quartersize);
+
+ rtc::scoped_refptr<I210Buffer> i210_buffer(I210Buffer::Create(width, height));
+ // Y = 4, U = 8, V = 16.
+ FillI210Buffer(i210_buffer);
+
+ // Confirm YUV values are as expected.
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < width; col++) {
+ EXPECT_EQ(4, GetY(i210_buffer, col, row));
+ }
+ }
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < halfwidth; col++) {
+ EXPECT_EQ(8, GetU(i210_buffer, col, row));
+ EXPECT_EQ(16, GetV(i210_buffer, col, row));
+ }
+ }
+
+ rtc::scoped_refptr<I420BufferInterface> i420_buffer(i210_buffer->ToI420());
+ EXPECT_TRUE(test::FrameBufsEqual(reference, i420_buffer));
+ EXPECT_EQ(height, i420_buffer->height());
+ EXPECT_EQ(width, i420_buffer->width());
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/test/i410_buffer_unittest.cc b/third_party/libwebrtc/api/video/test/i410_buffer_unittest.cc
new file mode 100644
index 0000000000..c5d2d5bf2d
--- /dev/null
+++ b/third_party/libwebrtc/api/video/test/i410_buffer_unittest.cc
@@ -0,0 +1,120 @@
+
+/*
+ * Copyright (c) 2023 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/i410_buffer.h"
+
+#include "api/video/i420_buffer.h"
+#include "test/frame_utils.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+namespace {
+constexpr uint16_t kYValue = 4;
+constexpr uint16_t kUValue = 8;
+constexpr uint16_t kVValue = 16;
+
+int GetY(rtc::scoped_refptr<I410BufferInterface> buf, int col, int row) {
+ return buf->DataY()[row * buf->StrideY() + col];
+}
+
+int GetU(rtc::scoped_refptr<I410BufferInterface> buf, int col, int row) {
+ return buf->DataU()[row * buf->StrideU() + col];
+}
+
+int GetV(rtc::scoped_refptr<I410BufferInterface> buf, int col, int row) {
+ return buf->DataV()[row * buf->StrideV() + col];
+}
+
+void FillI410Buffer(rtc::scoped_refptr<I410Buffer> buf) {
+ for (int row = 0; row < buf->height(); ++row) {
+ for (int col = 0; col < buf->width(); ++col) {
+ buf->MutableDataY()[row * buf->StrideY() + col] = kYValue;
+ buf->MutableDataU()[row * buf->StrideU() + col] = kUValue;
+ buf->MutableDataV()[row * buf->StrideV() + col] = kVValue;
+ }
+ }
+}
+
+} // namespace
+
+TEST(I410BufferTest, InitialData) {
+ constexpr int stride = 3;
+ constexpr int width = 3;
+ constexpr int height = 3;
+
+ rtc::scoped_refptr<I410Buffer> i410_buffer(I410Buffer::Create(width, height));
+ EXPECT_EQ(width, i410_buffer->width());
+ EXPECT_EQ(height, i410_buffer->height());
+ EXPECT_EQ(stride, i410_buffer->StrideY());
+ EXPECT_EQ(stride, i410_buffer->StrideU());
+ EXPECT_EQ(stride, i410_buffer->StrideV());
+ EXPECT_EQ(3, i410_buffer->ChromaWidth());
+ EXPECT_EQ(3, i410_buffer->ChromaHeight());
+}
+
+TEST(I410BufferTest, ReadPixels) {
+ constexpr int width = 3;
+ constexpr int height = 3;
+
+ rtc::scoped_refptr<I410Buffer> i410_buffer(I410Buffer::Create(width, height));
+ FillI410Buffer(i410_buffer);
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < width; col++) {
+ EXPECT_EQ(kYValue, GetY(i410_buffer, col, row));
+ EXPECT_EQ(kUValue, GetU(i410_buffer, col, row));
+ EXPECT_EQ(kVValue, GetV(i410_buffer, col, row));
+ }
+ }
+}
+
+TEST(I410BufferTest, ToI420) {
+ // libyuv I410ToI420 only handles correctly even sizes and skips last row/col
+ // if odd.
+ constexpr int width = 4;
+ constexpr int height = 4;
+ constexpr int size_y = width * height;
+ constexpr int size_u = (width + 1) / 2 * (height + 1) / 2;
+ constexpr int size_v = (width + 1) / 2 * (height + 1) / 2;
+ rtc::scoped_refptr<I420Buffer> reference(I420Buffer::Create(width, height));
+ // I410 is 10-bit while I420 is 8 bit, so last 2 bits would be discarded.
+ memset(reference->MutableDataY(), kYValue >> 2, size_y);
+ memset(reference->MutableDataU(), kUValue >> 2, size_u);
+ memset(reference->MutableDataV(), kVValue >> 2, size_v);
+
+ rtc::scoped_refptr<I410Buffer> i410_buffer(I410Buffer::Create(width, height));
+ FillI410Buffer(i410_buffer);
+
+ // Confirm YUV values are as expected.
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < width; col++) {
+ EXPECT_EQ(kYValue, GetY(i410_buffer, col, row));
+ EXPECT_EQ(kUValue, GetU(i410_buffer, col, row));
+ EXPECT_EQ(kVValue, GetV(i410_buffer, col, row));
+ }
+ }
+
+ rtc::scoped_refptr<I420BufferInterface> i420_buffer(i410_buffer->ToI420());
+
+ // Confirm YUV values are as expected.
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < width; col++) {
+ EXPECT_EQ(1, i420_buffer->DataY()[row * i420_buffer->StrideY() + col]);
+ }
+ }
+
+ EXPECT_EQ(height, i420_buffer->height());
+ EXPECT_EQ(width, i420_buffer->width());
+ EXPECT_TRUE(test::FrameBufsEqual(reference, i420_buffer));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/test/i422_buffer_unittest.cc b/third_party/libwebrtc/api/video/test/i422_buffer_unittest.cc
new file mode 100644
index 0000000000..499b268546
--- /dev/null
+++ b/third_party/libwebrtc/api/video/test/i422_buffer_unittest.cc
@@ -0,0 +1,128 @@
+
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/i422_buffer.h"
+
+#include "api/video/i420_buffer.h"
+#include "test/frame_utils.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+namespace {
+int GetY(rtc::scoped_refptr<I422BufferInterface> buf, int col, int row) {
+ return buf->DataY()[row * buf->StrideY() + col];
+}
+
+int GetU(rtc::scoped_refptr<I422BufferInterface> buf, int col, int row) {
+ return buf->DataU()[row * buf->StrideU() + col];
+}
+
+int GetV(rtc::scoped_refptr<I422BufferInterface> buf, int col, int row) {
+ return buf->DataV()[row * buf->StrideV() + col];
+}
+
+void FillI422Buffer(rtc::scoped_refptr<I422Buffer> buf) {
+ const uint8_t Y = 1;
+ const uint8_t U = 2;
+ const uint8_t V = 3;
+ for (int row = 0; row < buf->height(); ++row) {
+ for (int col = 0; col < buf->width(); ++col) {
+ buf->MutableDataY()[row * buf->StrideY() + col] = Y;
+ }
+ }
+ for (int row = 0; row < buf->ChromaHeight(); ++row) {
+ for (int col = 0; col < buf->ChromaWidth(); ++col) {
+ buf->MutableDataU()[row * buf->StrideU() + col] = U;
+ buf->MutableDataV()[row * buf->StrideV() + col] = V;
+ }
+ }
+}
+
+} // namespace
+
+TEST(I422BufferTest, InitialData) {
+ constexpr int stride = 3;
+ constexpr int halfstride = (stride + 1) >> 1;
+ constexpr int width = 3;
+ constexpr int halfwidth = (width + 1) >> 1;
+ constexpr int height = 3;
+
+ rtc::scoped_refptr<I422Buffer> i422_buffer(I422Buffer::Create(width, height));
+ EXPECT_EQ(width, i422_buffer->width());
+ EXPECT_EQ(height, i422_buffer->height());
+ EXPECT_EQ(stride, i422_buffer->StrideY());
+ EXPECT_EQ(halfstride, i422_buffer->StrideU());
+ EXPECT_EQ(halfstride, i422_buffer->StrideV());
+ EXPECT_EQ(halfwidth, i422_buffer->ChromaWidth());
+ EXPECT_EQ(height, i422_buffer->ChromaHeight());
+}
+
+TEST(I422BufferTest, ReadPixels) {
+ constexpr int width = 3;
+ constexpr int halfwidth = (width + 1) >> 1;
+ constexpr int height = 3;
+
+ rtc::scoped_refptr<I422Buffer> i422_buffer(I422Buffer::Create(width, height));
+ // Y = 1, U = 2, V = 3.
+ FillI422Buffer(i422_buffer);
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < width; col++) {
+ EXPECT_EQ(1, GetY(i422_buffer, col, row));
+ }
+ }
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < halfwidth; col++) {
+ EXPECT_EQ(2, GetU(i422_buffer, col, row));
+ EXPECT_EQ(3, GetV(i422_buffer, col, row));
+ }
+ }
+}
+
+TEST(I422BufferTest, ToI420) {
+ constexpr int width = 3;
+ constexpr int halfwidth = (width + 1) >> 1;
+ constexpr int height = 3;
+ constexpr int size = width * height;
+ constexpr int halfsize = (width + 1) / 2 * height;
+ constexpr int quartersize = (width + 1) / 2 * (height + 1) / 2;
+ rtc::scoped_refptr<I420Buffer> reference(I420Buffer::Create(width, height));
+ memset(reference->MutableDataY(), 8, size);
+ memset(reference->MutableDataU(), 4, quartersize);
+ memset(reference->MutableDataV(), 2, quartersize);
+
+ rtc::scoped_refptr<I422Buffer> i422_buffer(I422Buffer::Create(width, height));
+ // Convert the reference buffer to I422.
+ memset(i422_buffer->MutableDataY(), 8, size);
+ memset(i422_buffer->MutableDataU(), 4, halfsize);
+ memset(i422_buffer->MutableDataV(), 2, halfsize);
+
+ // Confirm YUV values are as expected.
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < width; col++) {
+ EXPECT_EQ(8, GetY(i422_buffer, col, row));
+ }
+ }
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < halfwidth; col++) {
+ EXPECT_EQ(4, GetU(i422_buffer, col, row));
+ EXPECT_EQ(2, GetV(i422_buffer, col, row));
+ }
+ }
+
+ rtc::scoped_refptr<I420BufferInterface> i420_buffer(i422_buffer->ToI420());
+ EXPECT_EQ(height, i420_buffer->height());
+ EXPECT_EQ(width, i420_buffer->width());
+ EXPECT_TRUE(test::FrameBufsEqual(reference, i420_buffer));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/test/i444_buffer_unittest.cc b/third_party/libwebrtc/api/video/test/i444_buffer_unittest.cc
new file mode 100644
index 0000000000..9a1a9315aa
--- /dev/null
+++ b/third_party/libwebrtc/api/video/test/i444_buffer_unittest.cc
@@ -0,0 +1,112 @@
+
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/i444_buffer.h"
+
+#include "api/video/i420_buffer.h"
+#include "test/frame_utils.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+namespace {
+int GetY(rtc::scoped_refptr<I444BufferInterface> buf, int col, int row) {
+ return buf->DataY()[row * buf->StrideY() + col];
+}
+
+int GetU(rtc::scoped_refptr<I444BufferInterface> buf, int col, int row) {
+ return buf->DataU()[row * buf->StrideU() + col];
+}
+
+int GetV(rtc::scoped_refptr<I444BufferInterface> buf, int col, int row) {
+ return buf->DataV()[row * buf->StrideV() + col];
+}
+
+void FillI444Buffer(rtc::scoped_refptr<I444Buffer> buf) {
+ const uint8_t Y = 1;
+ const uint8_t U = 2;
+ const uint8_t V = 3;
+ for (int row = 0; row < buf->height(); ++row) {
+ for (int col = 0; col < buf->width(); ++col) {
+ buf->MutableDataY()[row * buf->StrideY() + col] = Y;
+ buf->MutableDataU()[row * buf->StrideU() + col] = U;
+ buf->MutableDataV()[row * buf->StrideV() + col] = V;
+ }
+ }
+}
+
+} // namespace
+
+TEST(I444BufferTest, InitialData) {
+ constexpr int stride = 3;
+ constexpr int width = 3;
+ constexpr int height = 3;
+
+ rtc::scoped_refptr<I444Buffer> i444_buffer(I444Buffer::Create(width, height));
+ EXPECT_EQ(width, i444_buffer->width());
+ EXPECT_EQ(height, i444_buffer->height());
+ EXPECT_EQ(stride, i444_buffer->StrideY());
+ EXPECT_EQ(stride, i444_buffer->StrideU());
+ EXPECT_EQ(stride, i444_buffer->StrideV());
+ EXPECT_EQ(3, i444_buffer->ChromaWidth());
+ EXPECT_EQ(3, i444_buffer->ChromaHeight());
+}
+
+TEST(I444BufferTest, ReadPixels) {
+ constexpr int width = 3;
+ constexpr int height = 3;
+
+ rtc::scoped_refptr<I444Buffer> i444_buffer(I444Buffer::Create(width, height));
+ // Y = 1, U = 2, V = 3.
+ FillI444Buffer(i444_buffer);
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < width; col++) {
+ EXPECT_EQ(1, GetY(i444_buffer, col, row));
+ EXPECT_EQ(2, GetU(i444_buffer, col, row));
+ EXPECT_EQ(3, GetV(i444_buffer, col, row));
+ }
+ }
+}
+
+TEST(I444BufferTest, ToI420) {
+ constexpr int width = 3;
+ constexpr int height = 3;
+ constexpr int size_y = width * height;
+ constexpr int size_u = (width + 1) / 2 * (height + 1) / 2;
+ constexpr int size_v = (width + 1) / 2 * (height + 1) / 2;
+ rtc::scoped_refptr<I420Buffer> reference(I420Buffer::Create(width, height));
+ memset(reference->MutableDataY(), 8, size_y);
+ memset(reference->MutableDataU(), 4, size_u);
+ memset(reference->MutableDataV(), 2, size_v);
+
+ rtc::scoped_refptr<I444Buffer> i444_buffer(I444Buffer::Create(width, height));
+ // Convert the reference buffer to I444.
+ memset(i444_buffer->MutableDataY(), 8, size_y);
+ memset(i444_buffer->MutableDataU(), 4, size_y);
+ memset(i444_buffer->MutableDataV(), 2, size_y);
+
+ // Confirm YUV values are as expected.
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < width; col++) {
+ EXPECT_EQ(8, GetY(i444_buffer, col, row));
+ EXPECT_EQ(4, GetU(i444_buffer, col, row));
+ EXPECT_EQ(2, GetV(i444_buffer, col, row));
+ }
+ }
+
+ rtc::scoped_refptr<I420BufferInterface> i420_buffer(i444_buffer->ToI420());
+ EXPECT_EQ(height, i420_buffer->height());
+ EXPECT_EQ(width, i420_buffer->width());
+ EXPECT_TRUE(test::FrameBufsEqual(reference, i420_buffer));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/test/mock_recordable_encoded_frame.h b/third_party/libwebrtc/api/video/test/mock_recordable_encoded_frame.h
new file mode 100644
index 0000000000..2178932d2a
--- /dev/null
+++ b/third_party/libwebrtc/api/video/test/mock_recordable_encoded_frame.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_TEST_MOCK_RECORDABLE_ENCODED_FRAME_H_
+#define API_VIDEO_TEST_MOCK_RECORDABLE_ENCODED_FRAME_H_
+
+#include "api/video/recordable_encoded_frame.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+class MockRecordableEncodedFrame : public RecordableEncodedFrame {
+ public:
+ MOCK_METHOD(rtc::scoped_refptr<const EncodedImageBufferInterface>,
+ encoded_buffer,
+ (),
+ (const, override));
+ MOCK_METHOD(absl::optional<webrtc::ColorSpace>,
+ color_space,
+ (),
+ (const, override));
+ MOCK_METHOD(VideoCodecType, codec, (), (const, override));
+ MOCK_METHOD(bool, is_key_frame, (), (const, override));
+ MOCK_METHOD(EncodedResolution, resolution, (), (const, override));
+ MOCK_METHOD(Timestamp, render_time, (), (const, override));
+};
+} // namespace webrtc
+#endif // API_VIDEO_TEST_MOCK_RECORDABLE_ENCODED_FRAME_H_
diff --git a/third_party/libwebrtc/api/video/test/nv12_buffer_unittest.cc b/third_party/libwebrtc/api/video/test/nv12_buffer_unittest.cc
new file mode 100644
index 0000000000..d84adb5bf5
--- /dev/null
+++ b/third_party/libwebrtc/api/video/test/nv12_buffer_unittest.cc
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/nv12_buffer.h"
+
+#include "api/video/i420_buffer.h"
+#include "test/frame_utils.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+namespace {
+int GetY(rtc::scoped_refptr<NV12BufferInterface> buf, int col, int row) {
+ return buf->DataY()[row * buf->StrideY() + col];
+}
+
+int GetU(rtc::scoped_refptr<NV12BufferInterface> buf, int col, int row) {
+ return buf->DataUV()[(row / 2) * buf->StrideUV() + (col / 2) * 2];
+}
+
+int GetV(rtc::scoped_refptr<NV12BufferInterface> buf, int col, int row) {
+ return buf->DataUV()[(row / 2) * buf->StrideUV() + (col / 2) * 2 + 1];
+}
+
+void FillNV12Buffer(rtc::scoped_refptr<NV12Buffer> buf) {
+ const uint8_t Y = 1;
+ const uint8_t U = 2;
+ const uint8_t V = 3;
+ for (int row = 0; row < buf->height(); ++row) {
+ for (int col = 0; col < buf->width(); ++col) {
+ buf->MutableDataY()[row * buf->StrideY() + col] = Y;
+ }
+ }
+ // Fill interleaving UV values.
+ for (int row = 0; row < buf->ChromaHeight(); row++) {
+ for (int col = 0; col < buf->StrideUV(); col += 2) {
+ int uv_index = row * buf->StrideUV() + col;
+ buf->MutableDataUV()[uv_index] = U;
+ buf->MutableDataUV()[uv_index + 1] = V;
+ }
+ }
+}
+
+} // namespace
+
+TEST(NV12BufferTest, InitialData) {
+ constexpr int stride_y = 3;
+ constexpr int stride_uv = 4;
+ constexpr int width = 3;
+ constexpr int height = 3;
+
+ rtc::scoped_refptr<NV12Buffer> nv12_buffer(NV12Buffer::Create(width, height));
+ EXPECT_EQ(width, nv12_buffer->width());
+ EXPECT_EQ(height, nv12_buffer->height());
+ EXPECT_EQ(stride_y, nv12_buffer->StrideY());
+ EXPECT_EQ(stride_uv, nv12_buffer->StrideUV());
+ EXPECT_EQ(2, nv12_buffer->ChromaWidth());
+ EXPECT_EQ(2, nv12_buffer->ChromaHeight());
+}
+
+TEST(NV12BufferTest, ReadPixels) {
+ constexpr int width = 3;
+ constexpr int height = 3;
+
+ rtc::scoped_refptr<NV12Buffer> nv12_buffer(NV12Buffer::Create(width, height));
+ // Y = 1, U = 2, V = 3.
+ FillNV12Buffer(nv12_buffer);
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < width; col++) {
+ EXPECT_EQ(1, GetY(nv12_buffer, col, row));
+ EXPECT_EQ(2, GetU(nv12_buffer, col, row));
+ EXPECT_EQ(3, GetV(nv12_buffer, col, row));
+ }
+ }
+}
+
+TEST(NV12BufferTest, ToI420) {
+ constexpr int width = 3;
+ constexpr int height = 3;
+ constexpr int size_y = width * height;
+ constexpr int size_u = (width + 1) / 2 * (height + 1) / 2;
+ constexpr int size_v = (width + 1) / 2 * (height + 1) / 2;
+ rtc::scoped_refptr<I420Buffer> reference(I420Buffer::Create(width, height));
+ memset(reference->MutableDataY(), 8, size_y);
+ memset(reference->MutableDataU(), 4, size_u);
+ memset(reference->MutableDataV(), 2, size_v);
+
+ rtc::scoped_refptr<NV12Buffer> nv12_buffer(NV12Buffer::Create(width, height));
+ // Convert the reference buffer to NV12.
+ memset(nv12_buffer->MutableDataY(), 8, size_y);
+ // Interleaving u/v values.
+ for (int i = 0; i < size_u + size_v; i += 2) {
+ nv12_buffer->MutableDataUV()[i] = 4;
+ nv12_buffer->MutableDataUV()[i + 1] = 2;
+ }
+ // Confirm YUV values are as expected.
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < width; col++) {
+ EXPECT_EQ(8, GetY(nv12_buffer, col, row));
+ EXPECT_EQ(4, GetU(nv12_buffer, col, row));
+ EXPECT_EQ(2, GetV(nv12_buffer, col, row));
+ }
+ }
+
+ rtc::scoped_refptr<I420BufferInterface> i420_buffer(nv12_buffer->ToI420());
+ EXPECT_EQ(height, i420_buffer->height());
+ EXPECT_EQ(width, i420_buffer->width());
+ EXPECT_TRUE(test::FrameBufsEqual(reference, i420_buffer));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/test/video_adaptation_counters_unittest.cc b/third_party/libwebrtc/api/video/test/video_adaptation_counters_unittest.cc
new file mode 100644
index 0000000000..a7d0bda7d2
--- /dev/null
+++ b/third_party/libwebrtc/api/video/test/video_adaptation_counters_unittest.cc
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/video_adaptation_counters.h"
+
+#include "test/gtest.h"
+
+namespace webrtc {
+
+TEST(AdaptationCountersTest, Addition) {
+ VideoAdaptationCounters a{0, 0};
+ VideoAdaptationCounters b{1, 2};
+ VideoAdaptationCounters total = a + b;
+ EXPECT_EQ(1, total.resolution_adaptations);
+ EXPECT_EQ(2, total.fps_adaptations);
+}
+
+TEST(AdaptationCountersTest, Equality) {
+ VideoAdaptationCounters a{1, 2};
+ VideoAdaptationCounters b{2, 1};
+ EXPECT_EQ(a, a);
+ EXPECT_NE(a, b);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/test/video_bitrate_allocation_unittest.cc b/third_party/libwebrtc/api/video/test/video_bitrate_allocation_unittest.cc
new file mode 100644
index 0000000000..8e66d4b0a1
--- /dev/null
+++ b/third_party/libwebrtc/api/video/test/video_bitrate_allocation_unittest.cc
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/video_bitrate_allocation.h"
+
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+TEST(VideoBitrateAllocation, SimulcastTargetBitrate) {
+ VideoBitrateAllocation bitrate;
+ bitrate.SetBitrate(0, 0, 10000);
+ bitrate.SetBitrate(0, 1, 20000);
+ bitrate.SetBitrate(1, 0, 40000);
+ bitrate.SetBitrate(1, 1, 80000);
+
+ VideoBitrateAllocation layer0_bitrate;
+ layer0_bitrate.SetBitrate(0, 0, 10000);
+ layer0_bitrate.SetBitrate(0, 1, 20000);
+
+ VideoBitrateAllocation layer1_bitrate;
+ layer1_bitrate.SetBitrate(0, 0, 40000);
+ layer1_bitrate.SetBitrate(0, 1, 80000);
+
+ std::vector<absl::optional<VideoBitrateAllocation>> layer_allocations =
+ bitrate.GetSimulcastAllocations();
+
+ EXPECT_EQ(layer0_bitrate, layer_allocations[0]);
+ EXPECT_EQ(layer1_bitrate, layer_allocations[1]);
+}
+
+TEST(VideoBitrateAllocation, SimulcastTargetBitrateWithInactiveStream) {
+ // Create bitrate allocation with bitrate only for the first and third stream.
+ VideoBitrateAllocation bitrate;
+ bitrate.SetBitrate(0, 0, 10000);
+ bitrate.SetBitrate(0, 1, 20000);
+ bitrate.SetBitrate(2, 0, 40000);
+ bitrate.SetBitrate(2, 1, 80000);
+
+ VideoBitrateAllocation layer0_bitrate;
+ layer0_bitrate.SetBitrate(0, 0, 10000);
+ layer0_bitrate.SetBitrate(0, 1, 20000);
+
+ VideoBitrateAllocation layer2_bitrate;
+ layer2_bitrate.SetBitrate(0, 0, 40000);
+ layer2_bitrate.SetBitrate(0, 1, 80000);
+
+ std::vector<absl::optional<VideoBitrateAllocation>> layer_allocations =
+ bitrate.GetSimulcastAllocations();
+
+ EXPECT_EQ(layer0_bitrate, layer_allocations[0]);
+ EXPECT_FALSE(layer_allocations[1]);
+ EXPECT_EQ(layer2_bitrate, layer_allocations[2]);
+}
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/test/video_frame_matchers.h b/third_party/libwebrtc/api/video/test/video_frame_matchers.h
new file mode 100644
index 0000000000..250459377b
--- /dev/null
+++ b/third_party/libwebrtc/api/video/test/video_frame_matchers.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_TEST_VIDEO_FRAME_MATCHERS_H_
+#define API_VIDEO_TEST_VIDEO_FRAME_MATCHERS_H_
+
+#include "api/rtp_packet_infos.h"
+#include "api/video/video_frame.h"
+#include "test/gmock.h"
+
+namespace webrtc::test::video_frame_matchers {
+
+MATCHER_P(Rotation, rotation, "") {
+ return ::testing::Matches(::testing::Eq(rotation))(arg.rotation());
+}
+
+MATCHER_P(NtpTimestamp, ntp_ts, "") {
+ return arg.ntp_time_ms() == ntp_ts.ms();
+}
+
+MATCHER_P(PacketInfos, m, "") {
+ return ::testing::Matches(m)(arg.packet_infos());
+}
+
+} // namespace webrtc::test::video_frame_matchers
+
+#endif // API_VIDEO_TEST_VIDEO_FRAME_MATCHERS_H_
diff --git a/third_party/libwebrtc/api/video/video_adaptation_counters.cc b/third_party/libwebrtc/api/video/video_adaptation_counters.cc
new file mode 100644
index 0000000000..df1769d5d4
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_adaptation_counters.cc
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2020 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/video_adaptation_counters.h"
+
+#include "rtc_base/strings/string_builder.h"
+
+namespace webrtc {
+
+bool VideoAdaptationCounters::operator==(
+ const VideoAdaptationCounters& rhs) const {
+ return fps_adaptations == rhs.fps_adaptations &&
+ resolution_adaptations == rhs.resolution_adaptations;
+}
+
+bool VideoAdaptationCounters::operator!=(
+ const VideoAdaptationCounters& rhs) const {
+ return !(rhs == *this);
+}
+
+VideoAdaptationCounters VideoAdaptationCounters::operator+(
+ const VideoAdaptationCounters& other) const {
+ return VideoAdaptationCounters(
+ resolution_adaptations + other.resolution_adaptations,
+ fps_adaptations + other.fps_adaptations);
+}
+
+std::string VideoAdaptationCounters::ToString() const {
+ rtc::StringBuilder ss;
+ ss << "{ res=" << resolution_adaptations << " fps=" << fps_adaptations
+ << " }";
+ return ss.Release();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/video_adaptation_counters.h b/third_party/libwebrtc/api/video/video_adaptation_counters.h
new file mode 100644
index 0000000000..2dea902f2f
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_adaptation_counters.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2020 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_ADAPTATION_COUNTERS_H_
+#define API_VIDEO_VIDEO_ADAPTATION_COUNTERS_H_
+
+#include <string>
+
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+// Counts the number of adaptations have resulted due to resource overuse.
+// Today we can adapt resolution and fps.
+struct VideoAdaptationCounters {
+ VideoAdaptationCounters() : resolution_adaptations(0), fps_adaptations(0) {}
+ VideoAdaptationCounters(int resolution_adaptations, int fps_adaptations)
+ : resolution_adaptations(resolution_adaptations),
+ fps_adaptations(fps_adaptations) {
+ RTC_DCHECK_GE(resolution_adaptations, 0);
+ RTC_DCHECK_GE(fps_adaptations, 0);
+ }
+
+ int Total() const { return fps_adaptations + resolution_adaptations; }
+
+ bool operator==(const VideoAdaptationCounters& rhs) const;
+ bool operator!=(const VideoAdaptationCounters& rhs) const;
+
+ VideoAdaptationCounters operator+(const VideoAdaptationCounters& other) const;
+
+ std::string ToString() const;
+
+ int resolution_adaptations;
+ int fps_adaptations;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_ADAPTATION_COUNTERS_H_
diff --git a/third_party/libwebrtc/api/video/video_adaptation_gn/moz.build b/third_party/libwebrtc/api/video/video_adaptation_gn/moz.build
new file mode 100644
index 0000000000..3b4495f26c
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_adaptation_gn/moz.build
@@ -0,0 +1,221 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/video/video_adaptation_counters.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("video_adaptation_gn")
diff --git a/third_party/libwebrtc/api/video/video_adaptation_reason.h b/third_party/libwebrtc/api/video/video_adaptation_reason.h
new file mode 100644
index 0000000000..3b7fc36eed
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_adaptation_reason.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_ADAPTATION_REASON_H_
+#define API_VIDEO_VIDEO_ADAPTATION_REASON_H_
+
+namespace webrtc {
+
+enum class VideoAdaptationReason { kQuality, kCpu };
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_ADAPTATION_REASON_H_
diff --git a/third_party/libwebrtc/api/video/video_bitrate_allocation.cc b/third_party/libwebrtc/api/video/video_bitrate_allocation.cc
new file mode 100644
index 0000000000..e189db1c19
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_bitrate_allocation.cc
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/video_bitrate_allocation.h"
+
+#include <cstdint>
+
+#include "rtc_base/checks.h"
+#include "rtc_base/numerics/safe_conversions.h"
+#include "rtc_base/strings/string_builder.h"
+
+namespace webrtc {
+
+VideoBitrateAllocation::VideoBitrateAllocation()
+ : sum_(0), is_bw_limited_(false) {}
+
+bool VideoBitrateAllocation::SetBitrate(size_t spatial_index,
+ size_t temporal_index,
+ uint32_t bitrate_bps) {
+ RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
+ RTC_CHECK_LT(temporal_index, kMaxTemporalStreams);
+ int64_t new_bitrate_sum_bps = sum_;
+ absl::optional<uint32_t>& layer_bitrate =
+ bitrates_[spatial_index][temporal_index];
+ if (layer_bitrate) {
+ RTC_DCHECK_LE(*layer_bitrate, sum_);
+ new_bitrate_sum_bps -= *layer_bitrate;
+ }
+ new_bitrate_sum_bps += bitrate_bps;
+ if (new_bitrate_sum_bps > kMaxBitrateBps)
+ return false;
+
+ layer_bitrate = bitrate_bps;
+ sum_ = rtc::dchecked_cast<uint32_t>(new_bitrate_sum_bps);
+ return true;
+}
+
+bool VideoBitrateAllocation::HasBitrate(size_t spatial_index,
+ size_t temporal_index) const {
+ RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
+ RTC_CHECK_LT(temporal_index, kMaxTemporalStreams);
+ return bitrates_[spatial_index][temporal_index].has_value();
+}
+
+uint32_t VideoBitrateAllocation::GetBitrate(size_t spatial_index,
+ size_t temporal_index) const {
+ RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
+ RTC_CHECK_LT(temporal_index, kMaxTemporalStreams);
+ return bitrates_[spatial_index][temporal_index].value_or(0);
+}
+
+// Whether the specific spatial layers has the bitrate set in any of its
+// temporal layers.
+bool VideoBitrateAllocation::IsSpatialLayerUsed(size_t spatial_index) const {
+ RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
+ for (size_t i = 0; i < kMaxTemporalStreams; ++i) {
+ if (bitrates_[spatial_index][i].has_value())
+ return true;
+ }
+ return false;
+}
+
+// Get the sum of all the temporal layer for a specific spatial layer.
+uint32_t VideoBitrateAllocation::GetSpatialLayerSum(
+ size_t spatial_index) const {
+ RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
+ return GetTemporalLayerSum(spatial_index, kMaxTemporalStreams - 1);
+}
+
+uint32_t VideoBitrateAllocation::GetTemporalLayerSum(
+ size_t spatial_index,
+ size_t temporal_index) const {
+ RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
+ RTC_CHECK_LT(temporal_index, kMaxTemporalStreams);
+ uint32_t sum = 0;
+ for (size_t i = 0; i <= temporal_index; ++i) {
+ sum += bitrates_[spatial_index][i].value_or(0);
+ }
+ return sum;
+}
+
+std::vector<uint32_t> VideoBitrateAllocation::GetTemporalLayerAllocation(
+ size_t spatial_index) const {
+ RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
+ std::vector<uint32_t> temporal_rates;
+
+ // Find the highest temporal layer with a defined bitrate in order to
+ // determine the size of the temporal layer allocation.
+ for (size_t i = kMaxTemporalStreams; i > 0; --i) {
+ if (bitrates_[spatial_index][i - 1].has_value()) {
+ temporal_rates.resize(i);
+ break;
+ }
+ }
+
+ for (size_t i = 0; i < temporal_rates.size(); ++i) {
+ temporal_rates[i] = bitrates_[spatial_index][i].value_or(0);
+ }
+
+ return temporal_rates;
+}
+
+std::vector<absl::optional<VideoBitrateAllocation>>
+VideoBitrateAllocation::GetSimulcastAllocations() const {
+ std::vector<absl::optional<VideoBitrateAllocation>> bitrates;
+ for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
+ absl::optional<VideoBitrateAllocation> layer_bitrate;
+ if (IsSpatialLayerUsed(si)) {
+ layer_bitrate = VideoBitrateAllocation();
+ for (int tl = 0; tl < kMaxTemporalStreams; ++tl) {
+ if (HasBitrate(si, tl))
+ layer_bitrate->SetBitrate(0, tl, GetBitrate(si, tl));
+ }
+ }
+ bitrates.push_back(layer_bitrate);
+ }
+ return bitrates;
+}
+
+bool VideoBitrateAllocation::operator==(
+ const VideoBitrateAllocation& other) const {
+ for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
+ for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
+ if (bitrates_[si][ti] != other.bitrates_[si][ti])
+ return false;
+ }
+ }
+ return true;
+}
+
+std::string VideoBitrateAllocation::ToString() const {
+ if (sum_ == 0)
+ return "VideoBitrateAllocation [ [] ]";
+
+ // Max string length in practice is 260, but let's have some overhead and
+ // round up to nearest power of two.
+ char string_buf[512];
+ rtc::SimpleStringBuilder ssb(string_buf);
+
+ ssb << "VideoBitrateAllocation [";
+ uint32_t spatial_cumulator = 0;
+ for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
+ RTC_DCHECK_LE(spatial_cumulator, sum_);
+ if (spatial_cumulator == sum_)
+ break;
+
+ const uint32_t layer_sum = GetSpatialLayerSum(si);
+ if (layer_sum == sum_ && si == 0) {
+ ssb << " [";
+ } else {
+ if (si > 0)
+ ssb << ",";
+ ssb << '\n' << " [";
+ }
+ spatial_cumulator += layer_sum;
+
+ uint32_t temporal_cumulator = 0;
+ for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
+ RTC_DCHECK_LE(temporal_cumulator, layer_sum);
+ if (temporal_cumulator == layer_sum)
+ break;
+
+ if (ti > 0)
+ ssb << ", ";
+
+ uint32_t bitrate = bitrates_[si][ti].value_or(0);
+ ssb << bitrate;
+ temporal_cumulator += bitrate;
+ }
+ ssb << "]";
+ }
+
+ RTC_DCHECK_EQ(spatial_cumulator, sum_);
+ ssb << " ]";
+ return ssb.str();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/video_bitrate_allocation.h b/third_party/libwebrtc/api/video/video_bitrate_allocation.h
new file mode 100644
index 0000000000..4feffa2e66
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_bitrate_allocation.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_BITRATE_ALLOCATION_H_
+#define API_VIDEO_VIDEO_BITRATE_ALLOCATION_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <limits>
+#include <string>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/video/video_codec_constants.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Class that describes how video bitrate, in bps, is allocated across temporal
+// and spatial layers. Not that bitrates are NOT cumulative. Depending on if
+// layers are dependent or not, it is up to the user to aggregate.
+// For each index, the bitrate can also both set and unset. This is used with a
+// set bps = 0 to signal an explicit "turn off" signal.
+class RTC_EXPORT VideoBitrateAllocation {
+ public:
+ static constexpr uint32_t kMaxBitrateBps =
+ std::numeric_limits<uint32_t>::max();
+ VideoBitrateAllocation();
+
+ bool SetBitrate(size_t spatial_index,
+ size_t temporal_index,
+ uint32_t bitrate_bps);
+
+ bool HasBitrate(size_t spatial_index, size_t temporal_index) const;
+
+ uint32_t GetBitrate(size_t spatial_index, size_t temporal_index) const;
+
+ // Whether the specific spatial layers has the bitrate set in any of its
+ // temporal layers.
+ bool IsSpatialLayerUsed(size_t spatial_index) const;
+
+ // Get the sum of all the temporal layer for a specific spatial layer.
+ uint32_t GetSpatialLayerSum(size_t spatial_index) const;
+
+ // Sum of bitrates of temporal layers, from layer 0 to `temporal_index`
+ // inclusive, of specified spatial layer `spatial_index`. Bitrates of lower
+ // spatial layers are not included.
+ uint32_t GetTemporalLayerSum(size_t spatial_index,
+ size_t temporal_index) const;
+
+ // Returns a vector of the temporal layer bitrates for the specific spatial
+ // layer. Length of the returned vector is cropped to the highest temporal
+ // layer with a defined bitrate.
+ std::vector<uint32_t> GetTemporalLayerAllocation(size_t spatial_index) const;
+
+ // Returns one VideoBitrateAllocation for each spatial layer. This is used to
+ // configure simulcast streams. Note that the length of the returned vector is
+ // always kMaxSpatialLayers, the optional is unset for unused layers.
+ std::vector<absl::optional<VideoBitrateAllocation>> GetSimulcastAllocations()
+ const;
+
+ uint32_t get_sum_bps() const { return sum_; } // Sum of all bitrates.
+ uint32_t get_sum_kbps() const {
+ // Round down to not exceed the allocated bitrate.
+ return sum_ / 1000;
+ }
+
+ bool operator==(const VideoBitrateAllocation& other) const;
+ inline bool operator!=(const VideoBitrateAllocation& other) const {
+ return !(*this == other);
+ }
+
+ std::string ToString() const;
+
+ // Indicates if the allocation has some layers/streams disabled due to
+ // low available bandwidth.
+ void set_bw_limited(bool limited) { is_bw_limited_ = limited; }
+ bool is_bw_limited() const { return is_bw_limited_; }
+
+ private:
+ uint32_t sum_;
+ absl::optional<uint32_t> bitrates_[kMaxSpatialLayers][kMaxTemporalStreams];
+ bool is_bw_limited_;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_BITRATE_ALLOCATION_H_
diff --git a/third_party/libwebrtc/api/video/video_bitrate_allocation_gn/moz.build b/third_party/libwebrtc/api/video/video_bitrate_allocation_gn/moz.build
new file mode 100644
index 0000000000..2c7b1f39e7
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_bitrate_allocation_gn/moz.build
@@ -0,0 +1,221 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/video/video_bitrate_allocation.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("video_bitrate_allocation_gn")
diff --git a/third_party/libwebrtc/api/video/video_bitrate_allocator.cc b/third_party/libwebrtc/api/video/video_bitrate_allocator.cc
new file mode 100644
index 0000000000..f4e843b348
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_bitrate_allocator.cc
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/video_bitrate_allocator.h"
+
+namespace webrtc {
+
+VideoBitrateAllocationParameters::VideoBitrateAllocationParameters(
+ uint32_t total_bitrate_bps,
+ uint32_t framerate)
+ : total_bitrate(DataRate::BitsPerSec(total_bitrate_bps)),
+ stable_bitrate(DataRate::BitsPerSec(total_bitrate_bps)),
+ framerate(static_cast<double>(framerate)) {}
+
+VideoBitrateAllocationParameters::VideoBitrateAllocationParameters(
+ DataRate total_bitrate,
+ double framerate)
+ : total_bitrate(total_bitrate),
+ stable_bitrate(total_bitrate),
+ framerate(framerate) {}
+
+VideoBitrateAllocationParameters::VideoBitrateAllocationParameters(
+ DataRate total_bitrate,
+ DataRate stable_bitrate,
+ double framerate)
+ : total_bitrate(total_bitrate),
+ stable_bitrate(stable_bitrate),
+ framerate(framerate) {}
+
+VideoBitrateAllocationParameters::~VideoBitrateAllocationParameters() = default;
+
+VideoBitrateAllocation VideoBitrateAllocator::GetAllocation(
+ uint32_t total_bitrate_bps,
+ uint32_t framerate) {
+ return Allocate({DataRate::BitsPerSec(total_bitrate_bps),
+ DataRate::BitsPerSec(total_bitrate_bps),
+ static_cast<double>(framerate)});
+}
+
+VideoBitrateAllocation VideoBitrateAllocator::Allocate(
+ VideoBitrateAllocationParameters parameters) {
+ return GetAllocation(parameters.total_bitrate.bps(), parameters.framerate);
+}
+
+void VideoBitrateAllocator::SetLegacyConferenceMode(bool enabled) {}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/video_bitrate_allocator.h b/third_party/libwebrtc/api/video/video_bitrate_allocator.h
new file mode 100644
index 0000000000..fdc86dbc57
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_bitrate_allocator.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_BITRATE_ALLOCATOR_H_
+#define API_VIDEO_VIDEO_BITRATE_ALLOCATOR_H_
+
+#include "api/units/data_rate.h"
+#include "api/video/video_bitrate_allocation.h"
+
+namespace webrtc {
+
+struct VideoBitrateAllocationParameters {
+ VideoBitrateAllocationParameters(uint32_t total_bitrate_bps,
+ uint32_t framerate);
+ VideoBitrateAllocationParameters(DataRate total_bitrate, double framerate);
+ VideoBitrateAllocationParameters(DataRate total_bitrate,
+ DataRate stable_bitrate,
+ double framerate);
+ ~VideoBitrateAllocationParameters();
+
+ DataRate total_bitrate;
+ DataRate stable_bitrate;
+ double framerate;
+};
+
+class VideoBitrateAllocator {
+ public:
+ VideoBitrateAllocator() {}
+ virtual ~VideoBitrateAllocator() {}
+
+ virtual VideoBitrateAllocation GetAllocation(uint32_t total_bitrate_bps,
+ uint32_t framerate);
+
+ virtual VideoBitrateAllocation Allocate(
+ VideoBitrateAllocationParameters parameters);
+
+ // Deprecated: Only used to work around issues with the legacy conference
+ // screenshare mode and shouldn't be needed by any subclasses.
+ virtual void SetLegacyConferenceMode(bool enabled);
+};
+
+class VideoBitrateAllocationObserver {
+ public:
+ VideoBitrateAllocationObserver() {}
+ virtual ~VideoBitrateAllocationObserver() {}
+
+ virtual void OnBitrateAllocationUpdated(
+ const VideoBitrateAllocation& allocation) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_BITRATE_ALLOCATOR_H_
diff --git a/third_party/libwebrtc/api/video/video_bitrate_allocator_factory.h b/third_party/libwebrtc/api/video/video_bitrate_allocator_factory.h
new file mode 100644
index 0000000000..cb34ebb5e1
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_bitrate_allocator_factory.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_BITRATE_ALLOCATOR_FACTORY_H_
+#define API_VIDEO_VIDEO_BITRATE_ALLOCATOR_FACTORY_H_
+
+#include <memory>
+
+#include "api/video/video_bitrate_allocator.h"
+#include "api/video_codecs/video_codec.h"
+
+namespace webrtc {
+
+// A factory that creates VideoBitrateAllocator.
+// NOTE: This class is still under development and may change without notice.
+class VideoBitrateAllocatorFactory {
+ public:
+ virtual ~VideoBitrateAllocatorFactory() = default;
+ // Creates a VideoBitrateAllocator for a specific video codec.
+ virtual std::unique_ptr<VideoBitrateAllocator> CreateVideoBitrateAllocator(
+ const VideoCodec& codec) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_BITRATE_ALLOCATOR_FACTORY_H_
diff --git a/third_party/libwebrtc/api/video/video_bitrate_allocator_factory_gn/moz.build b/third_party/libwebrtc/api/video/video_bitrate_allocator_factory_gn/moz.build
new file mode 100644
index 0000000000..a6e2e2c6f5
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_bitrate_allocator_factory_gn/moz.build
@@ -0,0 +1,209 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("video_bitrate_allocator_factory_gn")
diff --git a/third_party/libwebrtc/api/video/video_bitrate_allocator_gn/moz.build b/third_party/libwebrtc/api/video/video_bitrate_allocator_gn/moz.build
new file mode 100644
index 0000000000..f09476aacb
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_bitrate_allocator_gn/moz.build
@@ -0,0 +1,221 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/video/video_bitrate_allocator.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("video_bitrate_allocator_gn")
diff --git a/third_party/libwebrtc/api/video/video_codec_constants.h b/third_party/libwebrtc/api/video/video_codec_constants.h
new file mode 100644
index 0000000000..5859f9b4cf
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_codec_constants.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_CODEC_CONSTANTS_H_
+#define API_VIDEO_VIDEO_CODEC_CONSTANTS_H_
+
+namespace webrtc {
+
+enum : int { kMaxEncoderBuffers = 8 };
+enum : int { kMaxSimulcastStreams = 3 };
+enum : int { kMaxSpatialLayers = 5 };
+enum : int { kMaxTemporalStreams = 4 };
+enum : int { kMaxPreferredPixelFormats = 5 };
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_CODEC_CONSTANTS_H_
diff --git a/third_party/libwebrtc/api/video/video_codec_constants_gn/moz.build b/third_party/libwebrtc/api/video/video_codec_constants_gn/moz.build
new file mode 100644
index 0000000000..2ac72c5b54
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_codec_constants_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("video_codec_constants_gn")
diff --git a/third_party/libwebrtc/api/video/video_codec_type.h b/third_party/libwebrtc/api/video/video_codec_type.h
new file mode 100644
index 0000000000..74a4bc4258
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_codec_type.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_CODEC_TYPE_H_
+#define API_VIDEO_VIDEO_CODEC_TYPE_H_
+
+namespace webrtc {
+
+enum VideoCodecType {
+ // There are various memset(..., 0, ...) calls in the code that rely on
+ // kVideoCodecGeneric being zero.
+ kVideoCodecGeneric = 0,
+ kVideoCodecVP8,
+ kVideoCodecVP9,
+ kVideoCodecAV1,
+ kVideoCodecH264,
+ kVideoCodecMultiplex,
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_CODEC_TYPE_H_
diff --git a/third_party/libwebrtc/api/video/video_content_type.cc b/third_party/libwebrtc/api/video/video_content_type.cc
new file mode 100644
index 0000000000..9ba3ece79b
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_content_type.cc
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/video_content_type.h"
+
+// VideoContentType stored as a single byte, which is sent over the network.
+// Structure:
+//
+// 0 1 2 3 4 5 6 7
+// +---------------+
+// |r r e e e s s c|
+//
+// where:
+// r - reserved bits.
+// e - 3-bit number of an experiment group counted from 1. 0 means there's no
+// experiment ongoing.
+// s - 2-bit simulcast stream id or spatial layer, counted from 1. 0 means that
+// no simulcast information is set.
+// c - content type. 0 means real-time video, 1 means screenshare.
+//
+
+namespace webrtc {
+namespace videocontenttypehelpers {
+
+namespace {
+static constexpr uint8_t kScreenshareBitsSize = 1;
+static constexpr uint8_t kScreenshareBitsMask =
+ (1u << kScreenshareBitsSize) - 1;
+
+static constexpr uint8_t kSimulcastShift = 1;
+static constexpr uint8_t kSimulcastBitsSize = 2;
+static constexpr uint8_t kSimulcastBitsMask = ((1u << kSimulcastBitsSize) - 1)
+ << kSimulcastShift; // 0b00000110
+
+static constexpr uint8_t kExperimentShift = 3;
+static constexpr uint8_t kExperimentBitsSize = 3;
+static constexpr uint8_t kExperimentBitsMask =
+ ((1u << kExperimentBitsSize) - 1) << kExperimentShift; // 0b00111000
+
+static constexpr uint8_t kTotalBitsSize =
+ kScreenshareBitsSize + kSimulcastBitsSize + kExperimentBitsSize;
+} // namespace
+
+bool SetExperimentId(VideoContentType* content_type, uint8_t experiment_id) {
+ // Store in bits 2-4.
+ if (experiment_id >= (1 << kExperimentBitsSize))
+ return false;
+ *content_type = static_cast<VideoContentType>(
+ (static_cast<uint8_t>(*content_type) & ~kExperimentBitsMask) |
+ ((experiment_id << kExperimentShift) & kExperimentBitsMask));
+ return true;
+}
+
+bool SetSimulcastId(VideoContentType* content_type, uint8_t simulcast_id) {
+ // Store in bits 5-6.
+ if (simulcast_id >= (1 << kSimulcastBitsSize))
+ return false;
+ *content_type = static_cast<VideoContentType>(
+ (static_cast<uint8_t>(*content_type) & ~kSimulcastBitsMask) |
+ ((simulcast_id << kSimulcastShift) & kSimulcastBitsMask));
+ return true;
+}
+
+uint8_t GetExperimentId(const VideoContentType& content_type) {
+ return (static_cast<uint8_t>(content_type) & kExperimentBitsMask) >>
+ kExperimentShift;
+}
+uint8_t GetSimulcastId(const VideoContentType& content_type) {
+ return (static_cast<uint8_t>(content_type) & kSimulcastBitsMask) >>
+ kSimulcastShift;
+}
+
+bool IsScreenshare(const VideoContentType& content_type) {
+ return (static_cast<uint8_t>(content_type) & kScreenshareBitsMask) > 0;
+}
+
+bool IsValidContentType(uint8_t value) {
+ // Any 6-bit value is allowed.
+ return value < (1 << kTotalBitsSize);
+}
+
+const char* ToString(const VideoContentType& content_type) {
+ return IsScreenshare(content_type) ? "screen" : "realtime";
+}
+} // namespace videocontenttypehelpers
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/video_content_type.h b/third_party/libwebrtc/api/video/video_content_type.h
new file mode 100644
index 0000000000..2d38a62366
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_content_type.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_CONTENT_TYPE_H_
+#define API_VIDEO_VIDEO_CONTENT_TYPE_H_
+
+#include <stdint.h>
+
+namespace webrtc {
+
+enum class VideoContentType : uint8_t {
+ UNSPECIFIED = 0,
+ SCREENSHARE = 1,
+};
+
+namespace videocontenttypehelpers {
+bool SetExperimentId(VideoContentType* content_type, uint8_t experiment_id);
+bool SetSimulcastId(VideoContentType* content_type, uint8_t simulcast_id);
+
+uint8_t GetExperimentId(const VideoContentType& content_type);
+uint8_t GetSimulcastId(const VideoContentType& content_type);
+
+bool IsScreenshare(const VideoContentType& content_type);
+
+bool IsValidContentType(uint8_t value);
+
+const char* ToString(const VideoContentType& content_type);
+} // namespace videocontenttypehelpers
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_CONTENT_TYPE_H_
diff --git a/third_party/libwebrtc/api/video/video_frame.cc b/third_party/libwebrtc/api/video/video_frame.cc
new file mode 100644
index 0000000000..130820a886
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_frame.cc
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/video_frame.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "rtc_base/checks.h"
+#include "rtc_base/time_utils.h"
+
+namespace webrtc {
+
+void VideoFrame::UpdateRect::Union(const UpdateRect& other) {
+ if (other.IsEmpty())
+ return;
+ if (IsEmpty()) {
+ *this = other;
+ return;
+ }
+ int right = std::max(offset_x + width, other.offset_x + other.width);
+ int bottom = std::max(offset_y + height, other.offset_y + other.height);
+ offset_x = std::min(offset_x, other.offset_x);
+ offset_y = std::min(offset_y, other.offset_y);
+ width = right - offset_x;
+ height = bottom - offset_y;
+ RTC_DCHECK_GT(width, 0);
+ RTC_DCHECK_GT(height, 0);
+}
+
+void VideoFrame::UpdateRect::Intersect(const UpdateRect& other) {
+ if (other.IsEmpty() || IsEmpty()) {
+ MakeEmptyUpdate();
+ return;
+ }
+
+ int right = std::min(offset_x + width, other.offset_x + other.width);
+ int bottom = std::min(offset_y + height, other.offset_y + other.height);
+ offset_x = std::max(offset_x, other.offset_x);
+ offset_y = std::max(offset_y, other.offset_y);
+ width = right - offset_x;
+ height = bottom - offset_y;
+ if (width <= 0 || height <= 0) {
+ MakeEmptyUpdate();
+ }
+}
+
+void VideoFrame::UpdateRect::MakeEmptyUpdate() {
+ width = height = offset_x = offset_y = 0;
+}
+
+bool VideoFrame::UpdateRect::IsEmpty() const {
+ return width == 0 && height == 0;
+}
+
+VideoFrame::UpdateRect VideoFrame::UpdateRect::ScaleWithFrame(
+ int frame_width,
+ int frame_height,
+ int crop_x,
+ int crop_y,
+ int crop_width,
+ int crop_height,
+ int scaled_width,
+ int scaled_height) const {
+ RTC_DCHECK_GT(frame_width, 0);
+ RTC_DCHECK_GT(frame_height, 0);
+
+ RTC_DCHECK_GT(crop_width, 0);
+ RTC_DCHECK_GT(crop_height, 0);
+
+ RTC_DCHECK_LE(crop_width + crop_x, frame_width);
+ RTC_DCHECK_LE(crop_height + crop_y, frame_height);
+
+ RTC_DCHECK_GT(scaled_width, 0);
+ RTC_DCHECK_GT(scaled_height, 0);
+
+ // Check if update rect is out of the cropped area.
+ if (offset_x + width < crop_x || offset_x > crop_x + crop_width ||
+ offset_y + height < crop_y || offset_y > crop_y + crop_width) {
+ return {0, 0, 0, 0};
+ }
+
+ int x = offset_x - crop_x;
+ int w = width;
+ if (x < 0) {
+ w += x;
+ x = 0;
+ }
+ int y = offset_y - crop_y;
+ int h = height;
+ if (y < 0) {
+ h += y;
+ y = 0;
+ }
+
+ // Lower corner is rounded down.
+ x = x * scaled_width / crop_width;
+ y = y * scaled_height / crop_height;
+ // Upper corner is rounded up.
+ w = (w * scaled_width + crop_width - 1) / crop_width;
+ h = (h * scaled_height + crop_height - 1) / crop_height;
+
+ // Round to full 2x2 blocks due to possible subsampling in the pixel data.
+ if (x % 2) {
+ --x;
+ ++w;
+ }
+ if (y % 2) {
+ --y;
+ ++h;
+ }
+ if (w % 2) {
+ ++w;
+ }
+ if (h % 2) {
+ ++h;
+ }
+
+ // Expand the update rect by 2 pixels in each direction to include any
+ // possible scaling artifacts.
+ if (scaled_width != crop_width || scaled_height != crop_height) {
+ if (x > 0) {
+ x -= 2;
+ w += 2;
+ }
+ if (y > 0) {
+ y -= 2;
+ h += 2;
+ }
+ w += 2;
+ h += 2;
+ }
+
+ // Ensure update rect is inside frame dimensions.
+ if (x + w > scaled_width) {
+ w = scaled_width - x;
+ }
+ if (y + h > scaled_height) {
+ h = scaled_height - y;
+ }
+ RTC_DCHECK_GE(w, 0);
+ RTC_DCHECK_GE(h, 0);
+ if (w == 0 || h == 0) {
+ w = 0;
+ h = 0;
+ x = 0;
+ y = 0;
+ }
+
+ return {x, y, w, h};
+}
+
+VideoFrame::Builder::Builder() = default;
+
+VideoFrame::Builder::~Builder() = default;
+
+VideoFrame VideoFrame::Builder::build() {
+ RTC_CHECK(video_frame_buffer_ != nullptr);
+ return VideoFrame(id_, video_frame_buffer_, timestamp_us_, timestamp_rtp_,
+ ntp_time_ms_, rotation_, color_space_, render_parameters_,
+ update_rect_, packet_infos_);
+}
+
+VideoFrame::Builder& VideoFrame::Builder::set_video_frame_buffer(
+ const rtc::scoped_refptr<VideoFrameBuffer>& buffer) {
+ video_frame_buffer_ = buffer;
+ return *this;
+}
+
+VideoFrame::Builder& VideoFrame::Builder::set_timestamp_ms(
+ int64_t timestamp_ms) {
+ timestamp_us_ = timestamp_ms * rtc::kNumMicrosecsPerMillisec;
+ return *this;
+}
+
+VideoFrame::Builder& VideoFrame::Builder::set_timestamp_us(
+ int64_t timestamp_us) {
+ timestamp_us_ = timestamp_us;
+ return *this;
+}
+
+VideoFrame::Builder& VideoFrame::Builder::set_timestamp_rtp(
+ uint32_t timestamp_rtp) {
+ timestamp_rtp_ = timestamp_rtp;
+ return *this;
+}
+
+VideoFrame::Builder& VideoFrame::Builder::set_ntp_time_ms(int64_t ntp_time_ms) {
+ ntp_time_ms_ = ntp_time_ms;
+ return *this;
+}
+
+VideoFrame::Builder& VideoFrame::Builder::set_rotation(VideoRotation rotation) {
+ rotation_ = rotation;
+ return *this;
+}
+
+VideoFrame::Builder& VideoFrame::Builder::set_color_space(
+ const absl::optional<ColorSpace>& color_space) {
+ color_space_ = color_space;
+ return *this;
+}
+
+VideoFrame::Builder& VideoFrame::Builder::set_color_space(
+ const ColorSpace* color_space) {
+ color_space_ =
+ color_space ? absl::make_optional(*color_space) : absl::nullopt;
+ return *this;
+}
+
+VideoFrame::Builder& VideoFrame::Builder::set_id(uint16_t id) {
+ id_ = id;
+ return *this;
+}
+
+VideoFrame::Builder& VideoFrame::Builder::set_update_rect(
+ const absl::optional<VideoFrame::UpdateRect>& update_rect) {
+ update_rect_ = update_rect;
+ return *this;
+}
+
+VideoFrame::Builder& VideoFrame::Builder::set_packet_infos(
+ RtpPacketInfos packet_infos) {
+ packet_infos_ = std::move(packet_infos);
+ return *this;
+}
+
+VideoFrame::VideoFrame(const rtc::scoped_refptr<VideoFrameBuffer>& buffer,
+ webrtc::VideoRotation rotation,
+ int64_t timestamp_us)
+ : video_frame_buffer_(buffer),
+ timestamp_rtp_(0),
+ ntp_time_ms_(0),
+ timestamp_us_(timestamp_us),
+ rotation_(rotation) {}
+
+VideoFrame::VideoFrame(const rtc::scoped_refptr<VideoFrameBuffer>& buffer,
+ uint32_t timestamp_rtp,
+ int64_t render_time_ms,
+ VideoRotation rotation)
+ : video_frame_buffer_(buffer),
+ timestamp_rtp_(timestamp_rtp),
+ ntp_time_ms_(0),
+ timestamp_us_(render_time_ms * rtc::kNumMicrosecsPerMillisec),
+ rotation_(rotation) {
+ RTC_DCHECK(buffer);
+}
+
+VideoFrame::VideoFrame(uint16_t id,
+ const rtc::scoped_refptr<VideoFrameBuffer>& buffer,
+ int64_t timestamp_us,
+ uint32_t timestamp_rtp,
+ int64_t ntp_time_ms,
+ VideoRotation rotation,
+ const absl::optional<ColorSpace>& color_space,
+ const RenderParameters& render_parameters,
+ const absl::optional<UpdateRect>& update_rect,
+ RtpPacketInfos packet_infos)
+ : id_(id),
+ video_frame_buffer_(buffer),
+ timestamp_rtp_(timestamp_rtp),
+ ntp_time_ms_(ntp_time_ms),
+ timestamp_us_(timestamp_us),
+ rotation_(rotation),
+ color_space_(color_space),
+ render_parameters_(render_parameters),
+ update_rect_(update_rect),
+ packet_infos_(std::move(packet_infos)) {
+ if (update_rect_) {
+ RTC_DCHECK_GE(update_rect_->offset_x, 0);
+ RTC_DCHECK_GE(update_rect_->offset_y, 0);
+ RTC_DCHECK_LE(update_rect_->offset_x + update_rect_->width, width());
+ RTC_DCHECK_LE(update_rect_->offset_y + update_rect_->height, height());
+ }
+}
+
+VideoFrame::~VideoFrame() = default;
+
+VideoFrame::VideoFrame(const VideoFrame&) = default;
+VideoFrame::VideoFrame(VideoFrame&&) = default;
+VideoFrame& VideoFrame::operator=(const VideoFrame&) = default;
+VideoFrame& VideoFrame::operator=(VideoFrame&&) = default;
+
+int VideoFrame::width() const {
+ return video_frame_buffer_ ? video_frame_buffer_->width() : 0;
+}
+
+int VideoFrame::height() const {
+ return video_frame_buffer_ ? video_frame_buffer_->height() : 0;
+}
+
+uint32_t VideoFrame::size() const {
+ return width() * height();
+}
+
+rtc::scoped_refptr<VideoFrameBuffer> VideoFrame::video_frame_buffer() const {
+ return video_frame_buffer_;
+}
+
+void VideoFrame::set_video_frame_buffer(
+ const rtc::scoped_refptr<VideoFrameBuffer>& buffer) {
+ RTC_CHECK(buffer);
+ video_frame_buffer_ = buffer;
+}
+
+int64_t VideoFrame::render_time_ms() const {
+ return timestamp_us() / rtc::kNumMicrosecsPerMillisec;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/video_frame.h b/third_party/libwebrtc/api/video/video_frame.h
new file mode 100644
index 0000000000..086aad820f
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_frame.h
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_FRAME_H_
+#define API_VIDEO_VIDEO_FRAME_H_
+
+#include <stdint.h>
+
+#include <utility>
+
+#include "absl/types/optional.h"
+#include "api/rtp_packet_infos.h"
+#include "api/scoped_refptr.h"
+#include "api/video/color_space.h"
+#include "api/video/hdr_metadata.h"
+#include "api/video/video_frame_buffer.h"
+#include "api/video/video_rotation.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+class RTC_EXPORT VideoFrame {
+ public:
+ // Value used to signal that `VideoFrame::id()` is not set.
+ static constexpr uint16_t kNotSetId = 0;
+
+ struct RTC_EXPORT UpdateRect {
+ int offset_x;
+ int offset_y;
+ int width;
+ int height;
+
+ // Makes this UpdateRect a bounding box of this and other rect.
+ void Union(const UpdateRect& other);
+
+ // Makes this UpdateRect an intersection of this and other rect.
+ void Intersect(const UpdateRect& other);
+
+ // Sets everything to 0, making this UpdateRect a zero-size (empty) update.
+ void MakeEmptyUpdate();
+
+ bool IsEmpty() const;
+
+ // Per-member equality check. Empty rectangles with different offsets would
+ // be considered different.
+ bool operator==(const UpdateRect& other) const {
+ return other.offset_x == offset_x && other.offset_y == offset_y &&
+ other.width == width && other.height == height;
+ }
+
+ bool operator!=(const UpdateRect& other) const { return !(*this == other); }
+
+ // Scales update_rect given original frame dimensions.
+ // Cropping is applied first, then rect is scaled down.
+ // Update rect is snapped to 2x2 grid due to possible UV subsampling and
+ // then expanded by additional 2 pixels in each direction to accommodate any
+ // possible scaling artifacts.
+ // Note, close but not equal update_rects on original frame may result in
+ // the same scaled update rects.
+ UpdateRect ScaleWithFrame(int frame_width,
+ int frame_height,
+ int crop_x,
+ int crop_y,
+ int crop_width,
+ int crop_height,
+ int scaled_width,
+ int scaled_height) const;
+ };
+
+ struct RTC_EXPORT ProcessingTime {
+ TimeDelta Elapsed() const { return finish - start; }
+ Timestamp start;
+ Timestamp finish;
+ };
+
+ struct RTC_EXPORT RenderParameters {
+ bool use_low_latency_rendering = false;
+ absl::optional<int32_t> max_composition_delay_in_frames;
+
+ bool operator==(const RenderParameters& other) const {
+ return other.use_low_latency_rendering == use_low_latency_rendering &&
+ other.max_composition_delay_in_frames ==
+ max_composition_delay_in_frames;
+ }
+
+ bool operator!=(const RenderParameters& other) const {
+ return !(*this == other);
+ }
+ };
+
+ // Preferred way of building VideoFrame objects.
+ class RTC_EXPORT Builder {
+ public:
+ Builder();
+ ~Builder();
+
+ VideoFrame build();
+ Builder& set_video_frame_buffer(
+ const rtc::scoped_refptr<VideoFrameBuffer>& buffer);
+ Builder& set_timestamp_ms(int64_t timestamp_ms);
+ Builder& set_timestamp_us(int64_t timestamp_us);
+ Builder& set_timestamp_rtp(uint32_t timestamp_rtp);
+ Builder& set_ntp_time_ms(int64_t ntp_time_ms);
+ Builder& set_rotation(VideoRotation rotation);
+ Builder& set_color_space(const absl::optional<ColorSpace>& color_space);
+ Builder& set_color_space(const ColorSpace* color_space);
+ Builder& set_id(uint16_t id);
+ Builder& set_update_rect(const absl::optional<UpdateRect>& update_rect);
+ Builder& set_packet_infos(RtpPacketInfos packet_infos);
+
+ private:
+ uint16_t id_ = kNotSetId;
+ rtc::scoped_refptr<webrtc::VideoFrameBuffer> video_frame_buffer_;
+ int64_t timestamp_us_ = 0;
+ uint32_t timestamp_rtp_ = 0;
+ int64_t ntp_time_ms_ = 0;
+ VideoRotation rotation_ = kVideoRotation_0;
+ absl::optional<ColorSpace> color_space_;
+ RenderParameters render_parameters_;
+ absl::optional<UpdateRect> update_rect_;
+ RtpPacketInfos packet_infos_;
+ };
+
+ // To be deprecated. Migrate all use to Builder.
+ VideoFrame(const rtc::scoped_refptr<VideoFrameBuffer>& buffer,
+ webrtc::VideoRotation rotation,
+ int64_t timestamp_us);
+ VideoFrame(const rtc::scoped_refptr<VideoFrameBuffer>& buffer,
+ uint32_t timestamp_rtp,
+ int64_t render_time_ms,
+ VideoRotation rotation);
+
+ ~VideoFrame();
+
+ // Support move and copy.
+ VideoFrame(const VideoFrame&);
+ VideoFrame(VideoFrame&&);
+ VideoFrame& operator=(const VideoFrame&);
+ VideoFrame& operator=(VideoFrame&&);
+
+ // Get frame width.
+ int width() const;
+ // Get frame height.
+ int height() const;
+ // Get frame size in pixels.
+ uint32_t size() const;
+
+ // Get frame ID. Returns `kNotSetId` if ID is not set. Not guaranteed to be
+ // transferred from the sender to the receiver, but preserved on the sender
+ // side. The id should be propagated between all frame modifications during
+ // its lifetime from capturing to sending as encoded image. It is intended to
+ // be unique over a time window of a few minutes for the peer connection to
+ // which the corresponding video stream belongs to.
+ uint16_t id() const { return id_; }
+ void set_id(uint16_t id) { id_ = id; }
+
+ // System monotonic clock, same timebase as rtc::TimeMicros().
+ int64_t timestamp_us() const { return timestamp_us_; }
+ void set_timestamp_us(int64_t timestamp_us) { timestamp_us_ = timestamp_us; }
+
+ // Set frame timestamp (90kHz).
+ void set_timestamp(uint32_t timestamp) { timestamp_rtp_ = timestamp; }
+
+ // Get frame timestamp (90kHz).
+ uint32_t timestamp() const { return timestamp_rtp_; }
+
+ // Set capture ntp time in milliseconds.
+ void set_ntp_time_ms(int64_t ntp_time_ms) { ntp_time_ms_ = ntp_time_ms; }
+
+ // Get capture ntp time in milliseconds.
+ int64_t ntp_time_ms() const { return ntp_time_ms_; }
+
+ // Naming convention for Coordination of Video Orientation. Please see
+ // http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/ts_126114v120700p.pdf
+ //
+ // "pending rotation" or "pending" = a frame that has a VideoRotation > 0.
+ //
+ // "not pending" = a frame that has a VideoRotation == 0.
+ //
+ // "apply rotation" = modify a frame from being "pending" to being "not
+ // pending" rotation (a no-op for "unrotated").
+ //
+ VideoRotation rotation() const { return rotation_; }
+ void set_rotation(VideoRotation rotation) { rotation_ = rotation; }
+
+ // Get color space when available.
+ const absl::optional<ColorSpace>& color_space() const { return color_space_; }
+ void set_color_space(const absl::optional<ColorSpace>& color_space) {
+ color_space_ = color_space;
+ }
+
+ RenderParameters render_parameters() const { return render_parameters_; }
+ void set_render_parameters(const RenderParameters& render_parameters) {
+ render_parameters_ = render_parameters;
+ }
+
+ // Deprecated in favor of render_parameters, will be removed once Chromium is
+ // updated. max_composition_delay_in_frames() is used in an experiment of a
+ // low-latency renderer algorithm see crbug.com/1138888.
+ [[deprecated("Use render_parameters() instead.")]] absl::optional<int32_t>
+ max_composition_delay_in_frames() const {
+ return render_parameters_.max_composition_delay_in_frames;
+ }
+
+ // Get render time in milliseconds.
+ int64_t render_time_ms() const;
+
+ // Return the underlying buffer. Never nullptr for a properly
+ // initialized VideoFrame.
+ rtc::scoped_refptr<webrtc::VideoFrameBuffer> video_frame_buffer() const;
+
+ void set_video_frame_buffer(
+ const rtc::scoped_refptr<VideoFrameBuffer>& buffer);
+
+ // Return true if the frame is stored in a texture.
+ bool is_texture() const {
+ return video_frame_buffer()->type() == VideoFrameBuffer::Type::kNative;
+ }
+
+ bool has_update_rect() const { return update_rect_.has_value(); }
+
+ // Returns update_rect set by the builder or set_update_rect() or whole frame
+ // rect if no update rect is available.
+ UpdateRect update_rect() const {
+ return update_rect_.value_or(UpdateRect{0, 0, width(), height()});
+ }
+
+ // Rectangle must be within the frame dimensions.
+ void set_update_rect(const VideoFrame::UpdateRect& update_rect) {
+ RTC_DCHECK_GE(update_rect.offset_x, 0);
+ RTC_DCHECK_GE(update_rect.offset_y, 0);
+ RTC_DCHECK_LE(update_rect.offset_x + update_rect.width, width());
+ RTC_DCHECK_LE(update_rect.offset_y + update_rect.height, height());
+ update_rect_ = update_rect;
+ }
+
+ void clear_update_rect() { update_rect_ = absl::nullopt; }
+
+ // Get information about packets used to assemble this video frame. Might be
+ // empty if the information isn't available.
+ const RtpPacketInfos& packet_infos() const { return packet_infos_; }
+ void set_packet_infos(RtpPacketInfos value) {
+ packet_infos_ = std::move(value);
+ }
+
+ const absl::optional<ProcessingTime> processing_time() const {
+ return processing_time_;
+ }
+ void set_processing_time(const ProcessingTime& processing_time) {
+ processing_time_ = processing_time;
+ }
+
+ private:
+ VideoFrame(uint16_t id,
+ const rtc::scoped_refptr<VideoFrameBuffer>& buffer,
+ int64_t timestamp_us,
+ uint32_t timestamp_rtp,
+ int64_t ntp_time_ms,
+ VideoRotation rotation,
+ const absl::optional<ColorSpace>& color_space,
+ const RenderParameters& render_parameters,
+ const absl::optional<UpdateRect>& update_rect,
+ RtpPacketInfos packet_infos);
+
+ uint16_t id_;
+ // An opaque reference counted handle that stores the pixel data.
+ rtc::scoped_refptr<webrtc::VideoFrameBuffer> video_frame_buffer_;
+ uint32_t timestamp_rtp_;
+ int64_t ntp_time_ms_;
+ int64_t timestamp_us_;
+ VideoRotation rotation_;
+ absl::optional<ColorSpace> color_space_;
+ // Contains parameters that affect have the frame should be rendered.
+ RenderParameters render_parameters_;
+ // Updated since the last frame area. If present it means that the bounding
+ // box of all the changes is within the rectangular area and is close to it.
+ // If absent, it means that there's no information about the change at all and
+ // update_rect() will return a rectangle corresponding to the entire frame.
+ absl::optional<UpdateRect> update_rect_;
+ // Information about packets used to assemble this video frame. This is needed
+ // by `SourceTracker` when the frame is delivered to the RTCRtpReceiver's
+ // MediaStreamTrack, in order to implement getContributingSources(). See:
+ // https://w3c.github.io/webrtc-pc/#dom-rtcrtpreceiver-getcontributingsources
+ RtpPacketInfos packet_infos_;
+ // Processing timestamps of the frame. For received video frames these are the
+ // timestamps when the frame is sent to the decoder and the decoded image
+ // returned from the decoder.
+ // Currently, not set for locally captured video frames.
+ absl::optional<ProcessingTime> processing_time_;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_FRAME_H_
diff --git a/third_party/libwebrtc/api/video/video_frame_buffer.cc b/third_party/libwebrtc/api/video/video_frame_buffer.cc
new file mode 100644
index 0000000000..374b438adc
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_frame_buffer.cc
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/video_frame_buffer.h"
+
+#include "api/video/i420_buffer.h"
+#include "api/video/i422_buffer.h"
+#include "api/video/i444_buffer.h"
+#include "api/video/nv12_buffer.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+rtc::scoped_refptr<VideoFrameBuffer> VideoFrameBuffer::CropAndScale(
+ int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height,
+ int scaled_width,
+ int scaled_height) {
+ rtc::scoped_refptr<I420Buffer> result =
+ I420Buffer::Create(scaled_width, scaled_height);
+ result->CropAndScaleFrom(*this->ToI420(), offset_x, offset_y, crop_width,
+ crop_height);
+ return result;
+}
+
+const I420BufferInterface* VideoFrameBuffer::GetI420() const {
+ // Overridden by subclasses that can return an I420 buffer without any
+ // conversion, in particular, I420BufferInterface.
+ return nullptr;
+}
+
+const I420ABufferInterface* VideoFrameBuffer::GetI420A() const {
+ RTC_CHECK(type() == Type::kI420A);
+ return static_cast<const I420ABufferInterface*>(this);
+}
+
+const I444BufferInterface* VideoFrameBuffer::GetI444() const {
+ RTC_CHECK(type() == Type::kI444);
+ return static_cast<const I444BufferInterface*>(this);
+}
+
+const I422BufferInterface* VideoFrameBuffer::GetI422() const {
+ RTC_CHECK(type() == Type::kI422);
+ return static_cast<const I422BufferInterface*>(this);
+}
+
+const I010BufferInterface* VideoFrameBuffer::GetI010() const {
+ RTC_CHECK(type() == Type::kI010);
+ return static_cast<const I010BufferInterface*>(this);
+}
+
+const I210BufferInterface* VideoFrameBuffer::GetI210() const {
+ RTC_CHECK(type() == Type::kI210);
+ return static_cast<const I210BufferInterface*>(this);
+}
+
+const I410BufferInterface* VideoFrameBuffer::GetI410() const {
+ RTC_CHECK(type() == Type::kI410);
+ return static_cast<const I410BufferInterface*>(this);
+}
+
+const NV12BufferInterface* VideoFrameBuffer::GetNV12() const {
+ RTC_CHECK(type() == Type::kNV12);
+ return static_cast<const NV12BufferInterface*>(this);
+}
+
+rtc::scoped_refptr<VideoFrameBuffer> VideoFrameBuffer::GetMappedFrameBuffer(
+ rtc::ArrayView<Type> types) {
+ RTC_CHECK(type() == Type::kNative);
+ return nullptr;
+}
+
+VideoFrameBuffer::Type I420BufferInterface::type() const {
+ return Type::kI420;
+}
+
+const char* VideoFrameBufferTypeToString(VideoFrameBuffer::Type type) {
+ switch (type) {
+ case VideoFrameBuffer::Type::kNative:
+ return "kNative";
+ case VideoFrameBuffer::Type::kI420:
+ return "kI420";
+ case VideoFrameBuffer::Type::kI420A:
+ return "kI420A";
+ case VideoFrameBuffer::Type::kI444:
+ return "kI444";
+ case VideoFrameBuffer::Type::kI422:
+ return "kI422";
+ case VideoFrameBuffer::Type::kI010:
+ return "kI010";
+ case VideoFrameBuffer::Type::kI210:
+ return "kI210";
+ case VideoFrameBuffer::Type::kI410:
+ return "kI410";
+ case VideoFrameBuffer::Type::kNV12:
+ return "kNV12";
+ default:
+ RTC_DCHECK_NOTREACHED();
+ }
+}
+
+int I420BufferInterface::ChromaWidth() const {
+ return (width() + 1) / 2;
+}
+
+int I420BufferInterface::ChromaHeight() const {
+ return (height() + 1) / 2;
+}
+
+rtc::scoped_refptr<I420BufferInterface> I420BufferInterface::ToI420() {
+ return rtc::scoped_refptr<I420BufferInterface>(this);
+}
+
+const I420BufferInterface* I420BufferInterface::GetI420() const {
+ return this;
+}
+
+VideoFrameBuffer::Type I420ABufferInterface::type() const {
+ return Type::kI420A;
+}
+
+VideoFrameBuffer::Type I444BufferInterface::type() const {
+ return Type::kI444;
+}
+
+int I444BufferInterface::ChromaWidth() const {
+ return width();
+}
+
+int I444BufferInterface::ChromaHeight() const {
+ return height();
+}
+
+rtc::scoped_refptr<VideoFrameBuffer> I444BufferInterface::CropAndScale(
+ int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height,
+ int scaled_width,
+ int scaled_height) {
+ rtc::scoped_refptr<I444Buffer> result =
+ I444Buffer::Create(scaled_width, scaled_height);
+ result->CropAndScaleFrom(*this, offset_x, offset_y, crop_width, crop_height);
+ return result;
+}
+
+VideoFrameBuffer::Type I422BufferInterface::type() const {
+ return Type::kI422;
+}
+
+int I422BufferInterface::ChromaWidth() const {
+ return (width() + 1) / 2;
+}
+
+int I422BufferInterface::ChromaHeight() const {
+ return height();
+}
+
+rtc::scoped_refptr<VideoFrameBuffer> I422BufferInterface::CropAndScale(
+ int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height,
+ int scaled_width,
+ int scaled_height) {
+ rtc::scoped_refptr<I422Buffer> result =
+ I422Buffer::Create(scaled_width, scaled_height);
+ result->CropAndScaleFrom(*this, offset_x, offset_y, crop_width, crop_height);
+ return result;
+}
+
+VideoFrameBuffer::Type I010BufferInterface::type() const {
+ return Type::kI010;
+}
+
+int I010BufferInterface::ChromaWidth() const {
+ return (width() + 1) / 2;
+}
+
+int I010BufferInterface::ChromaHeight() const {
+ return (height() + 1) / 2;
+}
+
+VideoFrameBuffer::Type I210BufferInterface::type() const {
+ return Type::kI210;
+}
+
+int I210BufferInterface::ChromaWidth() const {
+ return (width() + 1) / 2;
+}
+
+int I210BufferInterface::ChromaHeight() const {
+ return height();
+}
+
+VideoFrameBuffer::Type I410BufferInterface::type() const {
+ return Type::kI410;
+}
+
+int I410BufferInterface::ChromaWidth() const {
+ return width();
+}
+
+int I410BufferInterface::ChromaHeight() const {
+ return height();
+}
+
+VideoFrameBuffer::Type NV12BufferInterface::type() const {
+ return Type::kNV12;
+}
+
+int NV12BufferInterface::ChromaWidth() const {
+ return (width() + 1) / 2;
+}
+
+int NV12BufferInterface::ChromaHeight() const {
+ return (height() + 1) / 2;
+}
+
+rtc::scoped_refptr<VideoFrameBuffer> NV12BufferInterface::CropAndScale(
+ int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height,
+ int scaled_width,
+ int scaled_height) {
+ rtc::scoped_refptr<NV12Buffer> result =
+ NV12Buffer::Create(scaled_width, scaled_height);
+ result->CropAndScaleFrom(*this, offset_x, offset_y, crop_width, crop_height);
+ return result;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/video_frame_buffer.h b/third_party/libwebrtc/api/video/video_frame_buffer.h
new file mode 100644
index 0000000000..aaf786699f
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_frame_buffer.h
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_FRAME_BUFFER_H_
+#define API_VIDEO_VIDEO_FRAME_BUFFER_H_
+
+#include <stdint.h>
+
+#include "api/array_view.h"
+#include "api/scoped_refptr.h"
+#include "rtc_base/ref_count.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+class I420BufferInterface;
+class I420ABufferInterface;
+class I422BufferInterface;
+class I444BufferInterface;
+class I010BufferInterface;
+class I210BufferInterface;
+class I410BufferInterface;
+class NV12BufferInterface;
+
+// Base class for frame buffers of different types of pixel format and storage.
+// The tag in type() indicates how the data is represented, and each type is
+// implemented as a subclass. To access the pixel data, call the appropriate
+// GetXXX() function, where XXX represents the type. There is also a function
+// ToI420() that returns a frame buffer in I420 format, converting from the
+// underlying representation if necessary. I420 is the most widely accepted
+// format and serves as a fallback for video sinks that can only handle I420,
+// e.g. the internal WebRTC software encoders. A special enum value 'kNative' is
+// provided for external clients to implement their own frame buffer
+// representations, e.g. as textures. The external client can produce such
+// native frame buffers from custom video sources, and then cast it back to the
+// correct subclass in custom video sinks. The purpose of this is to improve
+// performance by providing an optimized path without intermediate conversions.
+// Frame metadata such as rotation and timestamp are stored in
+// webrtc::VideoFrame, and not here.
+class RTC_EXPORT VideoFrameBuffer : public rtc::RefCountInterface {
+ public:
+ // New frame buffer types will be added conservatively when there is an
+ // opportunity to optimize the path between some pair of video source and
+ // video sink.
+ // GENERATED_JAVA_ENUM_PACKAGE: org.webrtc
+ // GENERATED_JAVA_CLASS_NAME_OVERRIDE: VideoFrameBufferType
+ enum class Type {
+ kNative,
+ kI420,
+ kI420A,
+ kI422,
+ kI444,
+ kI010,
+ kI210,
+ kI410,
+ kNV12,
+ };
+
+ // This function specifies in what pixel format the data is stored in.
+ virtual Type type() const = 0;
+
+ // The resolution of the frame in pixels. For formats where some planes are
+ // subsampled, this is the highest-resolution plane.
+ virtual int width() const = 0;
+ virtual int height() const = 0;
+
+ // Returns a memory-backed frame buffer in I420 format. If the pixel data is
+ // in another format, a conversion will take place. All implementations must
+ // provide a fallback to I420 for compatibility with e.g. the internal WebRTC
+ // software encoders.
+ // Conversion may fail, for example if reading the pixel data from a texture
+ // fails. If the conversion fails, nullptr is returned.
+ virtual rtc::scoped_refptr<I420BufferInterface> ToI420() = 0;
+
+ // GetI420() methods should return I420 buffer if conversion is trivial, i.e
+ // no change for binary data is needed. Otherwise these methods should return
+ // nullptr. One example of buffer with that property is
+ // WebrtcVideoFrameAdapter in Chrome - it's I420 buffer backed by a shared
+ // memory buffer. Therefore it must have type kNative. Yet, ToI420()
+ // doesn't affect binary data at all. Another example is any I420A buffer.
+ // TODO(https://crbug.com/webrtc/12021): Make this method non-virtual and
+ // behave as the other GetXXX methods below.
+ virtual const I420BufferInterface* GetI420() const;
+
+ // A format specific scale function. Default implementation works by
+ // converting to I420. But more efficient implementations may override it,
+ // especially for kNative.
+ // First, the image is cropped to `crop_width` and `crop_height` and then
+ // scaled to `scaled_width` and `scaled_height`.
+ virtual rtc::scoped_refptr<VideoFrameBuffer> CropAndScale(int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height,
+ int scaled_width,
+ int scaled_height);
+
+ // Alias for common use case.
+ rtc::scoped_refptr<VideoFrameBuffer> Scale(int scaled_width,
+ int scaled_height) {
+ return CropAndScale(0, 0, width(), height(), scaled_width, scaled_height);
+ }
+
+ // These functions should only be called if type() is of the correct type.
+ // Calling with a different type will result in a crash.
+ const I420ABufferInterface* GetI420A() const;
+ const I422BufferInterface* GetI422() const;
+ const I444BufferInterface* GetI444() const;
+ const I010BufferInterface* GetI010() const;
+ const I210BufferInterface* GetI210() const;
+ const I410BufferInterface* GetI410() const;
+ const NV12BufferInterface* GetNV12() const;
+
+ // From a kNative frame, returns a VideoFrameBuffer with a pixel format in
+ // the list of types that is in the main memory with a pixel perfect
+ // conversion for encoding with a software encoder. Returns nullptr if the
+ // frame type is not supported, mapping is not possible, or if the kNative
+ // frame has not implemented this method. Only callable if type() is kNative.
+ virtual rtc::scoped_refptr<VideoFrameBuffer> GetMappedFrameBuffer(
+ rtc::ArrayView<Type> types);
+
+ protected:
+ ~VideoFrameBuffer() override {}
+};
+
+// Update when VideoFrameBuffer::Type is updated.
+const char* VideoFrameBufferTypeToString(VideoFrameBuffer::Type type);
+
+// This interface represents planar formats.
+class PlanarYuvBuffer : public VideoFrameBuffer {
+ public:
+ virtual int ChromaWidth() const = 0;
+ virtual int ChromaHeight() const = 0;
+
+ // Returns the number of steps(in terms of Data*() return type) between
+ // successive rows for a given plane.
+ virtual int StrideY() const = 0;
+ virtual int StrideU() const = 0;
+ virtual int StrideV() const = 0;
+
+ protected:
+ ~PlanarYuvBuffer() override {}
+};
+
+// This interface represents 8-bit color depth formats: Type::kI420,
+// Type::kI420A, Type::kI422 and Type::kI444.
+class PlanarYuv8Buffer : public PlanarYuvBuffer {
+ public:
+ // Returns pointer to the pixel data for a given plane. The memory is owned by
+ // the VideoFrameBuffer object and must not be freed by the caller.
+ virtual const uint8_t* DataY() const = 0;
+ virtual const uint8_t* DataU() const = 0;
+ virtual const uint8_t* DataV() const = 0;
+
+ protected:
+ ~PlanarYuv8Buffer() override {}
+};
+
+class RTC_EXPORT I420BufferInterface : public PlanarYuv8Buffer {
+ public:
+ Type type() const override;
+
+ int ChromaWidth() const final;
+ int ChromaHeight() const final;
+
+ rtc::scoped_refptr<I420BufferInterface> ToI420() final;
+ const I420BufferInterface* GetI420() const final;
+
+ protected:
+ ~I420BufferInterface() override {}
+};
+
+class RTC_EXPORT I420ABufferInterface : public I420BufferInterface {
+ public:
+ Type type() const final;
+ virtual const uint8_t* DataA() const = 0;
+ virtual int StrideA() const = 0;
+
+ protected:
+ ~I420ABufferInterface() override {}
+};
+
+// Represents Type::kI422, 4:2:2 planar with 8 bits per pixel.
+class I422BufferInterface : public PlanarYuv8Buffer {
+ public:
+ Type type() const final;
+
+ int ChromaWidth() const final;
+ int ChromaHeight() const final;
+
+ rtc::scoped_refptr<VideoFrameBuffer> CropAndScale(int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height,
+ int scaled_width,
+ int scaled_height) override;
+
+ protected:
+ ~I422BufferInterface() override {}
+};
+
+// Represents Type::kI444, 4:4:4 planar with 8 bits per pixel.
+class I444BufferInterface : public PlanarYuv8Buffer {
+ public:
+ Type type() const final;
+
+ int ChromaWidth() const final;
+ int ChromaHeight() const final;
+
+ rtc::scoped_refptr<VideoFrameBuffer> CropAndScale(int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height,
+ int scaled_width,
+ int scaled_height) override;
+
+ protected:
+ ~I444BufferInterface() override {}
+};
+
+// This interface represents 8-bit to 16-bit color depth formats: Type::kI010 or
+// Type::kI210 .
+class PlanarYuv16BBuffer : public PlanarYuvBuffer {
+ public:
+ // Returns pointer to the pixel data for a given plane. The memory is owned by
+ // the VideoFrameBuffer object and must not be freed by the caller.
+ virtual const uint16_t* DataY() const = 0;
+ virtual const uint16_t* DataU() const = 0;
+ virtual const uint16_t* DataV() const = 0;
+
+ protected:
+ ~PlanarYuv16BBuffer() override {}
+};
+
+// Represents Type::kI010, allocates 16 bits per pixel and fills 10 least
+// significant bits with color information.
+class I010BufferInterface : public PlanarYuv16BBuffer {
+ public:
+ Type type() const override;
+
+ int ChromaWidth() const final;
+ int ChromaHeight() const final;
+
+ protected:
+ ~I010BufferInterface() override {}
+};
+
+// Represents Type::kI210, allocates 16 bits per pixel and fills 10 least
+// significant bits with color information.
+class I210BufferInterface : public PlanarYuv16BBuffer {
+ public:
+ Type type() const override;
+
+ int ChromaWidth() const final;
+ int ChromaHeight() const final;
+
+ protected:
+ ~I210BufferInterface() override {}
+};
+
+// Represents Type::kI410, allocates 16 bits per pixel and fills 10 least
+// significant bits with color information.
+class I410BufferInterface : public PlanarYuv16BBuffer {
+ public:
+ Type type() const override;
+
+ int ChromaWidth() const final;
+ int ChromaHeight() const final;
+
+ protected:
+ ~I410BufferInterface() override {}
+};
+
+class BiplanarYuvBuffer : public VideoFrameBuffer {
+ public:
+ virtual int ChromaWidth() const = 0;
+ virtual int ChromaHeight() const = 0;
+
+ // Returns the number of steps(in terms of Data*() return type) between
+ // successive rows for a given plane.
+ virtual int StrideY() const = 0;
+ virtual int StrideUV() const = 0;
+
+ protected:
+ ~BiplanarYuvBuffer() override {}
+};
+
+class BiplanarYuv8Buffer : public BiplanarYuvBuffer {
+ public:
+ virtual const uint8_t* DataY() const = 0;
+ virtual const uint8_t* DataUV() const = 0;
+
+ protected:
+ ~BiplanarYuv8Buffer() override {}
+};
+
+// Represents Type::kNV12. NV12 is full resolution Y and half-resolution
+// interleved UV.
+class RTC_EXPORT NV12BufferInterface : public BiplanarYuv8Buffer {
+ public:
+ Type type() const override;
+
+ int ChromaWidth() const final;
+ int ChromaHeight() const final;
+
+ rtc::scoped_refptr<VideoFrameBuffer> CropAndScale(int offset_x,
+ int offset_y,
+ int crop_width,
+ int crop_height,
+ int scaled_width,
+ int scaled_height) override;
+
+ protected:
+ ~NV12BufferInterface() override {}
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_FRAME_BUFFER_H_
diff --git a/third_party/libwebrtc/api/video/video_frame_gn/moz.build b/third_party/libwebrtc/api/video/video_frame_gn/moz.build
new file mode 100644
index 0000000000..7a4e9fdc2c
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_frame_gn/moz.build
@@ -0,0 +1,236 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/media/libyuv/",
+ "/media/libyuv/libyuv/include/",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+SOURCES += [
+ "/third_party/libwebrtc/api/video/i422_buffer.cc",
+ "/third_party/libwebrtc/api/video/i444_buffer.cc"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/video/i420_buffer.cc",
+ "/third_party/libwebrtc/api/video/nv12_buffer.cc",
+ "/third_party/libwebrtc/api/video/video_frame.cc",
+ "/third_party/libwebrtc/api/video/video_frame_buffer.cc",
+ "/third_party/libwebrtc/api/video/video_source_interface.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("video_frame_gn")
diff --git a/third_party/libwebrtc/api/video/video_frame_i010_gn/moz.build b/third_party/libwebrtc/api/video/video_frame_i010_gn/moz.build
new file mode 100644
index 0000000000..e56d43a299
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_frame_i010_gn/moz.build
@@ -0,0 +1,232 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/media/libyuv/",
+ "/media/libyuv/libyuv/include/",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+SOURCES += [
+ "/third_party/libwebrtc/api/video/i210_buffer.cc",
+ "/third_party/libwebrtc/api/video/i410_buffer.cc"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/video/i010_buffer.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("video_frame_i010_gn")
diff --git a/third_party/libwebrtc/api/video/video_frame_metadata.cc b/third_party/libwebrtc/api/video/video_frame_metadata.cc
new file mode 100644
index 0000000000..e1863e9c13
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_frame_metadata.cc
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/video_frame_metadata.h"
+
+#include <utility>
+
+namespace webrtc {
+
+VideoFrameMetadata::VideoFrameMetadata() = default;
+
+VideoFrameType VideoFrameMetadata::GetFrameType() const {
+ return frame_type_;
+}
+
+void VideoFrameMetadata::SetFrameType(VideoFrameType frame_type) {
+ frame_type_ = frame_type;
+}
+
+uint16_t VideoFrameMetadata::GetWidth() const {
+ return width_;
+}
+
+void VideoFrameMetadata::SetWidth(uint16_t width) {
+ width_ = width;
+}
+
+uint16_t VideoFrameMetadata::GetHeight() const {
+ return height_;
+}
+
+void VideoFrameMetadata::SetHeight(uint16_t height) {
+ height_ = height;
+}
+
+VideoRotation VideoFrameMetadata::GetRotation() const {
+ return rotation_;
+}
+
+void VideoFrameMetadata::SetRotation(VideoRotation rotation) {
+ rotation_ = rotation;
+}
+
+VideoContentType VideoFrameMetadata::GetContentType() const {
+ return content_type_;
+}
+
+void VideoFrameMetadata::SetContentType(VideoContentType content_type) {
+ content_type_ = content_type;
+}
+
+absl::optional<int64_t> VideoFrameMetadata::GetFrameId() const {
+ return frame_id_;
+}
+
+void VideoFrameMetadata::SetFrameId(absl::optional<int64_t> frame_id) {
+ frame_id_ = frame_id;
+}
+
+int VideoFrameMetadata::GetSpatialIndex() const {
+ return spatial_index_;
+}
+
+void VideoFrameMetadata::SetSpatialIndex(int spatial_index) {
+ spatial_index_ = spatial_index;
+}
+
+int VideoFrameMetadata::GetTemporalIndex() const {
+ return temporal_index_;
+}
+
+void VideoFrameMetadata::SetTemporalIndex(int temporal_index) {
+ temporal_index_ = temporal_index;
+}
+
+rtc::ArrayView<const int64_t> VideoFrameMetadata::GetFrameDependencies() const {
+ return frame_dependencies_;
+}
+
+void VideoFrameMetadata::SetFrameDependencies(
+ rtc::ArrayView<const int64_t> frame_dependencies) {
+ frame_dependencies_.assign(frame_dependencies.begin(),
+ frame_dependencies.end());
+}
+
+rtc::ArrayView<const DecodeTargetIndication>
+VideoFrameMetadata::GetDecodeTargetIndications() const {
+ return decode_target_indications_;
+}
+
+void VideoFrameMetadata::SetDecodeTargetIndications(
+ rtc::ArrayView<const DecodeTargetIndication> decode_target_indications) {
+ decode_target_indications_.assign(decode_target_indications.begin(),
+ decode_target_indications.end());
+}
+
+bool VideoFrameMetadata::GetIsLastFrameInPicture() const {
+ return is_last_frame_in_picture_;
+}
+
+void VideoFrameMetadata::SetIsLastFrameInPicture(
+ bool is_last_frame_in_picture) {
+ is_last_frame_in_picture_ = is_last_frame_in_picture;
+}
+
+uint8_t VideoFrameMetadata::GetSimulcastIdx() const {
+ return simulcast_idx_;
+}
+
+void VideoFrameMetadata::SetSimulcastIdx(uint8_t simulcast_idx) {
+ simulcast_idx_ = simulcast_idx;
+}
+
+VideoCodecType VideoFrameMetadata::GetCodec() const {
+ return codec_;
+}
+
+void VideoFrameMetadata::SetCodec(VideoCodecType codec) {
+ codec_ = codec;
+}
+
+const RTPVideoHeaderCodecSpecifics&
+VideoFrameMetadata::GetRTPVideoHeaderCodecSpecifics() const {
+ return codec_specifics_;
+}
+
+void VideoFrameMetadata::SetRTPVideoHeaderCodecSpecifics(
+ RTPVideoHeaderCodecSpecifics codec_specifics) {
+ codec_specifics_ = std::move(codec_specifics);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/video_frame_metadata.h b/third_party/libwebrtc/api/video/video_frame_metadata.h
new file mode 100644
index 0000000000..2703f11324
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_frame_metadata.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_FRAME_METADATA_H_
+#define API_VIDEO_VIDEO_FRAME_METADATA_H_
+
+#include <cstdint>
+
+#include "absl/container/inlined_vector.h"
+#include "absl/types/optional.h"
+#include "absl/types/variant.h"
+#include "api/array_view.h"
+#include "api/transport/rtp/dependency_descriptor.h"
+#include "api/video/video_codec_type.h"
+#include "api/video/video_content_type.h"
+#include "api/video/video_frame_type.h"
+#include "api/video/video_rotation.h"
+#include "modules/video_coding/codecs/h264/include/h264_globals.h"
+#include "modules/video_coding/codecs/vp8/include/vp8_globals.h"
+#include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+using RTPVideoHeaderCodecSpecifics = absl::variant<absl::monostate,
+ RTPVideoHeaderVP8,
+ RTPVideoHeaderVP9,
+ RTPVideoHeaderH264>;
+
+// A subset of metadata from the RTP video header, exposed in insertable streams
+// API.
+class RTC_EXPORT VideoFrameMetadata {
+ public:
+ VideoFrameMetadata();
+ VideoFrameMetadata(const VideoFrameMetadata&) = default;
+ VideoFrameMetadata& operator=(const VideoFrameMetadata&) = default;
+
+ VideoFrameType GetFrameType() const;
+ void SetFrameType(VideoFrameType frame_type);
+
+ uint16_t GetWidth() const;
+ void SetWidth(uint16_t width);
+
+ uint16_t GetHeight() const;
+ void SetHeight(uint16_t height);
+
+ VideoRotation GetRotation() const;
+ void SetRotation(VideoRotation rotation);
+
+ VideoContentType GetContentType() const;
+ void SetContentType(VideoContentType content_type);
+
+ absl::optional<int64_t> GetFrameId() const;
+ void SetFrameId(absl::optional<int64_t> frame_id);
+
+ int GetSpatialIndex() const;
+ void SetSpatialIndex(int spatial_index);
+
+ int GetTemporalIndex() const;
+ void SetTemporalIndex(int temporal_index);
+
+ rtc::ArrayView<const int64_t> GetFrameDependencies() const;
+ void SetFrameDependencies(rtc::ArrayView<const int64_t> frame_dependencies);
+
+ rtc::ArrayView<const DecodeTargetIndication> GetDecodeTargetIndications()
+ const;
+ void SetDecodeTargetIndications(
+ rtc::ArrayView<const DecodeTargetIndication> decode_target_indications);
+
+ bool GetIsLastFrameInPicture() const;
+ void SetIsLastFrameInPicture(bool is_last_frame_in_picture);
+
+ uint8_t GetSimulcastIdx() const;
+ void SetSimulcastIdx(uint8_t simulcast_idx);
+
+ VideoCodecType GetCodec() const;
+ void SetCodec(VideoCodecType codec);
+
+ // Which varient is used depends on the VideoCodecType from GetCodecs().
+ const RTPVideoHeaderCodecSpecifics& GetRTPVideoHeaderCodecSpecifics() const;
+ void SetRTPVideoHeaderCodecSpecifics(
+ RTPVideoHeaderCodecSpecifics codec_specifics);
+
+ private:
+ VideoFrameType frame_type_ = VideoFrameType::kEmptyFrame;
+ int16_t width_ = 0;
+ int16_t height_ = 0;
+ VideoRotation rotation_ = VideoRotation::kVideoRotation_0;
+ VideoContentType content_type_ = VideoContentType::UNSPECIFIED;
+
+ // Corresponding to GenericDescriptorInfo.
+ absl::optional<int64_t> frame_id_;
+ int spatial_index_ = 0;
+ int temporal_index_ = 0;
+ absl::InlinedVector<int64_t, 5> frame_dependencies_;
+ absl::InlinedVector<DecodeTargetIndication, 10> decode_target_indications_;
+
+ bool is_last_frame_in_picture_ = true;
+ uint8_t simulcast_idx_ = 0;
+ VideoCodecType codec_ = VideoCodecType::kVideoCodecGeneric;
+ RTPVideoHeaderCodecSpecifics codec_specifics_;
+};
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_FRAME_METADATA_H_
diff --git a/third_party/libwebrtc/api/video/video_frame_metadata_gn/moz.build b/third_party/libwebrtc/api/video/video_frame_metadata_gn/moz.build
new file mode 100644
index 0000000000..2d2221dbb5
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_frame_metadata_gn/moz.build
@@ -0,0 +1,225 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/video/video_frame_metadata.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("video_frame_metadata_gn")
diff --git a/third_party/libwebrtc/api/video/video_frame_type.h b/third_party/libwebrtc/api/video/video_frame_type.h
new file mode 100644
index 0000000000..4a96f1fe9e
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_frame_type.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_FRAME_TYPE_H_
+#define API_VIDEO_VIDEO_FRAME_TYPE_H_
+
+namespace webrtc {
+
+enum class VideoFrameType {
+ kEmptyFrame = 0,
+ // Wire format for MultiplexEncodedImagePacker seems to depend on numerical
+ // values of these constants.
+ kVideoFrameKey = 3,
+ kVideoFrameDelta = 4,
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_FRAME_TYPE_H_
diff --git a/third_party/libwebrtc/api/video/video_frame_type_gn/moz.build b/third_party/libwebrtc/api/video/video_frame_type_gn/moz.build
new file mode 100644
index 0000000000..bc4c46bfbd
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_frame_type_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("video_frame_type_gn")
diff --git a/third_party/libwebrtc/api/video/video_layers_allocation.h b/third_party/libwebrtc/api/video/video_layers_allocation.h
new file mode 100644
index 0000000000..39734151ae
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_layers_allocation.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_LAYERS_ALLOCATION_H_
+#define API_VIDEO_VIDEO_LAYERS_ALLOCATION_H_
+
+#include <cstdint>
+
+#include "absl/container/inlined_vector.h"
+#include "api/units/data_rate.h"
+
+namespace webrtc {
+
+// This struct contains additional stream-level information needed by a
+// Selective Forwarding Middlebox to make relay decisions of RTP streams.
+struct VideoLayersAllocation {
+ static constexpr int kMaxSpatialIds = 4;
+ static constexpr int kMaxTemporalIds = 4;
+
+ friend bool operator==(const VideoLayersAllocation& lhs,
+ const VideoLayersAllocation& rhs) {
+ return lhs.rtp_stream_index == rhs.rtp_stream_index &&
+ lhs.resolution_and_frame_rate_is_valid ==
+ rhs.resolution_and_frame_rate_is_valid &&
+ lhs.active_spatial_layers == rhs.active_spatial_layers;
+ }
+
+ friend bool operator!=(const VideoLayersAllocation& lhs,
+ const VideoLayersAllocation& rhs) {
+ return !(lhs == rhs);
+ }
+
+ struct SpatialLayer {
+ friend bool operator==(const SpatialLayer& lhs, const SpatialLayer& rhs) {
+ return lhs.rtp_stream_index == rhs.rtp_stream_index &&
+ lhs.spatial_id == rhs.spatial_id &&
+ lhs.target_bitrate_per_temporal_layer ==
+ rhs.target_bitrate_per_temporal_layer &&
+ lhs.width == rhs.width && lhs.height == rhs.height &&
+ lhs.frame_rate_fps == rhs.frame_rate_fps;
+ }
+
+ friend bool operator!=(const SpatialLayer& lhs, const SpatialLayer& rhs) {
+ return !(lhs == rhs);
+ }
+ int rtp_stream_index = 0;
+ // Index of the spatial layer per `rtp_stream_index`.
+ int spatial_id = 0;
+ // Target bitrate per decode target.
+ absl::InlinedVector<DataRate, kMaxTemporalIds>
+ target_bitrate_per_temporal_layer;
+
+ // These fields are only valid if `resolution_and_frame_rate_is_valid` is
+ // true
+ uint16_t width = 0;
+ uint16_t height = 0;
+ // Max frame rate used in any temporal layer of this spatial layer.
+ uint8_t frame_rate_fps = 0;
+ };
+
+ // Index of the rtp stream this allocation is sent on. Used for mapping
+ // a SpatialLayer to a rtp stream.
+ int rtp_stream_index = 0;
+ bool resolution_and_frame_rate_is_valid = false;
+ absl::InlinedVector<SpatialLayer, kMaxSpatialIds> active_spatial_layers;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_LAYERS_ALLOCATION_H_
diff --git a/third_party/libwebrtc/api/video/video_layers_allocation_gn/moz.build b/third_party/libwebrtc/api/video/video_layers_allocation_gn/moz.build
new file mode 100644
index 0000000000..ded4d37ab6
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_layers_allocation_gn/moz.build
@@ -0,0 +1,205 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("video_layers_allocation_gn")
diff --git a/third_party/libwebrtc/api/video/video_rotation.h b/third_party/libwebrtc/api/video/video_rotation.h
new file mode 100644
index 0000000000..6a29588ee5
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_rotation.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_ROTATION_H_
+#define API_VIDEO_VIDEO_ROTATION_H_
+
+namespace webrtc {
+
+// enum for clockwise rotation.
+enum VideoRotation {
+ kVideoRotation_0 = 0,
+ kVideoRotation_90 = 90,
+ kVideoRotation_180 = 180,
+ kVideoRotation_270 = 270
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_ROTATION_H_
diff --git a/third_party/libwebrtc/api/video/video_rtp_headers_gn/moz.build b/third_party/libwebrtc/api/video/video_rtp_headers_gn/moz.build
new file mode 100644
index 0000000000..fffe252ebd
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_rtp_headers_gn/moz.build
@@ -0,0 +1,228 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/video/color_space.cc",
+ "/third_party/libwebrtc/api/video/hdr_metadata.cc",
+ "/third_party/libwebrtc/api/video/video_content_type.cc",
+ "/third_party/libwebrtc/api/video/video_timing.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("video_rtp_headers_gn")
diff --git a/third_party/libwebrtc/api/video/video_sink_interface.h b/third_party/libwebrtc/api/video/video_sink_interface.h
new file mode 100644
index 0000000000..9c1f5f3214
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_sink_interface.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_SINK_INTERFACE_H_
+#define API_VIDEO_VIDEO_SINK_INTERFACE_H_
+
+#include "absl/types/optional.h"
+#include "api/video_track_source_constraints.h"
+#include "rtc_base/checks.h"
+
+namespace rtc {
+
+template <typename VideoFrameT>
+class VideoSinkInterface {
+ public:
+ virtual ~VideoSinkInterface() = default;
+
+ virtual void OnFrame(const VideoFrameT& frame) = 0;
+
+ // Should be called by the source when it discards the frame due to rate
+ // limiting.
+ virtual void OnDiscardedFrame() {}
+
+ // Called on the network thread when video constraints change.
+ // TODO(crbug/1255737): make pure virtual once downstream project adapts.
+ virtual void OnConstraintsChanged(
+ const webrtc::VideoTrackSourceConstraints& constraints) {}
+};
+
+} // namespace rtc
+
+#endif // API_VIDEO_VIDEO_SINK_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/video/video_source_interface.cc b/third_party/libwebrtc/api/video/video_source_interface.cc
new file mode 100644
index 0000000000..70a86c3d64
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_source_interface.cc
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/video_source_interface.h"
+
+namespace rtc {
+
+VideoSinkWants::VideoSinkWants() = default;
+VideoSinkWants::VideoSinkWants(const VideoSinkWants&) = default;
+VideoSinkWants::~VideoSinkWants() = default;
+
+} // namespace rtc
diff --git a/third_party/libwebrtc/api/video/video_source_interface.h b/third_party/libwebrtc/api/video/video_source_interface.h
new file mode 100644
index 0000000000..38d0041718
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_source_interface.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_SOURCE_INTERFACE_H_
+#define API_VIDEO_VIDEO_SOURCE_INTERFACE_H_
+
+#include <limits>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/video/video_sink_interface.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace rtc {
+
+// VideoSinkWants is used for notifying the source of properties a video frame
+// should have when it is delivered to a certain sink.
+struct RTC_EXPORT VideoSinkWants {
+ struct FrameSize {
+ FrameSize(int width, int height) : width(width), height(height) {}
+ FrameSize(const FrameSize&) = default;
+ ~FrameSize() = default;
+
+ int width;
+ int height;
+ };
+
+ VideoSinkWants();
+ VideoSinkWants(const VideoSinkWants&);
+ ~VideoSinkWants();
+ // Tells the source whether the sink wants frames with rotation applied.
+ // By default, any rotation must be applied by the sink.
+ bool rotation_applied = false;
+
+ // Tells the source that the sink only wants black frames.
+ bool black_frames = false;
+
+ // Tells the source the maximum number of pixels the sink wants.
+ int max_pixel_count = std::numeric_limits<int>::max();
+ // Tells the source the desired number of pixels the sinks wants. This will
+ // typically be used when stepping the resolution up again when conditions
+ // have improved after an earlier downgrade. The source should select the
+ // closest resolution to this pixel count, but if max_pixel_count is set, it
+ // still sets the absolute upper bound.
+ absl::optional<int> target_pixel_count;
+ // Tells the source the maximum framerate the sink wants.
+ int max_framerate_fps = std::numeric_limits<int>::max();
+
+ // Tells the source that the sink wants width and height of the video frames
+ // to be divisible by `resolution_alignment`.
+ // For example: With I420, this value would be a multiple of 2.
+ // Note that this field is unrelated to any horizontal or vertical stride
+ // requirements the encoder has on the incoming video frame buffers.
+ int resolution_alignment = 1;
+
+ // The resolutions that sink is configured to consume. If the sink is an
+ // encoder this is what the encoder is configured to encode. In singlecast we
+ // only encode one resolution, but in simulcast and SVC this can mean multiple
+ // resolutions per frame.
+ //
+ // The sink is always configured to consume a subset of the
+ // webrtc::VideoFrame's resolution. In the case of encoding, we usually encode
+ // at webrtc::VideoFrame's resolution but this may not always be the case due
+ // to scaleResolutionDownBy or turning off simulcast or SVC layers.
+ //
+ // For example, we may capture at 720p and due to adaptation (e.g. applying
+ // `max_pixel_count` constraints) create webrtc::VideoFrames of size 480p, but
+ // if we do scaleResolutionDownBy:2 then the only resolution we end up
+ // encoding is 240p. In this case we still need to provide webrtc::VideoFrames
+ // of size 480p but we can optimize internal buffers for 240p, avoiding
+ // downsampling to 480p if possible.
+ //
+ // Note that the `resolutions` can change while frames are in flight and
+ // should only be used as a hint when constructing the webrtc::VideoFrame.
+ std::vector<FrameSize> resolutions;
+
+ // This is the resolution requested by the user using RtpEncodingParameters.
+ absl::optional<FrameSize> requested_resolution;
+
+ // `active` : is (any) of the layers/sink(s) active.
+ bool is_active = true;
+
+ // This sub-struct contains information computed by VideoBroadcaster
+ // that aggregates several VideoSinkWants (and sends them to
+ // AdaptedVideoTrackSource).
+ struct Aggregates {
+ // `active_without_requested_resolution` is set by VideoBroadcaster
+ // when aggregating sink wants if there exists any sink (encoder) that is
+ // active but has not set the `requested_resolution`, i.e is relying on
+ // OnOutputFormatRequest to handle encode resolution.
+ bool any_active_without_requested_resolution = false;
+ };
+ absl::optional<Aggregates> aggregates;
+};
+
+inline bool operator==(const VideoSinkWants::FrameSize& a,
+ const VideoSinkWants::FrameSize& b) {
+ return a.width == b.width && a.height == b.height;
+}
+
+inline bool operator!=(const VideoSinkWants::FrameSize& a,
+ const VideoSinkWants::FrameSize& b) {
+ return !(a == b);
+}
+
+template <typename VideoFrameT>
+class VideoSourceInterface {
+ public:
+ virtual ~VideoSourceInterface() = default;
+
+ virtual void AddOrUpdateSink(VideoSinkInterface<VideoFrameT>* sink,
+ const VideoSinkWants& wants) = 0;
+ // RemoveSink must guarantee that at the time the method returns,
+ // there is no current and no future calls to VideoSinkInterface::OnFrame.
+ virtual void RemoveSink(VideoSinkInterface<VideoFrameT>* sink) = 0;
+
+ // Request underlying source to capture a new frame.
+ // TODO(crbug/1255737): make pure virtual once downstream projects adapt.
+ virtual void RequestRefreshFrame() {}
+};
+
+} // namespace rtc
+#endif // API_VIDEO_VIDEO_SOURCE_INTERFACE_H_
diff --git a/third_party/libwebrtc/api/video/video_stream_decoder.h b/third_party/libwebrtc/api/video/video_stream_decoder.h
new file mode 100644
index 0000000000..8d71dd300c
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_stream_decoder.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_STREAM_DECODER_H_
+#define API_VIDEO_VIDEO_STREAM_DECODER_H_
+
+#include <map>
+#include <memory>
+#include <utility>
+
+#include "api/units/time_delta.h"
+#include "api/video/encoded_frame.h"
+#include "api/video/video_content_type.h"
+#include "api/video/video_frame.h"
+#include "api/video_codecs/sdp_video_format.h"
+#include "api/video_codecs/video_decoder_factory.h"
+
+namespace webrtc {
+// NOTE: This class is still under development and may change without notice.
+class VideoStreamDecoderInterface {
+ public:
+ class Callbacks {
+ public:
+ virtual ~Callbacks() = default;
+
+ struct FrameInfo {
+ absl::optional<int> qp;
+ VideoContentType content_type;
+ };
+
+ // Called when the VideoStreamDecoder enters a non-decodable state.
+ virtual void OnNonDecodableState() = 0;
+
+ virtual void OnContinuousUntil(int64_t frame_id) {}
+
+ virtual void OnDecodedFrame(VideoFrame frame,
+ const FrameInfo& frame_info) = 0;
+ };
+
+ virtual ~VideoStreamDecoderInterface() = default;
+
+ virtual void OnFrame(std::unique_ptr<EncodedFrame> frame) = 0;
+
+ virtual void SetMinPlayoutDelay(TimeDelta min_delay) = 0;
+ virtual void SetMaxPlayoutDelay(TimeDelta max_delay) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_STREAM_DECODER_H_
diff --git a/third_party/libwebrtc/api/video/video_stream_decoder_create.cc b/third_party/libwebrtc/api/video/video_stream_decoder_create.cc
new file mode 100644
index 0000000000..e14c3bc851
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_stream_decoder_create.cc
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/video_stream_decoder_create.h"
+
+#include <memory>
+
+#include "video/video_stream_decoder_impl.h"
+
+namespace webrtc {
+
+std::unique_ptr<VideoStreamDecoderInterface> CreateVideoStreamDecoder(
+ VideoStreamDecoderInterface::Callbacks* callbacks,
+ VideoDecoderFactory* decoder_factory,
+ TaskQueueFactory* task_queue_factory,
+ std::map<int, std::pair<SdpVideoFormat, int>> decoder_settings,
+ // TODO(jonaso, webrtc:10335): Consider what to do with factories
+ // vs. field trials.
+ const FieldTrialsView* field_trials) {
+ return std::make_unique<VideoStreamDecoderImpl>(
+ callbacks, decoder_factory, task_queue_factory,
+ std::move(decoder_settings), field_trials);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/video_stream_decoder_create.h b/third_party/libwebrtc/api/video/video_stream_decoder_create.h
new file mode 100644
index 0000000000..974fd804ce
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_stream_decoder_create.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_STREAM_DECODER_CREATE_H_
+#define API_VIDEO_VIDEO_STREAM_DECODER_CREATE_H_
+
+#include <map>
+#include <memory>
+#include <utility>
+
+#include "api/field_trials_view.h"
+#include "api/task_queue/task_queue_factory.h"
+#include "api/video/video_stream_decoder.h"
+#include "api/video_codecs/sdp_video_format.h"
+
+namespace webrtc {
+// The `decoder_settings` parameter is a map between:
+// <payload type> --> <<video format>, <number of cores>>.
+// The video format is used when instantiating a decoder, and
+// the number of cores is used when initializing the decoder.
+std::unique_ptr<VideoStreamDecoderInterface> CreateVideoStreamDecoder(
+ VideoStreamDecoderInterface::Callbacks* callbacks,
+ VideoDecoderFactory* decoder_factory,
+ TaskQueueFactory* task_queue_factory,
+ std::map<int, std::pair<SdpVideoFormat, int>> decoder_settings,
+ const FieldTrialsView* field_trials = nullptr);
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_STREAM_DECODER_CREATE_H_
diff --git a/third_party/libwebrtc/api/video/video_stream_decoder_create_unittest.cc b/third_party/libwebrtc/api/video/video_stream_decoder_create_unittest.cc
new file mode 100644
index 0000000000..849a054a04
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_stream_decoder_create_unittest.cc
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/video_stream_decoder_create.h"
+
+#include "api/task_queue/default_task_queue_factory.h"
+#include "api/video_codecs/builtin_video_decoder_factory.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace {
+
+class NullCallbacks : public VideoStreamDecoderInterface::Callbacks {
+ public:
+ ~NullCallbacks() override = default;
+ void OnNonDecodableState() override {}
+ void OnDecodedFrame(VideoFrame frame,
+ const VideoStreamDecoderInterface::Callbacks::FrameInfo&
+ frame_info) override {}
+};
+
+TEST(VideoStreamDecoderCreate, CreateVideoStreamDecoder) {
+ std::map<int, std::pair<SdpVideoFormat, int>> decoder_settings = {
+ {/*payload_type=*/111, {SdpVideoFormat("VP8"), /*number_of_cores=*/2}}};
+ NullCallbacks callbacks;
+ std::unique_ptr<VideoDecoderFactory> decoder_factory =
+ CreateBuiltinVideoDecoderFactory();
+
+ std::unique_ptr<TaskQueueFactory> task_queue_factory =
+ CreateDefaultTaskQueueFactory();
+
+ std::unique_ptr<VideoStreamDecoderInterface> decoder =
+ CreateVideoStreamDecoder(&callbacks, decoder_factory.get(),
+ task_queue_factory.get(), decoder_settings);
+ EXPECT_TRUE(decoder);
+}
+
+} // namespace
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/video_stream_encoder_gn/moz.build b/third_party/libwebrtc/api/video/video_stream_encoder_gn/moz.build
new file mode 100644
index 0000000000..e36bc0df98
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_stream_encoder_gn/moz.build
@@ -0,0 +1,209 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("video_stream_encoder_gn")
diff --git a/third_party/libwebrtc/api/video/video_stream_encoder_settings.h b/third_party/libwebrtc/api/video/video_stream_encoder_settings.h
new file mode 100644
index 0000000000..3aee5b7050
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_stream_encoder_settings.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_STREAM_ENCODER_SETTINGS_H_
+#define API_VIDEO_VIDEO_STREAM_ENCODER_SETTINGS_H_
+
+#include <string>
+
+#include "api/video/video_bitrate_allocator_factory.h"
+#include "api/video_codecs/video_encoder.h"
+#include "api/video_codecs/video_encoder_factory.h"
+
+namespace webrtc {
+
+class EncoderSwitchRequestCallback {
+ public:
+ virtual ~EncoderSwitchRequestCallback() {}
+
+ // Requests switch to next negotiated encoder.
+ virtual void RequestEncoderFallback() = 0;
+
+ // Requests switch to a specific encoder. If the encoder is not available and
+ // `allow_default_fallback` is `true` the default fallback is invoked.
+ virtual void RequestEncoderSwitch(const SdpVideoFormat& format,
+ bool allow_default_fallback) = 0;
+};
+
+struct VideoStreamEncoderSettings {
+ explicit VideoStreamEncoderSettings(
+ const VideoEncoder::Capabilities& capabilities)
+ : capabilities(capabilities) {}
+
+ // Enables the new method to estimate the cpu load from encoding, used for
+ // cpu adaptation.
+ bool experiment_cpu_load_estimator = false;
+
+ // Ownership stays with WebrtcVideoEngine (delegated from PeerConnection).
+ VideoEncoderFactory* encoder_factory = nullptr;
+
+ // Requests the WebRtcVideoChannel to perform a codec switch.
+ EncoderSwitchRequestCallback* encoder_switch_request_callback = nullptr;
+
+ // Ownership stays with WebrtcVideoEngine (delegated from PeerConnection).
+ VideoBitrateAllocatorFactory* bitrate_allocator_factory = nullptr;
+
+ // Negotiated capabilities which the VideoEncoder may expect the other
+ // side to use.
+ VideoEncoder::Capabilities capabilities;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_STREAM_ENCODER_SETTINGS_H_
diff --git a/third_party/libwebrtc/api/video/video_timing.cc b/third_party/libwebrtc/api/video/video_timing.cc
new file mode 100644
index 0000000000..0483c20e66
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_timing.cc
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video/video_timing.h"
+
+#include "api/array_view.h"
+#include "api/units/time_delta.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/numerics/safe_conversions.h"
+#include "rtc_base/strings/string_builder.h"
+
+namespace webrtc {
+
+uint16_t VideoSendTiming::GetDeltaCappedMs(int64_t base_ms, int64_t time_ms) {
+ if (time_ms < base_ms) {
+ RTC_DLOG(LS_ERROR) << "Delta " << (time_ms - base_ms)
+ << "ms expected to be positive";
+ }
+ return rtc::saturated_cast<uint16_t>(time_ms - base_ms);
+}
+
+uint16_t VideoSendTiming::GetDeltaCappedMs(TimeDelta delta) {
+ if (delta < TimeDelta::Zero()) {
+ RTC_DLOG(LS_ERROR) << "Delta " << delta.ms()
+ << "ms expected to be positive";
+ }
+ return rtc::saturated_cast<uint16_t>(delta.ms());
+}
+
+TimingFrameInfo::TimingFrameInfo()
+ : rtp_timestamp(0),
+ capture_time_ms(-1),
+ encode_start_ms(-1),
+ encode_finish_ms(-1),
+ packetization_finish_ms(-1),
+ pacer_exit_ms(-1),
+ network_timestamp_ms(-1),
+ network2_timestamp_ms(-1),
+ receive_start_ms(-1),
+ receive_finish_ms(-1),
+ decode_start_ms(-1),
+ decode_finish_ms(-1),
+ render_time_ms(-1),
+ flags(VideoSendTiming::kNotTriggered) {}
+
+int64_t TimingFrameInfo::EndToEndDelay() const {
+ return capture_time_ms >= 0 ? decode_finish_ms - capture_time_ms : -1;
+}
+
+bool TimingFrameInfo::IsLongerThan(const TimingFrameInfo& other) const {
+ int64_t other_delay = other.EndToEndDelay();
+ return other_delay == -1 || EndToEndDelay() > other_delay;
+}
+
+bool TimingFrameInfo::operator<(const TimingFrameInfo& other) const {
+ return other.IsLongerThan(*this);
+}
+
+bool TimingFrameInfo::operator<=(const TimingFrameInfo& other) const {
+ return !IsLongerThan(other);
+}
+
+bool TimingFrameInfo::IsOutlier() const {
+ return !IsInvalid() && (flags & VideoSendTiming::kTriggeredBySize);
+}
+
+bool TimingFrameInfo::IsTimerTriggered() const {
+ return !IsInvalid() && (flags & VideoSendTiming::kTriggeredByTimer);
+}
+
+bool TimingFrameInfo::IsInvalid() const {
+ return flags == VideoSendTiming::kInvalid;
+}
+
+std::string TimingFrameInfo::ToString() const {
+ if (IsInvalid()) {
+ return "";
+ }
+
+ char buf[1024];
+ rtc::SimpleStringBuilder sb(buf);
+
+ sb << rtp_timestamp << ',' << capture_time_ms << ',' << encode_start_ms << ','
+ << encode_finish_ms << ',' << packetization_finish_ms << ','
+ << pacer_exit_ms << ',' << network_timestamp_ms << ','
+ << network2_timestamp_ms << ',' << receive_start_ms << ','
+ << receive_finish_ms << ',' << decode_start_ms << ',' << decode_finish_ms
+ << ',' << render_time_ms << ',' << IsOutlier() << ','
+ << IsTimerTriggered();
+
+ return sb.str();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video/video_timing.h b/third_party/libwebrtc/api/video/video_timing.h
new file mode 100644
index 0000000000..698477a81a
--- /dev/null
+++ b/third_party/libwebrtc/api/video/video_timing.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_VIDEO_TIMING_H_
+#define API_VIDEO_VIDEO_TIMING_H_
+
+#include <stdint.h>
+
+#include <limits>
+#include <string>
+
+#include "api/units/time_delta.h"
+
+namespace webrtc {
+
+// Video timing timestamps in ms counted from capture_time_ms of a frame.
+// This structure represents data sent in video-timing RTP header extension.
+struct VideoSendTiming {
+ enum TimingFrameFlags : uint8_t {
+ kNotTriggered = 0, // Timing info valid, but not to be transmitted.
+ // Used on send-side only.
+ kTriggeredByTimer = 1 << 0, // Frame marked for tracing by periodic timer.
+ kTriggeredBySize = 1 << 1, // Frame marked for tracing due to size.
+ kInvalid = std::numeric_limits<uint8_t>::max() // Invalid, ignore!
+ };
+
+ // Returns |time_ms - base_ms| capped at max 16-bit value.
+ // Used to fill this data structure as per
+ // https://webrtc.org/experiments/rtp-hdrext/video-timing/ extension stores
+ // 16-bit deltas of timestamps from packet capture time.
+ static uint16_t GetDeltaCappedMs(int64_t base_ms, int64_t time_ms);
+ static uint16_t GetDeltaCappedMs(TimeDelta delta);
+
+ uint16_t encode_start_delta_ms;
+ uint16_t encode_finish_delta_ms;
+ uint16_t packetization_finish_delta_ms;
+ uint16_t pacer_exit_delta_ms;
+ uint16_t network_timestamp_delta_ms;
+ uint16_t network2_timestamp_delta_ms;
+ uint8_t flags = TimingFrameFlags::kInvalid;
+};
+
+// Used to report precise timings of a 'timing frames'. Contains all important
+// timestamps for a lifetime of that specific frame. Reported as a string via
+// GetStats(). Only frame which took the longest between two GetStats calls is
+// reported.
+struct TimingFrameInfo {
+ TimingFrameInfo();
+
+ // Returns end-to-end delay of a frame, if sender and receiver timestamps are
+ // synchronized, -1 otherwise.
+ int64_t EndToEndDelay() const;
+
+ // Returns true if current frame took longer to process than `other` frame.
+ // If other frame's clocks are not synchronized, current frame is always
+ // preferred.
+ bool IsLongerThan(const TimingFrameInfo& other) const;
+
+ // Returns true if flags are set to indicate this frame was marked for tracing
+ // due to the size being outside some limit.
+ bool IsOutlier() const;
+
+ // Returns true if flags are set to indicate this frame was marked fro tracing
+ // due to cyclic timer.
+ bool IsTimerTriggered() const;
+
+ // Returns true if the timing data is marked as invalid, in which case it
+ // should be ignored.
+ bool IsInvalid() const;
+
+ std::string ToString() const;
+
+ bool operator<(const TimingFrameInfo& other) const;
+
+ bool operator<=(const TimingFrameInfo& other) const;
+
+ uint32_t rtp_timestamp; // Identifier of a frame.
+ // All timestamps below are in local monotonous clock of a receiver.
+ // If sender clock is not yet estimated, sender timestamps
+ // (capture_time_ms ... pacer_exit_ms) are negative values, still
+ // relatively correct.
+ int64_t capture_time_ms; // Captrue time of a frame.
+ int64_t encode_start_ms; // Encode start time.
+ int64_t encode_finish_ms; // Encode completion time.
+ int64_t packetization_finish_ms; // Time when frame was passed to pacer.
+ int64_t pacer_exit_ms; // Time when last packet was pushed out of pacer.
+ // Two in-network RTP processor timestamps: meaning is application specific.
+ int64_t network_timestamp_ms;
+ int64_t network2_timestamp_ms;
+ int64_t receive_start_ms; // First received packet time.
+ int64_t receive_finish_ms; // Last received packet time.
+ int64_t decode_start_ms; // Decode start time.
+ int64_t decode_finish_ms; // Decode completion time.
+ int64_t render_time_ms; // Proposed render time to insure smooth playback.
+
+ uint8_t flags; // Flags indicating validity and/or why tracing was triggered.
+};
+
+// Minimum and maximum playout delay values from capture to render.
+// These are best effort values.
+//
+// A value < 0 indicates no change from previous valid value.
+//
+// min = max = 0 indicates that the receiver should try and render
+// frame as soon as possible.
+//
+// min = x, max = y indicates that the receiver is free to adapt
+// in the range (x, y) based on network jitter.
+struct VideoPlayoutDelay {
+ VideoPlayoutDelay() = default;
+ VideoPlayoutDelay(int min_ms, int max_ms) : min_ms(min_ms), max_ms(max_ms) {}
+ int min_ms = -1;
+ int max_ms = -1;
+
+ bool operator==(const VideoPlayoutDelay& rhs) const {
+ return min_ms == rhs.min_ms && max_ms == rhs.max_ms;
+ }
+};
+
+// TODO(bugs.webrtc.org/7660): Old name, delete after downstream use is updated.
+using PlayoutDelay = VideoPlayoutDelay;
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_TIMING_H_
diff --git a/third_party/libwebrtc/api/video_codecs/BUILD.gn b/third_party/libwebrtc/api/video_codecs/BUILD.gn
new file mode 100644
index 0000000000..101848a2e4
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/BUILD.gn
@@ -0,0 +1,314 @@
+# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../webrtc.gni")
+if (is_android) {
+ import("//build/config/android/config.gni")
+ import("//build/config/android/rules.gni")
+}
+
+rtc_source_set("scalability_mode") {
+ visibility = [ "*" ]
+ sources = [
+ "scalability_mode.cc",
+ "scalability_mode.h",
+ ]
+ deps = [
+ "../../rtc_base:checks",
+ "../../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
+}
+
+rtc_source_set("scalability_mode_helper") {
+ visibility = [ "*" ]
+ sources = [
+ "scalability_mode_helper.cc",
+ "scalability_mode_helper.h",
+ ]
+ deps = [ "../../modules/video_coding/svc:scalability_mode_util" ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
+rtc_library("video_codecs_api") {
+ visibility = [ "*" ]
+ sources = [
+ "av1_profile.cc",
+ "av1_profile.h",
+ "h264_profile_level_id.cc",
+ "h264_profile_level_id.h",
+ "sdp_video_format.cc",
+ "sdp_video_format.h",
+ "simulcast_stream.cc",
+ "simulcast_stream.h",
+ "spatial_layer.cc",
+ "spatial_layer.h",
+ "video_codec.cc",
+ "video_codec.h",
+ "video_decoder.cc",
+ "video_decoder.h",
+ "video_decoder_factory.h",
+ "video_encoder.cc",
+ "video_encoder.h",
+ "video_encoder_factory.h",
+ "vp8_frame_buffer_controller.h",
+ "vp8_frame_config.cc",
+ "vp8_frame_config.h",
+ "vp8_temporal_layers.cc",
+ "vp8_temporal_layers.h",
+ "vp9_profile.cc",
+ "vp9_profile.h",
+ ]
+
+ deps = [
+ ":scalability_mode",
+ "..:fec_controller_api",
+ "..:scoped_refptr",
+ "../../api:array_view",
+ "../../modules/video_coding:codec_globals_headers",
+ "../../rtc_base:checks",
+ "../../rtc_base:logging",
+ "../../rtc_base:macromagic",
+ "../../rtc_base:refcount",
+ "../../rtc_base:stringutils",
+ "../../rtc_base/system:rtc_export",
+ "../units:data_rate",
+ "../video:encoded_image",
+ "../video:render_resolution",
+ "../video:resolution",
+ "../video:video_bitrate_allocation",
+ "../video:video_codec_constants",
+ "../video:video_frame",
+ "../video:video_rtp_headers",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/algorithm:container",
+ "//third_party/abseil-cpp/absl/container:inlined_vector",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
+rtc_source_set("bitstream_parser_api") {
+ visibility = [ "*" ]
+ sources = [ "bitstream_parser.h" ]
+ deps = [ "..:array_view" ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+}
+
+rtc_library("builtin_video_decoder_factory") {
+ visibility = [ "*" ]
+ allow_poison = [
+ "audio_codecs", # TODO(bugs.webrtc.org/8396): Remove.
+ "software_video_codecs",
+ ]
+ sources = [
+ "builtin_video_decoder_factory.cc",
+ "builtin_video_decoder_factory.h",
+ ]
+
+ deps = [
+ ":video_codecs_api",
+ "../../api:scoped_refptr",
+ "../../media:rtc_internal_video_codecs",
+ "../../rtc_base/system:rtc_export",
+ ]
+}
+
+rtc_library("builtin_video_encoder_factory") {
+ visibility = [ "*" ]
+ allow_poison = [
+ "audio_codecs", # TODO(bugs.webrtc.org/8396): Remove.
+ "software_video_codecs",
+ ]
+ sources = [
+ "builtin_video_encoder_factory.cc",
+ "builtin_video_encoder_factory.h",
+ ]
+
+ deps = [
+ ":video_codecs_api",
+ "../../api:scoped_refptr",
+ "../../media:codec",
+ "../../media:media_constants",
+ "../../media:rtc_encoder_simulcast_proxy",
+ "../../media:rtc_internal_video_codecs",
+ "../../media:rtc_media_base",
+ "../../rtc_base:checks",
+ "../../rtc_base/system:rtc_export",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
+rtc_source_set("video_encoder_factory_template") {
+ visibility = [ "*" ]
+ allow_poison = [ "software_video_codecs" ]
+ public = [ "video_encoder_factory_template.h" ]
+
+ deps = [
+ ":video_codecs_api",
+ "../../api:array_view",
+ "../../modules/video_coding/svc:scalability_mode_util",
+ ]
+
+ absl_deps = [ "//third_party/abseil-cpp/absl/algorithm:container" ]
+}
+
+rtc_source_set("video_encoder_factory_template_libvpx_vp8_adapter") {
+ visibility = [ "*" ]
+ allow_poison = [ "software_video_codecs" ]
+ public = [ "video_encoder_factory_template_libvpx_vp8_adapter.h" ]
+
+ deps = [
+ ":video_codecs_api",
+ "../../modules/video_coding:webrtc_vp8",
+ "../../modules/video_coding:webrtc_vp8_scalability",
+ ]
+
+ absl_deps = [ "//third_party/abseil-cpp/absl/container:inlined_vector" ]
+}
+
+rtc_source_set("video_encoder_factory_template_libvpx_vp9_adapter") {
+ visibility = [ "*" ]
+ allow_poison = [ "software_video_codecs" ]
+ public = [ "video_encoder_factory_template_libvpx_vp9_adapter.h" ]
+
+ deps = [ "../../modules/video_coding:webrtc_vp9" ]
+}
+
+rtc_source_set("video_encoder_factory_template_open_h264_adapter") {
+ visibility = [ "*" ]
+ allow_poison = [ "software_video_codecs" ]
+ public = [ "video_encoder_factory_template_open_h264_adapter.h" ]
+
+ deps = [ "../../modules/video_coding:webrtc_h264" ]
+}
+
+rtc_source_set("video_encoder_factory_template_libaom_av1_adapter") {
+ visibility = [ "*" ]
+ allow_poison = [ "software_video_codecs" ]
+ public = [ "video_encoder_factory_template_libaom_av1_adapter.h" ]
+
+ deps = [
+ ":scalability_mode",
+ ":video_codecs_api",
+ "../../modules/video_coding/codecs/av1:av1_svc_config",
+ "../../modules/video_coding/codecs/av1:libaom_av1_encoder",
+ "../../modules/video_coding/svc:scalability_mode_util",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/container:inlined_vector" ]
+}
+
+rtc_source_set("video_decoder_factory_template") {
+ visibility = [ "*" ]
+ allow_poison = [ "software_video_codecs" ]
+ public = [ "video_decoder_factory_template.h" ]
+
+ deps = [
+ ":video_codecs_api",
+ "../../api:array_view",
+ ]
+
+ absl_deps = [ "//third_party/abseil-cpp/absl/algorithm:container" ]
+}
+
+rtc_source_set("video_decoder_factory_template_libvpx_vp8_adapter") {
+ visibility = [ "*" ]
+ allow_poison = [ "software_video_codecs" ]
+ public = [ "video_decoder_factory_template_libvpx_vp8_adapter.h" ]
+
+ deps = [
+ ":video_codecs_api",
+ "../../modules/video_coding:webrtc_vp8",
+ ]
+}
+
+rtc_source_set("video_decoder_factory_template_libvpx_vp9_adapter") {
+ visibility = [ "*" ]
+ allow_poison = [ "software_video_codecs" ]
+ public = [ "video_decoder_factory_template_libvpx_vp9_adapter.h" ]
+
+ deps = [ "../../modules/video_coding:webrtc_vp9" ]
+}
+
+rtc_source_set("video_decoder_factory_template_open_h264_adapter") {
+ visibility = [ "*" ]
+ allow_poison = [ "software_video_codecs" ]
+ public = [ "video_decoder_factory_template_open_h264_adapter.h" ]
+
+ deps = [ "../../modules/video_coding:webrtc_h264" ]
+}
+
+rtc_source_set("video_decoder_factory_template_dav1d_adapter") {
+ visibility = [ "*" ]
+ allow_poison = [ "software_video_codecs" ]
+ public = [ "video_decoder_factory_template_dav1d_adapter.h" ]
+
+ deps = [
+ ":video_codecs_api",
+ "../../modules/video_coding/codecs/av1:dav1d_decoder",
+ ]
+}
+
+rtc_library("vp8_temporal_layers_factory") {
+ visibility = [ "*" ]
+ allow_poison = [ "software_video_codecs" ]
+ sources = [
+ "vp8_temporal_layers_factory.cc",
+ "vp8_temporal_layers_factory.h",
+ ]
+
+ deps = [
+ ":video_codecs_api",
+ "../:fec_controller_api",
+ "../../modules/video_coding:video_coding_utility",
+ "../../modules/video_coding:webrtc_vp8_temporal_layers",
+ "../../rtc_base:checks",
+ ]
+}
+
+rtc_library("rtc_software_fallback_wrappers") {
+ visibility = [ "*" ]
+
+ sources = [
+ "video_decoder_software_fallback_wrapper.cc",
+ "video_decoder_software_fallback_wrapper.h",
+ "video_encoder_software_fallback_wrapper.cc",
+ "video_encoder_software_fallback_wrapper.h",
+ ]
+
+ deps = [
+ ":video_codecs_api",
+ "..:fec_controller_api",
+ "../../api/video:video_frame",
+ "../../media:rtc_media_base",
+ "../../modules/video_coding:video_codec_interface",
+ "../../modules/video_coding:video_coding_utility",
+ "../../rtc_base:checks",
+ "../../rtc_base:event_tracer",
+ "../../rtc_base:logging",
+ "../../rtc_base/system:rtc_export",
+ "../../system_wrappers:field_trial",
+ "../../system_wrappers:metrics",
+ "../video:encoded_image",
+ "../video:video_bitrate_allocation",
+ "../video:video_frame",
+ "../video:video_rtp_headers",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
diff --git a/third_party/libwebrtc/api/video_codecs/OWNERS b/third_party/libwebrtc/api/video_codecs/OWNERS
new file mode 100644
index 0000000000..f73b04f829
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/OWNERS
@@ -0,0 +1,4 @@
+magjed@webrtc.org
+sprang@webrtc.org
+brandtr@webrtc.org
+philipel@webrtc.org
diff --git a/third_party/libwebrtc/api/video_codecs/av1_profile.cc b/third_party/libwebrtc/api/video_codecs/av1_profile.cc
new file mode 100644
index 0000000000..eefe166d80
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/av1_profile.cc
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/av1_profile.h"
+
+#include <map>
+#include <utility>
+
+#include "rtc_base/string_to_number.h"
+
+namespace webrtc {
+
+// Parameter name in the format parameter map for AV1 video.
+const char kAV1FmtpProfile[] = "profile";
+
+absl::string_view AV1ProfileToString(AV1Profile profile) {
+ switch (profile) {
+ case AV1Profile::kProfile0:
+ return "0";
+ case AV1Profile::kProfile1:
+ return "1";
+ case AV1Profile::kProfile2:
+ return "2";
+ }
+ return "0";
+}
+
+absl::optional<AV1Profile> StringToAV1Profile(absl::string_view str) {
+ const absl::optional<int> i = rtc::StringToNumber<int>(str);
+ if (!i.has_value())
+ return absl::nullopt;
+
+ switch (i.value()) {
+ case 0:
+ return AV1Profile::kProfile0;
+ case 1:
+ return AV1Profile::kProfile1;
+ case 2:
+ return AV1Profile::kProfile2;
+ default:
+ return absl::nullopt;
+ }
+}
+
+absl::optional<AV1Profile> ParseSdpForAV1Profile(
+ const SdpVideoFormat::Parameters& params) {
+ const auto profile_it = params.find(kAV1FmtpProfile);
+ if (profile_it == params.end())
+ return AV1Profile::kProfile0;
+ const std::string& profile_str = profile_it->second;
+ return StringToAV1Profile(profile_str);
+}
+
+bool AV1IsSameProfile(const SdpVideoFormat::Parameters& params1,
+ const SdpVideoFormat::Parameters& params2) {
+ const absl::optional<AV1Profile> profile = ParseSdpForAV1Profile(params1);
+ const absl::optional<AV1Profile> other_profile =
+ ParseSdpForAV1Profile(params2);
+ return profile && other_profile && profile == other_profile;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/av1_profile.h b/third_party/libwebrtc/api/video_codecs/av1_profile.h
new file mode 100644
index 0000000000..2254d5ecd3
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/av1_profile.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_AV1_PROFILE_H_
+#define API_VIDEO_CODECS_AV1_PROFILE_H_
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "api/video_codecs/sdp_video_format.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Profile information for AV1 video.
+extern RTC_EXPORT const char kAV1FmtpProfile[];
+
+// Profiles can be found at:
+// https://aomedia.org/av1/specification/annex-a/#profiles
+// The enum values match the number specified in the SDP.
+enum class AV1Profile {
+ kProfile0 = 0,
+ kProfile1 = 1,
+ kProfile2 = 2,
+};
+
+// Helper function which converts an AV1Profile to std::string. Returns "0" if
+// an unknown value is passed in.
+RTC_EXPORT absl::string_view AV1ProfileToString(AV1Profile profile);
+
+// Helper function which converts a std::string to AV1Profile. Returns null if
+// |profile| is not a valid profile string.
+absl::optional<AV1Profile> StringToAV1Profile(absl::string_view profile);
+
+// Parses an SDP key-value map of format parameters to retrive an AV1 profile.
+// Returns an AV1Profile if one has been specified, `kProfile0` if no profile is
+// specified and an empty value if the profile key is present but contains an
+// invalid value.
+RTC_EXPORT absl::optional<AV1Profile> ParseSdpForAV1Profile(
+ const SdpVideoFormat::Parameters& params);
+
+// Returns true if the parameters have the same AV1 profile or neither contains
+// an AV1 profile, otherwise false.
+bool AV1IsSameProfile(const SdpVideoFormat::Parameters& params1,
+ const SdpVideoFormat::Parameters& params2);
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_AV1_PROFILE_H_
diff --git a/third_party/libwebrtc/api/video_codecs/bitstream_parser.h b/third_party/libwebrtc/api/video_codecs/bitstream_parser.h
new file mode 100644
index 0000000000..86ce192e49
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/bitstream_parser.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_BITSTREAM_PARSER_H_
+#define API_VIDEO_CODECS_BITSTREAM_PARSER_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+
+namespace webrtc {
+
+// This class is an interface for bitstream parsers.
+class BitstreamParser {
+ public:
+ virtual ~BitstreamParser() = default;
+
+ // Parse an additional chunk of the bitstream.
+ virtual void ParseBitstream(rtc::ArrayView<const uint8_t> bitstream) = 0;
+
+ // Get the last extracted QP value from the parsed bitstream. If no QP
+ // value could be parsed, returns absl::nullopt.
+ virtual absl::optional<int> GetLastSliceQp() const = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_BITSTREAM_PARSER_H_
diff --git a/third_party/libwebrtc/api/video_codecs/bitstream_parser_api_gn/moz.build b/third_party/libwebrtc/api/video_codecs/bitstream_parser_api_gn/moz.build
new file mode 100644
index 0000000000..dcf5d2273c
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/bitstream_parser_api_gn/moz.build
@@ -0,0 +1,205 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("bitstream_parser_api_gn")
diff --git a/third_party/libwebrtc/api/video_codecs/builtin_video_decoder_factory.cc b/third_party/libwebrtc/api/video_codecs/builtin_video_decoder_factory.cc
new file mode 100644
index 0000000000..f831905189
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/builtin_video_decoder_factory.cc
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/builtin_video_decoder_factory.h"
+
+#include <memory>
+
+#include "media/engine/internal_decoder_factory.h"
+
+namespace webrtc {
+
+std::unique_ptr<VideoDecoderFactory> CreateBuiltinVideoDecoderFactory() {
+ return std::make_unique<InternalDecoderFactory>();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/builtin_video_decoder_factory.h b/third_party/libwebrtc/api/video_codecs/builtin_video_decoder_factory.h
new file mode 100644
index 0000000000..d516077d99
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/builtin_video_decoder_factory.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_BUILTIN_VIDEO_DECODER_FACTORY_H_
+#define API_VIDEO_CODECS_BUILTIN_VIDEO_DECODER_FACTORY_H_
+
+#include <memory>
+
+#include "api/video_codecs/video_decoder_factory.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Creates a new factory that can create the built-in types of video decoders.
+RTC_EXPORT std::unique_ptr<VideoDecoderFactory>
+CreateBuiltinVideoDecoderFactory();
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_BUILTIN_VIDEO_DECODER_FACTORY_H_
diff --git a/third_party/libwebrtc/api/video_codecs/builtin_video_encoder_factory.cc b/third_party/libwebrtc/api/video_codecs/builtin_video_encoder_factory.cc
new file mode 100644
index 0000000000..7c5f35b216
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/builtin_video_encoder_factory.cc
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/builtin_video_encoder_factory.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/match.h"
+#include "absl/types/optional.h"
+#include "api/video_codecs/sdp_video_format.h"
+#include "api/video_codecs/video_encoder.h"
+#include "media/base/codec.h"
+#include "media/base/media_constants.h"
+#include "media/engine/encoder_simulcast_proxy.h"
+#include "media/engine/internal_encoder_factory.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+namespace {
+
+// This class wraps the internal factory and adds simulcast.
+class BuiltinVideoEncoderFactory : public VideoEncoderFactory {
+ public:
+ BuiltinVideoEncoderFactory()
+ : internal_encoder_factory_(new InternalEncoderFactory()) {}
+
+ std::unique_ptr<VideoEncoder> CreateVideoEncoder(
+ const SdpVideoFormat& format) override {
+ // Try creating internal encoder.
+ std::unique_ptr<VideoEncoder> internal_encoder;
+ if (format.IsCodecInList(
+ internal_encoder_factory_->GetSupportedFormats())) {
+ internal_encoder = std::make_unique<EncoderSimulcastProxy>(
+ internal_encoder_factory_.get(), format);
+ }
+
+ return internal_encoder;
+ }
+
+ std::vector<SdpVideoFormat> GetSupportedFormats() const override {
+ return internal_encoder_factory_->GetSupportedFormats();
+ }
+
+ CodecSupport QueryCodecSupport(
+ const SdpVideoFormat& format,
+ absl::optional<std::string> scalability_mode) const override {
+ return internal_encoder_factory_->QueryCodecSupport(format,
+ scalability_mode);
+ }
+
+ private:
+ const std::unique_ptr<VideoEncoderFactory> internal_encoder_factory_;
+};
+
+} // namespace
+
+std::unique_ptr<VideoEncoderFactory> CreateBuiltinVideoEncoderFactory() {
+ return std::make_unique<BuiltinVideoEncoderFactory>();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/builtin_video_encoder_factory.h b/third_party/libwebrtc/api/video_codecs/builtin_video_encoder_factory.h
new file mode 100644
index 0000000000..2c4537205c
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/builtin_video_encoder_factory.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_BUILTIN_VIDEO_ENCODER_FACTORY_H_
+#define API_VIDEO_CODECS_BUILTIN_VIDEO_ENCODER_FACTORY_H_
+
+#include <memory>
+
+#include "api/video_codecs/video_encoder_factory.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Creates a new factory that can create the built-in types of video encoders.
+// The factory has simulcast support for VP8.
+RTC_EXPORT std::unique_ptr<VideoEncoderFactory>
+CreateBuiltinVideoEncoderFactory();
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_BUILTIN_VIDEO_ENCODER_FACTORY_H_
diff --git a/third_party/libwebrtc/api/video_codecs/h264_profile_level_id.cc b/third_party/libwebrtc/api/video_codecs/h264_profile_level_id.cc
new file mode 100644
index 0000000000..02b43ba4f2
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/h264_profile_level_id.cc
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/h264_profile_level_id.h"
+
+#include <cstdio>
+#include <cstdlib>
+#include <string>
+
+#include "rtc_base/arraysize.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+namespace {
+
+const char kProfileLevelId[] = "profile-level-id";
+
+// For level_idc=11 and profile_idc=0x42, 0x4D, or 0x58, the constraint set3
+// flag specifies if level 1b or level 1.1 is used.
+const uint8_t kConstraintSet3Flag = 0x10;
+
+// Convert a string of 8 characters into a byte where the positions containing
+// character c will have their bit set. For example, c = 'x', str = "x1xx0000"
+// will return 0b10110000. constexpr is used so that the pattern table in
+// kProfilePatterns is statically initialized.
+constexpr uint8_t ByteMaskString(char c, const char (&str)[9]) {
+ return (str[0] == c) << 7 | (str[1] == c) << 6 | (str[2] == c) << 5 |
+ (str[3] == c) << 4 | (str[4] == c) << 3 | (str[5] == c) << 2 |
+ (str[6] == c) << 1 | (str[7] == c) << 0;
+}
+
+// Class for matching bit patterns such as "x1xx0000" where 'x' is allowed to be
+// either 0 or 1.
+class BitPattern {
+ public:
+ explicit constexpr BitPattern(const char (&str)[9])
+ : mask_(~ByteMaskString('x', str)),
+ masked_value_(ByteMaskString('1', str)) {}
+
+ bool IsMatch(uint8_t value) const { return masked_value_ == (value & mask_); }
+
+ private:
+ const uint8_t mask_;
+ const uint8_t masked_value_;
+};
+
+// Table for converting between profile_idc/profile_iop to H264Profile.
+struct ProfilePattern {
+ const uint8_t profile_idc;
+ const BitPattern profile_iop;
+ const H264Profile profile;
+};
+
+// This is from https://tools.ietf.org/html/rfc6184#section-8.1.
+constexpr ProfilePattern kProfilePatterns[] = {
+ {0x42, BitPattern("x1xx0000"), H264Profile::kProfileConstrainedBaseline},
+ {0x4D, BitPattern("1xxx0000"), H264Profile::kProfileConstrainedBaseline},
+ {0x58, BitPattern("11xx0000"), H264Profile::kProfileConstrainedBaseline},
+ {0x42, BitPattern("x0xx0000"), H264Profile::kProfileBaseline},
+ {0x58, BitPattern("10xx0000"), H264Profile::kProfileBaseline},
+ {0x4D, BitPattern("0x0x0000"), H264Profile::kProfileMain},
+ {0x64, BitPattern("00000000"), H264Profile::kProfileHigh},
+ {0x64, BitPattern("00001100"), H264Profile::kProfileConstrainedHigh},
+ {0xF4, BitPattern("00000000"), H264Profile::kProfilePredictiveHigh444}};
+
+struct LevelConstraint {
+ const int max_macroblocks_per_second;
+ const int max_macroblock_frame_size;
+ const H264Level level;
+};
+
+// This is from ITU-T H.264 (02/2016) Table A-1 – Level limits.
+static constexpr LevelConstraint kLevelConstraints[] = {
+ {1485, 99, H264Level::kLevel1},
+ {1485, 99, H264Level::kLevel1_b},
+ {3000, 396, H264Level::kLevel1_1},
+ {6000, 396, H264Level::kLevel1_2},
+ {11880, 396, H264Level::kLevel1_3},
+ {11880, 396, H264Level::kLevel2},
+ {19800, 792, H264Level::kLevel2_1},
+ {20250, 1620, H264Level::kLevel2_2},
+ {40500, 1620, H264Level::kLevel3},
+ {108000, 3600, H264Level::kLevel3_1},
+ {216000, 5120, H264Level::kLevel3_2},
+ {245760, 8192, H264Level::kLevel4},
+ {245760, 8192, H264Level::kLevel4_1},
+ {522240, 8704, H264Level::kLevel4_2},
+ {589824, 22080, H264Level::kLevel5},
+ {983040, 36864, H264Level::kLevel5_1},
+ {2073600, 36864, H264Level::kLevel5_2},
+};
+
+} // anonymous namespace
+
+absl::optional<H264ProfileLevelId> ParseH264ProfileLevelId(const char* str) {
+ // The string should consist of 3 bytes in hexadecimal format.
+ if (strlen(str) != 6u)
+ return absl::nullopt;
+ const uint32_t profile_level_id_numeric = strtol(str, nullptr, 16);
+ if (profile_level_id_numeric == 0)
+ return absl::nullopt;
+
+ // Separate into three bytes.
+ const uint8_t level_idc =
+ static_cast<uint8_t>(profile_level_id_numeric & 0xFF);
+ const uint8_t profile_iop =
+ static_cast<uint8_t>((profile_level_id_numeric >> 8) & 0xFF);
+ const uint8_t profile_idc =
+ static_cast<uint8_t>((profile_level_id_numeric >> 16) & 0xFF);
+
+ // Parse level based on level_idc and constraint set 3 flag.
+ H264Level level_casted = static_cast<H264Level>(level_idc);
+ H264Level level;
+
+ switch (level_casted) {
+ case H264Level::kLevel1_1:
+ level = (profile_iop & kConstraintSet3Flag) != 0 ? H264Level::kLevel1_b
+ : H264Level::kLevel1_1;
+ break;
+ case H264Level::kLevel1:
+ case H264Level::kLevel1_2:
+ case H264Level::kLevel1_3:
+ case H264Level::kLevel2:
+ case H264Level::kLevel2_1:
+ case H264Level::kLevel2_2:
+ case H264Level::kLevel3:
+ case H264Level::kLevel3_1:
+ case H264Level::kLevel3_2:
+ case H264Level::kLevel4:
+ case H264Level::kLevel4_1:
+ case H264Level::kLevel4_2:
+ case H264Level::kLevel5:
+ case H264Level::kLevel5_1:
+ case H264Level::kLevel5_2:
+ level = level_casted;
+ break;
+ default:
+ // Unrecognized level_idc.
+ return absl::nullopt;
+ }
+
+ // Parse profile_idc/profile_iop into a Profile enum.
+ for (const ProfilePattern& pattern : kProfilePatterns) {
+ if (profile_idc == pattern.profile_idc &&
+ pattern.profile_iop.IsMatch(profile_iop)) {
+ return H264ProfileLevelId(pattern.profile, level);
+ }
+ }
+
+ // Unrecognized profile_idc/profile_iop combination.
+ return absl::nullopt;
+}
+
+absl::optional<H264Level> H264SupportedLevel(int max_frame_pixel_count,
+ float max_fps) {
+ static const int kPixelsPerMacroblock = 16 * 16;
+
+ for (int i = arraysize(kLevelConstraints) - 1; i >= 0; --i) {
+ const LevelConstraint& level_constraint = kLevelConstraints[i];
+ if (level_constraint.max_macroblock_frame_size * kPixelsPerMacroblock <=
+ max_frame_pixel_count &&
+ level_constraint.max_macroblocks_per_second <=
+ max_fps * level_constraint.max_macroblock_frame_size) {
+ return level_constraint.level;
+ }
+ }
+
+ // No level supported.
+ return absl::nullopt;
+}
+
+absl::optional<H264ProfileLevelId> ParseSdpForH264ProfileLevelId(
+ const SdpVideoFormat::Parameters& params) {
+ // TODO(magjed): The default should really be kProfileBaseline and kLevel1
+ // according to the spec: https://tools.ietf.org/html/rfc6184#section-8.1. In
+ // order to not break backwards compatibility with older versions of WebRTC
+ // where external codecs don't have any parameters, use
+ // kProfileConstrainedBaseline kLevel3_1 instead. This workaround will only be
+ // done in an interim period to allow external clients to update their code.
+ // http://crbug/webrtc/6337.
+ static const H264ProfileLevelId kDefaultProfileLevelId(
+ H264Profile::kProfileConstrainedBaseline, H264Level::kLevel3_1);
+
+ const auto profile_level_id_it = params.find(kProfileLevelId);
+ return (profile_level_id_it == params.end())
+ ? kDefaultProfileLevelId
+ : ParseH264ProfileLevelId(profile_level_id_it->second.c_str());
+}
+
+absl::optional<std::string> H264ProfileLevelIdToString(
+ const H264ProfileLevelId& profile_level_id) {
+ // Handle special case level == 1b.
+ if (profile_level_id.level == H264Level::kLevel1_b) {
+ switch (profile_level_id.profile) {
+ case H264Profile::kProfileConstrainedBaseline:
+ return {"42f00b"};
+ case H264Profile::kProfileBaseline:
+ return {"42100b"};
+ case H264Profile::kProfileMain:
+ return {"4d100b"};
+ // Level 1b is not allowed for other profiles.
+ default:
+ return absl::nullopt;
+ }
+ }
+
+ const char* profile_idc_iop_string;
+ switch (profile_level_id.profile) {
+ case H264Profile::kProfileConstrainedBaseline:
+ profile_idc_iop_string = "42e0";
+ break;
+ case H264Profile::kProfileBaseline:
+ profile_idc_iop_string = "4200";
+ break;
+ case H264Profile::kProfileMain:
+ profile_idc_iop_string = "4d00";
+ break;
+ case H264Profile::kProfileConstrainedHigh:
+ profile_idc_iop_string = "640c";
+ break;
+ case H264Profile::kProfileHigh:
+ profile_idc_iop_string = "6400";
+ break;
+ case H264Profile::kProfilePredictiveHigh444:
+ profile_idc_iop_string = "f400";
+ break;
+ // Unrecognized profile.
+ default:
+ return absl::nullopt;
+ }
+
+ char str[7];
+ snprintf(str, 7u, "%s%02x", profile_idc_iop_string, profile_level_id.level);
+ return {str};
+}
+
+bool H264IsSameProfile(const SdpVideoFormat::Parameters& params1,
+ const SdpVideoFormat::Parameters& params2) {
+ const absl::optional<H264ProfileLevelId> profile_level_id =
+ ParseSdpForH264ProfileLevelId(params1);
+ const absl::optional<H264ProfileLevelId> other_profile_level_id =
+ ParseSdpForH264ProfileLevelId(params2);
+ // Compare H264 profiles, but not levels.
+ return profile_level_id && other_profile_level_id &&
+ profile_level_id->profile == other_profile_level_id->profile;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/h264_profile_level_id.h b/third_party/libwebrtc/api/video_codecs/h264_profile_level_id.h
new file mode 100644
index 0000000000..4b46ad329d
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/h264_profile_level_id.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_H264_PROFILE_LEVEL_ID_H_
+#define API_VIDEO_CODECS_H264_PROFILE_LEVEL_ID_H_
+
+#include <string>
+
+#include "absl/types/optional.h"
+#include "api/video_codecs/sdp_video_format.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+enum class H264Profile {
+ kProfileConstrainedBaseline,
+ kProfileBaseline,
+ kProfileMain,
+ kProfileConstrainedHigh,
+ kProfileHigh,
+ kProfilePredictiveHigh444,
+};
+
+// All values are equal to ten times the level number, except level 1b which is
+// special.
+enum class H264Level {
+ kLevel1_b = 0,
+ kLevel1 = 10,
+ kLevel1_1 = 11,
+ kLevel1_2 = 12,
+ kLevel1_3 = 13,
+ kLevel2 = 20,
+ kLevel2_1 = 21,
+ kLevel2_2 = 22,
+ kLevel3 = 30,
+ kLevel3_1 = 31,
+ kLevel3_2 = 32,
+ kLevel4 = 40,
+ kLevel4_1 = 41,
+ kLevel4_2 = 42,
+ kLevel5 = 50,
+ kLevel5_1 = 51,
+ kLevel5_2 = 52
+};
+
+struct H264ProfileLevelId {
+ constexpr H264ProfileLevelId(H264Profile profile, H264Level level)
+ : profile(profile), level(level) {}
+ H264Profile profile;
+ H264Level level;
+};
+
+// Parse profile level id that is represented as a string of 3 hex bytes.
+// Nothing will be returned if the string is not a recognized H264
+// profile level id.
+absl::optional<H264ProfileLevelId> ParseH264ProfileLevelId(const char* str);
+
+// Parse profile level id that is represented as a string of 3 hex bytes
+// contained in an SDP key-value map. A default profile level id will be
+// returned if the profile-level-id key is missing. Nothing will be returned if
+// the key is present but the string is invalid.
+RTC_EXPORT absl::optional<H264ProfileLevelId> ParseSdpForH264ProfileLevelId(
+ const SdpVideoFormat::Parameters& params);
+
+// Given that a decoder supports up to a given frame size (in pixels) at up to a
+// given number of frames per second, return the highest H.264 level where it
+// can guarantee that it will be able to support all valid encoded streams that
+// are within that level.
+RTC_EXPORT absl::optional<H264Level> H264SupportedLevel(
+ int max_frame_pixel_count,
+ float max_fps);
+
+// Returns canonical string representation as three hex bytes of the profile
+// level id, or returns nothing for invalid profile level ids.
+RTC_EXPORT absl::optional<std::string> H264ProfileLevelIdToString(
+ const H264ProfileLevelId& profile_level_id);
+
+// Returns true if the parameters have the same H264 profile (Baseline, High,
+// etc).
+RTC_EXPORT bool H264IsSameProfile(const SdpVideoFormat::Parameters& params1,
+ const SdpVideoFormat::Parameters& params2);
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_H264_PROFILE_LEVEL_ID_H_
diff --git a/third_party/libwebrtc/api/video_codecs/rtc_software_fallback_wrappers_gn/moz.build b/third_party/libwebrtc/api/video_codecs/rtc_software_fallback_wrappers_gn/moz.build
new file mode 100644
index 0000000000..987a01bd2f
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/rtc_software_fallback_wrappers_gn/moz.build
@@ -0,0 +1,234 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/video_codecs/video_decoder_software_fallback_wrapper.cc",
+ "/third_party/libwebrtc/api/video_codecs/video_encoder_software_fallback_wrapper.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "GLESv2",
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "rt"
+ ]
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "crypt32",
+ "iphlpapi",
+ "secur32",
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("rtc_software_fallback_wrappers_gn")
diff --git a/third_party/libwebrtc/api/video_codecs/scalability_mode.cc b/third_party/libwebrtc/api/video_codecs/scalability_mode.cc
new file mode 100644
index 0000000000..c449b4217e
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/scalability_mode.cc
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/scalability_mode.h"
+
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+absl::string_view ScalabilityModeToString(ScalabilityMode scalability_mode) {
+ switch (scalability_mode) {
+ case ScalabilityMode::kL1T1:
+ return "L1T1";
+ case ScalabilityMode::kL1T2:
+ return "L1T2";
+ case ScalabilityMode::kL1T3:
+ return "L1T3";
+ case ScalabilityMode::kL2T1:
+ return "L2T1";
+ case ScalabilityMode::kL2T1h:
+ return "L2T1h";
+ case ScalabilityMode::kL2T1_KEY:
+ return "L2T1_KEY";
+ case ScalabilityMode::kL2T2:
+ return "L2T2";
+ case ScalabilityMode::kL2T2h:
+ return "L2T2h";
+ case ScalabilityMode::kL2T2_KEY:
+ return "L2T2_KEY";
+ case ScalabilityMode::kL2T2_KEY_SHIFT:
+ return "L2T2_KEY_SHIFT";
+ case ScalabilityMode::kL2T3:
+ return "L2T3";
+ case ScalabilityMode::kL2T3h:
+ return "L2T3h";
+ case ScalabilityMode::kL2T3_KEY:
+ return "L2T3_KEY";
+ case ScalabilityMode::kL3T1:
+ return "L3T1";
+ case ScalabilityMode::kL3T1h:
+ return "L3T1h";
+ case ScalabilityMode::kL3T1_KEY:
+ return "L3T1_KEY";
+ case ScalabilityMode::kL3T2:
+ return "L3T2";
+ case ScalabilityMode::kL3T2h:
+ return "L3T2h";
+ case ScalabilityMode::kL3T2_KEY:
+ return "L3T2_KEY";
+ case ScalabilityMode::kL3T3:
+ return "L3T3";
+ case ScalabilityMode::kL3T3h:
+ return "L3T3h";
+ case ScalabilityMode::kL3T3_KEY:
+ return "L3T3_KEY";
+ case ScalabilityMode::kS2T1:
+ return "S2T1";
+ case ScalabilityMode::kS2T1h:
+ return "S2T1h";
+ case ScalabilityMode::kS2T2:
+ return "S2T2";
+ case ScalabilityMode::kS2T2h:
+ return "S2T2h";
+ case ScalabilityMode::kS2T3:
+ return "S2T3";
+ case ScalabilityMode::kS2T3h:
+ return "S2T3h";
+ case ScalabilityMode::kS3T1:
+ return "S3T1";
+ case ScalabilityMode::kS3T1h:
+ return "S3T1h";
+ case ScalabilityMode::kS3T2:
+ return "S3T2";
+ case ScalabilityMode::kS3T2h:
+ return "S3T2h";
+ case ScalabilityMode::kS3T3:
+ return "S3T3";
+ case ScalabilityMode::kS3T3h:
+ return "S3T3h";
+ }
+ RTC_CHECK_NOTREACHED();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/scalability_mode.h b/third_party/libwebrtc/api/video_codecs/scalability_mode.h
new file mode 100644
index 0000000000..b26f32eb22
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/scalability_mode.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_SCALABILITY_MODE_H_
+#define API_VIDEO_CODECS_SCALABILITY_MODE_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "absl/strings/string_view.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Supported scalability modes. Most applications should use the
+// PeerConnection-level apis where scalability mode is represented as a string.
+// This list of currently recognized modes is intended for the api boundary
+// between webrtc and injected encoders. Any application usage outside of
+// injected encoders is strongly discouraged.
+enum class ScalabilityMode : uint8_t {
+ kL1T1,
+ kL1T2,
+ kL1T3,
+ kL2T1,
+ kL2T1h,
+ kL2T1_KEY,
+ kL2T2,
+ kL2T2h,
+ kL2T2_KEY,
+ kL2T2_KEY_SHIFT,
+ kL2T3,
+ kL2T3h,
+ kL2T3_KEY,
+ kL3T1,
+ kL3T1h,
+ kL3T1_KEY,
+ kL3T2,
+ kL3T2h,
+ kL3T2_KEY,
+ kL3T3,
+ kL3T3h,
+ kL3T3_KEY,
+ kS2T1,
+ kS2T1h,
+ kS2T2,
+ kS2T2h,
+ kS2T3,
+ kS2T3h,
+ kS3T1,
+ kS3T1h,
+ kS3T2,
+ kS3T2h,
+ kS3T3,
+ kS3T3h,
+};
+
+inline constexpr ScalabilityMode kAllScalabilityModes[] = {
+ // clang-format off
+ ScalabilityMode::kL1T1,
+ ScalabilityMode::kL1T2,
+ ScalabilityMode::kL1T3,
+ ScalabilityMode::kL2T1,
+ ScalabilityMode::kL2T1h,
+ ScalabilityMode::kL2T1_KEY,
+ ScalabilityMode::kL2T2,
+ ScalabilityMode::kL2T2h,
+ ScalabilityMode::kL2T2_KEY,
+ ScalabilityMode::kL2T2_KEY_SHIFT,
+ ScalabilityMode::kL2T3,
+ ScalabilityMode::kL2T3h,
+ ScalabilityMode::kL2T3_KEY,
+ ScalabilityMode::kL3T1,
+ ScalabilityMode::kL3T1h,
+ ScalabilityMode::kL3T1_KEY,
+ ScalabilityMode::kL3T2,
+ ScalabilityMode::kL3T2h,
+ ScalabilityMode::kL3T2_KEY,
+ ScalabilityMode::kL3T3,
+ ScalabilityMode::kL3T3h,
+ ScalabilityMode::kL3T3_KEY,
+ ScalabilityMode::kS2T1,
+ ScalabilityMode::kS2T1h,
+ ScalabilityMode::kS2T2,
+ ScalabilityMode::kS2T2h,
+ ScalabilityMode::kS2T3,
+ ScalabilityMode::kS2T3h,
+ ScalabilityMode::kS3T1,
+ ScalabilityMode::kS3T1h,
+ ScalabilityMode::kS3T2,
+ ScalabilityMode::kS3T2h,
+ ScalabilityMode::kS3T3,
+ ScalabilityMode::kS3T3h,
+ // clang-format on
+};
+
+inline constexpr size_t kScalabilityModeCount =
+ sizeof(kAllScalabilityModes) / sizeof(ScalabilityMode);
+
+RTC_EXPORT
+absl::string_view ScalabilityModeToString(ScalabilityMode scalability_mode);
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_SCALABILITY_MODE_H_
diff --git a/third_party/libwebrtc/api/video_codecs/scalability_mode_gn/moz.build b/third_party/libwebrtc/api/video_codecs/scalability_mode_gn/moz.build
new file mode 100644
index 0000000000..a308bfc58f
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/scalability_mode_gn/moz.build
@@ -0,0 +1,221 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/video_codecs/scalability_mode.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("scalability_mode_gn")
diff --git a/third_party/libwebrtc/api/video_codecs/scalability_mode_helper.cc b/third_party/libwebrtc/api/video_codecs/scalability_mode_helper.cc
new file mode 100644
index 0000000000..b4571632d9
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/scalability_mode_helper.cc
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/scalability_mode_helper.h"
+
+#include "modules/video_coding/svc/scalability_mode_util.h"
+
+namespace webrtc {
+
+absl::optional<int> ScalabilityModeStringToNumSpatialLayers(
+ absl::string_view scalability_mode_string) {
+ absl::optional<ScalabilityMode> scalability_mode =
+ ScalabilityModeFromString(scalability_mode_string);
+ if (!scalability_mode.has_value()) {
+ return absl::nullopt;
+ }
+ return ScalabilityModeToNumSpatialLayers(*scalability_mode);
+}
+
+absl::optional<int> ScalabilityModeStringToNumTemporalLayers(
+ absl::string_view scalability_mode_string) {
+ absl::optional<ScalabilityMode> scalability_mode =
+ ScalabilityModeFromString(scalability_mode_string);
+ if (!scalability_mode.has_value()) {
+ return absl::nullopt;
+ }
+ return ScalabilityModeToNumTemporalLayers(*scalability_mode);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/scalability_mode_helper.h b/third_party/libwebrtc/api/video_codecs/scalability_mode_helper.h
new file mode 100644
index 0000000000..a8b060d079
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/scalability_mode_helper.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_SCALABILITY_MODE_HELPER_H_
+#define API_VIDEO_CODECS_SCALABILITY_MODE_HELPER_H_
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+
+namespace webrtc {
+
+// Returns the number of spatial layers from the `scalability_mode_string`
+// or nullopt if the given mode is unknown.
+absl::optional<int> ScalabilityModeStringToNumSpatialLayers(
+ absl::string_view scalability_mode_string);
+
+// Returns the number of temporal layers from the `scalability_mode_string`
+// or nullopt if the given mode is unknown.
+absl::optional<int> ScalabilityModeStringToNumTemporalLayers(
+ absl::string_view scalability_mode_string);
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_SCALABILITY_MODE_HELPER_H_
diff --git a/third_party/libwebrtc/api/video_codecs/sdp_video_format.cc b/third_party/libwebrtc/api/video_codecs/sdp_video_format.cc
new file mode 100644
index 0000000000..cb7e98a682
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/sdp_video_format.cc
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/sdp_video_format.h"
+
+#include "absl/strings/match.h"
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/video_codecs/av1_profile.h"
+#include "api/video_codecs/h264_profile_level_id.h"
+#include "api/video_codecs/video_codec.h"
+#include "api/video_codecs/vp9_profile.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/strings/string_builder.h"
+
+namespace webrtc {
+
+namespace {
+
+std::string H264GetPacketizationModeOrDefault(
+ const SdpVideoFormat::Parameters& params) {
+ constexpr char kH264FmtpPacketizationMode[] = "packetization-mode";
+ const auto it = params.find(kH264FmtpPacketizationMode);
+ if (it != params.end()) {
+ return it->second;
+ }
+ // If packetization-mode is not present, default to "0".
+ // https://tools.ietf.org/html/rfc6184#section-6.2
+ return "0";
+}
+
+bool H264IsSamePacketizationMode(const SdpVideoFormat::Parameters& left,
+ const SdpVideoFormat::Parameters& right) {
+ return H264GetPacketizationModeOrDefault(left) ==
+ H264GetPacketizationModeOrDefault(right);
+}
+
+// Some (video) codecs are actually families of codecs and rely on parameters
+// to distinguish different incompatible family members.
+bool IsSameCodecSpecific(const SdpVideoFormat& format1,
+ const SdpVideoFormat& format2) {
+ // The assumption when calling this function is that the two formats have the
+ // same name.
+ RTC_DCHECK(absl::EqualsIgnoreCase(format1.name, format2.name));
+
+ VideoCodecType codec_type = PayloadStringToCodecType(format1.name);
+ switch (codec_type) {
+ case kVideoCodecH264:
+ return H264IsSameProfile(format1.parameters, format2.parameters) &&
+ H264IsSamePacketizationMode(format1.parameters,
+ format2.parameters);
+ case kVideoCodecVP9:
+ return VP9IsSameProfile(format1.parameters, format2.parameters);
+ case kVideoCodecAV1:
+ return AV1IsSameProfile(format1.parameters, format2.parameters);
+ default:
+ return true;
+ }
+}
+} // namespace
+
+SdpVideoFormat::SdpVideoFormat(const std::string& name) : name(name) {}
+
+SdpVideoFormat::SdpVideoFormat(const std::string& name,
+ const Parameters& parameters)
+ : name(name), parameters(parameters) {}
+
+SdpVideoFormat::SdpVideoFormat(
+ const std::string& name,
+ const Parameters& parameters,
+ const absl::InlinedVector<ScalabilityMode, kScalabilityModeCount>&
+ scalability_modes)
+ : name(name),
+ parameters(parameters),
+ scalability_modes(scalability_modes) {}
+
+SdpVideoFormat::SdpVideoFormat(const SdpVideoFormat&) = default;
+SdpVideoFormat::SdpVideoFormat(SdpVideoFormat&&) = default;
+SdpVideoFormat& SdpVideoFormat::operator=(const SdpVideoFormat&) = default;
+SdpVideoFormat& SdpVideoFormat::operator=(SdpVideoFormat&&) = default;
+
+SdpVideoFormat::~SdpVideoFormat() = default;
+
+std::string SdpVideoFormat::ToString() const {
+ rtc::StringBuilder builder;
+ builder << "Codec name: " << name << ", parameters: {";
+ for (const auto& kv : parameters) {
+ builder << " " << kv.first << "=" << kv.second;
+ }
+
+ builder << " }";
+ if (!scalability_modes.empty()) {
+ builder << ", scalability_modes: [";
+ bool first = true;
+ for (const auto scalability_mode : scalability_modes) {
+ if (first) {
+ first = false;
+ } else {
+ builder << ", ";
+ }
+ builder << ScalabilityModeToString(scalability_mode);
+ }
+ builder << "]";
+ }
+
+ return builder.str();
+}
+
+bool SdpVideoFormat::IsSameCodec(const SdpVideoFormat& other) const {
+ // Two codecs are considered the same if the name matches (case insensitive)
+ // and certain codec-specific parameters match.
+ return absl::EqualsIgnoreCase(name, other.name) &&
+ IsSameCodecSpecific(*this, other);
+}
+
+bool SdpVideoFormat::IsCodecInList(
+ rtc::ArrayView<const webrtc::SdpVideoFormat> formats) const {
+ for (const auto& format : formats) {
+ if (IsSameCodec(format)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool operator==(const SdpVideoFormat& a, const SdpVideoFormat& b) {
+ return a.name == b.name && a.parameters == b.parameters &&
+ a.scalability_modes == b.scalability_modes;
+}
+
+absl::optional<SdpVideoFormat> FuzzyMatchSdpVideoFormat(
+ rtc::ArrayView<const SdpVideoFormat> supported_formats,
+ const SdpVideoFormat& format) {
+ absl::optional<SdpVideoFormat> res;
+ int best_parameter_match = 0;
+ for (const auto& supported_format : supported_formats) {
+ if (absl::EqualsIgnoreCase(supported_format.name, format.name)) {
+ int matching_parameters = 0;
+ for (const auto& kv : supported_format.parameters) {
+ auto it = format.parameters.find(kv.first);
+ if (it != format.parameters.end() && it->second == kv.second) {
+ matching_parameters += 1;
+ }
+ }
+
+ if (!res || matching_parameters > best_parameter_match) {
+ res = supported_format;
+ best_parameter_match = matching_parameters;
+ }
+ }
+ }
+
+ if (!res) {
+ RTC_LOG(LS_INFO) << "Failed to match SdpVideoFormat " << format.ToString();
+ } else if (*res != format) {
+ RTC_LOG(LS_INFO) << "Matched SdpVideoFormat " << format.ToString()
+ << " with " << res->ToString();
+ }
+
+ return res;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/sdp_video_format.h b/third_party/libwebrtc/api/video_codecs/sdp_video_format.h
new file mode 100644
index 0000000000..faaa66c241
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/sdp_video_format.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_SDP_VIDEO_FORMAT_H_
+#define API_VIDEO_CODECS_SDP_VIDEO_FORMAT_H_
+
+#include <map>
+#include <string>
+
+#include "absl/container/inlined_vector.h"
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/video_codecs/scalability_mode.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// SDP specification for a single video codec.
+// NOTE: This class is still under development and may change without notice.
+struct RTC_EXPORT SdpVideoFormat {
+ using Parameters = std::map<std::string, std::string>;
+
+ explicit SdpVideoFormat(const std::string& name);
+ SdpVideoFormat(const std::string& name, const Parameters& parameters);
+ SdpVideoFormat(
+ const std::string& name,
+ const Parameters& parameters,
+ const absl::InlinedVector<ScalabilityMode, kScalabilityModeCount>&
+ scalability_modes);
+ SdpVideoFormat(const SdpVideoFormat&);
+ SdpVideoFormat(SdpVideoFormat&&);
+ SdpVideoFormat& operator=(const SdpVideoFormat&);
+ SdpVideoFormat& operator=(SdpVideoFormat&&);
+
+ ~SdpVideoFormat();
+
+ // Returns true if the SdpVideoFormats have the same names as well as codec
+ // specific parameters. Please note that two SdpVideoFormats can represent the
+ // same codec even though not all parameters are the same.
+ bool IsSameCodec(const SdpVideoFormat& other) const;
+ bool IsCodecInList(
+ rtc::ArrayView<const webrtc::SdpVideoFormat> formats) const;
+
+ std::string ToString() const;
+
+ friend RTC_EXPORT bool operator==(const SdpVideoFormat& a,
+ const SdpVideoFormat& b);
+ friend RTC_EXPORT bool operator!=(const SdpVideoFormat& a,
+ const SdpVideoFormat& b) {
+ return !(a == b);
+ }
+
+ std::string name;
+ Parameters parameters;
+ absl::InlinedVector<ScalabilityMode, kScalabilityModeCount> scalability_modes;
+};
+
+// For not so good reasons sometimes additional parameters are added to an
+// SdpVideoFormat, which makes instances that should compare equal to not match
+// anymore. Until we stop misusing SdpVideoFormats provide this convenience
+// function to perform fuzzy matching.
+absl::optional<SdpVideoFormat> FuzzyMatchSdpVideoFormat(
+ rtc::ArrayView<const SdpVideoFormat> supported_formats,
+ const SdpVideoFormat& format);
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_SDP_VIDEO_FORMAT_H_
diff --git a/third_party/libwebrtc/api/video_codecs/simulcast_stream.cc b/third_party/libwebrtc/api/video_codecs/simulcast_stream.cc
new file mode 100644
index 0000000000..312429ef9f
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/simulcast_stream.cc
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/simulcast_stream.h"
+
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+unsigned char SimulcastStream::GetNumberOfTemporalLayers() const {
+ return numberOfTemporalLayers;
+}
+void SimulcastStream::SetNumberOfTemporalLayers(unsigned char n) {
+ RTC_DCHECK_GE(n, 1);
+ RTC_DCHECK_LE(n, 3);
+ numberOfTemporalLayers = n;
+}
+
+ScalabilityMode SimulcastStream::GetScalabilityMode() const {
+ RTC_CHECK_GE(numberOfTemporalLayers, 1);
+ RTC_CHECK_LE(numberOfTemporalLayers, 3);
+ static const ScalabilityMode scalability_modes[3] = {
+ ScalabilityMode::kL1T1,
+ ScalabilityMode::kL1T2,
+ ScalabilityMode::kL1T3,
+ };
+ return scalability_modes[numberOfTemporalLayers - 1];
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/simulcast_stream.h b/third_party/libwebrtc/api/video_codecs/simulcast_stream.h
new file mode 100644
index 0000000000..7c0dd5d786
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/simulcast_stream.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_SIMULCAST_STREAM_H_
+#define API_VIDEO_CODECS_SIMULCAST_STREAM_H_
+
+#include "api/video_codecs/scalability_mode.h"
+
+namespace webrtc {
+
+// TODO(bugs.webrtc.org/6883): Unify with struct VideoStream, part of
+// VideoEncoderConfig.
+struct SimulcastStream {
+ // Temporary utility methods for transition from numberOfTemporalLayers
+ // setting to ScalabilityMode.
+ unsigned char GetNumberOfTemporalLayers() const;
+ ScalabilityMode GetScalabilityMode() const;
+ void SetNumberOfTemporalLayers(unsigned char n);
+
+ int width = 0;
+ int height = 0;
+ float maxFramerate = 0; // fps.
+ unsigned char numberOfTemporalLayers = 1;
+ unsigned int maxBitrate = 0; // kilobits/sec.
+ unsigned int targetBitrate = 0; // kilobits/sec.
+ unsigned int minBitrate = 0; // kilobits/sec.
+ unsigned int qpMax = 0; // minimum quality
+ bool active = false; // encoded and sent.
+};
+
+} // namespace webrtc
+#endif // API_VIDEO_CODECS_SIMULCAST_STREAM_H_
diff --git a/third_party/libwebrtc/api/video_codecs/spatial_layer.cc b/third_party/libwebrtc/api/video_codecs/spatial_layer.cc
new file mode 100644
index 0000000000..25ccdfeb48
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/spatial_layer.cc
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/spatial_layer.h"
+
+namespace webrtc {
+
+bool SpatialLayer::operator==(const SpatialLayer& other) const {
+ return (width == other.width && height == other.height &&
+ maxFramerate == other.maxFramerate &&
+ numberOfTemporalLayers == other.numberOfTemporalLayers &&
+ maxBitrate == other.maxBitrate &&
+ targetBitrate == other.targetBitrate &&
+ minBitrate == other.minBitrate && qpMax == other.qpMax &&
+ active == other.active);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/spatial_layer.h b/third_party/libwebrtc/api/video_codecs/spatial_layer.h
new file mode 100644
index 0000000000..5a1b425427
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/spatial_layer.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_SPATIAL_LAYER_H_
+#define API_VIDEO_CODECS_SPATIAL_LAYER_H_
+
+namespace webrtc {
+
+struct SpatialLayer {
+ bool operator==(const SpatialLayer& other) const;
+ bool operator!=(const SpatialLayer& other) const { return !(*this == other); }
+
+ unsigned short width; // NOLINT(runtime/int)
+ unsigned short height; // NOLINT(runtime/int)
+ float maxFramerate; // fps.
+ unsigned char numberOfTemporalLayers;
+ unsigned int maxBitrate; // kilobits/sec.
+ unsigned int targetBitrate; // kilobits/sec.
+ unsigned int minBitrate; // kilobits/sec.
+ unsigned int qpMax; // minimum quality
+ bool active; // encoded and sent.
+};
+
+} // namespace webrtc
+#endif // API_VIDEO_CODECS_SPATIAL_LAYER_H_
diff --git a/third_party/libwebrtc/api/video_codecs/test/BUILD.gn b/third_party/libwebrtc/api/video_codecs/test/BUILD.gn
new file mode 100644
index 0000000000..47d5ff9aa3
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/test/BUILD.gn
@@ -0,0 +1,81 @@
+# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+
+if (rtc_include_tests) {
+ rtc_library("video_codecs_api_unittests") {
+ testonly = true
+ sources = [
+ "builtin_video_encoder_factory_unittest.cc",
+ "h264_profile_level_id_unittest.cc",
+ "sdp_video_format_unittest.cc",
+ "video_decoder_software_fallback_wrapper_unittest.cc",
+ "video_encoder_software_fallback_wrapper_unittest.cc",
+ ]
+
+ deps = [
+ ":video_decoder_factory_template_tests",
+ ":video_encoder_factory_template_tests",
+ "..:builtin_video_encoder_factory",
+ "..:rtc_software_fallback_wrappers",
+ "..:video_codecs_api",
+ "../..:fec_controller_api",
+ "../..:mock_video_encoder",
+ "../../../api:scoped_refptr",
+ "../../../media:media_constants",
+ "../../../media:rtc_media_base",
+ "../../../modules/video_coding:video_codec_interface",
+ "../../../modules/video_coding:video_coding_utility",
+ "../../../modules/video_coding:webrtc_vp8",
+ "../../../rtc_base:checks",
+ "../../../rtc_base:rtc_base_tests_utils",
+ "../../../test:field_trial",
+ "../../../test:test_support",
+ "../../../test:video_test_common",
+ "../../video:encoded_image",
+ "../../video:video_bitrate_allocation",
+ "../../video:video_frame",
+ "../../video:video_rtp_headers",
+ "//testing/gtest",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+ }
+
+ rtc_library("video_encoder_factory_template_tests") {
+ testonly = true
+ sources = [ "video_encoder_factory_template_tests.cc" ]
+
+ deps = [
+ "..:video_encoder_factory_template",
+ "..:video_encoder_factory_template_libaom_av1_adapter",
+ "..:video_encoder_factory_template_libvpx_vp8_adapter",
+ "..:video_encoder_factory_template_libvpx_vp9_adapter",
+ "..:video_encoder_factory_template_open_h264_adapter",
+ "../../:mock_video_encoder",
+ "../../../test:test_support",
+ "//testing/gtest",
+ ]
+ }
+
+ rtc_library("video_decoder_factory_template_tests") {
+ testonly = true
+ sources = [ "video_decoder_factory_template_tests.cc" ]
+
+ deps = [
+ "..:video_decoder_factory_template",
+ "..:video_decoder_factory_template_dav1d_adapter",
+ "..:video_decoder_factory_template_libvpx_vp8_adapter",
+ "..:video_decoder_factory_template_libvpx_vp9_adapter",
+ "..:video_decoder_factory_template_open_h264_adapter",
+ "../../:mock_video_decoder",
+ "../../../test:test_support",
+ "//testing/gtest",
+ ]
+ }
+}
diff --git a/third_party/libwebrtc/api/video_codecs/test/builtin_video_encoder_factory_unittest.cc b/third_party/libwebrtc/api/video_codecs/test/builtin_video_encoder_factory_unittest.cc
new file mode 100644
index 0000000000..84fd594b4c
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/test/builtin_video_encoder_factory_unittest.cc
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/builtin_video_encoder_factory.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "api/video_codecs/sdp_video_format.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+TEST(BuiltinVideoEncoderFactoryTest, AnnouncesVp9AccordingToBuildFlags) {
+ std::unique_ptr<VideoEncoderFactory> factory =
+ CreateBuiltinVideoEncoderFactory();
+ bool claims_vp9_support = false;
+ for (const SdpVideoFormat& format : factory->GetSupportedFormats()) {
+ if (format.name == "VP9") {
+ claims_vp9_support = true;
+ break;
+ }
+ }
+#if defined(RTC_ENABLE_VP9)
+ EXPECT_TRUE(claims_vp9_support);
+#else
+ EXPECT_FALSE(claims_vp9_support);
+#endif // defined(RTC_ENABLE_VP9)
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/test/h264_profile_level_id_unittest.cc b/third_party/libwebrtc/api/video_codecs/test/h264_profile_level_id_unittest.cc
new file mode 100644
index 0000000000..47098d2682
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/test/h264_profile_level_id_unittest.cc
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/h264_profile_level_id.h"
+
+#include <map>
+#include <string>
+
+#include "absl/types/optional.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+TEST(H264ProfileLevelId, TestParsingInvalid) {
+ // Malformed strings.
+ EXPECT_FALSE(ParseH264ProfileLevelId(""));
+ EXPECT_FALSE(ParseH264ProfileLevelId(" 42e01f"));
+ EXPECT_FALSE(ParseH264ProfileLevelId("4242e01f"));
+ EXPECT_FALSE(ParseH264ProfileLevelId("e01f"));
+ EXPECT_FALSE(ParseH264ProfileLevelId("gggggg"));
+
+ // Invalid level.
+ EXPECT_FALSE(ParseH264ProfileLevelId("42e000"));
+ EXPECT_FALSE(ParseH264ProfileLevelId("42e00f"));
+ EXPECT_FALSE(ParseH264ProfileLevelId("42e0ff"));
+
+ // Invalid profile.
+ EXPECT_FALSE(ParseH264ProfileLevelId("42e11f"));
+ EXPECT_FALSE(ParseH264ProfileLevelId("58601f"));
+ EXPECT_FALSE(ParseH264ProfileLevelId("64e01f"));
+}
+
+TEST(H264ProfileLevelId, TestParsingLevel) {
+ EXPECT_EQ(H264Level::kLevel3_1, ParseH264ProfileLevelId("42e01f")->level);
+ EXPECT_EQ(H264Level::kLevel1_1, ParseH264ProfileLevelId("42e00b")->level);
+ EXPECT_EQ(H264Level::kLevel1_b, ParseH264ProfileLevelId("42f00b")->level);
+ EXPECT_EQ(H264Level::kLevel4_2, ParseH264ProfileLevelId("42C02A")->level);
+ EXPECT_EQ(H264Level::kLevel5_2, ParseH264ProfileLevelId("640c34")->level);
+}
+
+TEST(H264ProfileLevelId, TestParsingConstrainedBaseline) {
+ EXPECT_EQ(H264Profile::kProfileConstrainedBaseline,
+ ParseH264ProfileLevelId("42e01f")->profile);
+ EXPECT_EQ(H264Profile::kProfileConstrainedBaseline,
+ ParseH264ProfileLevelId("42C02A")->profile);
+ EXPECT_EQ(H264Profile::kProfileConstrainedBaseline,
+ ParseH264ProfileLevelId("4de01f")->profile);
+ EXPECT_EQ(H264Profile::kProfileConstrainedBaseline,
+ ParseH264ProfileLevelId("58f01f")->profile);
+}
+
+TEST(H264ProfileLevelId, TestParsingBaseline) {
+ EXPECT_EQ(H264Profile::kProfileBaseline,
+ ParseH264ProfileLevelId("42a01f")->profile);
+ EXPECT_EQ(H264Profile::kProfileBaseline,
+ ParseH264ProfileLevelId("58A01F")->profile);
+}
+
+TEST(H264ProfileLevelId, TestParsingMain) {
+ EXPECT_EQ(H264Profile::kProfileMain,
+ ParseH264ProfileLevelId("4D401f")->profile);
+}
+
+TEST(H264ProfileLevelId, TestParsingHigh) {
+ EXPECT_EQ(H264Profile::kProfileHigh,
+ ParseH264ProfileLevelId("64001f")->profile);
+}
+
+TEST(H264ProfileLevelId, TestParsingConstrainedHigh) {
+ EXPECT_EQ(H264Profile::kProfileConstrainedHigh,
+ ParseH264ProfileLevelId("640c1f")->profile);
+}
+
+TEST(H264ProfileLevelId, TestSupportedLevel) {
+ EXPECT_EQ(H264Level::kLevel2_1, *H264SupportedLevel(640 * 480, 25));
+ EXPECT_EQ(H264Level::kLevel3_1, *H264SupportedLevel(1280 * 720, 30));
+ EXPECT_EQ(H264Level::kLevel4_2, *H264SupportedLevel(1920 * 1280, 60));
+}
+
+// Test supported level below level 1 requirements.
+TEST(H264ProfileLevelId, TestSupportedLevelInvalid) {
+ EXPECT_FALSE(H264SupportedLevel(0, 0));
+ // All levels support fps > 5.
+ EXPECT_FALSE(H264SupportedLevel(1280 * 720, 5));
+ // All levels support frame sizes > 183 * 137.
+ EXPECT_FALSE(H264SupportedLevel(183 * 137, 30));
+}
+
+TEST(H264ProfileLevelId, TestToString) {
+ EXPECT_EQ("42e01f", *H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileConstrainedBaseline,
+ H264Level::kLevel3_1)));
+ EXPECT_EQ("42000a", *H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileBaseline, H264Level::kLevel1)));
+ EXPECT_EQ("4d001f", H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileMain, H264Level::kLevel3_1)));
+ EXPECT_EQ("640c2a",
+ *H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileConstrainedHigh, H264Level::kLevel4_2)));
+ EXPECT_EQ("64002a", *H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileHigh, H264Level::kLevel4_2)));
+}
+
+TEST(H264ProfileLevelId, TestToStringLevel1b) {
+ EXPECT_EQ("42f00b", *H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileConstrainedBaseline,
+ H264Level::kLevel1_b)));
+ EXPECT_EQ("42100b",
+ *H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileBaseline, H264Level::kLevel1_b)));
+ EXPECT_EQ("4d100b", *H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileMain, H264Level::kLevel1_b)));
+}
+
+TEST(H264ProfileLevelId, TestToStringRoundTrip) {
+ EXPECT_EQ("42e01f",
+ *H264ProfileLevelIdToString(*ParseH264ProfileLevelId("42e01f")));
+ EXPECT_EQ("42e01f",
+ *H264ProfileLevelIdToString(*ParseH264ProfileLevelId("42E01F")));
+ EXPECT_EQ("4d100b",
+ *H264ProfileLevelIdToString(*ParseH264ProfileLevelId("4d100b")));
+ EXPECT_EQ("4d100b",
+ *H264ProfileLevelIdToString(*ParseH264ProfileLevelId("4D100B")));
+ EXPECT_EQ("640c2a",
+ *H264ProfileLevelIdToString(*ParseH264ProfileLevelId("640c2a")));
+ EXPECT_EQ("640c2a",
+ *H264ProfileLevelIdToString(*ParseH264ProfileLevelId("640C2A")));
+}
+
+TEST(H264ProfileLevelId, TestToStringInvalid) {
+ EXPECT_FALSE(H264ProfileLevelIdToString(
+ H264ProfileLevelId(H264Profile::kProfileHigh, H264Level::kLevel1_b)));
+ EXPECT_FALSE(H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileConstrainedHigh, H264Level::kLevel1_b)));
+ EXPECT_FALSE(H264ProfileLevelIdToString(
+ H264ProfileLevelId(static_cast<H264Profile>(255), H264Level::kLevel3_1)));
+}
+
+TEST(H264ProfileLevelId, TestParseSdpProfileLevelIdEmpty) {
+ const absl::optional<H264ProfileLevelId> profile_level_id =
+ ParseSdpForH264ProfileLevelId(SdpVideoFormat::Parameters());
+ EXPECT_TRUE(profile_level_id);
+ EXPECT_EQ(H264Profile::kProfileConstrainedBaseline,
+ profile_level_id->profile);
+ EXPECT_EQ(H264Level::kLevel3_1, profile_level_id->level);
+}
+
+TEST(H264ProfileLevelId, TestParseSdpProfileLevelIdConstrainedHigh) {
+ SdpVideoFormat::Parameters params;
+ params["profile-level-id"] = "640c2a";
+ const absl::optional<H264ProfileLevelId> profile_level_id =
+ ParseSdpForH264ProfileLevelId(params);
+ EXPECT_TRUE(profile_level_id);
+ EXPECT_EQ(H264Profile::kProfileConstrainedHigh, profile_level_id->profile);
+ EXPECT_EQ(H264Level::kLevel4_2, profile_level_id->level);
+}
+
+TEST(H264ProfileLevelId, TestParseSdpProfileLevelIdInvalid) {
+ SdpVideoFormat::Parameters params;
+ params["profile-level-id"] = "foobar";
+ EXPECT_FALSE(ParseSdpForH264ProfileLevelId(params));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/test/sdp_video_format_unittest.cc b/third_party/libwebrtc/api/video_codecs/test/sdp_video_format_unittest.cc
new file mode 100644
index 0000000000..bb158aeb95
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/test/sdp_video_format_unittest.cc
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/sdp_video_format.h"
+
+#include <stdint.h>
+
+#include "media/base/media_constants.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+typedef SdpVideoFormat Sdp;
+typedef SdpVideoFormat::Parameters Params;
+
+TEST(SdpVideoFormatTest, SameCodecNameNoParameters) {
+ EXPECT_TRUE(Sdp("H264").IsSameCodec(Sdp("h264")));
+ EXPECT_TRUE(Sdp("VP8").IsSameCodec(Sdp("vp8")));
+ EXPECT_TRUE(Sdp("VP9").IsSameCodec(Sdp("vp9")));
+ EXPECT_TRUE(Sdp("AV1").IsSameCodec(Sdp("Av1")));
+}
+
+TEST(SdpVideoFormatTest, DifferentCodecNameNoParameters) {
+ EXPECT_FALSE(Sdp("H264").IsSameCodec(Sdp("VP8")));
+ EXPECT_FALSE(Sdp("VP8").IsSameCodec(Sdp("VP9")));
+ EXPECT_FALSE(Sdp("AV1").IsSameCodec(Sdp("VP8")));
+}
+
+TEST(SdpVideoFormatTest, SameCodecNameSameParameters) {
+ EXPECT_TRUE(Sdp("VP9").IsSameCodec(Sdp("VP9", Params{{"profile-id", "0"}})));
+ EXPECT_TRUE(Sdp("VP9", Params{{"profile-id", "0"}})
+ .IsSameCodec(Sdp("VP9", Params{{"profile-id", "0"}})));
+ EXPECT_TRUE(Sdp("VP9", Params{{"profile-id", "2"}})
+ .IsSameCodec(Sdp("VP9", Params{{"profile-id", "2"}})));
+ EXPECT_TRUE(
+ Sdp("H264", Params{{"profile-level-id", "42e01f"}})
+ .IsSameCodec(Sdp("H264", Params{{"profile-level-id", "42e01f"}})));
+ EXPECT_TRUE(
+ Sdp("H264", Params{{"profile-level-id", "640c34"}})
+ .IsSameCodec(Sdp("H264", Params{{"profile-level-id", "640c34"}})));
+ EXPECT_TRUE(Sdp("AV1").IsSameCodec(Sdp("AV1", Params{{"profile", "0"}})));
+ EXPECT_TRUE(Sdp("AV1", Params{{"profile", "0"}})
+ .IsSameCodec(Sdp("AV1", Params{{"profile", "0"}})));
+ EXPECT_TRUE(Sdp("AV1", Params{{"profile", "2"}})
+ .IsSameCodec(Sdp("AV1", Params{{"profile", "2"}})));
+}
+
+TEST(SdpVideoFormatTest, SameCodecNameDifferentParameters) {
+ EXPECT_FALSE(Sdp("VP9").IsSameCodec(Sdp("VP9", Params{{"profile-id", "2"}})));
+ EXPECT_FALSE(Sdp("VP9", Params{{"profile-id", "0"}})
+ .IsSameCodec(Sdp("VP9", Params{{"profile-id", "1"}})));
+ EXPECT_FALSE(Sdp("VP9", Params{{"profile-id", "2"}})
+ .IsSameCodec(Sdp("VP9", Params{{"profile-id", "0"}})));
+ EXPECT_FALSE(
+ Sdp("H264", Params{{"profile-level-id", "42e01f"}})
+ .IsSameCodec(Sdp("H264", Params{{"profile-level-id", "640c34"}})));
+ EXPECT_FALSE(
+ Sdp("H264", Params{{"profile-level-id", "640c34"}})
+ .IsSameCodec(Sdp("H264", Params{{"profile-level-id", "42f00b"}})));
+ EXPECT_FALSE(Sdp("AV1").IsSameCodec(Sdp("AV1", Params{{"profile", "1"}})));
+ EXPECT_FALSE(Sdp("AV1", Params{{"profile", "0"}})
+ .IsSameCodec(Sdp("AV1", Params{{"profile", "1"}})));
+ EXPECT_FALSE(Sdp("AV1", Params{{"profile", "1"}})
+ .IsSameCodec(Sdp("AV1", Params{{"profile", "2"}})));
+}
+
+TEST(SdpVideoFormatTest, DifferentCodecNameSameParameters) {
+ EXPECT_FALSE(Sdp("VP9", Params{{"profile-id", "0"}})
+ .IsSameCodec(Sdp("H264", Params{{"profile-id", "0"}})));
+ EXPECT_FALSE(Sdp("VP9", Params{{"profile-id", "2"}})
+ .IsSameCodec(Sdp("VP8", Params{{"profile-id", "2"}})));
+ EXPECT_FALSE(
+ Sdp("H264", Params{{"profile-level-id", "42e01f"}})
+ .IsSameCodec(Sdp("VP9", Params{{"profile-level-id", "42e01f"}})));
+ EXPECT_FALSE(
+ Sdp("H264", Params{{"profile-level-id", "640c34"}})
+ .IsSameCodec(Sdp("VP8", Params{{"profile-level-id", "640c34"}})));
+ EXPECT_FALSE(Sdp("AV1", Params{{"profile", "0"}})
+ .IsSameCodec(Sdp("H264", Params{{"profile", "0"}})));
+ EXPECT_FALSE(Sdp("AV1", Params{{"profile", "2"}})
+ .IsSameCodec(Sdp("VP9", Params{{"profile", "2"}})));
+}
+
+TEST(SdpVideoFormatTest, H264PacketizationMode) {
+ // The default packetization mode is 0.
+ EXPECT_TRUE(Sdp("H264", Params{{cricket::kH264FmtpPacketizationMode, "0"}})
+ .IsSameCodec(Sdp("H264")));
+ EXPECT_FALSE(Sdp("H264", Params{{cricket::kH264FmtpPacketizationMode, "1"}})
+ .IsSameCodec(Sdp("H264")));
+
+ EXPECT_TRUE(
+ Sdp("H264", Params{{cricket::kH264FmtpPacketizationMode, "1"}})
+ .IsSameCodec(
+ Sdp("H264", Params{{cricket::kH264FmtpPacketizationMode, "1"}})));
+}
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/test/video_decoder_factory_template_tests.cc b/third_party/libwebrtc/api/video_codecs/test/video_decoder_factory_template_tests.cc
new file mode 100644
index 0000000000..e9d7052501
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/test/video_decoder_factory_template_tests.cc
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/mock_video_decoder.h"
+#include "api/video_codecs/video_decoder_factory_template.h"
+#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h"
+#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h"
+#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h"
+#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+using ::testing::Contains;
+using ::testing::Each;
+using ::testing::Eq;
+using ::testing::Field;
+using ::testing::IsEmpty;
+using ::testing::Ne;
+using ::testing::Not;
+using ::testing::UnorderedElementsAre;
+
+namespace webrtc {
+namespace {
+const SdpVideoFormat kFooSdp("Foo");
+const SdpVideoFormat kBarLowSdp("Bar", {{"profile", "low"}});
+const SdpVideoFormat kBarHighSdp("Bar", {{"profile", "high"}});
+
+struct FooDecoderTemplateAdapter {
+ static std::vector<SdpVideoFormat> SupportedFormats() { return {kFooSdp}; }
+
+ static std::unique_ptr<VideoDecoder> CreateDecoder(
+ const SdpVideoFormat& format) {
+ auto decoder = std::make_unique<testing::StrictMock<MockVideoDecoder>>();
+ EXPECT_CALL(*decoder, Destruct);
+ return decoder;
+ }
+};
+
+struct BarDecoderTemplateAdapter {
+ static std::vector<SdpVideoFormat> SupportedFormats() {
+ return {kBarLowSdp, kBarHighSdp};
+ }
+
+ static std::unique_ptr<VideoDecoder> CreateDecoder(
+ const SdpVideoFormat& format) {
+ auto decoder = std::make_unique<testing::StrictMock<MockVideoDecoder>>();
+ EXPECT_CALL(*decoder, Destruct);
+ return decoder;
+ }
+};
+
+TEST(VideoDecoderFactoryTemplate, OneTemplateAdapterCreateDecoder) {
+ VideoDecoderFactoryTemplate<FooDecoderTemplateAdapter> factory;
+ EXPECT_THAT(factory.GetSupportedFormats(), UnorderedElementsAre(kFooSdp));
+ EXPECT_THAT(factory.CreateVideoDecoder(kFooSdp), Ne(nullptr));
+ EXPECT_THAT(factory.CreateVideoDecoder(SdpVideoFormat("FooX")), Eq(nullptr));
+}
+
+TEST(VideoDecoderFactoryTemplate, TwoTemplateAdaptersNoDuplicates) {
+ VideoDecoderFactoryTemplate<FooDecoderTemplateAdapter,
+ FooDecoderTemplateAdapter>
+ factory;
+ EXPECT_THAT(factory.GetSupportedFormats(), UnorderedElementsAre(kFooSdp));
+}
+
+TEST(VideoDecoderFactoryTemplate, TwoTemplateAdaptersCreateDecoders) {
+ VideoDecoderFactoryTemplate<FooDecoderTemplateAdapter,
+ BarDecoderTemplateAdapter>
+ factory;
+ EXPECT_THAT(factory.GetSupportedFormats(),
+ UnorderedElementsAre(kFooSdp, kBarLowSdp, kBarHighSdp));
+ EXPECT_THAT(factory.CreateVideoDecoder(kFooSdp), Ne(nullptr));
+ EXPECT_THAT(factory.CreateVideoDecoder(kBarLowSdp), Ne(nullptr));
+ EXPECT_THAT(factory.CreateVideoDecoder(kBarHighSdp), Ne(nullptr));
+ EXPECT_THAT(factory.CreateVideoDecoder(SdpVideoFormat("FooX")), Eq(nullptr));
+ EXPECT_THAT(factory.CreateVideoDecoder(SdpVideoFormat("Bar")), Eq(nullptr));
+}
+
+TEST(VideoDecoderFactoryTemplate, LibvpxVp8) {
+ VideoDecoderFactoryTemplate<LibvpxVp8DecoderTemplateAdapter> factory;
+ auto formats = factory.GetSupportedFormats();
+ EXPECT_THAT(formats.size(), 1);
+ EXPECT_THAT(formats[0], Field(&SdpVideoFormat::name, "VP8"));
+ EXPECT_THAT(factory.CreateVideoDecoder(formats[0]), Ne(nullptr));
+}
+
+TEST(VideoDecoderFactoryTemplate, LibvpxVp9) {
+ VideoDecoderFactoryTemplate<LibvpxVp9DecoderTemplateAdapter> factory;
+ auto formats = factory.GetSupportedFormats();
+ EXPECT_THAT(formats, Not(IsEmpty()));
+ EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::name, "VP9")));
+ EXPECT_THAT(factory.CreateVideoDecoder(formats[0]), Ne(nullptr));
+}
+
+// TODO(bugs.webrtc.org/13573): When OpenH264 is no longer a conditional build
+// target remove this #ifdef.
+#if defined(WEBRTC_USE_H264)
+TEST(VideoDecoderFactoryTemplate, OpenH264) {
+ VideoDecoderFactoryTemplate<OpenH264DecoderTemplateAdapter> factory;
+ auto formats = factory.GetSupportedFormats();
+ EXPECT_THAT(formats, Not(IsEmpty()));
+ EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::name, "H264")));
+ EXPECT_THAT(factory.CreateVideoDecoder(formats[0]), Ne(nullptr));
+}
+#endif // defined(WEBRTC_USE_H264)
+
+TEST(VideoDecoderFactoryTemplate, Dav1d) {
+ VideoDecoderFactoryTemplate<Dav1dDecoderTemplateAdapter> factory;
+ auto formats = factory.GetSupportedFormats();
+ EXPECT_THAT(formats.size(), 1);
+ EXPECT_THAT(formats[0], Field(&SdpVideoFormat::name, "AV1"));
+ EXPECT_THAT(factory.CreateVideoDecoder(formats[0]), Ne(nullptr));
+}
+
+} // namespace
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc b/third_party/libwebrtc/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc
new file mode 100644
index 0000000000..73dedc8395
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/video_decoder_software_fallback_wrapper.h"
+
+#include <stdint.h>
+
+#include "absl/types/optional.h"
+#include "api/video/encoded_image.h"
+#include "api/video/video_frame.h"
+#include "api/video_codecs/video_decoder.h"
+#include "modules/video_coding/codecs/vp8/include/vp8.h"
+#include "modules/video_coding/include/video_codec_interface.h"
+#include "modules/video_coding/include/video_error_codes.h"
+#include "rtc_base/checks.h"
+#include "test/field_trial.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+class VideoDecoderSoftwareFallbackWrapperTest : public ::testing::Test {
+ protected:
+ VideoDecoderSoftwareFallbackWrapperTest()
+ : VideoDecoderSoftwareFallbackWrapperTest("") {}
+ explicit VideoDecoderSoftwareFallbackWrapperTest(
+ const std::string& field_trials)
+ : override_field_trials_(field_trials),
+ fake_decoder_(new CountingFakeDecoder()),
+ fallback_wrapper_(CreateVideoDecoderSoftwareFallbackWrapper(
+ std::unique_ptr<VideoDecoder>(VP8Decoder::Create()),
+ std::unique_ptr<VideoDecoder>(fake_decoder_))) {}
+
+ class CountingFakeDecoder : public VideoDecoder {
+ public:
+ bool Configure(const Settings& settings) override {
+ ++configure_count_;
+ return configure_return_value_;
+ }
+
+ int32_t Decode(const EncodedImage& input_image,
+ bool missing_frames,
+ int64_t render_time_ms) override {
+ ++decode_count_;
+ return decode_return_code_;
+ }
+
+ int32_t RegisterDecodeCompleteCallback(
+ DecodedImageCallback* callback) override {
+ decode_complete_callback_ = callback;
+ return WEBRTC_VIDEO_CODEC_OK;
+ }
+
+ int32_t Release() override {
+ ++release_count_;
+ return WEBRTC_VIDEO_CODEC_OK;
+ }
+
+ const char* ImplementationName() const override { return "fake-decoder"; }
+
+ int configure_count_ = 0;
+ int decode_count_ = 0;
+ bool configure_return_value_ = true;
+ int32_t decode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
+ DecodedImageCallback* decode_complete_callback_ = nullptr;
+ int release_count_ = 0;
+ int reset_count_ = 0;
+ };
+ test::ScopedFieldTrials override_field_trials_;
+ // `fake_decoder_` is owned and released by `fallback_wrapper_`.
+ CountingFakeDecoder* fake_decoder_;
+ std::unique_ptr<VideoDecoder> fallback_wrapper_;
+};
+
+TEST_F(VideoDecoderSoftwareFallbackWrapperTest, InitializesDecoder) {
+ fallback_wrapper_->Configure({});
+ EXPECT_EQ(1, fake_decoder_->configure_count_);
+
+ EncodedImage encoded_image;
+ encoded_image._frameType = VideoFrameType::kVideoFrameKey;
+ fallback_wrapper_->Decode(encoded_image, false, -1);
+ EXPECT_EQ(1, fake_decoder_->configure_count_)
+ << "Initialized decoder should not be reinitialized.";
+ EXPECT_EQ(1, fake_decoder_->decode_count_);
+}
+
+TEST_F(VideoDecoderSoftwareFallbackWrapperTest,
+ UsesFallbackDecoderAfterAnyInitDecodeFailure) {
+ fake_decoder_->configure_return_value_ = false;
+ fallback_wrapper_->Configure({});
+ EXPECT_EQ(1, fake_decoder_->configure_count_);
+
+ EncodedImage encoded_image;
+ encoded_image._frameType = VideoFrameType::kVideoFrameKey;
+ fallback_wrapper_->Decode(encoded_image, false, -1);
+ EXPECT_EQ(1, fake_decoder_->configure_count_)
+ << "Should not have attempted reinitializing the fallback decoder on "
+ "keyframe.";
+ // Unfortunately faking a VP8 frame is hard. Rely on no Decode -> using SW
+ // decoder.
+ EXPECT_EQ(0, fake_decoder_->decode_count_)
+ << "Decoder used even though no InitDecode had succeeded.";
+}
+
+TEST_F(VideoDecoderSoftwareFallbackWrapperTest, IsSoftwareFallbackSticky) {
+ fallback_wrapper_->Configure({});
+
+ fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
+ EncodedImage encoded_image;
+ fallback_wrapper_->Decode(encoded_image, false, -1);
+ EXPECT_EQ(1, fake_decoder_->decode_count_);
+
+ // Software fallback should be sticky, fake_decoder_ shouldn't be used.
+ encoded_image._frameType = VideoFrameType::kVideoFrameKey;
+ fallback_wrapper_->Decode(encoded_image, false, -1);
+ EXPECT_EQ(1, fake_decoder_->decode_count_)
+ << "Decoder shouldn't be used after failure.";
+
+ // fake_decoder_ should have only been initialized once during the test.
+ EXPECT_EQ(1, fake_decoder_->configure_count_);
+}
+
+TEST_F(VideoDecoderSoftwareFallbackWrapperTest, DoesNotFallbackOnEveryError) {
+ fallback_wrapper_->Configure({});
+ fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
+ EncodedImage encoded_image;
+ EXPECT_EQ(fake_decoder_->decode_return_code_,
+ fallback_wrapper_->Decode(encoded_image, false, -1));
+ EXPECT_EQ(1, fake_decoder_->decode_count_);
+
+ fallback_wrapper_->Decode(encoded_image, false, -1);
+ EXPECT_EQ(2, fake_decoder_->decode_count_)
+ << "Decoder should be active even though previous decode failed.";
+}
+
+TEST_F(VideoDecoderSoftwareFallbackWrapperTest, UsesHwDecoderAfterReinit) {
+ fallback_wrapper_->Configure({});
+
+ fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
+ EncodedImage encoded_image;
+ fallback_wrapper_->Decode(encoded_image, false, -1);
+ EXPECT_EQ(1, fake_decoder_->decode_count_);
+
+ fallback_wrapper_->Release();
+ fallback_wrapper_->Configure({});
+
+ fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
+ fallback_wrapper_->Decode(encoded_image, false, -1);
+ EXPECT_EQ(2, fake_decoder_->decode_count_)
+ << "Should not be using fallback after reinit.";
+}
+
+TEST_F(VideoDecoderSoftwareFallbackWrapperTest, ForwardsReleaseCall) {
+ fallback_wrapper_->Configure({});
+ fallback_wrapper_->Release();
+ EXPECT_EQ(1, fake_decoder_->release_count_);
+
+ fallback_wrapper_->Configure({});
+ fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
+ EncodedImage encoded_image;
+ fallback_wrapper_->Decode(encoded_image, false, -1);
+ EXPECT_EQ(2, fake_decoder_->release_count_)
+ << "Decoder should be released during fallback.";
+ fallback_wrapper_->Release();
+ EXPECT_EQ(2, fake_decoder_->release_count_);
+}
+
+// TODO(pbos): Fake a VP8 frame well enough to actually receive a callback from
+// the software decoder.
+TEST_F(VideoDecoderSoftwareFallbackWrapperTest,
+ ForwardsRegisterDecodeCompleteCallback) {
+ class FakeDecodedImageCallback : public DecodedImageCallback {
+ int32_t Decoded(VideoFrame& decodedImage) override { return 0; }
+ int32_t Decoded(webrtc::VideoFrame& decodedImage,
+ int64_t decode_time_ms) override {
+ RTC_DCHECK_NOTREACHED();
+ return -1;
+ }
+ void Decoded(webrtc::VideoFrame& decodedImage,
+ absl::optional<int32_t> decode_time_ms,
+ absl::optional<uint8_t> qp) override {
+ RTC_DCHECK_NOTREACHED();
+ }
+ } callback;
+
+ fallback_wrapper_->Configure({});
+ fallback_wrapper_->RegisterDecodeCompleteCallback(&callback);
+ EXPECT_EQ(&callback, fake_decoder_->decode_complete_callback_);
+}
+
+TEST_F(VideoDecoderSoftwareFallbackWrapperTest,
+ ReportsFallbackImplementationName) {
+ fallback_wrapper_->Configure({});
+
+ fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
+ EncodedImage encoded_image;
+ fallback_wrapper_->Decode(encoded_image, false, -1);
+ // Hard coded expected value since libvpx is the software implementation name
+ // for VP8. Change accordingly if the underlying implementation does.
+ EXPECT_STREQ("libvpx (fallback from: fake-decoder)",
+ fallback_wrapper_->ImplementationName());
+ fallback_wrapper_->Release();
+}
+
+TEST_F(VideoDecoderSoftwareFallbackWrapperTest, FallbacksOnTooManyErrors) {
+ fallback_wrapper_->Configure({});
+
+ fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
+ EncodedImage encoded_image;
+ encoded_image._frameType = VideoFrameType::kVideoFrameKey;
+ // Doesn't fallback from a single error.
+ fallback_wrapper_->Decode(encoded_image, false, -1);
+ EXPECT_STREQ("fake-decoder", fallback_wrapper_->ImplementationName());
+
+ // However, many frames with the same error, fallback should happen.
+ const int kNumFramesToEncode = 10;
+ for (int i = 0; i < kNumFramesToEncode; ++i) {
+ fallback_wrapper_->Decode(encoded_image, false, -1);
+ }
+ // Hard coded expected value since libvpx is the software implementation name
+ // for VP8. Change accordingly if the underlying implementation does.
+ EXPECT_STREQ("libvpx (fallback from: fake-decoder)",
+ fallback_wrapper_->ImplementationName());
+ fallback_wrapper_->Release();
+}
+
+TEST_F(VideoDecoderSoftwareFallbackWrapperTest,
+ DoesNotFallbackOnDeltaFramesErrors) {
+ fallback_wrapper_->Configure({});
+
+ fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
+ EncodedImage encoded_image;
+ encoded_image._frameType = VideoFrameType::kVideoFrameDelta;
+
+ // Many decoded frames with the same error
+ const int kNumFramesToEncode = 10;
+ for (int i = 0; i < kNumFramesToEncode; ++i) {
+ fallback_wrapper_->Decode(encoded_image, false, -1);
+ }
+ EXPECT_STREQ("fake-decoder", fallback_wrapper_->ImplementationName());
+
+ fallback_wrapper_->Release();
+}
+
+TEST_F(VideoDecoderSoftwareFallbackWrapperTest,
+ DoesNotFallbacksOnNonConsequtiveErrors) {
+ fallback_wrapper_->Configure({});
+
+ EncodedImage encoded_image;
+ encoded_image._frameType = VideoFrameType::kVideoFrameKey;
+
+ const int kNumFramesToEncode = 10;
+ for (int i = 0; i < kNumFramesToEncode; ++i) {
+ // Interleaved errors and successful decodes.
+ fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
+ fallback_wrapper_->Decode(encoded_image, false, -1);
+ fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
+ fallback_wrapper_->Decode(encoded_image, false, -1);
+ }
+ EXPECT_STREQ("fake-decoder", fallback_wrapper_->ImplementationName());
+ fallback_wrapper_->Release();
+}
+
+class ForcedSoftwareDecoderFallbackTest
+ : public VideoDecoderSoftwareFallbackWrapperTest {
+ public:
+ ForcedSoftwareDecoderFallbackTest()
+ : VideoDecoderSoftwareFallbackWrapperTest(
+ "WebRTC-Video-ForcedSwDecoderFallback/Enabled/") {
+ fake_decoder_ = new CountingFakeDecoder();
+ sw_fallback_decoder_ = new CountingFakeDecoder();
+ fallback_wrapper_ = CreateVideoDecoderSoftwareFallbackWrapper(
+ std::unique_ptr<VideoDecoder>(sw_fallback_decoder_),
+ std::unique_ptr<VideoDecoder>(fake_decoder_));
+ }
+
+ CountingFakeDecoder* sw_fallback_decoder_;
+};
+
+TEST_F(ForcedSoftwareDecoderFallbackTest, UsesForcedFallback) {
+ fallback_wrapper_->Configure({});
+ EXPECT_EQ(1, sw_fallback_decoder_->configure_count_);
+
+ EncodedImage encoded_image;
+ encoded_image._frameType = VideoFrameType::kVideoFrameKey;
+ fallback_wrapper_->Decode(encoded_image, false, -1);
+ EXPECT_EQ(1, sw_fallback_decoder_->configure_count_);
+ EXPECT_EQ(1, sw_fallback_decoder_->decode_count_);
+
+ fallback_wrapper_->Release();
+ EXPECT_EQ(1, sw_fallback_decoder_->release_count_);
+
+ // Only fallback decoder should have been used.
+ EXPECT_EQ(0, fake_decoder_->configure_count_);
+ EXPECT_EQ(0, fake_decoder_->decode_count_);
+ EXPECT_EQ(0, fake_decoder_->release_count_);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/test/video_encoder_factory_template_tests.cc b/third_party/libwebrtc/api/video_codecs/test/video_encoder_factory_template_tests.cc
new file mode 100644
index 0000000000..4c3d0cd24e
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/test/video_encoder_factory_template_tests.cc
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/test/mock_video_encoder.h"
+#include "api/video_codecs/video_encoder_factory_template.h"
+#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h"
+#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h"
+#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h"
+#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+using ::testing::Contains;
+using ::testing::Each;
+using ::testing::Eq;
+using ::testing::Field;
+using ::testing::IsEmpty;
+using ::testing::Ne;
+using ::testing::Not;
+using ::testing::UnorderedElementsAre;
+
+namespace webrtc {
+namespace {
+using CodecSupport = VideoEncoderFactory::CodecSupport;
+const SdpVideoFormat kFooSdp("Foo");
+const SdpVideoFormat kBarLowSdp("Bar", {{"profile", "low"}});
+const SdpVideoFormat kBarHighSdp("Bar", {{"profile", "high"}});
+
+struct FooEncoderTemplateAdapter {
+ static std::vector<SdpVideoFormat> SupportedFormats() { return {kFooSdp}; }
+
+ static std::unique_ptr<VideoEncoder> CreateEncoder(
+ const SdpVideoFormat& format) {
+ return std::make_unique<testing::StrictMock<MockVideoEncoder>>();
+ }
+
+ static bool IsScalabilityModeSupported(ScalabilityMode scalability_mode) {
+ return scalability_mode == ScalabilityMode::kL1T2 ||
+ scalability_mode == ScalabilityMode::kL1T3;
+ }
+};
+
+struct BarEncoderTemplateAdapter {
+ static std::vector<SdpVideoFormat> SupportedFormats() {
+ return {kBarLowSdp, kBarHighSdp};
+ }
+
+ static std::unique_ptr<VideoEncoder> CreateEncoder(
+ const SdpVideoFormat& format) {
+ return std::make_unique<testing::StrictMock<MockVideoEncoder>>();
+ }
+
+ static bool IsScalabilityModeSupported(ScalabilityMode scalability_mode) {
+ return scalability_mode == ScalabilityMode::kL1T2 ||
+ scalability_mode == ScalabilityMode::kL1T3 ||
+ scalability_mode == ScalabilityMode::kS2T1 ||
+ scalability_mode == ScalabilityMode::kS3T3;
+ }
+};
+
+TEST(VideoEncoderFactoryTemplate, OneTemplateAdapterCreateEncoder) {
+ VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter> factory;
+ EXPECT_THAT(factory.GetSupportedFormats(), UnorderedElementsAre(kFooSdp));
+ EXPECT_THAT(factory.CreateVideoEncoder(kFooSdp), Ne(nullptr));
+ EXPECT_THAT(factory.CreateVideoEncoder(SdpVideoFormat("FooX")), Eq(nullptr));
+}
+
+TEST(VideoEncoderFactoryTemplate, OneTemplateAdapterCodecSupport) {
+ VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter> factory;
+ EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, absl::nullopt),
+ Field(&CodecSupport::is_supported, true));
+ EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, "L1T2"),
+ Field(&CodecSupport::is_supported, true));
+ EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, "S3T3"),
+ Field(&CodecSupport::is_supported, false));
+ EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat("FooX"), absl::nullopt),
+ Field(&CodecSupport::is_supported, false));
+}
+
+TEST(VideoEncoderFactoryTemplate, TwoTemplateAdaptersNoDuplicates) {
+ VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter,
+ FooEncoderTemplateAdapter>
+ factory;
+ EXPECT_THAT(factory.GetSupportedFormats(), UnorderedElementsAre(kFooSdp));
+}
+
+TEST(VideoEncoderFactoryTemplate, TwoTemplateAdaptersCreateEncoders) {
+ VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter,
+ BarEncoderTemplateAdapter>
+ factory;
+ EXPECT_THAT(factory.GetSupportedFormats(),
+ UnorderedElementsAre(kFooSdp, kBarLowSdp, kBarHighSdp));
+ EXPECT_THAT(factory.CreateVideoEncoder(kFooSdp), Ne(nullptr));
+ EXPECT_THAT(factory.CreateVideoEncoder(kBarLowSdp), Ne(nullptr));
+ EXPECT_THAT(factory.CreateVideoEncoder(kBarHighSdp), Ne(nullptr));
+ EXPECT_THAT(factory.CreateVideoEncoder(SdpVideoFormat("FooX")), Eq(nullptr));
+ EXPECT_THAT(factory.CreateVideoEncoder(SdpVideoFormat("Bar")), Eq(nullptr));
+}
+
+TEST(VideoEncoderFactoryTemplate, TwoTemplateAdaptersCodecSupport) {
+ VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter,
+ BarEncoderTemplateAdapter>
+ factory;
+ EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, absl::nullopt),
+ Field(&CodecSupport::is_supported, true));
+ EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, "L1T2"),
+ Field(&CodecSupport::is_supported, true));
+ EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, "S3T3"),
+ Field(&CodecSupport::is_supported, false));
+ EXPECT_THAT(factory.QueryCodecSupport(kBarLowSdp, absl::nullopt),
+ Field(&CodecSupport::is_supported, true));
+ EXPECT_THAT(factory.QueryCodecSupport(kBarHighSdp, absl::nullopt),
+ Field(&CodecSupport::is_supported, true));
+ EXPECT_THAT(factory.QueryCodecSupport(kBarLowSdp, "S2T1"),
+ Field(&CodecSupport::is_supported, true));
+ EXPECT_THAT(factory.QueryCodecSupport(kBarHighSdp, "S3T2"),
+ Field(&CodecSupport::is_supported, false));
+}
+
+TEST(VideoEncoderFactoryTemplate, LibvpxVp8) {
+ VideoEncoderFactoryTemplate<LibvpxVp8EncoderTemplateAdapter> factory;
+ auto formats = factory.GetSupportedFormats();
+ EXPECT_THAT(formats.size(), 1);
+ EXPECT_THAT(formats[0], Field(&SdpVideoFormat::name, "VP8"));
+ EXPECT_THAT(formats[0], Field(&SdpVideoFormat::scalability_modes,
+ Contains(ScalabilityMode::kL1T3)));
+ EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), Ne(nullptr));
+}
+
+TEST(VideoEncoderFactoryTemplate, LibvpxVp9) {
+ VideoEncoderFactoryTemplate<LibvpxVp9EncoderTemplateAdapter> factory;
+ auto formats = factory.GetSupportedFormats();
+ EXPECT_THAT(formats, Not(IsEmpty()));
+ EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::name, "VP9")));
+ EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::scalability_modes,
+ Contains(ScalabilityMode::kL3T3_KEY))));
+ EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), Ne(nullptr));
+}
+
+// TODO(bugs.webrtc.org/13573): When OpenH264 is no longer a conditional build
+// target remove this #ifdef.
+#if defined(WEBRTC_USE_H264)
+TEST(VideoEncoderFactoryTemplate, OpenH264) {
+ VideoEncoderFactoryTemplate<OpenH264EncoderTemplateAdapter> factory;
+ auto formats = factory.GetSupportedFormats();
+ EXPECT_THAT(formats, Not(IsEmpty()));
+ EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::name, "H264")));
+ EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::scalability_modes,
+ Contains(ScalabilityMode::kL1T3))));
+ EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), Ne(nullptr));
+}
+#endif // defined(WEBRTC_USE_H264)
+
+TEST(VideoEncoderFactoryTemplate, LibaomAv1) {
+ VideoEncoderFactoryTemplate<LibaomAv1EncoderTemplateAdapter> factory;
+ auto formats = factory.GetSupportedFormats();
+ EXPECT_THAT(formats.size(), 1);
+ EXPECT_THAT(formats[0], Field(&SdpVideoFormat::name, "AV1"));
+ EXPECT_THAT(formats[0], Field(&SdpVideoFormat::scalability_modes,
+ Contains(ScalabilityMode::kL3T3_KEY)));
+ EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), Ne(nullptr));
+}
+
+} // namespace
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc b/third_party/libwebrtc/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc
new file mode 100644
index 0000000000..b213356e7b
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/test/video_encoder_software_fallback_wrapper_unittest.cc
@@ -0,0 +1,1055 @@
+/*
+ * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/video_encoder_software_fallback_wrapper.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/fec_controller_override.h"
+#include "api/scoped_refptr.h"
+#include "api/test/mock_video_encoder.h"
+#include "api/video/encoded_image.h"
+#include "api/video/i420_buffer.h"
+#include "api/video/video_bitrate_allocation.h"
+#include "api/video/video_frame.h"
+#include "api/video/video_frame_buffer.h"
+#include "api/video/video_rotation.h"
+#include "api/video_codecs/video_codec.h"
+#include "api/video_codecs/video_encoder.h"
+#include "modules/video_coding/codecs/vp8/include/vp8.h"
+#include "modules/video_coding/include/video_codec_interface.h"
+#include "modules/video_coding/include/video_error_codes.h"
+#include "modules/video_coding/utility/simulcast_rate_allocator.h"
+#include "rtc_base/fake_clock.h"
+#include "test/fake_texture_frame.h"
+#include "test/field_trial.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+using ::testing::_;
+using ::testing::Return;
+
+namespace {
+const int kWidth = 320;
+const int kHeight = 240;
+const int kNumCores = 2;
+const uint32_t kFramerate = 30;
+const size_t kMaxPayloadSize = 800;
+const int kLowThreshold = 10;
+const int kHighThreshold = 20;
+
+const VideoEncoder::Capabilities kCapabilities(false);
+const VideoEncoder::Settings kSettings(kCapabilities,
+ kNumCores,
+ kMaxPayloadSize);
+
+VideoEncoder::EncoderInfo GetEncoderInfoWithTrustedRateController(
+ bool trusted_rate_controller) {
+ VideoEncoder::EncoderInfo info;
+ info.has_trusted_rate_controller = trusted_rate_controller;
+ return info;
+}
+
+VideoEncoder::EncoderInfo GetEncoderInfoWithHardwareAccelerated(
+ bool hardware_accelerated) {
+ VideoEncoder::EncoderInfo info;
+ info.is_hardware_accelerated = hardware_accelerated;
+ return info;
+}
+
+class FakeEncodedImageCallback : public EncodedImageCallback {
+ public:
+ Result OnEncodedImage(const EncodedImage& encoded_image,
+ const CodecSpecificInfo* codec_specific_info) override {
+ ++callback_count_;
+ return Result(Result::OK, callback_count_);
+ }
+ int callback_count_ = 0;
+};
+} // namespace
+
+class VideoEncoderSoftwareFallbackWrapperTestBase : public ::testing::Test {
+ protected:
+ VideoEncoderSoftwareFallbackWrapperTestBase(
+ const std::string& field_trials,
+ std::unique_ptr<VideoEncoder> sw_encoder)
+ : override_field_trials_(field_trials),
+ fake_encoder_(new CountingFakeEncoder()),
+ wrapper_initialized_(false),
+ fallback_wrapper_(CreateVideoEncoderSoftwareFallbackWrapper(
+ std::move(sw_encoder),
+ std::unique_ptr<VideoEncoder>(fake_encoder_),
+ false)) {}
+
+ class CountingFakeEncoder : public VideoEncoder {
+ public:
+ void SetFecControllerOverride(
+ FecControllerOverride* fec_controller_override) override {
+ // Ignored.
+ }
+
+ int32_t InitEncode(const VideoCodec* codec_settings,
+ const VideoEncoder::Settings& settings) override {
+ ++init_encode_count_;
+ return init_encode_return_code_;
+ }
+
+ int32_t Encode(const VideoFrame& frame,
+ const std::vector<VideoFrameType>* frame_types) override {
+ ++encode_count_;
+ last_video_frame_ = frame;
+ if (encode_complete_callback_ &&
+ encode_return_code_ == WEBRTC_VIDEO_CODEC_OK) {
+ encode_complete_callback_->OnEncodedImage(EncodedImage(), nullptr);
+ }
+ return encode_return_code_;
+ }
+
+ int32_t RegisterEncodeCompleteCallback(
+ EncodedImageCallback* callback) override {
+ encode_complete_callback_ = callback;
+ return WEBRTC_VIDEO_CODEC_OK;
+ }
+
+ int32_t Release() override {
+ ++release_count_;
+ return WEBRTC_VIDEO_CODEC_OK;
+ }
+
+ void SetRates(const RateControlParameters& parameters) override {}
+
+ EncoderInfo GetEncoderInfo() const override {
+ ++supports_native_handle_count_;
+ EncoderInfo info;
+ info.scaling_settings = ScalingSettings(kLowThreshold, kHighThreshold);
+ info.supports_native_handle = supports_native_handle_;
+ info.implementation_name = implementation_name_;
+ if (is_qp_trusted_)
+ info.is_qp_trusted = is_qp_trusted_;
+ return info;
+ }
+
+ int init_encode_count_ = 0;
+ int32_t init_encode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
+ int32_t encode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
+ int encode_count_ = 0;
+ EncodedImageCallback* encode_complete_callback_ = nullptr;
+ int release_count_ = 0;
+ mutable int supports_native_handle_count_ = 0;
+ bool supports_native_handle_ = false;
+ bool is_qp_trusted_ = false;
+ std::string implementation_name_ = "fake-encoder";
+ absl::optional<VideoFrame> last_video_frame_;
+ };
+
+ void InitEncode();
+ void UtilizeFallbackEncoder();
+ void FallbackFromEncodeRequest();
+ void EncodeFrame();
+ void EncodeFrame(int expected_ret);
+ void CheckLastEncoderName(const char* expected_name) {
+ EXPECT_EQ(expected_name,
+ fallback_wrapper_->GetEncoderInfo().implementation_name);
+ }
+
+ test::ScopedFieldTrials override_field_trials_;
+ FakeEncodedImageCallback callback_;
+ // `fake_encoder_` is owned and released by `fallback_wrapper_`.
+ CountingFakeEncoder* fake_encoder_;
+ CountingFakeEncoder* fake_sw_encoder_;
+ bool wrapper_initialized_;
+ std::unique_ptr<VideoEncoder> fallback_wrapper_;
+ VideoCodec codec_ = {};
+ std::unique_ptr<VideoFrame> frame_;
+ std::unique_ptr<SimulcastRateAllocator> rate_allocator_;
+};
+
+class VideoEncoderSoftwareFallbackWrapperTest
+ : public VideoEncoderSoftwareFallbackWrapperTestBase {
+ protected:
+ VideoEncoderSoftwareFallbackWrapperTest()
+ : VideoEncoderSoftwareFallbackWrapperTest(new CountingFakeEncoder()) {}
+ explicit VideoEncoderSoftwareFallbackWrapperTest(
+ CountingFakeEncoder* fake_sw_encoder)
+ : VideoEncoderSoftwareFallbackWrapperTestBase(
+ "",
+ std::unique_ptr<VideoEncoder>(fake_sw_encoder)),
+ fake_sw_encoder_(fake_sw_encoder) {
+ fake_sw_encoder_->implementation_name_ = "fake_sw_encoder";
+ }
+
+ CountingFakeEncoder* fake_sw_encoder_;
+};
+
+void VideoEncoderSoftwareFallbackWrapperTestBase::EncodeFrame() {
+ EncodeFrame(WEBRTC_VIDEO_CODEC_OK);
+}
+
+void VideoEncoderSoftwareFallbackWrapperTestBase::EncodeFrame(
+ int expected_ret) {
+ rtc::scoped_refptr<I420Buffer> buffer =
+ I420Buffer::Create(codec_.width, codec_.height);
+ I420Buffer::SetBlack(buffer.get());
+ std::vector<VideoFrameType> types(1, VideoFrameType::kVideoFrameKey);
+
+ frame_ =
+ std::make_unique<VideoFrame>(VideoFrame::Builder()
+ .set_video_frame_buffer(buffer)
+ .set_rotation(webrtc::kVideoRotation_0)
+ .set_timestamp_us(0)
+ .build());
+ EXPECT_EQ(expected_ret, fallback_wrapper_->Encode(*frame_, &types));
+}
+
+void VideoEncoderSoftwareFallbackWrapperTestBase::InitEncode() {
+ if (!wrapper_initialized_) {
+ fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
+ EXPECT_EQ(&callback_, fake_encoder_->encode_complete_callback_);
+ }
+
+ // Register fake encoder as main.
+ codec_.codecType = kVideoCodecVP8;
+ codec_.maxFramerate = kFramerate;
+ codec_.width = kWidth;
+ codec_.height = kHeight;
+ codec_.VP8()->numberOfTemporalLayers = 1;
+ rate_allocator_.reset(new SimulcastRateAllocator(codec_));
+
+ if (wrapper_initialized_) {
+ fallback_wrapper_->Release();
+ }
+
+ fake_encoder_->init_encode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ fallback_wrapper_->InitEncode(&codec_, kSettings));
+
+ if (!wrapper_initialized_) {
+ fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
+ rate_allocator_->Allocate(
+ VideoBitrateAllocationParameters(300000, kFramerate)),
+ kFramerate));
+ }
+ wrapper_initialized_ = true;
+}
+
+void VideoEncoderSoftwareFallbackWrapperTestBase::UtilizeFallbackEncoder() {
+ if (!wrapper_initialized_) {
+ fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
+ EXPECT_EQ(&callback_, fake_encoder_->encode_complete_callback_);
+ }
+
+ // Register with failing fake encoder. Should succeed with VP8 fallback.
+ codec_.codecType = kVideoCodecVP8;
+ codec_.maxFramerate = kFramerate;
+ codec_.width = kWidth;
+ codec_.height = kHeight;
+ codec_.VP8()->numberOfTemporalLayers = 1;
+ rate_allocator_.reset(new SimulcastRateAllocator(codec_));
+
+ if (wrapper_initialized_) {
+ fallback_wrapper_->Release();
+ }
+
+ fake_encoder_->init_encode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ fallback_wrapper_->InitEncode(&codec_, kSettings));
+ fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
+ rate_allocator_->Allocate(
+ VideoBitrateAllocationParameters(300000, kFramerate)),
+ kFramerate));
+
+ int callback_count = callback_.callback_count_;
+ int encode_count = fake_encoder_->encode_count_;
+ EncodeFrame();
+ EXPECT_EQ(encode_count, fake_encoder_->encode_count_);
+ EXPECT_EQ(callback_count + 1, callback_.callback_count_);
+}
+
+void VideoEncoderSoftwareFallbackWrapperTestBase::FallbackFromEncodeRequest() {
+ fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
+ codec_.codecType = kVideoCodecVP8;
+ codec_.maxFramerate = kFramerate;
+ codec_.width = kWidth;
+ codec_.height = kHeight;
+ codec_.VP8()->numberOfTemporalLayers = 1;
+ rate_allocator_.reset(new SimulcastRateAllocator(codec_));
+ if (wrapper_initialized_) {
+ fallback_wrapper_->Release();
+ }
+ fallback_wrapper_->InitEncode(&codec_, kSettings);
+ fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
+ rate_allocator_->Allocate(
+ VideoBitrateAllocationParameters(300000, kFramerate)),
+ kFramerate));
+ EXPECT_EQ(1, fake_encoder_->init_encode_count_);
+
+ // Have the non-fallback encoder request a software fallback.
+ fake_encoder_->encode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
+ int callback_count = callback_.callback_count_;
+ int encode_count = fake_encoder_->encode_count_;
+ EncodeFrame();
+ // Single encode request, which returned failure.
+ EXPECT_EQ(encode_count + 1, fake_encoder_->encode_count_);
+ EXPECT_EQ(callback_count + 1, callback_.callback_count_);
+}
+
+TEST_F(VideoEncoderSoftwareFallbackWrapperTest, InitializesEncoder) {
+ VideoCodec codec = {};
+ fallback_wrapper_->InitEncode(&codec, kSettings);
+ EXPECT_EQ(1, fake_encoder_->init_encode_count_);
+}
+
+TEST_F(VideoEncoderSoftwareFallbackWrapperTest, EncodeRequestsFallback) {
+ FallbackFromEncodeRequest();
+ // After fallback, further encodes shouldn't hit the fake encoder.
+ int encode_count = fake_encoder_->encode_count_;
+ EncodeFrame();
+ EXPECT_EQ(encode_count, fake_encoder_->encode_count_);
+}
+
+TEST_F(VideoEncoderSoftwareFallbackWrapperTest, CanUtilizeFallbackEncoder) {
+ UtilizeFallbackEncoder();
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
+}
+
+TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
+ InternalEncoderReleasedDuringFallback) {
+ EXPECT_EQ(0, fake_encoder_->init_encode_count_);
+ EXPECT_EQ(0, fake_encoder_->release_count_);
+
+ InitEncode();
+
+ EXPECT_EQ(1, fake_encoder_->init_encode_count_);
+ EXPECT_EQ(0, fake_encoder_->release_count_);
+
+ UtilizeFallbackEncoder();
+
+ // One successful InitEncode(), one failed.
+ EXPECT_EQ(2, fake_encoder_->init_encode_count_);
+ EXPECT_EQ(1, fake_encoder_->release_count_);
+
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
+
+ // No extra release when the fallback is released.
+ EXPECT_EQ(2, fake_encoder_->init_encode_count_);
+ EXPECT_EQ(1, fake_encoder_->release_count_);
+}
+
+TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
+ InternalEncoderNotEncodingDuringFallback) {
+ UtilizeFallbackEncoder();
+ int encode_count = fake_encoder_->encode_count_;
+ EncodeFrame();
+ EXPECT_EQ(encode_count, fake_encoder_->encode_count_);
+
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
+}
+
+TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
+ CanRegisterCallbackWhileUsingFallbackEncoder) {
+ InitEncode();
+ EXPECT_EQ(&callback_, fake_encoder_->encode_complete_callback_);
+
+ UtilizeFallbackEncoder();
+
+ // Registering an encode-complete callback will now pass to the fallback
+ // instead of the main encoder.
+ FakeEncodedImageCallback callback2;
+ fallback_wrapper_->RegisterEncodeCompleteCallback(&callback2);
+ EXPECT_EQ(&callback_, fake_encoder_->encode_complete_callback_);
+
+ // Encoding a frame using the fallback should arrive at the new callback.
+ std::vector<VideoFrameType> types(1, VideoFrameType::kVideoFrameKey);
+ frame_->set_timestamp(frame_->timestamp() + 1000);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Encode(*frame_, &types));
+ EXPECT_EQ(callback2.callback_count_, 1);
+
+ // Re-initialize to use the main encoder, the new callback should be in use.
+ InitEncode();
+ EXPECT_EQ(&callback2, fake_encoder_->encode_complete_callback_);
+
+ frame_->set_timestamp(frame_->timestamp() + 2000);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Encode(*frame_, &types));
+ EXPECT_EQ(callback2.callback_count_, 2);
+}
+
+TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
+ SupportsNativeHandleForwardedWithoutFallback) {
+ fallback_wrapper_->GetEncoderInfo();
+ EXPECT_EQ(1, fake_encoder_->supports_native_handle_count_);
+}
+
+TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
+ SupportsNativeHandleNotForwardedDuringFallback) {
+ // Fake encoder signals support for native handle, default (libvpx) does not.
+ fake_encoder_->supports_native_handle_ = true;
+ EXPECT_TRUE(fallback_wrapper_->GetEncoderInfo().supports_native_handle);
+ UtilizeFallbackEncoder();
+ EXPECT_FALSE(fallback_wrapper_->GetEncoderInfo().supports_native_handle);
+ // Both times, both encoders are queried.
+ EXPECT_EQ(2, fake_encoder_->supports_native_handle_count_);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
+}
+
+TEST_F(VideoEncoderSoftwareFallbackWrapperTest, ReportsImplementationName) {
+ codec_.width = kWidth;
+ codec_.height = kHeight;
+ fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
+ fallback_wrapper_->InitEncode(&codec_, kSettings);
+ EncodeFrame();
+ CheckLastEncoderName("fake-encoder");
+}
+
+TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
+ IsQpTrustedNotForwardedDuringFallback) {
+ // Fake encoder signals trusted QP, default (libvpx) does not.
+ fake_encoder_->is_qp_trusted_ = true;
+ EXPECT_TRUE(fake_encoder_->GetEncoderInfo().is_qp_trusted.value_or(false));
+ UtilizeFallbackEncoder();
+ EXPECT_FALSE(fallback_wrapper_->GetEncoderInfo().is_qp_trusted.has_value());
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
+}
+
+TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
+ ReportsFallbackImplementationName) {
+ UtilizeFallbackEncoder();
+ CheckLastEncoderName(fake_sw_encoder_->implementation_name_.c_str());
+}
+
+TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
+ OnEncodeFallbackNativeFrameScaledIfFallbackDoesNotSupportNativeFrames) {
+ fake_encoder_->supports_native_handle_ = true;
+ fake_sw_encoder_->supports_native_handle_ = false;
+ InitEncode();
+ int width = codec_.width * 2;
+ int height = codec_.height * 2;
+ VideoFrame native_frame = test::FakeNativeBuffer::CreateFrame(
+ width, height, 0, 0, VideoRotation::kVideoRotation_0);
+ std::vector<VideoFrameType> types(1, VideoFrameType::kVideoFrameKey);
+ fake_encoder_->encode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
+
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ fallback_wrapper_->Encode(native_frame, &types));
+ EXPECT_EQ(1, fake_sw_encoder_->encode_count_);
+ ASSERT_TRUE(fake_sw_encoder_->last_video_frame_.has_value());
+ EXPECT_NE(VideoFrameBuffer::Type::kNative,
+ fake_sw_encoder_->last_video_frame_->video_frame_buffer()->type());
+ EXPECT_EQ(codec_.width, fake_sw_encoder_->last_video_frame_->width());
+ EXPECT_EQ(codec_.height, fake_sw_encoder_->last_video_frame_->height());
+}
+
+TEST_F(VideoEncoderSoftwareFallbackWrapperTest,
+ OnEncodeFallbackNativeFrameForwardedToFallbackIfItSupportsNativeFrames) {
+ fake_encoder_->supports_native_handle_ = true;
+ fake_sw_encoder_->supports_native_handle_ = true;
+ InitEncode();
+ int width = codec_.width * 2;
+ int height = codec_.height * 2;
+ VideoFrame native_frame = test::FakeNativeBuffer::CreateFrame(
+ width, height, 0, 0, VideoRotation::kVideoRotation_0);
+ std::vector<VideoFrameType> types(1, VideoFrameType::kVideoFrameKey);
+ fake_encoder_->encode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
+
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ fallback_wrapper_->Encode(native_frame, &types));
+ EXPECT_EQ(1, fake_sw_encoder_->encode_count_);
+ ASSERT_TRUE(fake_sw_encoder_->last_video_frame_.has_value());
+ EXPECT_EQ(VideoFrameBuffer::Type::kNative,
+ fake_sw_encoder_->last_video_frame_->video_frame_buffer()->type());
+ EXPECT_EQ(native_frame.width(), fake_sw_encoder_->last_video_frame_->width());
+ EXPECT_EQ(native_frame.height(),
+ fake_sw_encoder_->last_video_frame_->height());
+}
+
+namespace {
+const int kBitrateKbps = 200;
+const int kMinPixelsPerFrame = 1;
+const char kFieldTrial[] = "WebRTC-VP8-Forced-Fallback-Encoder-v2";
+} // namespace
+
+class ForcedFallbackTest : public VideoEncoderSoftwareFallbackWrapperTestBase {
+ public:
+ explicit ForcedFallbackTest(const std::string& field_trials)
+ : VideoEncoderSoftwareFallbackWrapperTestBase(field_trials,
+ VP8Encoder::Create()) {}
+
+ ~ForcedFallbackTest() override {}
+
+ protected:
+ void SetUp() override {
+ clock_.SetTime(Timestamp::Micros(1234));
+ ConfigureVp8Codec();
+ }
+
+ void TearDown() override {
+ if (wrapper_initialized_) {
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, fallback_wrapper_->Release());
+ }
+ }
+
+ void ConfigureVp8Codec() {
+ codec_.codecType = kVideoCodecVP8;
+ codec_.maxFramerate = kFramerate;
+ codec_.width = kWidth;
+ codec_.height = kHeight;
+ codec_.VP8()->numberOfTemporalLayers = 1;
+ codec_.VP8()->automaticResizeOn = true;
+ codec_.SetFrameDropEnabled(true);
+ rate_allocator_.reset(new SimulcastRateAllocator(codec_));
+ }
+
+ void InitEncode(int width, int height) {
+ codec_.width = width;
+ codec_.height = height;
+ if (wrapper_initialized_) {
+ fallback_wrapper_->Release();
+ }
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ fallback_wrapper_->InitEncode(&codec_, kSettings));
+ fallback_wrapper_->RegisterEncodeCompleteCallback(&callback_);
+ wrapper_initialized_ = true;
+ SetRateAllocation(kBitrateKbps);
+ }
+
+ void SetRateAllocation(uint32_t bitrate_kbps) {
+ fallback_wrapper_->SetRates(VideoEncoder::RateControlParameters(
+ rate_allocator_->Allocate(
+ VideoBitrateAllocationParameters(bitrate_kbps * 1000, kFramerate)),
+ kFramerate));
+ }
+
+ void EncodeFrameAndVerifyLastName(const char* expected_name) {
+ EncodeFrameAndVerifyLastName(expected_name, WEBRTC_VIDEO_CODEC_OK);
+ }
+
+ void EncodeFrameAndVerifyLastName(const char* expected_name,
+ int expected_ret) {
+ EncodeFrame(expected_ret);
+ CheckLastEncoderName(expected_name);
+ }
+
+ rtc::ScopedFakeClock clock_;
+};
+
+class ForcedFallbackTestEnabled : public ForcedFallbackTest {
+ public:
+ ForcedFallbackTestEnabled()
+ : ForcedFallbackTest(std::string(kFieldTrial) + "/Enabled-" +
+ std::to_string(kMinPixelsPerFrame) + "," +
+ std::to_string(kWidth * kHeight) + ",30000/") {}
+};
+
+class ForcedFallbackTestDisabled : public ForcedFallbackTest {
+ public:
+ ForcedFallbackTestDisabled()
+ : ForcedFallbackTest(std::string(kFieldTrial) + "/Disabled/") {}
+};
+
+TEST_F(ForcedFallbackTestDisabled, NoFallbackWithoutFieldTrial) {
+ // Resolution above max threshold.
+ InitEncode(kWidth + 1, kHeight);
+ EXPECT_EQ(1, fake_encoder_->init_encode_count_);
+ EncodeFrameAndVerifyLastName("fake-encoder");
+
+ // Resolution at max threshold.
+ InitEncode(kWidth, kHeight);
+ EncodeFrameAndVerifyLastName("fake-encoder");
+}
+
+TEST_F(ForcedFallbackTestEnabled, FallbackIfAtMaxResolutionLimit) {
+ // Resolution above max threshold.
+ InitEncode(kWidth + 1, kHeight);
+ EXPECT_EQ(1, fake_encoder_->init_encode_count_);
+ EncodeFrameAndVerifyLastName("fake-encoder");
+
+ // Resolution at max threshold.
+ InitEncode(kWidth, kHeight);
+ EncodeFrameAndVerifyLastName("libvpx");
+}
+
+TEST_F(ForcedFallbackTestEnabled, FallbackIsKeptWhenInitEncodeIsCalled) {
+ // Resolution above max threshold.
+ InitEncode(kWidth + 1, kHeight);
+ EXPECT_EQ(1, fake_encoder_->init_encode_count_);
+ EncodeFrameAndVerifyLastName("fake-encoder");
+
+ // Resolution at max threshold.
+ InitEncode(kWidth, kHeight);
+ EncodeFrameAndVerifyLastName("libvpx");
+
+ // Re-initialize encoder, still expect fallback.
+ InitEncode(kWidth / 2, kHeight / 2);
+ EXPECT_EQ(1, fake_encoder_->init_encode_count_); // No change.
+ EncodeFrameAndVerifyLastName("libvpx");
+}
+
+TEST_F(ForcedFallbackTestEnabled, FallbackIsEndedWhenResolutionIsTooLarge) {
+ // Resolution above max threshold.
+ InitEncode(kWidth + 1, kHeight);
+ EXPECT_EQ(1, fake_encoder_->init_encode_count_);
+ EncodeFrameAndVerifyLastName("fake-encoder");
+
+ // Resolution at max threshold.
+ InitEncode(kWidth, kHeight);
+ EncodeFrameAndVerifyLastName("libvpx");
+
+ // Re-initialize encoder with a larger resolution, expect no fallback.
+ InitEncode(kWidth + 1, kHeight);
+ EXPECT_EQ(2, fake_encoder_->init_encode_count_);
+ EncodeFrameAndVerifyLastName("fake-encoder");
+}
+
+TEST_F(ForcedFallbackTestEnabled, FallbackIsEndedForNonValidSettings) {
+ // Resolution at max threshold.
+ InitEncode(kWidth, kHeight);
+ EncodeFrameAndVerifyLastName("libvpx");
+
+ // Re-initialize encoder with invalid setting, expect no fallback.
+ codec_.numberOfSimulcastStreams = 2;
+ InitEncode(kWidth, kHeight);
+ EXPECT_EQ(1, fake_encoder_->init_encode_count_);
+ EncodeFrameAndVerifyLastName("fake-encoder");
+
+ // Re-initialize encoder with valid setting.
+ codec_.numberOfSimulcastStreams = 1;
+ InitEncode(kWidth, kHeight);
+ EXPECT_EQ(1, fake_encoder_->init_encode_count_);
+ EncodeFrameAndVerifyLastName("libvpx");
+}
+
+TEST_F(ForcedFallbackTestEnabled, MultipleStartEndFallback) {
+ const int kNumRuns = 5;
+ for (int i = 1; i <= kNumRuns; ++i) {
+ // Resolution at max threshold.
+ InitEncode(kWidth, kHeight);
+ EncodeFrameAndVerifyLastName("libvpx");
+ // Resolution above max threshold.
+ InitEncode(kWidth + 1, kHeight);
+ EXPECT_EQ(i, fake_encoder_->init_encode_count_);
+ EncodeFrameAndVerifyLastName("fake-encoder");
+ }
+}
+
+TEST_F(ForcedFallbackTestDisabled, GetScaleSettings) {
+ // Resolution above max threshold.
+ InitEncode(kWidth + 1, kHeight);
+ EXPECT_EQ(1, fake_encoder_->init_encode_count_);
+ EncodeFrameAndVerifyLastName("fake-encoder");
+
+ // Default min pixels per frame should be used.
+ const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
+ EXPECT_TRUE(settings.thresholds.has_value());
+ EXPECT_EQ(kDefaultMinPixelsPerFrame, settings.min_pixels_per_frame);
+}
+
+TEST_F(ForcedFallbackTestEnabled, GetScaleSettingsWithNoFallback) {
+ // Resolution above max threshold.
+ InitEncode(kWidth + 1, kHeight);
+ EncodeFrameAndVerifyLastName("fake-encoder");
+
+ // Configured min pixels per frame should be used.
+ const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
+ EXPECT_EQ(kMinPixelsPerFrame, settings.min_pixels_per_frame);
+ ASSERT_TRUE(settings.thresholds);
+ EXPECT_EQ(kLowThreshold, settings.thresholds->low);
+ EXPECT_EQ(kHighThreshold, settings.thresholds->high);
+}
+
+TEST_F(ForcedFallbackTestEnabled, GetScaleSettingsWithFallback) {
+ // Resolution at max threshold.
+ InitEncode(kWidth, kHeight);
+ EncodeFrameAndVerifyLastName("libvpx");
+
+ // Configured min pixels per frame should be used.
+ const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
+ EXPECT_TRUE(settings.thresholds.has_value());
+ EXPECT_EQ(kMinPixelsPerFrame, settings.min_pixels_per_frame);
+}
+
+TEST_F(ForcedFallbackTestEnabled, ScalingDisabledIfResizeOff) {
+ // Resolution at max threshold.
+ codec_.VP8()->automaticResizeOn = false;
+ InitEncode(kWidth, kHeight);
+ EncodeFrameAndVerifyLastName("libvpx");
+
+ // Should be disabled for automatic resize off.
+ const auto settings = fallback_wrapper_->GetEncoderInfo().scaling_settings;
+ EXPECT_FALSE(settings.thresholds.has_value());
+}
+
+TEST(SoftwareFallbackEncoderTest, BothRateControllersNotTrusted) {
+ auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
+ auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
+
+ EXPECT_CALL(*sw_encoder, GetEncoderInfo())
+ .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(false)));
+ EXPECT_CALL(*hw_encoder, GetEncoderInfo())
+ .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(false)));
+
+ std::unique_ptr<VideoEncoder> wrapper =
+ CreateVideoEncoderSoftwareFallbackWrapper(
+ std::unique_ptr<VideoEncoder>(sw_encoder),
+ std::unique_ptr<VideoEncoder>(hw_encoder));
+ EXPECT_FALSE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
+}
+
+TEST(SoftwareFallbackEncoderTest, SwRateControllerTrusted) {
+ auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
+ auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
+ EXPECT_CALL(*sw_encoder, GetEncoderInfo())
+ .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(true)));
+ EXPECT_CALL(*hw_encoder, GetEncoderInfo())
+ .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(false)));
+
+ std::unique_ptr<VideoEncoder> wrapper =
+ CreateVideoEncoderSoftwareFallbackWrapper(
+ std::unique_ptr<VideoEncoder>(sw_encoder),
+ std::unique_ptr<VideoEncoder>(hw_encoder));
+ EXPECT_FALSE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
+}
+
+TEST(SoftwareFallbackEncoderTest, HwRateControllerTrusted) {
+ auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
+ auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
+ EXPECT_CALL(*sw_encoder, GetEncoderInfo())
+ .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(false)));
+ EXPECT_CALL(*hw_encoder, GetEncoderInfo())
+ .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(true)));
+
+ std::unique_ptr<VideoEncoder> wrapper =
+ CreateVideoEncoderSoftwareFallbackWrapper(
+ std::unique_ptr<VideoEncoder>(sw_encoder),
+ std::unique_ptr<VideoEncoder>(hw_encoder));
+ EXPECT_TRUE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
+
+ VideoCodec codec_ = {};
+ codec_.width = 100;
+ codec_.height = 100;
+ wrapper->InitEncode(&codec_, kSettings);
+
+ // Trigger fallback to software.
+ EXPECT_CALL(*hw_encoder, Encode)
+ .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
+ VideoFrame frame = VideoFrame::Builder()
+ .set_video_frame_buffer(I420Buffer::Create(100, 100))
+ .build();
+ wrapper->Encode(frame, nullptr);
+
+ EXPECT_FALSE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
+}
+
+TEST(SoftwareFallbackEncoderTest, BothRateControllersTrusted) {
+ auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
+ auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
+ EXPECT_CALL(*sw_encoder, GetEncoderInfo())
+ .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(true)));
+ EXPECT_CALL(*hw_encoder, GetEncoderInfo())
+ .WillRepeatedly(Return(GetEncoderInfoWithTrustedRateController(true)));
+
+ std::unique_ptr<VideoEncoder> wrapper =
+ CreateVideoEncoderSoftwareFallbackWrapper(
+ std::unique_ptr<VideoEncoder>(sw_encoder),
+ std::unique_ptr<VideoEncoder>(hw_encoder));
+ EXPECT_TRUE(wrapper->GetEncoderInfo().has_trusted_rate_controller);
+}
+
+TEST(SoftwareFallbackEncoderTest, ReportsHardwareAccelerated) {
+ auto* sw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
+ auto* hw_encoder = new ::testing::NiceMock<MockVideoEncoder>();
+ EXPECT_CALL(*sw_encoder, GetEncoderInfo())
+ .WillRepeatedly(Return(GetEncoderInfoWithHardwareAccelerated(false)));
+ EXPECT_CALL(*hw_encoder, GetEncoderInfo())
+ .WillRepeatedly(Return(GetEncoderInfoWithHardwareAccelerated(true)));
+
+ std::unique_ptr<VideoEncoder> wrapper =
+ CreateVideoEncoderSoftwareFallbackWrapper(
+ std::unique_ptr<VideoEncoder>(sw_encoder),
+ std::unique_ptr<VideoEncoder>(hw_encoder));
+ EXPECT_TRUE(wrapper->GetEncoderInfo().is_hardware_accelerated);
+
+ VideoCodec codec_ = {};
+ codec_.width = 100;
+ codec_.height = 100;
+ wrapper->InitEncode(&codec_, kSettings);
+
+ // Trigger fallback to software.
+ EXPECT_CALL(*hw_encoder, Encode)
+ .WillOnce(Return(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE));
+ VideoFrame frame = VideoFrame::Builder()
+ .set_video_frame_buffer(I420Buffer::Create(100, 100))
+ .build();
+ wrapper->Encode(frame, nullptr);
+ EXPECT_FALSE(wrapper->GetEncoderInfo().is_hardware_accelerated);
+}
+
+class PreferTemporalLayersFallbackTest : public ::testing::Test {
+ public:
+ PreferTemporalLayersFallbackTest() {}
+ void SetUp() override {
+ sw_ = new ::testing::NiceMock<MockVideoEncoder>();
+ sw_info_.implementation_name = "sw";
+ EXPECT_CALL(*sw_, GetEncoderInfo).WillRepeatedly([&]() {
+ return sw_info_;
+ });
+ EXPECT_CALL(*sw_, InitEncode(_, _, _))
+ .WillRepeatedly(Return(WEBRTC_VIDEO_CODEC_OK));
+
+ hw_ = new ::testing::NiceMock<MockVideoEncoder>();
+ hw_info_.implementation_name = "hw";
+ EXPECT_CALL(*hw_, GetEncoderInfo()).WillRepeatedly([&]() {
+ return hw_info_;
+ });
+ EXPECT_CALL(*hw_, InitEncode(_, _, _))
+ .WillRepeatedly(Return(WEBRTC_VIDEO_CODEC_OK));
+
+ wrapper_ = CreateVideoEncoderSoftwareFallbackWrapper(
+ std::unique_ptr<VideoEncoder>(sw_), std::unique_ptr<VideoEncoder>(hw_),
+ /*prefer_temporal_support=*/true);
+
+ codec_settings.codecType = kVideoCodecVP8;
+ codec_settings.maxFramerate = kFramerate;
+ codec_settings.width = kWidth;
+ codec_settings.height = kHeight;
+ codec_settings.numberOfSimulcastStreams = 1;
+ codec_settings.VP8()->numberOfTemporalLayers = 1;
+ }
+
+ protected:
+ void SetSupportsLayers(VideoEncoder::EncoderInfo* info, bool tl_enabled) {
+ int num_layers = 1;
+ if (tl_enabled) {
+ num_layers = codec_settings.VP8()->numberOfTemporalLayers;
+ }
+ SetNumLayers(info, num_layers);
+ }
+
+ void SetNumLayers(VideoEncoder::EncoderInfo* info, int num_layers) {
+ info->fps_allocation[0].clear();
+ for (int i = 0; i < num_layers; ++i) {
+ info->fps_allocation[0].push_back(
+ VideoEncoder::EncoderInfo::kMaxFramerateFraction >>
+ (num_layers - i - 1));
+ }
+ }
+
+ VideoCodec codec_settings;
+ ::testing::NiceMock<MockVideoEncoder>* sw_;
+ ::testing::NiceMock<MockVideoEncoder>* hw_;
+ VideoEncoder::EncoderInfo sw_info_;
+ VideoEncoder::EncoderInfo hw_info_;
+ std::unique_ptr<VideoEncoder> wrapper_;
+};
+
+TEST_F(PreferTemporalLayersFallbackTest, UsesMainWhenLayersNotUsed) {
+ codec_settings.VP8()->numberOfTemporalLayers = 1;
+ SetSupportsLayers(&hw_info_, true);
+ SetSupportsLayers(&sw_info_, true);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ wrapper_->InitEncode(&codec_settings, kSettings));
+ EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "hw");
+}
+
+TEST_F(PreferTemporalLayersFallbackTest, UsesMainWhenLayersSupported) {
+ codec_settings.VP8()->numberOfTemporalLayers = 2;
+ SetSupportsLayers(&hw_info_, true);
+ SetSupportsLayers(&sw_info_, true);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ wrapper_->InitEncode(&codec_settings, kSettings));
+ EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "hw");
+}
+
+TEST_F(PreferTemporalLayersFallbackTest,
+ UsesFallbackWhenLayersNotSupportedOnMain) {
+ codec_settings.VP8()->numberOfTemporalLayers = 2;
+ SetSupportsLayers(&hw_info_, false);
+ SetSupportsLayers(&sw_info_, true);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ wrapper_->InitEncode(&codec_settings, kSettings));
+ EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "sw");
+}
+
+TEST_F(PreferTemporalLayersFallbackTest, UsesMainWhenNeitherSupportsTemporal) {
+ codec_settings.VP8()->numberOfTemporalLayers = 2;
+ SetSupportsLayers(&hw_info_, false);
+ SetSupportsLayers(&sw_info_, false);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ wrapper_->InitEncode(&codec_settings, kSettings));
+ EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "hw");
+}
+
+TEST_F(PreferTemporalLayersFallbackTest, UsesFallbackWhenLayersAreUndefined) {
+ codec_settings.VP8()->numberOfTemporalLayers = 2;
+ SetNumLayers(&hw_info_, 1);
+ SetNumLayers(&sw_info_, 0);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ wrapper_->InitEncode(&codec_settings, kSettings));
+ EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "sw");
+}
+
+TEST_F(PreferTemporalLayersFallbackTest, PrimesEncoderOnSwitch) {
+ codec_settings.VP8()->numberOfTemporalLayers = 2;
+ // Both support temporal layers, will use main one.
+ SetSupportsLayers(&hw_info_, true);
+ SetSupportsLayers(&sw_info_, true);
+
+ // On first InitEncode most params have no state and will not be
+ // called to update.
+ EXPECT_CALL(*hw_, RegisterEncodeCompleteCallback).Times(0);
+ EXPECT_CALL(*sw_, RegisterEncodeCompleteCallback).Times(0);
+
+ EXPECT_CALL(*hw_, SetFecControllerOverride).Times(0);
+ EXPECT_CALL(*sw_, SetFecControllerOverride).Times(0);
+
+ EXPECT_CALL(*hw_, SetRates).Times(0);
+ EXPECT_CALL(*hw_, SetRates).Times(0);
+
+ EXPECT_CALL(*hw_, OnPacketLossRateUpdate).Times(0);
+ EXPECT_CALL(*sw_, OnPacketLossRateUpdate).Times(0);
+
+ EXPECT_CALL(*hw_, OnRttUpdate).Times(0);
+ EXPECT_CALL(*sw_, OnRttUpdate).Times(0);
+
+ EXPECT_CALL(*hw_, OnLossNotification).Times(0);
+ EXPECT_CALL(*sw_, OnLossNotification).Times(0);
+
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ wrapper_->InitEncode(&codec_settings, kSettings));
+ EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "hw");
+
+ FakeEncodedImageCallback callback1;
+ class DummyFecControllerOverride : public FecControllerOverride {
+ public:
+ void SetFecAllowed(bool fec_allowed) override {}
+ };
+ DummyFecControllerOverride fec_controller_override1;
+ VideoEncoder::RateControlParameters rate_params1;
+ float packet_loss1 = 0.1;
+ int64_t rtt1 = 1;
+ VideoEncoder::LossNotification lntf1;
+
+ EXPECT_CALL(*hw_, RegisterEncodeCompleteCallback(&callback1));
+ EXPECT_CALL(*sw_, RegisterEncodeCompleteCallback).Times(0);
+ wrapper_->RegisterEncodeCompleteCallback(&callback1);
+
+ EXPECT_CALL(*hw_, SetFecControllerOverride(&fec_controller_override1));
+ EXPECT_CALL(*sw_, SetFecControllerOverride).Times(1);
+ wrapper_->SetFecControllerOverride(&fec_controller_override1);
+
+ EXPECT_CALL(*hw_, SetRates(rate_params1));
+ EXPECT_CALL(*sw_, SetRates).Times(0);
+ wrapper_->SetRates(rate_params1);
+
+ EXPECT_CALL(*hw_, OnPacketLossRateUpdate(packet_loss1));
+ EXPECT_CALL(*sw_, OnPacketLossRateUpdate).Times(0);
+ wrapper_->OnPacketLossRateUpdate(packet_loss1);
+
+ EXPECT_CALL(*hw_, OnRttUpdate(rtt1));
+ EXPECT_CALL(*sw_, OnRttUpdate).Times(0);
+ wrapper_->OnRttUpdate(rtt1);
+
+ EXPECT_CALL(*hw_, OnLossNotification).Times(1);
+ EXPECT_CALL(*sw_, OnLossNotification).Times(0);
+ wrapper_->OnLossNotification(lntf1);
+
+ // Release and re-init, with fallback to software. This should trigger
+ // the software encoder to be primed with the current state.
+ wrapper_->Release();
+ EXPECT_CALL(*sw_, RegisterEncodeCompleteCallback(&callback1));
+ EXPECT_CALL(*hw_, RegisterEncodeCompleteCallback).Times(0);
+
+ EXPECT_CALL(*sw_, SetFecControllerOverride).Times(0);
+ EXPECT_CALL(*hw_, SetFecControllerOverride).Times(0);
+
+ // Rate control parameters are cleared on InitEncode.
+ EXPECT_CALL(*sw_, SetRates).Times(0);
+ EXPECT_CALL(*hw_, SetRates).Times(0);
+
+ EXPECT_CALL(*sw_, OnPacketLossRateUpdate(packet_loss1));
+ EXPECT_CALL(*hw_, OnPacketLossRateUpdate).Times(0);
+
+ EXPECT_CALL(*sw_, OnRttUpdate(rtt1));
+ EXPECT_CALL(*hw_, OnRttUpdate).Times(0);
+
+ EXPECT_CALL(*sw_, OnLossNotification).Times(1);
+ EXPECT_CALL(*hw_, OnLossNotification).Times(0);
+
+ SetSupportsLayers(&hw_info_, false);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ wrapper_->InitEncode(&codec_settings, kSettings));
+ EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "sw");
+
+ // Update with all-new params for the software encoder.
+ FakeEncodedImageCallback callback2;
+ DummyFecControllerOverride fec_controller_override2;
+ VideoEncoder::RateControlParameters rate_params2;
+ float packet_loss2 = 0.2;
+ int64_t rtt2 = 2;
+ VideoEncoder::LossNotification lntf2;
+
+ EXPECT_CALL(*sw_, RegisterEncodeCompleteCallback(&callback2));
+ EXPECT_CALL(*hw_, RegisterEncodeCompleteCallback).Times(0);
+ wrapper_->RegisterEncodeCompleteCallback(&callback2);
+
+ EXPECT_CALL(*sw_, SetFecControllerOverride(&fec_controller_override2));
+ EXPECT_CALL(*hw_, SetFecControllerOverride).Times(1);
+ wrapper_->SetFecControllerOverride(&fec_controller_override2);
+
+ EXPECT_CALL(*sw_, SetRates(rate_params2));
+ EXPECT_CALL(*hw_, SetRates).Times(0);
+ wrapper_->SetRates(rate_params2);
+
+ EXPECT_CALL(*sw_, OnPacketLossRateUpdate(packet_loss2));
+ EXPECT_CALL(*hw_, OnPacketLossRateUpdate).Times(0);
+ wrapper_->OnPacketLossRateUpdate(packet_loss2);
+
+ EXPECT_CALL(*sw_, OnRttUpdate(rtt2));
+ EXPECT_CALL(*hw_, OnRttUpdate).Times(0);
+ wrapper_->OnRttUpdate(rtt2);
+
+ EXPECT_CALL(*sw_, OnLossNotification).Times(1);
+ EXPECT_CALL(*hw_, OnLossNotification).Times(0);
+ wrapper_->OnLossNotification(lntf2);
+
+ // Release and re-init, back to main encoder. This should trigger
+ // the main encoder to be primed with the current state.
+ wrapper_->Release();
+ EXPECT_CALL(*hw_, RegisterEncodeCompleteCallback(&callback2));
+ EXPECT_CALL(*sw_, RegisterEncodeCompleteCallback).Times(0);
+
+ EXPECT_CALL(*hw_, SetFecControllerOverride).Times(0);
+ EXPECT_CALL(*sw_, SetFecControllerOverride).Times(0);
+
+ // Rate control parameters are cleared on InitEncode.
+ EXPECT_CALL(*sw_, SetRates).Times(0);
+ EXPECT_CALL(*hw_, SetRates).Times(0);
+
+ EXPECT_CALL(*hw_, OnPacketLossRateUpdate(packet_loss2));
+ EXPECT_CALL(*sw_, OnPacketLossRateUpdate).Times(0);
+
+ EXPECT_CALL(*hw_, OnRttUpdate(rtt2));
+ EXPECT_CALL(*sw_, OnRttUpdate).Times(0);
+
+ EXPECT_CALL(*hw_, OnLossNotification).Times(1);
+ EXPECT_CALL(*sw_, OnLossNotification).Times(0);
+
+ SetSupportsLayers(&hw_info_, true);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ wrapper_->InitEncode(&codec_settings, kSettings));
+ EXPECT_EQ(wrapper_->GetEncoderInfo().implementation_name, "hw");
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/video_codec.cc b/third_party/libwebrtc/api/video_codecs/video_codec.cc
new file mode 100644
index 0000000000..c6122d3f6a
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_codec.cc
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/video_codec.h"
+
+#include <string.h>
+
+#include <string>
+
+#include "absl/strings/match.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+namespace {
+constexpr char kPayloadNameVp8[] = "VP8";
+constexpr char kPayloadNameVp9[] = "VP9";
+constexpr char kPayloadNameAv1[] = "AV1";
+// TODO(bugs.webrtc.org/13166): Remove AV1X when backwards compatibility is not
+// needed.
+constexpr char kPayloadNameAv1x[] = "AV1X";
+constexpr char kPayloadNameH264[] = "H264";
+constexpr char kPayloadNameGeneric[] = "Generic";
+constexpr char kPayloadNameMultiplex[] = "Multiplex";
+} // namespace
+
+bool VideoCodecVP8::operator==(const VideoCodecVP8& other) const {
+ return (numberOfTemporalLayers == other.numberOfTemporalLayers &&
+ denoisingOn == other.denoisingOn &&
+ automaticResizeOn == other.automaticResizeOn &&
+ keyFrameInterval == other.keyFrameInterval);
+}
+
+bool VideoCodecVP9::operator==(const VideoCodecVP9& other) const {
+ return (numberOfTemporalLayers == other.numberOfTemporalLayers &&
+ denoisingOn == other.denoisingOn &&
+ keyFrameInterval == other.keyFrameInterval &&
+ adaptiveQpMode == other.adaptiveQpMode &&
+ automaticResizeOn == other.automaticResizeOn &&
+ numberOfSpatialLayers == other.numberOfSpatialLayers &&
+ flexibleMode == other.flexibleMode);
+}
+
+bool VideoCodecH264::operator==(const VideoCodecH264& other) const {
+ return (keyFrameInterval == other.keyFrameInterval &&
+ numberOfTemporalLayers == other.numberOfTemporalLayers);
+}
+
+VideoCodec::VideoCodec()
+ : codecType(kVideoCodecGeneric),
+ width(0),
+ height(0),
+ startBitrate(0),
+ maxBitrate(0),
+ minBitrate(0),
+ maxFramerate(0),
+ active(true),
+ qpMax(0),
+ numberOfSimulcastStreams(0),
+ simulcastStream(),
+ spatialLayers(),
+ mode(VideoCodecMode::kRealtimeVideo),
+ expect_encode_from_texture(false),
+ timing_frame_thresholds({0, 0}),
+ legacy_conference_mode(false),
+ codec_specific_(),
+ complexity_(VideoCodecComplexity::kComplexityNormal) {}
+
+VideoCodecVP8* VideoCodec::VP8() {
+ RTC_DCHECK_EQ(codecType, kVideoCodecVP8);
+ return &codec_specific_.VP8;
+}
+
+const VideoCodecVP8& VideoCodec::VP8() const {
+ RTC_DCHECK_EQ(codecType, kVideoCodecVP8);
+ return codec_specific_.VP8;
+}
+
+VideoCodecVP9* VideoCodec::VP9() {
+ RTC_DCHECK_EQ(codecType, kVideoCodecVP9);
+ return &codec_specific_.VP9;
+}
+
+const VideoCodecVP9& VideoCodec::VP9() const {
+ RTC_DCHECK_EQ(codecType, kVideoCodecVP9);
+ return codec_specific_.VP9;
+}
+
+VideoCodecH264* VideoCodec::H264() {
+ RTC_DCHECK_EQ(codecType, kVideoCodecH264);
+ return &codec_specific_.H264;
+}
+
+const VideoCodecH264& VideoCodec::H264() const {
+ RTC_DCHECK_EQ(codecType, kVideoCodecH264);
+ return codec_specific_.H264;
+}
+
+const char* CodecTypeToPayloadString(VideoCodecType type) {
+ switch (type) {
+ case kVideoCodecVP8:
+ return kPayloadNameVp8;
+ case kVideoCodecVP9:
+ return kPayloadNameVp9;
+ case kVideoCodecAV1:
+ return kPayloadNameAv1;
+ case kVideoCodecH264:
+ return kPayloadNameH264;
+ case kVideoCodecMultiplex:
+ return kPayloadNameMultiplex;
+ case kVideoCodecGeneric:
+ return kPayloadNameGeneric;
+ }
+ RTC_CHECK_NOTREACHED();
+}
+
+VideoCodecType PayloadStringToCodecType(const std::string& name) {
+ if (absl::EqualsIgnoreCase(name, kPayloadNameVp8))
+ return kVideoCodecVP8;
+ if (absl::EqualsIgnoreCase(name, kPayloadNameVp9))
+ return kVideoCodecVP9;
+ if (absl::EqualsIgnoreCase(name, kPayloadNameAv1) ||
+ absl::EqualsIgnoreCase(name, kPayloadNameAv1x))
+ return kVideoCodecAV1;
+ if (absl::EqualsIgnoreCase(name, kPayloadNameH264))
+ return kVideoCodecH264;
+ if (absl::EqualsIgnoreCase(name, kPayloadNameMultiplex))
+ return kVideoCodecMultiplex;
+ return kVideoCodecGeneric;
+}
+
+VideoCodecComplexity VideoCodec::GetVideoEncoderComplexity() const {
+ return complexity_;
+}
+
+void VideoCodec::SetVideoEncoderComplexity(
+ VideoCodecComplexity complexity_setting) {
+ complexity_ = complexity_setting;
+}
+
+bool VideoCodec::GetFrameDropEnabled() const {
+ return frame_drop_enabled_;
+}
+
+void VideoCodec::SetFrameDropEnabled(bool enabled) {
+ frame_drop_enabled_ = enabled;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/video_codec.h b/third_party/libwebrtc/api/video_codecs/video_codec.h
new file mode 100644
index 0000000000..10bceda0d2
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_codec.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VIDEO_CODEC_H_
+#define API_VIDEO_CODECS_VIDEO_CODEC_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "api/video/video_bitrate_allocation.h"
+#include "api/video/video_codec_type.h"
+#include "api/video_codecs/scalability_mode.h"
+#include "api/video_codecs/simulcast_stream.h"
+#include "api/video_codecs/spatial_layer.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// The VideoCodec class represents an old defacto-apis, which we're migrating
+// away from slowly.
+
+// Video codec
+enum class VideoCodecComplexity {
+ kComplexityLow = -1,
+ kComplexityNormal = 0,
+ kComplexityHigh = 1,
+ kComplexityHigher = 2,
+ kComplexityMax = 3
+};
+
+// VP8 specific
+struct VideoCodecVP8 {
+ bool operator==(const VideoCodecVP8& other) const;
+ bool operator!=(const VideoCodecVP8& other) const {
+ return !(*this == other);
+ }
+ // Temporary utility method for transition deleting numberOfTemporalLayers
+ // setting (replaced by ScalabilityMode).
+ void SetNumberOfTemporalLayers(unsigned char n) {
+ numberOfTemporalLayers = n;
+ }
+ unsigned char numberOfTemporalLayers;
+ bool denoisingOn;
+ bool automaticResizeOn;
+ int keyFrameInterval;
+};
+
+enum class InterLayerPredMode : int {
+ kOff = 0, // Inter-layer prediction is disabled.
+ kOn = 1, // Inter-layer prediction is enabled.
+ kOnKeyPic = 2 // Inter-layer prediction is enabled but limited to key frames.
+};
+
+// VP9 specific.
+struct VideoCodecVP9 {
+ bool operator==(const VideoCodecVP9& other) const;
+ bool operator!=(const VideoCodecVP9& other) const {
+ return !(*this == other);
+ }
+ // Temporary utility method for transition deleting numberOfTemporalLayers
+ // setting (replaced by ScalabilityMode).
+ void SetNumberOfTemporalLayers(unsigned char n) {
+ numberOfTemporalLayers = n;
+ }
+ unsigned char numberOfTemporalLayers;
+ bool denoisingOn;
+ int keyFrameInterval;
+ bool adaptiveQpMode;
+ bool automaticResizeOn;
+ unsigned char numberOfSpatialLayers;
+ bool flexibleMode;
+ InterLayerPredMode interLayerPred;
+};
+
+// H264 specific.
+struct VideoCodecH264 {
+ bool operator==(const VideoCodecH264& other) const;
+ bool operator!=(const VideoCodecH264& other) const {
+ return !(*this == other);
+ }
+ // Temporary utility method for transition deleting numberOfTemporalLayers
+ // setting (replaced by ScalabilityMode).
+ void SetNumberOfTemporalLayers(unsigned char n) {
+ numberOfTemporalLayers = n;
+ }
+ int keyFrameInterval;
+ uint8_t numberOfTemporalLayers;
+};
+
+// Translates from name of codec to codec type and vice versa.
+RTC_EXPORT const char* CodecTypeToPayloadString(VideoCodecType type);
+RTC_EXPORT VideoCodecType PayloadStringToCodecType(const std::string& name);
+
+union VideoCodecUnion {
+ VideoCodecVP8 VP8;
+ VideoCodecVP9 VP9;
+ VideoCodecH264 H264;
+};
+
+enum class VideoCodecMode { kRealtimeVideo, kScreensharing };
+
+// Common video codec properties
+class RTC_EXPORT VideoCodec {
+ public:
+ VideoCodec();
+
+ // Scalability mode as described in
+ // https://www.w3.org/TR/webrtc-svc/#scalabilitymodes*
+ absl::optional<ScalabilityMode> GetScalabilityMode() const {
+ return scalability_mode_;
+ }
+ void SetScalabilityMode(ScalabilityMode scalability_mode) {
+ scalability_mode_ = scalability_mode;
+ }
+ void UnsetScalabilityMode() { scalability_mode_ = absl::nullopt; }
+
+ VideoCodecComplexity GetVideoEncoderComplexity() const;
+ void SetVideoEncoderComplexity(VideoCodecComplexity complexity_setting);
+
+ bool GetFrameDropEnabled() const;
+ void SetFrameDropEnabled(bool enabled);
+
+ // Public variables. TODO(hta): Make them private with accessors.
+ VideoCodecType codecType;
+
+ // TODO(nisse): Change to int, for consistency.
+ uint16_t width;
+ uint16_t height;
+
+ unsigned int startBitrate; // kilobits/sec.
+ unsigned int maxBitrate; // kilobits/sec.
+ unsigned int minBitrate; // kilobits/sec.
+
+ uint32_t maxFramerate;
+
+ // This enables/disables encoding and sending when there aren't multiple
+ // simulcast streams,by allocating 0 bitrate if inactive.
+ bool active;
+
+ unsigned int qpMax;
+ unsigned char numberOfSimulcastStreams;
+ SimulcastStream simulcastStream[kMaxSimulcastStreams];
+ SpatialLayer spatialLayers[kMaxSpatialLayers];
+
+ VideoCodecMode mode;
+ bool expect_encode_from_texture;
+
+ // Timing frames configuration. There is delay of delay_ms between two
+ // consequent timing frames, excluding outliers. Frame is always made a
+ // timing frame if it's at least outlier_ratio in percent of "ideal" average
+ // frame given bitrate and framerate, i.e. if it's bigger than
+ // |outlier_ratio / 100.0 * bitrate_bps / fps| in bits. This way, timing
+ // frames will not be sent too often usually. Yet large frames will always
+ // have timing information for debug purposes because they are more likely to
+ // cause extra delays.
+ struct TimingFrameTriggerThresholds {
+ int64_t delay_ms;
+ uint16_t outlier_ratio_percent;
+ } timing_frame_thresholds;
+
+ // Legacy Google conference mode flag for simulcast screenshare
+ bool legacy_conference_mode;
+
+ bool operator==(const VideoCodec& other) const = delete;
+ bool operator!=(const VideoCodec& other) const = delete;
+
+ // Accessors for codec specific information.
+ // There is a const version of each that returns a reference,
+ // and a non-const version that returns a pointer, in order
+ // to allow modification of the parameters.
+ VideoCodecVP8* VP8();
+ const VideoCodecVP8& VP8() const;
+ VideoCodecVP9* VP9();
+ const VideoCodecVP9& VP9() const;
+ VideoCodecH264* H264();
+ const VideoCodecH264& H264() const;
+
+ private:
+ // TODO(hta): Consider replacing the union with a pointer type.
+ // This will allow removing the VideoCodec* types from this file.
+ VideoCodecUnion codec_specific_;
+ absl::optional<ScalabilityMode> scalability_mode_;
+ // 'complexity_' indicates the CPU capability of the client. It's used to
+ // determine encoder CPU complexity (e.g., cpu_used for VP8, VP9. and AV1).
+ VideoCodecComplexity complexity_;
+ bool frame_drop_enabled_ = false;
+};
+
+} // namespace webrtc
+#endif // API_VIDEO_CODECS_VIDEO_CODEC_H_
diff --git a/third_party/libwebrtc/api/video_codecs/video_codecs_api_gn/moz.build b/third_party/libwebrtc/api/video_codecs/video_codecs_api_gn/moz.build
new file mode 100644
index 0000000000..eccdc6cfc7
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_codecs_api_gn/moz.build
@@ -0,0 +1,235 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/video_codecs/av1_profile.cc",
+ "/third_party/libwebrtc/api/video_codecs/h264_profile_level_id.cc",
+ "/third_party/libwebrtc/api/video_codecs/sdp_video_format.cc",
+ "/third_party/libwebrtc/api/video_codecs/simulcast_stream.cc",
+ "/third_party/libwebrtc/api/video_codecs/spatial_layer.cc",
+ "/third_party/libwebrtc/api/video_codecs/video_codec.cc",
+ "/third_party/libwebrtc/api/video_codecs/video_decoder.cc",
+ "/third_party/libwebrtc/api/video_codecs/video_encoder.cc",
+ "/third_party/libwebrtc/api/video_codecs/vp8_frame_config.cc",
+ "/third_party/libwebrtc/api/video_codecs/vp8_temporal_layers.cc",
+ "/third_party/libwebrtc/api/video_codecs/vp9_profile.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("video_codecs_api_gn")
diff --git a/third_party/libwebrtc/api/video_codecs/video_decoder.cc b/third_party/libwebrtc/api/video_codecs/video_decoder.cc
new file mode 100644
index 0000000000..c8f40cee7f
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_decoder.cc
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/video_decoder.h"
+
+#include "absl/types/optional.h"
+#include "api/video/render_resolution.h"
+#include "api/video/video_codec_type.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/strings/string_builder.h"
+
+namespace webrtc {
+
+int32_t DecodedImageCallback::Decoded(VideoFrame& decodedImage,
+ int64_t decode_time_ms) {
+ // The default implementation ignores custom decode time value.
+ return Decoded(decodedImage);
+}
+
+void DecodedImageCallback::Decoded(VideoFrame& decodedImage,
+ absl::optional<int32_t> decode_time_ms,
+ absl::optional<uint8_t> qp) {
+ Decoded(decodedImage, decode_time_ms.value_or(-1));
+}
+
+VideoDecoder::DecoderInfo VideoDecoder::GetDecoderInfo() const {
+ DecoderInfo info;
+ info.implementation_name = ImplementationName();
+ return info;
+}
+
+const char* VideoDecoder::ImplementationName() const {
+ return "unknown";
+}
+
+std::string VideoDecoder::DecoderInfo::ToString() const {
+ char string_buf[2048];
+ rtc::SimpleStringBuilder oss(string_buf);
+
+ oss << "DecoderInfo { "
+ << "prefers_late_decoding = "
+ << "implementation_name = '" << implementation_name << "', "
+ << "is_hardware_accelerated = "
+ << (is_hardware_accelerated ? "true" : "false") << " }";
+ return oss.str();
+}
+
+bool VideoDecoder::DecoderInfo::operator==(const DecoderInfo& rhs) const {
+ return is_hardware_accelerated == rhs.is_hardware_accelerated &&
+ implementation_name == rhs.implementation_name;
+}
+
+void VideoDecoder::Settings::set_number_of_cores(int value) {
+ RTC_DCHECK_GT(value, 0);
+ number_of_cores_ = value;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/video_decoder.h b/third_party/libwebrtc/api/video_codecs/video_decoder.h
new file mode 100644
index 0000000000..aa7ee24307
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_decoder.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VIDEO_DECODER_H_
+#define API_VIDEO_CODECS_VIDEO_DECODER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/video/encoded_image.h"
+#include "api/video/render_resolution.h"
+#include "api/video/video_codec_type.h"
+#include "api/video/video_frame.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+class RTC_EXPORT DecodedImageCallback {
+ public:
+ virtual ~DecodedImageCallback() {}
+
+ virtual int32_t Decoded(VideoFrame& decodedImage) = 0;
+ // Provides an alternative interface that allows the decoder to specify the
+ // decode time excluding waiting time for any previous pending frame to
+ // return. This is necessary for breaking positive feedback in the delay
+ // estimation when the decoder has a single output buffer.
+ virtual int32_t Decoded(VideoFrame& decodedImage, int64_t decode_time_ms);
+
+ // TODO(sakal): Remove other implementations when upstream projects have been
+ // updated.
+ virtual void Decoded(VideoFrame& decodedImage,
+ absl::optional<int32_t> decode_time_ms,
+ absl::optional<uint8_t> qp);
+};
+
+class RTC_EXPORT VideoDecoder {
+ public:
+ struct DecoderInfo {
+ // Descriptive name of the decoder implementation.
+ std::string implementation_name;
+
+ // True if the decoder is backed by hardware acceleration.
+ bool is_hardware_accelerated = false;
+
+ std::string ToString() const;
+ bool operator==(const DecoderInfo& rhs) const;
+ bool operator!=(const DecoderInfo& rhs) const { return !(*this == rhs); }
+ };
+
+ class Settings {
+ public:
+ Settings() = default;
+ Settings(const Settings&) = default;
+ Settings& operator=(const Settings&) = default;
+ ~Settings() = default;
+
+ // The size of pool which is used to store video frame buffers inside
+ // decoder. If value isn't present some codec-default value will be used. If
+ // value is present and decoder doesn't have buffer pool the value will be
+ // ignored.
+ absl::optional<int> buffer_pool_size() const;
+ void set_buffer_pool_size(absl::optional<int> value);
+
+ // When valid, user of the VideoDecoder interface shouldn't `Decode`
+ // encoded images with render resolution larger than width and height
+ // specified here.
+ RenderResolution max_render_resolution() const;
+ void set_max_render_resolution(RenderResolution value);
+
+ // Maximum number of cpu cores the decoder is allowed to use in parallel.
+ // Must be positive.
+ int number_of_cores() const { return number_of_cores_; }
+ void set_number_of_cores(int value);
+
+ // Codec of encoded images user of the VideoDecoder interface will `Decode`.
+ VideoCodecType codec_type() const { return codec_type_; }
+ void set_codec_type(VideoCodecType value) { codec_type_ = value; }
+
+ private:
+ absl::optional<int> buffer_pool_size_;
+ RenderResolution max_resolution_;
+ int number_of_cores_ = 1;
+ VideoCodecType codec_type_ = kVideoCodecGeneric;
+ };
+
+ virtual ~VideoDecoder() = default;
+
+ // Prepares decoder to handle incoming encoded frames. Can be called multiple
+ // times, in such case only latest `settings` are in effect.
+ virtual bool Configure(const Settings& settings) = 0;
+
+ virtual int32_t Decode(const EncodedImage& input_image,
+ bool missing_frames,
+ int64_t render_time_ms) = 0;
+
+ virtual int32_t RegisterDecodeCompleteCallback(
+ DecodedImageCallback* callback) = 0;
+
+ virtual int32_t Release() = 0;
+
+ virtual DecoderInfo GetDecoderInfo() const;
+
+ // Deprecated, use GetDecoderInfo().implementation_name instead.
+ virtual const char* ImplementationName() const;
+};
+
+inline absl::optional<int> VideoDecoder::Settings::buffer_pool_size() const {
+ return buffer_pool_size_;
+}
+
+inline void VideoDecoder::Settings::set_buffer_pool_size(
+ absl::optional<int> value) {
+ buffer_pool_size_ = value;
+}
+
+inline RenderResolution VideoDecoder::Settings::max_render_resolution() const {
+ return max_resolution_;
+}
+
+inline void VideoDecoder::Settings::set_max_render_resolution(
+ RenderResolution value) {
+ max_resolution_ = value;
+}
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VIDEO_DECODER_H_
diff --git a/third_party/libwebrtc/api/video_codecs/video_decoder_factory.h b/third_party/libwebrtc/api/video_codecs/video_decoder_factory.h
new file mode 100644
index 0000000000..7e1d2ee883
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_decoder_factory.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_H_
+#define API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/video_codecs/sdp_video_format.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+class VideoDecoder;
+
+// A factory that creates VideoDecoders.
+// NOTE: This class is still under development and may change without notice.
+class RTC_EXPORT VideoDecoderFactory {
+ public:
+ struct CodecSupport {
+ bool is_supported = false;
+ bool is_power_efficient = false;
+ };
+
+ // Returns a list of supported video formats in order of preference, to use
+ // for signaling etc.
+ virtual std::vector<SdpVideoFormat> GetSupportedFormats() const = 0;
+
+ // Query whether the specifed format is supported or not and if it will be
+ // power efficient, which is currently interpreted as if there is support for
+ // hardware acceleration.
+ // The parameter `reference_scaling` is used to query support for prediction
+ // across spatial layers. An example where support for reference scaling is
+ // needed is if the video stream is produced with a scalability mode that has
+ // a dependency between the spatial layers. See
+ // https://w3c.github.io/webrtc-svc/#scalabilitymodes* for a specification of
+ // different scalabilty modes. NOTE: QueryCodecSupport is currently an
+ // experimental feature that is subject to change without notice.
+ virtual CodecSupport QueryCodecSupport(const SdpVideoFormat& format,
+ bool reference_scaling) const {
+ // Default implementation, query for supported formats and check if the
+ // specified format is supported. Returns false if `reference_scaling` is
+ // true.
+ CodecSupport codec_support;
+ codec_support.is_supported =
+ !reference_scaling && format.IsCodecInList(GetSupportedFormats());
+ return codec_support;
+ }
+
+ // Creates a VideoDecoder for the specified format.
+ virtual std::unique_ptr<VideoDecoder> CreateVideoDecoder(
+ const SdpVideoFormat& format) = 0;
+
+ virtual ~VideoDecoderFactory() {}
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_H_
diff --git a/third_party/libwebrtc/api/video_codecs/video_decoder_factory_template.h b/third_party/libwebrtc/api/video_codecs/video_decoder_factory_template.h
new file mode 100644
index 0000000000..703ae11664
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_decoder_factory_template.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_H_
+#define API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/algorithm/container.h"
+#include "api/array_view.h"
+#include "api/video_codecs/video_decoder.h"
+#include "api/video_codecs/video_decoder_factory.h"
+
+namespace webrtc {
+// The VideoDecoderFactoryTemplate supports decoder implementations given as
+// template arguments.
+//
+// To include a decoder in the factory it requires two static members
+// functions to be defined:
+//
+// // Returns the supported SdpVideoFormats this decoder can decode.
+// static std::vector<SdpVideoFormat> SupportedFormats();
+//
+// // Creates a decoder instance for the given format.
+// static std::unique_ptr<VideoDecoder>
+// CreateDecoder(const SdpVideoFormat& format);
+//
+// Note that the order of the template arguments matter as the factory will
+// return the first decoder implementation supporting the given SdpVideoFormat.
+template <typename... Ts>
+class VideoDecoderFactoryTemplate : public VideoDecoderFactory {
+ public:
+ std::vector<SdpVideoFormat> GetSupportedFormats() const override {
+ return GetSupportedFormatsInternal<Ts...>();
+ }
+
+ std::unique_ptr<VideoDecoder> CreateVideoDecoder(
+ const SdpVideoFormat& format) override {
+ return CreateVideoDecoderInternal<Ts...>(format);
+ }
+
+ private:
+ bool IsFormatInList(
+ const SdpVideoFormat& format,
+ rtc::ArrayView<const SdpVideoFormat> supported_formats) const {
+ return absl::c_any_of(
+ supported_formats, [&](const SdpVideoFormat& supported_format) {
+ return supported_format.name == format.name &&
+ supported_format.parameters == format.parameters;
+ });
+ }
+
+ template <typename V, typename... Vs>
+ std::vector<SdpVideoFormat> GetSupportedFormatsInternal() const {
+ auto supported_formats = V::SupportedFormats();
+
+ if constexpr (sizeof...(Vs) > 0) {
+ // Supported formats may overlap between implementations, so duplicates
+ // should be filtered out.
+ for (const auto& other_format : GetSupportedFormatsInternal<Vs...>()) {
+ if (!IsFormatInList(other_format, supported_formats)) {
+ supported_formats.push_back(other_format);
+ }
+ }
+ }
+
+ return supported_formats;
+ }
+
+ template <typename V, typename... Vs>
+ std::unique_ptr<VideoDecoder> CreateVideoDecoderInternal(
+ const SdpVideoFormat& format) {
+ if (IsFormatInList(format, V::SupportedFormats())) {
+ return V::CreateDecoder(format);
+ }
+
+ if constexpr (sizeof...(Vs) > 0) {
+ return CreateVideoDecoderInternal<Vs...>(format);
+ }
+
+ return nullptr;
+ }
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_H_
diff --git a/third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_dav1d_adapter.h b/third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_dav1d_adapter.h
new file mode 100644
index 0000000000..6d80cadf83
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_dav1d_adapter.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_DAV1D_ADAPTER_H_
+#define API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_DAV1D_ADAPTER_H_
+
+#include <memory>
+#include <vector>
+
+#include "api/video_codecs/sdp_video_format.h"
+#include "modules/video_coding/codecs/av1/dav1d_decoder.h"
+
+namespace webrtc {
+struct Dav1dDecoderTemplateAdapter {
+ static std::vector<SdpVideoFormat> SupportedFormats() {
+ return {SdpVideoFormat("AV1")};
+ }
+
+ static std::unique_ptr<VideoDecoder> CreateDecoder(
+ const SdpVideoFormat& format) {
+ return CreateDav1dDecoder();
+ }
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_DAV1D_ADAPTER_H_
diff --git a/third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h b/third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h
new file mode 100644
index 0000000000..0c45a4b622
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_LIBVPX_VP8_ADAPTER_H_
+#define API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_LIBVPX_VP8_ADAPTER_H_
+
+#include <memory>
+#include <vector>
+
+#include "api/video_codecs/sdp_video_format.h"
+#include "modules/video_coding/codecs/vp8/include/vp8.h"
+
+namespace webrtc {
+struct LibvpxVp8DecoderTemplateAdapter {
+ static std::vector<SdpVideoFormat> SupportedFormats() {
+ return {SdpVideoFormat("VP8")};
+ }
+
+ static std::unique_ptr<VideoDecoder> CreateDecoder(
+ const SdpVideoFormat& format) {
+ return VP8Decoder::Create();
+ }
+};
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_LIBVPX_VP8_ADAPTER_H_
diff --git a/third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h b/third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h
new file mode 100644
index 0000000000..e0ec0010be
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_LIBVPX_VP9_ADAPTER_H_
+#define API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_LIBVPX_VP9_ADAPTER_H_
+
+#include <memory>
+#include <vector>
+
+#include "modules/video_coding/codecs/vp9/include/vp9.h"
+
+namespace webrtc {
+struct LibvpxVp9DecoderTemplateAdapter {
+ static std::vector<SdpVideoFormat> SupportedFormats() {
+ return SupportedVP9DecoderCodecs();
+ }
+
+ static std::unique_ptr<VideoDecoder> CreateDecoder(
+ const SdpVideoFormat& format) {
+ return VP9Decoder::Create();
+ }
+};
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_LIBVPX_VP9_ADAPTER_H_
diff --git a/third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_open_h264_adapter.h b/third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_open_h264_adapter.h
new file mode 100644
index 0000000000..2746bde132
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_open_h264_adapter.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_OPEN_H264_ADAPTER_H_
+#define API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_OPEN_H264_ADAPTER_H_
+
+#include <memory>
+#include <vector>
+
+#include "modules/video_coding/codecs/h264/include/h264.h"
+
+namespace webrtc {
+// TODO(bugs.webrtc.org/13573): When OpenH264 is no longer a conditional build
+// target remove #ifdefs.
+struct OpenH264DecoderTemplateAdapter {
+ static std::vector<SdpVideoFormat> SupportedFormats() {
+#if defined(WEBRTC_USE_H264)
+
+ return SupportedH264DecoderCodecs();
+#else
+ return {};
+#endif
+ }
+
+ static std::unique_ptr<VideoDecoder> CreateDecoder(
+ const SdpVideoFormat& format) {
+#if defined(WEBRTC_USE_H264)
+
+ return H264Decoder::Create();
+#else
+ return nullptr;
+#endif
+ }
+};
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_OPEN_H264_ADAPTER_H_
diff --git a/third_party/libwebrtc/api/video_codecs/video_decoder_software_fallback_wrapper.cc b/third_party/libwebrtc/api/video_codecs/video_decoder_software_fallback_wrapper.cc
new file mode 100644
index 0000000000..cf6f823b92
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_decoder_software_fallback_wrapper.cc
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/video_decoder_software_fallback_wrapper.h"
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "api/video/encoded_image.h"
+#include "api/video_codecs/video_decoder.h"
+#include "modules/video_coding/include/video_error_codes.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/trace_event.h"
+#include "system_wrappers/include/field_trial.h"
+#include "system_wrappers/include/metrics.h"
+
+namespace webrtc {
+
+namespace {
+
+constexpr size_t kMaxConsequtiveHwErrors = 4;
+
+class VideoDecoderSoftwareFallbackWrapper final : public VideoDecoder {
+ public:
+ VideoDecoderSoftwareFallbackWrapper(
+ std::unique_ptr<VideoDecoder> sw_fallback_decoder,
+ std::unique_ptr<VideoDecoder> hw_decoder);
+ ~VideoDecoderSoftwareFallbackWrapper() override;
+
+ bool Configure(const Settings& settings) override;
+
+ int32_t Decode(const EncodedImage& input_image,
+ bool missing_frames,
+ int64_t render_time_ms) override;
+
+ int32_t RegisterDecodeCompleteCallback(
+ DecodedImageCallback* callback) override;
+
+ int32_t Release() override;
+
+ DecoderInfo GetDecoderInfo() const override;
+ const char* ImplementationName() const override;
+
+ private:
+ bool InitFallbackDecoder();
+ void UpdateFallbackDecoderHistograms();
+
+ bool InitHwDecoder();
+
+ VideoDecoder& active_decoder() const;
+
+ // Determines if we are trying to use the HW or SW decoder.
+ enum class DecoderType {
+ kNone,
+ kHardware,
+ kFallback,
+ } decoder_type_;
+ std::unique_ptr<VideoDecoder> hw_decoder_;
+
+ Settings decoder_settings_;
+ const std::unique_ptr<VideoDecoder> fallback_decoder_;
+ const std::string fallback_implementation_name_;
+ DecodedImageCallback* callback_;
+ int32_t hw_decoded_frames_since_last_fallback_;
+ size_t hw_consequtive_generic_errors_;
+};
+
+VideoDecoderSoftwareFallbackWrapper::VideoDecoderSoftwareFallbackWrapper(
+ std::unique_ptr<VideoDecoder> sw_fallback_decoder,
+ std::unique_ptr<VideoDecoder> hw_decoder)
+ : decoder_type_(DecoderType::kNone),
+ hw_decoder_(std::move(hw_decoder)),
+ fallback_decoder_(std::move(sw_fallback_decoder)),
+ fallback_implementation_name_(
+ fallback_decoder_->GetDecoderInfo().implementation_name +
+ " (fallback from: " +
+ hw_decoder_->GetDecoderInfo().implementation_name + ")"),
+ callback_(nullptr),
+ hw_decoded_frames_since_last_fallback_(0),
+ hw_consequtive_generic_errors_(0) {}
+VideoDecoderSoftwareFallbackWrapper::~VideoDecoderSoftwareFallbackWrapper() =
+ default;
+
+bool VideoDecoderSoftwareFallbackWrapper::Configure(const Settings& settings) {
+ decoder_settings_ = settings;
+
+ if (webrtc::field_trial::IsEnabled("WebRTC-Video-ForcedSwDecoderFallback")) {
+ RTC_LOG(LS_INFO) << "Forced software decoder fallback enabled.";
+ RTC_DCHECK(decoder_type_ == DecoderType::kNone);
+ return InitFallbackDecoder();
+ }
+ if (InitHwDecoder()) {
+ return true;
+ }
+
+ RTC_DCHECK(decoder_type_ == DecoderType::kNone);
+ return InitFallbackDecoder();
+}
+
+bool VideoDecoderSoftwareFallbackWrapper::InitHwDecoder() {
+ RTC_DCHECK(decoder_type_ == DecoderType::kNone);
+ if (!hw_decoder_->Configure(decoder_settings_)) {
+ return false;
+ }
+
+ decoder_type_ = DecoderType::kHardware;
+ if (callback_)
+ hw_decoder_->RegisterDecodeCompleteCallback(callback_);
+ return true;
+}
+
+bool VideoDecoderSoftwareFallbackWrapper::InitFallbackDecoder() {
+ RTC_DCHECK(decoder_type_ == DecoderType::kNone ||
+ decoder_type_ == DecoderType::kHardware);
+ RTC_LOG(LS_WARNING) << "Decoder falling back to software decoding.";
+ if (!fallback_decoder_->Configure(decoder_settings_)) {
+ RTC_LOG(LS_ERROR) << "Failed to initialize software-decoder fallback.";
+ return false;
+ }
+
+ UpdateFallbackDecoderHistograms();
+
+ if (decoder_type_ == DecoderType::kHardware) {
+ hw_decoder_->Release();
+ }
+ decoder_type_ = DecoderType::kFallback;
+
+ if (callback_)
+ fallback_decoder_->RegisterDecodeCompleteCallback(callback_);
+ return true;
+}
+
+void VideoDecoderSoftwareFallbackWrapper::UpdateFallbackDecoderHistograms() {
+ const std::string kFallbackHistogramsUmaPrefix =
+ "WebRTC.Video.HardwareDecodedFramesBetweenSoftwareFallbacks.";
+ // Each histogram needs its own code path for this to work otherwise the
+ // histogram names will be mixed up by the optimization that takes place.
+ switch (decoder_settings_.codec_type()) {
+ case kVideoCodecGeneric:
+ RTC_HISTOGRAM_COUNTS_100000(kFallbackHistogramsUmaPrefix + "Generic",
+ hw_decoded_frames_since_last_fallback_);
+ break;
+ case kVideoCodecVP8:
+ RTC_HISTOGRAM_COUNTS_100000(kFallbackHistogramsUmaPrefix + "Vp8",
+ hw_decoded_frames_since_last_fallback_);
+ break;
+ case kVideoCodecVP9:
+ RTC_HISTOGRAM_COUNTS_100000(kFallbackHistogramsUmaPrefix + "Vp9",
+ hw_decoded_frames_since_last_fallback_);
+ break;
+ case kVideoCodecAV1:
+ RTC_HISTOGRAM_COUNTS_100000(kFallbackHistogramsUmaPrefix + "Av1",
+ hw_decoded_frames_since_last_fallback_);
+ break;
+ case kVideoCodecH264:
+ RTC_HISTOGRAM_COUNTS_100000(kFallbackHistogramsUmaPrefix + "H264",
+ hw_decoded_frames_since_last_fallback_);
+ break;
+ case kVideoCodecMultiplex:
+ RTC_HISTOGRAM_COUNTS_100000(kFallbackHistogramsUmaPrefix + "Multiplex",
+ hw_decoded_frames_since_last_fallback_);
+ break;
+ }
+}
+
+int32_t VideoDecoderSoftwareFallbackWrapper::Decode(
+ const EncodedImage& input_image,
+ bool missing_frames,
+ int64_t render_time_ms) {
+ TRACE_EVENT0("webrtc", "VideoDecoderSoftwareFallbackWrapper::Decode");
+ switch (decoder_type_) {
+ case DecoderType::kNone:
+ return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
+ case DecoderType::kHardware: {
+ int32_t ret = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
+ ret = hw_decoder_->Decode(input_image, missing_frames, render_time_ms);
+ if (ret != WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE) {
+ if (ret != WEBRTC_VIDEO_CODEC_ERROR) {
+ ++hw_decoded_frames_since_last_fallback_;
+ hw_consequtive_generic_errors_ = 0;
+ return ret;
+ }
+ if (input_image._frameType == VideoFrameType::kVideoFrameKey) {
+ // Only count errors on key-frames, since generic errors can happen
+ // with hw decoder due to many arbitrary reasons.
+ // However, requesting a key-frame is supposed to fix the issue.
+ ++hw_consequtive_generic_errors_;
+ }
+ if (hw_consequtive_generic_errors_ < kMaxConsequtiveHwErrors) {
+ return ret;
+ }
+ }
+
+ // HW decoder returned WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE or
+ // too many generic errors on key-frames encountered.
+ if (!InitFallbackDecoder()) {
+ return ret;
+ }
+
+ // Fallback decoder initialized, fall-through.
+ [[fallthrough]];
+ }
+ case DecoderType::kFallback:
+ return fallback_decoder_->Decode(input_image, missing_frames,
+ render_time_ms);
+ default:
+ RTC_DCHECK_NOTREACHED();
+ return WEBRTC_VIDEO_CODEC_ERROR;
+ }
+}
+
+int32_t VideoDecoderSoftwareFallbackWrapper::RegisterDecodeCompleteCallback(
+ DecodedImageCallback* callback) {
+ callback_ = callback;
+ return active_decoder().RegisterDecodeCompleteCallback(callback);
+}
+
+int32_t VideoDecoderSoftwareFallbackWrapper::Release() {
+ int32_t status;
+ switch (decoder_type_) {
+ case DecoderType::kHardware:
+ status = hw_decoder_->Release();
+ break;
+ case DecoderType::kFallback:
+ RTC_LOG(LS_INFO) << "Releasing software fallback decoder.";
+ status = fallback_decoder_->Release();
+ break;
+ case DecoderType::kNone:
+ status = WEBRTC_VIDEO_CODEC_OK;
+ break;
+ default:
+ RTC_DCHECK_NOTREACHED();
+ status = WEBRTC_VIDEO_CODEC_ERROR;
+ }
+
+ decoder_type_ = DecoderType::kNone;
+ return status;
+}
+
+VideoDecoder::DecoderInfo VideoDecoderSoftwareFallbackWrapper::GetDecoderInfo()
+ const {
+ DecoderInfo info = active_decoder().GetDecoderInfo();
+ if (decoder_type_ == DecoderType::kFallback) {
+ // Cached "A (fallback from B)" string.
+ info.implementation_name = fallback_implementation_name_;
+ }
+ return info;
+}
+
+const char* VideoDecoderSoftwareFallbackWrapper::ImplementationName() const {
+ if (decoder_type_ == DecoderType::kFallback) {
+ // Cached "A (fallback from B)" string.
+ return fallback_implementation_name_.c_str();
+ } else {
+ return hw_decoder_->ImplementationName();
+ }
+}
+
+VideoDecoder& VideoDecoderSoftwareFallbackWrapper::active_decoder() const {
+ return decoder_type_ == DecoderType::kFallback ? *fallback_decoder_
+ : *hw_decoder_;
+}
+
+} // namespace
+
+std::unique_ptr<VideoDecoder> CreateVideoDecoderSoftwareFallbackWrapper(
+ std::unique_ptr<VideoDecoder> sw_fallback_decoder,
+ std::unique_ptr<VideoDecoder> hw_decoder) {
+ return std::make_unique<VideoDecoderSoftwareFallbackWrapper>(
+ std::move(sw_fallback_decoder), std::move(hw_decoder));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/video_decoder_software_fallback_wrapper.h b/third_party/libwebrtc/api/video_codecs/video_decoder_software_fallback_wrapper.h
new file mode 100644
index 0000000000..3f44e02b26
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_decoder_software_fallback_wrapper.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VIDEO_DECODER_SOFTWARE_FALLBACK_WRAPPER_H_
+#define API_VIDEO_CODECS_VIDEO_DECODER_SOFTWARE_FALLBACK_WRAPPER_H_
+
+#include <memory>
+
+#include "api/video_codecs/video_decoder.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Used to wrap external VideoDecoders to provide a fallback option on
+// software decoding when a hardware decoder fails to decode a stream due to
+// hardware restrictions, such as max resolution.
+RTC_EXPORT std::unique_ptr<VideoDecoder>
+CreateVideoDecoderSoftwareFallbackWrapper(
+ std::unique_ptr<VideoDecoder> sw_fallback_decoder,
+ std::unique_ptr<VideoDecoder> hw_decoder);
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VIDEO_DECODER_SOFTWARE_FALLBACK_WRAPPER_H_
diff --git a/third_party/libwebrtc/api/video_codecs/video_encoder.cc b/third_party/libwebrtc/api/video_codecs/video_encoder.cc
new file mode 100644
index 0000000000..deb4fdc637
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_encoder.cc
@@ -0,0 +1,345 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/video_encoder.h"
+
+#include <string.h>
+#include <algorithm>
+
+#include "rtc_base/checks.h"
+#include "rtc_base/strings/string_builder.h"
+
+namespace webrtc {
+
+// TODO(mflodman): Add default complexity for VP9 and VP9.
+VideoCodecVP8 VideoEncoder::GetDefaultVp8Settings() {
+ VideoCodecVP8 vp8_settings;
+ memset(&vp8_settings, 0, sizeof(vp8_settings));
+
+ vp8_settings.numberOfTemporalLayers = 1;
+ vp8_settings.denoisingOn = true;
+ vp8_settings.automaticResizeOn = false;
+ vp8_settings.keyFrameInterval = 3000;
+
+ return vp8_settings;
+}
+
+VideoCodecVP9 VideoEncoder::GetDefaultVp9Settings() {
+ VideoCodecVP9 vp9_settings;
+ memset(&vp9_settings, 0, sizeof(vp9_settings));
+
+ vp9_settings.numberOfTemporalLayers = 1;
+ vp9_settings.denoisingOn = true;
+ vp9_settings.keyFrameInterval = 3000;
+ vp9_settings.adaptiveQpMode = true;
+ vp9_settings.automaticResizeOn = true;
+ vp9_settings.numberOfSpatialLayers = 1;
+ vp9_settings.flexibleMode = false;
+ vp9_settings.interLayerPred = InterLayerPredMode::kOn;
+
+ return vp9_settings;
+}
+
+VideoCodecH264 VideoEncoder::GetDefaultH264Settings() {
+ VideoCodecH264 h264_settings;
+ memset(&h264_settings, 0, sizeof(h264_settings));
+
+ h264_settings.keyFrameInterval = 3000;
+ h264_settings.numberOfTemporalLayers = 1;
+
+ return h264_settings;
+}
+
+VideoEncoder::ScalingSettings::ScalingSettings() = default;
+
+VideoEncoder::ScalingSettings::ScalingSettings(KOff) : ScalingSettings() {}
+
+VideoEncoder::ScalingSettings::ScalingSettings(int low, int high)
+ : thresholds(QpThresholds(low, high)) {}
+
+VideoEncoder::ScalingSettings::ScalingSettings(int low,
+ int high,
+ int min_pixels)
+ : thresholds(QpThresholds(low, high)), min_pixels_per_frame(min_pixels) {}
+
+VideoEncoder::ScalingSettings::ScalingSettings(const ScalingSettings&) =
+ default;
+
+VideoEncoder::ScalingSettings::~ScalingSettings() {}
+
+// static
+constexpr VideoEncoder::ScalingSettings::KOff
+ VideoEncoder::ScalingSettings::kOff;
+// static
+constexpr uint8_t VideoEncoder::EncoderInfo::kMaxFramerateFraction;
+
+bool VideoEncoder::ResolutionBitrateLimits::operator==(
+ const ResolutionBitrateLimits& rhs) const {
+ return frame_size_pixels == rhs.frame_size_pixels &&
+ min_start_bitrate_bps == rhs.min_start_bitrate_bps &&
+ min_bitrate_bps == rhs.min_bitrate_bps &&
+ max_bitrate_bps == rhs.max_bitrate_bps;
+}
+
+VideoEncoder::EncoderInfo::EncoderInfo()
+ : scaling_settings(VideoEncoder::ScalingSettings::kOff),
+ requested_resolution_alignment(1),
+ apply_alignment_to_all_simulcast_layers(false),
+ supports_native_handle(false),
+ implementation_name("unknown"),
+ has_trusted_rate_controller(false),
+ is_hardware_accelerated(true),
+ fps_allocation{absl::InlinedVector<uint8_t, kMaxTemporalStreams>(
+ 1,
+ kMaxFramerateFraction)},
+ supports_simulcast(false),
+ preferred_pixel_formats{VideoFrameBuffer::Type::kI420} {}
+
+VideoEncoder::EncoderInfo::EncoderInfo(const EncoderInfo&) = default;
+
+VideoEncoder::EncoderInfo::~EncoderInfo() = default;
+
+std::string VideoEncoder::EncoderInfo::ToString() const {
+ char string_buf[2048];
+ rtc::SimpleStringBuilder oss(string_buf);
+
+ oss << "EncoderInfo { "
+ "ScalingSettings { ";
+ if (scaling_settings.thresholds) {
+ oss << "Thresholds { "
+ "low = "
+ << scaling_settings.thresholds->low
+ << ", high = " << scaling_settings.thresholds->high << "}, ";
+ }
+ oss << "min_pixels_per_frame = " << scaling_settings.min_pixels_per_frame
+ << " }";
+ oss << ", requested_resolution_alignment = " << requested_resolution_alignment
+ << ", apply_alignment_to_all_simulcast_layers = "
+ << apply_alignment_to_all_simulcast_layers
+ << ", supports_native_handle = " << supports_native_handle
+ << ", implementation_name = '" << implementation_name
+ << "'"
+ ", has_trusted_rate_controller = "
+ << has_trusted_rate_controller
+ << ", is_hardware_accelerated = " << is_hardware_accelerated
+ << ", fps_allocation = [";
+ size_t num_spatial_layer_with_fps_allocation = 0;
+ for (size_t i = 0; i < kMaxSpatialLayers; ++i) {
+ if (!fps_allocation[i].empty()) {
+ num_spatial_layer_with_fps_allocation = i + 1;
+ }
+ }
+ bool first = true;
+ for (size_t i = 0; i < num_spatial_layer_with_fps_allocation; ++i) {
+ if (fps_allocation[i].empty()) {
+ break;
+ }
+ if (!first) {
+ oss << ", ";
+ }
+ const absl::InlinedVector<uint8_t, kMaxTemporalStreams>& fractions =
+ fps_allocation[i];
+ if (!fractions.empty()) {
+ first = false;
+ oss << "[ ";
+ for (size_t i = 0; i < fractions.size(); ++i) {
+ if (i > 0) {
+ oss << ", ";
+ }
+ oss << (static_cast<double>(fractions[i]) / kMaxFramerateFraction);
+ }
+ oss << "] ";
+ }
+ }
+ oss << "]";
+ oss << ", resolution_bitrate_limits = [";
+ for (size_t i = 0; i < resolution_bitrate_limits.size(); ++i) {
+ if (i > 0) {
+ oss << ", ";
+ }
+ ResolutionBitrateLimits l = resolution_bitrate_limits[i];
+ oss << "Limits { "
+ "frame_size_pixels = "
+ << l.frame_size_pixels
+ << ", min_start_bitrate_bps = " << l.min_start_bitrate_bps
+ << ", min_bitrate_bps = " << l.min_bitrate_bps
+ << ", max_bitrate_bps = " << l.max_bitrate_bps << "} ";
+ }
+ oss << "] "
+ ", supports_simulcast = "
+ << supports_simulcast;
+ oss << ", preferred_pixel_formats = [";
+ for (size_t i = 0; i < preferred_pixel_formats.size(); ++i) {
+ if (i > 0)
+ oss << ", ";
+#if defined(WEBRTC_MOZILLA_BUILD)
+ // This could assert, as opposed to throw using the form in the
+ // else, but since we're in a for loop that uses .size() we can
+ // be fairly sure that this is safe without doing a further
+ // check to make sure 'i' is in-range.
+ oss << VideoFrameBufferTypeToString(preferred_pixel_formats[i]);
+#else
+ oss << VideoFrameBufferTypeToString(preferred_pixel_formats.at(i));
+#endif
+ }
+ oss << "]";
+ if (is_qp_trusted.has_value()) {
+ oss << ", is_qp_trusted = " << is_qp_trusted.value();
+ }
+ oss << "}";
+ return oss.str();
+}
+
+bool VideoEncoder::EncoderInfo::operator==(const EncoderInfo& rhs) const {
+ if (scaling_settings.thresholds.has_value() !=
+ rhs.scaling_settings.thresholds.has_value()) {
+ return false;
+ }
+ if (scaling_settings.thresholds.has_value()) {
+ QpThresholds l = *scaling_settings.thresholds;
+ QpThresholds r = *rhs.scaling_settings.thresholds;
+ if (l.low != r.low || l.high != r.high) {
+ return false;
+ }
+ }
+ if (scaling_settings.min_pixels_per_frame !=
+ rhs.scaling_settings.min_pixels_per_frame) {
+ return false;
+ }
+
+ if (supports_native_handle != rhs.supports_native_handle ||
+ implementation_name != rhs.implementation_name ||
+ has_trusted_rate_controller != rhs.has_trusted_rate_controller ||
+ is_hardware_accelerated != rhs.is_hardware_accelerated) {
+ return false;
+ }
+
+ for (size_t i = 0; i < kMaxSpatialLayers; ++i) {
+ if (fps_allocation[i] != rhs.fps_allocation[i]) {
+ return false;
+ }
+ }
+
+ if (resolution_bitrate_limits != rhs.resolution_bitrate_limits ||
+ supports_simulcast != rhs.supports_simulcast) {
+ return false;
+ }
+
+ return true;
+}
+
+absl::optional<VideoEncoder::ResolutionBitrateLimits>
+VideoEncoder::EncoderInfo::GetEncoderBitrateLimitsForResolution(
+ int frame_size_pixels) const {
+ std::vector<ResolutionBitrateLimits> bitrate_limits =
+ resolution_bitrate_limits;
+
+ // Sort the list of bitrate limits by resolution.
+ sort(bitrate_limits.begin(), bitrate_limits.end(),
+ [](const ResolutionBitrateLimits& lhs,
+ const ResolutionBitrateLimits& rhs) {
+ return lhs.frame_size_pixels < rhs.frame_size_pixels;
+ });
+
+ for (size_t i = 0; i < bitrate_limits.size(); ++i) {
+ RTC_DCHECK_GE(bitrate_limits[i].min_bitrate_bps, 0);
+ RTC_DCHECK_GE(bitrate_limits[i].min_start_bitrate_bps, 0);
+ RTC_DCHECK_GE(bitrate_limits[i].max_bitrate_bps,
+ bitrate_limits[i].min_bitrate_bps);
+ if (i > 0) {
+ // The bitrate limits aren't expected to decrease with resolution.
+ RTC_DCHECK_GE(bitrate_limits[i].min_bitrate_bps,
+ bitrate_limits[i - 1].min_bitrate_bps);
+ RTC_DCHECK_GE(bitrate_limits[i].min_start_bitrate_bps,
+ bitrate_limits[i - 1].min_start_bitrate_bps);
+ RTC_DCHECK_GE(bitrate_limits[i].max_bitrate_bps,
+ bitrate_limits[i - 1].max_bitrate_bps);
+ }
+
+ if (bitrate_limits[i].frame_size_pixels >= frame_size_pixels) {
+ return absl::optional<ResolutionBitrateLimits>(bitrate_limits[i]);
+ }
+ }
+
+ return absl::nullopt;
+}
+
+VideoEncoder::RateControlParameters::RateControlParameters()
+ : bitrate(VideoBitrateAllocation()),
+ framerate_fps(0.0),
+ bandwidth_allocation(DataRate::Zero()) {}
+
+VideoEncoder::RateControlParameters::RateControlParameters(
+ const VideoBitrateAllocation& bitrate,
+ double framerate_fps)
+ : bitrate(bitrate),
+ framerate_fps(framerate_fps),
+ bandwidth_allocation(DataRate::BitsPerSec(bitrate.get_sum_bps())) {}
+
+VideoEncoder::RateControlParameters::RateControlParameters(
+ const VideoBitrateAllocation& bitrate,
+ double framerate_fps,
+ DataRate bandwidth_allocation)
+ : bitrate(bitrate),
+ framerate_fps(framerate_fps),
+ bandwidth_allocation(bandwidth_allocation) {}
+
+bool VideoEncoder::RateControlParameters::operator==(
+ const VideoEncoder::RateControlParameters& rhs) const {
+ return std::tie(bitrate, framerate_fps, bandwidth_allocation) ==
+ std::tie(rhs.bitrate, rhs.framerate_fps, rhs.bandwidth_allocation);
+}
+
+bool VideoEncoder::RateControlParameters::operator!=(
+ const VideoEncoder::RateControlParameters& rhs) const {
+ return !(rhs == *this);
+}
+
+VideoEncoder::RateControlParameters::~RateControlParameters() = default;
+
+void VideoEncoder::SetFecControllerOverride(
+ FecControllerOverride* fec_controller_override) {}
+
+int32_t VideoEncoder::InitEncode(const VideoCodec* codec_settings,
+ int32_t number_of_cores,
+ size_t max_payload_size) {
+ const VideoEncoder::Capabilities capabilities(/* loss_notification= */ false);
+ const VideoEncoder::Settings settings(capabilities, number_of_cores,
+ max_payload_size);
+ // In theory, this and the other version of InitEncode() could end up calling
+ // each other in a loop until we get a stack overflow.
+ // In practice, any subclass of VideoEncoder would overload at least one
+ // of these, and we have a TODO in the header file to make this pure virtual.
+ return InitEncode(codec_settings, settings);
+}
+
+int VideoEncoder::InitEncode(const VideoCodec* codec_settings,
+ const VideoEncoder::Settings& settings) {
+ // In theory, this and the other version of InitEncode() could end up calling
+ // each other in a loop until we get a stack overflow.
+ // In practice, any subclass of VideoEncoder would overload at least one
+ // of these, and we have a TODO in the header file to make this pure virtual.
+ return InitEncode(codec_settings, settings.number_of_cores,
+ settings.max_payload_size);
+}
+
+void VideoEncoder::OnPacketLossRateUpdate(float packet_loss_rate) {}
+
+void VideoEncoder::OnRttUpdate(int64_t rtt_ms) {}
+
+void VideoEncoder::OnLossNotification(
+ const LossNotification& loss_notification) {}
+
+// TODO(webrtc:9722): Remove and make pure virtual.
+VideoEncoder::EncoderInfo VideoEncoder::GetEncoderInfo() const {
+ return EncoderInfo();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/video_encoder.h b/third_party/libwebrtc/api/video_codecs/video_encoder.h
new file mode 100644
index 0000000000..395a87e089
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_encoder.h
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VIDEO_ENCODER_H_
+#define API_VIDEO_CODECS_VIDEO_ENCODER_H_
+
+#include <limits>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/container/inlined_vector.h"
+#include "absl/types/optional.h"
+#include "api/fec_controller_override.h"
+#include "api/units/data_rate.h"
+#include "api/video/encoded_image.h"
+#include "api/video/video_bitrate_allocation.h"
+#include "api/video/video_codec_constants.h"
+#include "api/video/video_frame.h"
+#include "api/video_codecs/video_codec.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// TODO(pbos): Expose these through a public (root) header or change these APIs.
+struct CodecSpecificInfo;
+
+constexpr int kDefaultMinPixelsPerFrame = 320 * 180;
+
+class RTC_EXPORT EncodedImageCallback {
+ public:
+ virtual ~EncodedImageCallback() {}
+
+ struct Result {
+ enum Error {
+ OK,
+
+ // Failed to send the packet.
+ ERROR_SEND_FAILED,
+ };
+
+ explicit Result(Error error) : error(error) {}
+ Result(Error error, uint32_t frame_id) : error(error), frame_id(frame_id) {}
+
+ Error error;
+
+ // Frame ID assigned to the frame. The frame ID should be the same as the ID
+ // seen by the receiver for this frame. RTP timestamp of the frame is used
+ // as frame ID when RTP is used to send video. Must be used only when
+ // error=OK.
+ uint32_t frame_id = 0;
+
+ // Tells the encoder that the next frame is should be dropped.
+ bool drop_next_frame = false;
+ };
+
+ // Used to signal the encoder about reason a frame is dropped.
+ // kDroppedByMediaOptimizations - dropped by MediaOptimizations (for rate
+ // limiting purposes).
+ // kDroppedByEncoder - dropped by encoder's internal rate limiter.
+ // TODO(bugs.webrtc.org/10164): Delete this enum? It duplicates the more
+ // general VideoStreamEncoderObserver::DropReason. Also,
+ // kDroppedByMediaOptimizations is not produced by any encoder, but by
+ // VideoStreamEncoder.
+ enum class DropReason : uint8_t {
+ kDroppedByMediaOptimizations,
+ kDroppedByEncoder
+ };
+
+ // Callback function which is called when an image has been encoded.
+ virtual Result OnEncodedImage(
+ const EncodedImage& encoded_image,
+ const CodecSpecificInfo* codec_specific_info) = 0;
+
+ virtual void OnDroppedFrame(DropReason reason) {}
+};
+
+class RTC_EXPORT VideoEncoder {
+ public:
+ struct QpThresholds {
+ QpThresholds(int l, int h) : low(l), high(h) {}
+ QpThresholds() : low(-1), high(-1) {}
+ int low;
+ int high;
+ };
+
+ // Quality scaling is enabled if thresholds are provided.
+ struct RTC_EXPORT ScalingSettings {
+ private:
+ // Private magic type for kOff, implicitly convertible to
+ // ScalingSettings.
+ struct KOff {};
+
+ public:
+ // TODO(bugs.webrtc.org/9078): Since absl::optional should be trivially copy
+ // constructible, this magic value can likely be replaced by a constexpr
+ // ScalingSettings value.
+ static constexpr KOff kOff = {};
+
+ ScalingSettings(int low, int high);
+ ScalingSettings(int low, int high, int min_pixels);
+ ScalingSettings(const ScalingSettings&);
+ ScalingSettings(KOff); // NOLINT(runtime/explicit)
+ ~ScalingSettings();
+
+ absl::optional<QpThresholds> thresholds;
+
+ // We will never ask for a resolution lower than this.
+ // TODO(kthelgason): Lower this limit when better testing
+ // on MediaCodec and fallback implementations are in place.
+ // See https://bugs.chromium.org/p/webrtc/issues/detail?id=7206
+ int min_pixels_per_frame = kDefaultMinPixelsPerFrame;
+
+ private:
+ // Private constructor; to get an object without thresholds, use
+ // the magic constant ScalingSettings::kOff.
+ ScalingSettings();
+ };
+
+ // Bitrate limits for resolution.
+ struct ResolutionBitrateLimits {
+ ResolutionBitrateLimits(int frame_size_pixels,
+ int min_start_bitrate_bps,
+ int min_bitrate_bps,
+ int max_bitrate_bps)
+ : frame_size_pixels(frame_size_pixels),
+ min_start_bitrate_bps(min_start_bitrate_bps),
+ min_bitrate_bps(min_bitrate_bps),
+ max_bitrate_bps(max_bitrate_bps) {}
+ // Size of video frame, in pixels, the bitrate thresholds are intended for.
+ int frame_size_pixels = 0;
+ // Recommended minimum bitrate to start encoding.
+ int min_start_bitrate_bps = 0;
+ // Recommended minimum bitrate.
+ int min_bitrate_bps = 0;
+ // Recommended maximum bitrate.
+ int max_bitrate_bps = 0;
+
+ bool operator==(const ResolutionBitrateLimits& rhs) const;
+ bool operator!=(const ResolutionBitrateLimits& rhs) const {
+ return !(*this == rhs);
+ }
+ };
+
+ // Struct containing metadata about the encoder implementing this interface.
+ struct RTC_EXPORT EncoderInfo {
+ static constexpr uint8_t kMaxFramerateFraction =
+ std::numeric_limits<uint8_t>::max();
+
+ EncoderInfo();
+ EncoderInfo(const EncoderInfo&);
+
+ ~EncoderInfo();
+
+ std::string ToString() const;
+ bool operator==(const EncoderInfo& rhs) const;
+ bool operator!=(const EncoderInfo& rhs) const { return !(*this == rhs); }
+
+ // Any encoder implementation wishing to use the WebRTC provided
+ // quality scaler must populate this field.
+ ScalingSettings scaling_settings;
+
+ // The width and height of the incoming video frames should be divisible
+ // by `requested_resolution_alignment`. If they are not, the encoder may
+ // drop the incoming frame.
+ // For example: With I420, this value would be a multiple of 2.
+ // Note that this field is unrelated to any horizontal or vertical stride
+ // requirements the encoder has on the incoming video frame buffers.
+ uint32_t requested_resolution_alignment;
+
+ // Same as above but if true, each simulcast layer should also be divisible
+ // by `requested_resolution_alignment`.
+ // Note that scale factors `scale_resolution_down_by` may be adjusted so a
+ // common multiple is not too large to avoid largely cropped frames and
+ // possibly with an aspect ratio far from the original.
+ // Warning: large values of scale_resolution_down_by could be changed
+ // considerably, especially if `requested_resolution_alignment` is large.
+ bool apply_alignment_to_all_simulcast_layers;
+
+ // If true, encoder supports working with a native handle (e.g. texture
+ // handle for hw codecs) rather than requiring a raw I420 buffer.
+ bool supports_native_handle;
+
+ // The name of this particular encoder implementation, e.g. "libvpx".
+ std::string implementation_name;
+
+ // If this field is true, the encoder rate controller must perform
+ // well even in difficult situations, and produce close to the specified
+ // target bitrate seen over a reasonable time window, drop frames if
+ // necessary in order to keep the rate correct, and react quickly to
+ // changing bitrate targets. If this method returns true, we disable the
+ // frame dropper in the media optimization module and rely entirely on the
+ // encoder to produce media at a bitrate that closely matches the target.
+ // Any overshooting may result in delay buildup. If this method returns
+ // false (default behavior), the media opt frame dropper will drop input
+ // frames if it suspect encoder misbehavior. Misbehavior is common,
+ // especially in hardware codecs. Disable media opt at your own risk.
+ bool has_trusted_rate_controller;
+
+ // If this field is true, the encoder uses hardware support and different
+ // thresholds will be used in CPU adaptation.
+ bool is_hardware_accelerated;
+
+ // For each spatial layer (simulcast stream or SVC layer), represented as an
+ // element in `fps_allocation` a vector indicates how many temporal layers
+ // the encoder is using for that spatial layer.
+ // For each spatial/temporal layer pair, the frame rate fraction is given as
+ // an 8bit unsigned integer where 0 = 0% and 255 = 100%.
+ //
+ // If the vector is empty for a given spatial layer, it indicates that frame
+ // rates are not defined and we can't count on any specific frame rate to be
+ // generated. Likely this indicates Vp8TemporalLayersType::kBitrateDynamic.
+ //
+ // The encoder may update this on a per-frame basis in response to both
+ // internal and external signals.
+ //
+ // Spatial layers are treated independently, but temporal layers are
+ // cumulative. For instance, if:
+ // fps_allocation[0][0] = kFullFramerate / 2;
+ // fps_allocation[0][1] = kFullFramerate;
+ // Then half of the frames are in the base layer and half is in TL1, but
+ // since TL1 is assumed to depend on the base layer, the frame rate is
+ // indicated as the full 100% for the top layer.
+ //
+ // Defaults to a single spatial layer containing a single temporal layer
+ // with a 100% frame rate fraction.
+ absl::InlinedVector<uint8_t, kMaxTemporalStreams>
+ fps_allocation[kMaxSpatialLayers];
+
+ // Recommended bitrate limits for different resolutions.
+ std::vector<ResolutionBitrateLimits> resolution_bitrate_limits;
+
+ // Obtains the limits from `resolution_bitrate_limits` that best matches the
+ // `frame_size_pixels`.
+ absl::optional<ResolutionBitrateLimits>
+ GetEncoderBitrateLimitsForResolution(int frame_size_pixels) const;
+
+ // If true, this encoder has internal support for generating simulcast
+ // streams. Otherwise, an adapter class will be needed.
+ // Even if true, the config provided to InitEncode() might not be supported,
+ // in such case the encoder should return
+ // WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED.
+ bool supports_simulcast;
+
+ // The list of pixel formats preferred by the encoder. It is assumed that if
+ // the list is empty and supports_native_handle is false, then {I420} is the
+ // preferred pixel format. The order of the formats does not matter.
+ absl::InlinedVector<VideoFrameBuffer::Type, kMaxPreferredPixelFormats>
+ preferred_pixel_formats;
+
+ // Indicates whether or not QP value encoder writes into frame/slice/tile
+ // header can be interpreted as average frame/slice/tile QP.
+ absl::optional<bool> is_qp_trusted;
+ };
+
+ struct RTC_EXPORT RateControlParameters {
+ RateControlParameters();
+ RateControlParameters(const VideoBitrateAllocation& bitrate,
+ double framerate_fps);
+ RateControlParameters(const VideoBitrateAllocation& bitrate,
+ double framerate_fps,
+ DataRate bandwidth_allocation);
+ virtual ~RateControlParameters();
+
+ // Target bitrate, per spatial/temporal layer.
+ // A target bitrate of 0bps indicates a layer should not be encoded at all.
+ VideoBitrateAllocation target_bitrate;
+ // Adjusted target bitrate, per spatial/temporal layer. May be lower or
+ // higher than the target depending on encoder behaviour.
+ VideoBitrateAllocation bitrate;
+ // Target framerate, in fps. A value <= 0.0 is invalid and should be
+ // interpreted as framerate target not available. In this case the encoder
+ // should fall back to the max framerate specified in `codec_settings` of
+ // the last InitEncode() call.
+ double framerate_fps;
+ // The network bandwidth available for video. This is at least
+ // `bitrate.get_sum_bps()`, but may be higher if the application is not
+ // network constrained.
+ DataRate bandwidth_allocation;
+
+ bool operator==(const RateControlParameters& rhs) const;
+ bool operator!=(const RateControlParameters& rhs) const;
+ };
+
+ struct LossNotification {
+ // The timestamp of the last decodable frame *prior* to the last received.
+ // (The last received - described below - might itself be decodable or not.)
+ uint32_t timestamp_of_last_decodable;
+ // The timestamp of the last received frame.
+ uint32_t timestamp_of_last_received;
+ // Describes whether the dependencies of the last received frame were
+ // all decodable.
+ // `false` if some dependencies were undecodable, `true` if all dependencies
+ // were decodable, and `nullopt` if the dependencies are unknown.
+ absl::optional<bool> dependencies_of_last_received_decodable;
+ // Describes whether the received frame was decodable.
+ // `false` if some dependency was undecodable or if some packet belonging
+ // to the last received frame was missed.
+ // `true` if all dependencies were decodable and all packets belonging
+ // to the last received frame were received.
+ // `nullopt` if no packet belonging to the last frame was missed, but the
+ // last packet in the frame was not yet received.
+ absl::optional<bool> last_received_decodable;
+ };
+
+ // Negotiated capabilities which the VideoEncoder may expect the other
+ // side to use.
+ struct Capabilities {
+ explicit Capabilities(bool loss_notification)
+ : loss_notification(loss_notification) {}
+ bool loss_notification;
+ };
+
+ struct Settings {
+ Settings(const Capabilities& capabilities,
+ int number_of_cores,
+ size_t max_payload_size)
+ : capabilities(capabilities),
+ number_of_cores(number_of_cores),
+ max_payload_size(max_payload_size) {}
+
+ Capabilities capabilities;
+ int number_of_cores;
+ size_t max_payload_size;
+ };
+
+ static VideoCodecVP8 GetDefaultVp8Settings();
+ static VideoCodecVP9 GetDefaultVp9Settings();
+ static VideoCodecH264 GetDefaultH264Settings();
+
+ virtual ~VideoEncoder() {}
+
+ // Set a FecControllerOverride, through which the encoder may override
+ // decisions made by FecController.
+ // TODO(bugs.webrtc.org/10769): Update downstream, then make pure-virtual.
+ virtual void SetFecControllerOverride(
+ FecControllerOverride* fec_controller_override);
+
+ // Initialize the encoder with the information from the codecSettings
+ //
+ // Input:
+ // - codec_settings : Codec settings
+ // - settings : Settings affecting the encoding itself.
+ // Input for deprecated version:
+ // - number_of_cores : Number of cores available for the encoder
+ // - max_payload_size : The maximum size each payload is allowed
+ // to have. Usually MTU - overhead.
+ //
+ // Return value : Set bit rate if OK
+ // <0 - Errors:
+ // WEBRTC_VIDEO_CODEC_ERR_PARAMETER
+ // WEBRTC_VIDEO_CODEC_ERR_SIZE
+ // WEBRTC_VIDEO_CODEC_MEMORY
+ // WEBRTC_VIDEO_CODEC_ERROR
+ // TODO(bugs.webrtc.org/10720): After updating downstream projects and posting
+ // an announcement to discuss-webrtc, remove the three-parameters variant
+ // and make the two-parameters variant pure-virtual.
+ /* ABSL_DEPRECATED("bugs.webrtc.org/10720") */ virtual int32_t InitEncode(
+ const VideoCodec* codec_settings,
+ int32_t number_of_cores,
+ size_t max_payload_size);
+ virtual int InitEncode(const VideoCodec* codec_settings,
+ const VideoEncoder::Settings& settings);
+
+ // Register an encode complete callback object.
+ //
+ // Input:
+ // - callback : Callback object which handles encoded images.
+ //
+ // Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
+ virtual int32_t RegisterEncodeCompleteCallback(
+ EncodedImageCallback* callback) = 0;
+
+ // Free encoder memory.
+ // Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
+ virtual int32_t Release() = 0;
+
+ // Encode an image (as a part of a video stream). The encoded image
+ // will be returned to the user through the encode complete callback.
+ //
+ // Input:
+ // - frame : Image to be encoded
+ // - frame_types : Frame type to be generated by the encoder.
+ //
+ // Return value : WEBRTC_VIDEO_CODEC_OK if OK
+ // <0 - Errors:
+ // WEBRTC_VIDEO_CODEC_ERR_PARAMETER
+ // WEBRTC_VIDEO_CODEC_MEMORY
+ // WEBRTC_VIDEO_CODEC_ERROR
+ virtual int32_t Encode(const VideoFrame& frame,
+ const std::vector<VideoFrameType>* frame_types) = 0;
+
+ // Sets rate control parameters: bitrate, framerate, etc. These settings are
+ // instantaneous (i.e. not moving averages) and should apply from now until
+ // the next call to SetRates().
+ virtual void SetRates(const RateControlParameters& parameters) = 0;
+
+ // Inform the encoder when the packet loss rate changes.
+ //
+ // Input: - packet_loss_rate : The packet loss rate (0.0 to 1.0).
+ virtual void OnPacketLossRateUpdate(float packet_loss_rate);
+
+ // Inform the encoder when the round trip time changes.
+ //
+ // Input: - rtt_ms : The new RTT, in milliseconds.
+ virtual void OnRttUpdate(int64_t rtt_ms);
+
+ // Called when a loss notification is received.
+ virtual void OnLossNotification(const LossNotification& loss_notification);
+
+ // Returns meta-data about the encoder, such as implementation name.
+ // The output of this method may change during runtime. For instance if a
+ // hardware encoder fails, it may fall back to doing software encoding using
+ // an implementation with different characteristics.
+ virtual EncoderInfo GetEncoderInfo() const;
+};
+} // namespace webrtc
+#endif // API_VIDEO_CODECS_VIDEO_ENCODER_H_
diff --git a/third_party/libwebrtc/api/video_codecs/video_encoder_factory.h b/third_party/libwebrtc/api/video_codecs/video_encoder_factory.h
new file mode 100644
index 0000000000..d28a2a4035
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_encoder_factory.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_H_
+#define API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/units/data_rate.h"
+#include "api/video/render_resolution.h"
+#include "api/video_codecs/sdp_video_format.h"
+
+namespace webrtc {
+
+class VideoEncoder;
+
+// A factory that creates VideoEncoders.
+// NOTE: This class is still under development and may change without notice.
+class VideoEncoderFactory {
+ public:
+ struct CodecSupport {
+ bool is_supported = false;
+ bool is_power_efficient = false;
+ };
+
+ // An injectable class that is continuously updated with encoding conditions
+ // and selects the best encoder given those conditions. An implementation is
+ // typically stateful to avoid toggling between different encoders, which is
+ // costly due to recreation of objects, a new codec will always start with a
+ // key-frame.
+ class EncoderSelectorInterface {
+ public:
+ virtual ~EncoderSelectorInterface() {}
+
+ // Informs the encoder selector about which encoder that is currently being
+ // used.
+ virtual void OnCurrentEncoder(const SdpVideoFormat& format) = 0;
+
+ // Called every time the available bitrate is updated. Should return a
+ // non-empty if an encoder switch should be performed.
+ virtual absl::optional<SdpVideoFormat> OnAvailableBitrate(
+ const DataRate& rate) = 0;
+
+ // Called every time the encoder input resolution change. Should return a
+ // non-empty if an encoder switch should be performed.
+ virtual absl::optional<SdpVideoFormat> OnResolutionChange(
+ const RenderResolution& resolution) {
+ return absl::nullopt;
+ }
+
+ // Called if the currently used encoder reports itself as broken. Should
+ // return a non-empty if an encoder switch should be performed.
+ virtual absl::optional<SdpVideoFormat> OnEncoderBroken() = 0;
+ };
+
+ // Returns a list of supported video formats in order of preference, to use
+ // for signaling etc.
+ virtual std::vector<SdpVideoFormat> GetSupportedFormats() const = 0;
+
+ // Returns a list of supported video formats in order of preference, that can
+ // also be tagged with additional information to allow the VideoEncoderFactory
+ // to separate between different implementations when CreateVideoEncoder is
+ // called.
+ virtual std::vector<SdpVideoFormat> GetImplementations() const {
+ return GetSupportedFormats();
+ }
+
+ // Query whether the specifed format is supported or not and if it will be
+ // power efficient, which is currently interpreted as if there is support for
+ // hardware acceleration.
+ // See https://w3c.github.io/webrtc-svc/#scalabilitymodes* for a specification
+ // of valid values for `scalability_mode`.
+ // NOTE: QueryCodecSupport is currently an experimental feature that is
+ // subject to change without notice.
+ virtual CodecSupport QueryCodecSupport(
+ const SdpVideoFormat& format,
+ absl::optional<std::string> scalability_mode) const {
+ // Default implementation, query for supported formats and check if the
+ // specified format is supported. Returns false if scalability_mode is
+ // specified.
+ CodecSupport codec_support;
+ if (!scalability_mode) {
+ codec_support.is_supported = format.IsCodecInList(GetSupportedFormats());
+ }
+ return codec_support;
+ }
+
+ // Creates a VideoEncoder for the specified format.
+ virtual std::unique_ptr<VideoEncoder> CreateVideoEncoder(
+ const SdpVideoFormat& format) = 0;
+
+ // This method creates a EncoderSelector to use for a VideoSendStream.
+ // (and hence should probably been called CreateEncoderSelector()).
+ //
+ // Note: This method is unsuitable if encoding several streams that
+ // are using same VideoEncoderFactory (either by several streams in one
+ // PeerConnection or streams with different PeerConnection but same
+ // PeerConnectionFactory). This is due to the fact that the method is not
+ // given any stream identifier, nor is the EncoderSelectorInterface given any
+ // stream identifiers, i.e one does not know which stream is being encoded
+ // with help of the selector.
+ //
+ // In such scenario, the `RtpSenderInterface::SetEncoderSelector` is
+ // recommended.
+ //
+ // TODO(bugs.webrtc.org:14122): Deprecate and remove in favor of
+ // `RtpSenderInterface::SetEncoderSelector`.
+ virtual std::unique_ptr<EncoderSelectorInterface> GetEncoderSelector() const {
+ return nullptr;
+ }
+
+ virtual ~VideoEncoderFactory() {}
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_H_
diff --git a/third_party/libwebrtc/api/video_codecs/video_encoder_factory_template.h b/third_party/libwebrtc/api/video_codecs/video_encoder_factory_template.h
new file mode 100644
index 0000000000..643096dbbb
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_encoder_factory_template.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_H_
+#define API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/algorithm/container.h"
+#include "api/array_view.h"
+#include "api/video_codecs/video_encoder.h"
+#include "api/video_codecs/video_encoder_factory.h"
+#include "modules/video_coding/svc/scalability_mode_util.h"
+
+namespace webrtc {
+// The VideoEncoderFactoryTemplate supports encoders implementations given as
+// template arguments.
+//
+// To include an encoder in the factory it requires three static members
+// functions to be defined:
+//
+// // Returns the supported SdpVideoFormats this encoder can produce.
+// static std::vector<SdpVideoFormat> SupportedFormats();
+//
+// // Creates an encoder instance for the given format.
+// static std::unique_ptr<VideoEncoder>
+// CreateEncoder(const SdpVideoFormat& format);
+//
+// // Returns true if the encoder supports the given scalability mode.
+// static bool
+// IsScalabilityModeSupported(ScalabilityMode scalability_mode);
+//
+// Note that the order of the template arguments matter as the factory will
+// query/return the first encoder implementation supporting the given
+// SdpVideoFormat.
+template <typename... Ts>
+class VideoEncoderFactoryTemplate : public VideoEncoderFactory {
+ public:
+ std::vector<SdpVideoFormat> GetSupportedFormats() const override {
+ return GetSupportedFormatsInternal<Ts...>();
+ }
+
+ std::unique_ptr<VideoEncoder> CreateVideoEncoder(
+ const SdpVideoFormat& format) override {
+ return CreateVideoEncoderInternal<Ts...>(format);
+ }
+
+ CodecSupport QueryCodecSupport(
+ const SdpVideoFormat& format,
+ absl::optional<std::string> scalability_mode) const override {
+ return QueryCodecSupportInternal<Ts...>(format, scalability_mode);
+ }
+
+ private:
+ bool IsFormatInList(
+ const SdpVideoFormat& format,
+ rtc::ArrayView<const SdpVideoFormat> supported_formats) const {
+ return absl::c_any_of(
+ supported_formats, [&](const SdpVideoFormat& supported_format) {
+ return supported_format.name == format.name &&
+ supported_format.parameters == format.parameters;
+ });
+ }
+
+ template <typename V>
+ bool IsScalabilityModeSupported(
+ const absl::optional<std::string>& scalability_mode_string) const {
+ if (!scalability_mode_string.has_value()) {
+ return true;
+ }
+ absl::optional<ScalabilityMode> scalability_mode =
+ ScalabilityModeFromString(*scalability_mode_string);
+ return scalability_mode.has_value() &&
+ V::IsScalabilityModeSupported(*scalability_mode);
+ }
+
+ template <typename V, typename... Vs>
+ std::vector<SdpVideoFormat> GetSupportedFormatsInternal() const {
+ auto supported_formats = V::SupportedFormats();
+
+ if constexpr (sizeof...(Vs) > 0) {
+ // Supported formats may overlap between implementations, so duplicates
+ // should be filtered out.
+ for (const auto& other_format : GetSupportedFormatsInternal<Vs...>()) {
+ if (!IsFormatInList(other_format, supported_formats)) {
+ supported_formats.push_back(other_format);
+ }
+ }
+ }
+
+ return supported_formats;
+ }
+
+ template <typename V, typename... Vs>
+ std::unique_ptr<VideoEncoder> CreateVideoEncoderInternal(
+ const SdpVideoFormat& format) {
+ if (IsFormatInList(format, V::SupportedFormats())) {
+ return V::CreateEncoder(format);
+ }
+
+ if constexpr (sizeof...(Vs) > 0) {
+ return CreateVideoEncoderInternal<Vs...>(format);
+ }
+
+ return nullptr;
+ }
+
+ template <typename V, typename... Vs>
+ CodecSupport QueryCodecSupportInternal(
+ const SdpVideoFormat& format,
+ const absl::optional<std::string>& scalability_mode) const {
+ if (IsFormatInList(format, V::SupportedFormats())) {
+ return {.is_supported = IsScalabilityModeSupported<V>(scalability_mode)};
+ }
+
+ if constexpr (sizeof...(Vs) > 0) {
+ return QueryCodecSupportInternal<Vs...>(format, scalability_mode);
+ }
+
+ return {.is_supported = false};
+ }
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_H_
diff --git a/third_party/libwebrtc/api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h b/third_party/libwebrtc/api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h
new file mode 100644
index 0000000000..417df1e192
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_LIBAOM_AV1_ADAPTER_H_
+#define API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_LIBAOM_AV1_ADAPTER_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/container/inlined_vector.h"
+#include "api/video_codecs/sdp_video_format.h"
+#include "modules/video_coding/codecs/av1/av1_svc_config.h"
+#include "modules/video_coding/codecs/av1/libaom_av1_encoder.h"
+
+namespace webrtc {
+struct LibaomAv1EncoderTemplateAdapter {
+ static std::vector<SdpVideoFormat> SupportedFormats() {
+ absl::InlinedVector<ScalabilityMode, kScalabilityModeCount>
+ scalability_modes = LibaomAv1EncoderSupportedScalabilityModes();
+ return {
+ SdpVideoFormat("AV1", SdpVideoFormat::Parameters(), scalability_modes)};
+ }
+
+ static std::unique_ptr<VideoEncoder> CreateEncoder(
+ const SdpVideoFormat& format) {
+ return CreateLibaomAv1Encoder();
+ }
+
+ static bool IsScalabilityModeSupported(ScalabilityMode scalability_mode) {
+ return LibaomAv1EncoderSupportsScalabilityMode(scalability_mode);
+ }
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_LIBAOM_AV1_ADAPTER_H_
diff --git a/third_party/libwebrtc/api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h b/third_party/libwebrtc/api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h
new file mode 100644
index 0000000000..0f0a9bacd5
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_LIBVPX_VP8_ADAPTER_H_
+#define API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_LIBVPX_VP8_ADAPTER_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/container/inlined_vector.h"
+#include "api/video_codecs/sdp_video_format.h"
+#include "modules/video_coding/codecs/vp8/include/vp8.h"
+#include "modules/video_coding/codecs/vp8/vp8_scalability.h"
+
+namespace webrtc {
+struct LibvpxVp8EncoderTemplateAdapter {
+ static std::vector<SdpVideoFormat> SupportedFormats() {
+ absl::InlinedVector<ScalabilityMode, kScalabilityModeCount>
+ scalability_modes;
+ for (const auto scalability_mode : kVP8SupportedScalabilityModes) {
+ scalability_modes.push_back(scalability_mode);
+ }
+
+ return {
+ SdpVideoFormat("VP8", SdpVideoFormat::Parameters(), scalability_modes)};
+ }
+
+ static std::unique_ptr<VideoEncoder> CreateEncoder(
+ const SdpVideoFormat& format) {
+ return VP8Encoder::Create();
+ }
+
+ static bool IsScalabilityModeSupported(ScalabilityMode scalability_mode) {
+ return VP8SupportsScalabilityMode(scalability_mode);
+ }
+};
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_LIBVPX_VP8_ADAPTER_H_
diff --git a/third_party/libwebrtc/api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h b/third_party/libwebrtc/api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h
new file mode 100644
index 0000000000..c10fda4dc2
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_LIBVPX_VP9_ADAPTER_H_
+#define API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_LIBVPX_VP9_ADAPTER_H_
+
+#include <memory>
+#include <vector>
+
+#include "modules/video_coding/codecs/vp9/include/vp9.h"
+
+namespace webrtc {
+struct LibvpxVp9EncoderTemplateAdapter {
+ static std::vector<SdpVideoFormat> SupportedFormats() {
+ return SupportedVP9Codecs(/*add_scalability_modes=*/true);
+ }
+
+ static std::unique_ptr<VideoEncoder> CreateEncoder(
+ const SdpVideoFormat& format) {
+ return VP9Encoder::Create(cricket::VideoCodec(format));
+ }
+
+ static bool IsScalabilityModeSupported(ScalabilityMode scalability_mode) {
+ return VP9Encoder::SupportsScalabilityMode(scalability_mode);
+ }
+};
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_LIBVPX_VP9_ADAPTER_H_
diff --git a/third_party/libwebrtc/api/video_codecs/video_encoder_factory_template_open_h264_adapter.h b/third_party/libwebrtc/api/video_codecs/video_encoder_factory_template_open_h264_adapter.h
new file mode 100644
index 0000000000..0830460cdb
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_encoder_factory_template_open_h264_adapter.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_OPEN_H264_ADAPTER_H_
+#define API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_OPEN_H264_ADAPTER_H_
+
+#include <memory>
+#include <vector>
+
+#include "modules/video_coding/codecs/h264/include/h264.h"
+
+namespace webrtc {
+// TODO(bugs.webrtc.org/13573): When OpenH264 is no longer a conditional build
+// target remove #ifdefs.
+struct OpenH264EncoderTemplateAdapter {
+ static std::vector<SdpVideoFormat> SupportedFormats() {
+#if defined(WEBRTC_USE_H264)
+ return SupportedH264Codecs(/*add_scalability_modes=*/true);
+#else
+ return {};
+#endif
+ }
+
+ static std::unique_ptr<VideoEncoder> CreateEncoder(
+ const SdpVideoFormat& format) {
+#if defined(WEBRTC_USE_H264)
+ return H264Encoder::Create(cricket::VideoCodec(format));
+#else
+ return nullptr;
+#endif
+ }
+
+ static bool IsScalabilityModeSupported(ScalabilityMode scalability_mode) {
+#if defined(WEBRTC_USE_H264)
+ return H264Encoder::SupportsScalabilityMode(scalability_mode);
+#else
+ return false;
+#endif
+ }
+};
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_OPEN_H264_ADAPTER_H_
diff --git a/third_party/libwebrtc/api/video_codecs/video_encoder_software_fallback_wrapper.cc b/third_party/libwebrtc/api/video_codecs/video_encoder_software_fallback_wrapper.cc
new file mode 100644
index 0000000000..39c52a0081
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_encoder_software_fallback_wrapper.cc
@@ -0,0 +1,519 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/video_encoder_software_fallback_wrapper.h"
+
+#include <stdint.h>
+
+#include <cstdio>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/match.h"
+#include "absl/types/optional.h"
+#include "api/fec_controller_override.h"
+#include "api/video/i420_buffer.h"
+#include "api/video/video_bitrate_allocation.h"
+#include "api/video/video_frame.h"
+#include "api/video_codecs/video_codec.h"
+#include "api/video_codecs/video_encoder.h"
+#include "media/base/video_common.h"
+#include "modules/video_coding/include/video_error_codes.h"
+#include "modules/video_coding/utility/simulcast_utility.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/logging.h"
+#include "system_wrappers/include/field_trial.h"
+
+namespace webrtc {
+
+namespace {
+
+// If forced fallback is allowed, either:
+//
+// 1) The forced fallback is requested if the resolution is less than or equal
+// to `max_pixels_`. The resolution is allowed to be scaled down to
+// `min_pixels_`.
+//
+// 2) The forced fallback is requested if temporal support is preferred and the
+// SW fallback supports temporal layers while the HW encoder does not.
+
+struct ForcedFallbackParams {
+ public:
+ bool SupportsResolutionBasedSwitch(const VideoCodec& codec) const {
+ return enable_resolution_based_switch &&
+ codec.codecType == kVideoCodecVP8 &&
+ codec.numberOfSimulcastStreams <= 1 &&
+ codec.width * codec.height <= max_pixels;
+ }
+
+ bool SupportsTemporalBasedSwitch(const VideoCodec& codec) const {
+ return enable_temporal_based_switch &&
+ SimulcastUtility::NumberOfTemporalLayers(codec, 0) != 1;
+ }
+
+ bool enable_temporal_based_switch = false;
+ bool enable_resolution_based_switch = false;
+ int min_pixels = 320 * 180;
+ int max_pixels = 320 * 240;
+};
+
+const char kVp8ForceFallbackEncoderFieldTrial[] =
+ "WebRTC-VP8-Forced-Fallback-Encoder-v2";
+
+absl::optional<ForcedFallbackParams> ParseFallbackParamsFromFieldTrials(
+ const VideoEncoder& main_encoder) {
+ const std::string field_trial =
+ webrtc::field_trial::FindFullName(kVp8ForceFallbackEncoderFieldTrial);
+ if (!absl::StartsWith(field_trial, "Enabled")) {
+ return absl::nullopt;
+ }
+
+ int max_pixels_lower_bound =
+ main_encoder.GetEncoderInfo().scaling_settings.min_pixels_per_frame - 1;
+
+ ForcedFallbackParams params;
+ params.enable_resolution_based_switch = true;
+
+ int min_bps = 0;
+ if (sscanf(field_trial.c_str(), "Enabled-%d,%d,%d", &params.min_pixels,
+ &params.max_pixels, &min_bps) != 3) {
+ RTC_LOG(LS_WARNING)
+ << "Invalid number of forced fallback parameters provided.";
+ return absl::nullopt;
+ } else if (params.min_pixels <= 0 ||
+ params.max_pixels < max_pixels_lower_bound ||
+ params.max_pixels < params.min_pixels || min_bps <= 0) {
+ RTC_LOG(LS_WARNING) << "Invalid forced fallback parameter value provided.";
+ return absl::nullopt;
+ }
+
+ return params;
+}
+
+absl::optional<ForcedFallbackParams> GetForcedFallbackParams(
+ bool prefer_temporal_support,
+ const VideoEncoder& main_encoder) {
+ absl::optional<ForcedFallbackParams> params =
+ ParseFallbackParamsFromFieldTrials(main_encoder);
+ if (prefer_temporal_support) {
+ if (!params.has_value()) {
+ params.emplace();
+ }
+ params->enable_temporal_based_switch = prefer_temporal_support;
+ }
+ return params;
+}
+
+class VideoEncoderSoftwareFallbackWrapper final : public VideoEncoder {
+ public:
+ VideoEncoderSoftwareFallbackWrapper(
+ std::unique_ptr<webrtc::VideoEncoder> sw_encoder,
+ std::unique_ptr<webrtc::VideoEncoder> hw_encoder,
+ bool prefer_temporal_support);
+ ~VideoEncoderSoftwareFallbackWrapper() override;
+
+ void SetFecControllerOverride(
+ FecControllerOverride* fec_controller_override) override;
+
+ int32_t InitEncode(const VideoCodec* codec_settings,
+ const VideoEncoder::Settings& settings) override;
+
+ int32_t RegisterEncodeCompleteCallback(
+ EncodedImageCallback* callback) override;
+
+ int32_t Release() override;
+
+ int32_t Encode(const VideoFrame& frame,
+ const std::vector<VideoFrameType>* frame_types) override;
+
+ void OnPacketLossRateUpdate(float packet_loss_rate) override;
+
+ void OnRttUpdate(int64_t rtt_ms) override;
+
+ void OnLossNotification(const LossNotification& loss_notification) override;
+
+ void SetRates(const RateControlParameters& parameters) override;
+
+ EncoderInfo GetEncoderInfo() const override;
+
+ private:
+ bool InitFallbackEncoder(bool is_forced);
+ bool TryInitForcedFallbackEncoder();
+ bool IsFallbackActive() const;
+
+ VideoEncoder* current_encoder() {
+ switch (encoder_state_) {
+ case EncoderState::kUninitialized:
+ RTC_LOG(LS_WARNING)
+ << "Trying to access encoder in uninitialized fallback wrapper.";
+ // Return main encoder to preserve previous behavior.
+ [[fallthrough]];
+ case EncoderState::kMainEncoderUsed:
+ return encoder_.get();
+ case EncoderState::kFallbackDueToFailure:
+ case EncoderState::kForcedFallback:
+ return fallback_encoder_.get();
+ }
+ RTC_CHECK_NOTREACHED();
+ }
+
+ // Updates encoder with last observed parameters, such as callbacks, rates,
+ // etc.
+ void PrimeEncoder(VideoEncoder* encoder) const;
+
+ // Settings used in the last InitEncode call and used if a dynamic fallback to
+ // software is required.
+ VideoCodec codec_settings_;
+ absl::optional<VideoEncoder::Settings> encoder_settings_;
+
+ // The last rate control settings, if set.
+ absl::optional<RateControlParameters> rate_control_parameters_;
+
+ // The last channel parameters set.
+ absl::optional<float> packet_loss_;
+ absl::optional<int64_t> rtt_;
+ absl::optional<LossNotification> loss_notification_;
+
+ enum class EncoderState {
+ kUninitialized,
+ kMainEncoderUsed,
+ kFallbackDueToFailure,
+ kForcedFallback
+ };
+
+ EncoderState encoder_state_;
+ const std::unique_ptr<webrtc::VideoEncoder> encoder_;
+ const std::unique_ptr<webrtc::VideoEncoder> fallback_encoder_;
+
+ EncodedImageCallback* callback_;
+
+ const absl::optional<ForcedFallbackParams> fallback_params_;
+ int32_t EncodeWithMainEncoder(const VideoFrame& frame,
+ const std::vector<VideoFrameType>* frame_types);
+};
+
+VideoEncoderSoftwareFallbackWrapper::VideoEncoderSoftwareFallbackWrapper(
+ std::unique_ptr<webrtc::VideoEncoder> sw_encoder,
+ std::unique_ptr<webrtc::VideoEncoder> hw_encoder,
+ bool prefer_temporal_support)
+ : encoder_state_(EncoderState::kUninitialized),
+ encoder_(std::move(hw_encoder)),
+ fallback_encoder_(std::move(sw_encoder)),
+ callback_(nullptr),
+ fallback_params_(
+ GetForcedFallbackParams(prefer_temporal_support, *encoder_)) {
+ RTC_DCHECK(fallback_encoder_);
+}
+
+VideoEncoderSoftwareFallbackWrapper::~VideoEncoderSoftwareFallbackWrapper() =
+ default;
+
+void VideoEncoderSoftwareFallbackWrapper::PrimeEncoder(
+ VideoEncoder* encoder) const {
+ RTC_DCHECK(encoder);
+ // Replay callback, rates, and channel parameters.
+ if (callback_) {
+ encoder->RegisterEncodeCompleteCallback(callback_);
+ }
+ if (rate_control_parameters_) {
+ encoder->SetRates(*rate_control_parameters_);
+ }
+ if (rtt_.has_value()) {
+ encoder->OnRttUpdate(rtt_.value());
+ }
+ if (packet_loss_.has_value()) {
+ encoder->OnPacketLossRateUpdate(packet_loss_.value());
+ }
+
+ if (loss_notification_.has_value()) {
+ encoder->OnLossNotification(loss_notification_.value());
+ }
+}
+
+bool VideoEncoderSoftwareFallbackWrapper::InitFallbackEncoder(bool is_forced) {
+ RTC_LOG(LS_WARNING) << "Encoder falling back to software encoding.";
+
+ RTC_DCHECK(encoder_settings_.has_value());
+ const int ret = fallback_encoder_->InitEncode(&codec_settings_,
+ encoder_settings_.value());
+
+ if (ret != WEBRTC_VIDEO_CODEC_OK) {
+ RTC_LOG(LS_ERROR) << "Failed to initialize software-encoder fallback.";
+ fallback_encoder_->Release();
+ return false;
+ }
+
+ if (encoder_state_ == EncoderState::kMainEncoderUsed) {
+ // Since we're switching to the fallback encoder, Release the real encoder.
+ // It may be re-initialized via InitEncode later, and it will continue to
+ // get Set calls for rates and channel parameters in the meantime.
+ encoder_->Release();
+ }
+
+ if (is_forced) {
+ encoder_state_ = EncoderState::kForcedFallback;
+ } else {
+ encoder_state_ = EncoderState::kFallbackDueToFailure;
+ }
+
+ return true;
+}
+
+void VideoEncoderSoftwareFallbackWrapper::SetFecControllerOverride(
+ FecControllerOverride* fec_controller_override) {
+ // It is important that only one of those would ever interact with the
+ // `fec_controller_override` at a given time. This is the responsibility
+ // of `this` to maintain.
+
+ encoder_->SetFecControllerOverride(fec_controller_override);
+ fallback_encoder_->SetFecControllerOverride(fec_controller_override);
+}
+
+int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode(
+ const VideoCodec* codec_settings,
+ const VideoEncoder::Settings& settings) {
+ // Store settings, in case we need to dynamically switch to the fallback
+ // encoder after a failed Encode call.
+ codec_settings_ = *codec_settings;
+ encoder_settings_ = settings;
+ // Clear stored rate/channel parameters.
+ rate_control_parameters_ = absl::nullopt;
+
+ RTC_DCHECK_EQ(encoder_state_, EncoderState::kUninitialized)
+ << "InitEncode() should never be called on an active instance!";
+
+ // Try to init forced software codec if it should be used.
+ if (TryInitForcedFallbackEncoder()) {
+ PrimeEncoder(current_encoder());
+ return WEBRTC_VIDEO_CODEC_OK;
+ }
+
+ int32_t ret = encoder_->InitEncode(codec_settings, settings);
+ if (ret == WEBRTC_VIDEO_CODEC_OK) {
+ encoder_state_ = EncoderState::kMainEncoderUsed;
+ PrimeEncoder(current_encoder());
+ return ret;
+ }
+
+ // Try to instantiate software codec.
+ if (InitFallbackEncoder(/*is_forced=*/false)) {
+ PrimeEncoder(current_encoder());
+ return WEBRTC_VIDEO_CODEC_OK;
+ }
+
+ // Software encoder failed too, use original return code.
+ encoder_state_ = EncoderState::kUninitialized;
+ return ret;
+}
+
+int32_t VideoEncoderSoftwareFallbackWrapper::RegisterEncodeCompleteCallback(
+ EncodedImageCallback* callback) {
+ callback_ = callback;
+ return current_encoder()->RegisterEncodeCompleteCallback(callback);
+}
+
+int32_t VideoEncoderSoftwareFallbackWrapper::Release() {
+ if (encoder_state_ == EncoderState::kUninitialized) {
+ return WEBRTC_VIDEO_CODEC_OK;
+ }
+ int32_t ret = current_encoder()->Release();
+ encoder_state_ = EncoderState::kUninitialized;
+ return ret;
+}
+
+int32_t VideoEncoderSoftwareFallbackWrapper::Encode(
+ const VideoFrame& frame,
+ const std::vector<VideoFrameType>* frame_types) {
+ switch (encoder_state_) {
+ case EncoderState::kUninitialized:
+ return WEBRTC_VIDEO_CODEC_ERROR;
+ case EncoderState::kMainEncoderUsed: {
+ return EncodeWithMainEncoder(frame, frame_types);
+ }
+ case EncoderState::kFallbackDueToFailure:
+ case EncoderState::kForcedFallback:
+ return fallback_encoder_->Encode(frame, frame_types);
+ }
+ RTC_CHECK_NOTREACHED();
+}
+
+int32_t VideoEncoderSoftwareFallbackWrapper::EncodeWithMainEncoder(
+ const VideoFrame& frame,
+ const std::vector<VideoFrameType>* frame_types) {
+ int32_t ret = encoder_->Encode(frame, frame_types);
+ // If requested, try a software fallback.
+ bool fallback_requested = (ret == WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE);
+ if (fallback_requested && InitFallbackEncoder(/*is_forced=*/false)) {
+ // Start using the fallback with this frame.
+ PrimeEncoder(current_encoder());
+ if (frame.video_frame_buffer()->type() == VideoFrameBuffer::Type::kNative &&
+ fallback_encoder_->GetEncoderInfo().supports_native_handle) {
+ return fallback_encoder_->Encode(frame, frame_types);
+ } else {
+ RTC_LOG(LS_INFO) << "Fallback encoder does not support native handle - "
+ "converting frame to I420";
+ rtc::scoped_refptr<I420BufferInterface> src_buffer =
+ frame.video_frame_buffer()->ToI420();
+ if (!src_buffer) {
+ RTC_LOG(LS_ERROR) << "Failed to convert from to I420";
+ return WEBRTC_VIDEO_CODEC_ENCODER_FAILURE;
+ }
+ rtc::scoped_refptr<VideoFrameBuffer> dst_buffer =
+ src_buffer->Scale(codec_settings_.width, codec_settings_.height);
+ if (!dst_buffer) {
+ RTC_LOG(LS_ERROR) << "Failed to scale video frame.";
+ return WEBRTC_VIDEO_CODEC_ENCODER_FAILURE;
+ }
+ VideoFrame scaled_frame = frame;
+ scaled_frame.set_video_frame_buffer(dst_buffer);
+ scaled_frame.set_update_rect(VideoFrame::UpdateRect{
+ 0, 0, scaled_frame.width(), scaled_frame.height()});
+ return fallback_encoder_->Encode(scaled_frame, frame_types);
+ }
+ }
+ // Fallback encoder failed too, return original error code.
+ return ret;
+}
+
+void VideoEncoderSoftwareFallbackWrapper::SetRates(
+ const RateControlParameters& parameters) {
+ rate_control_parameters_ = parameters;
+ return current_encoder()->SetRates(parameters);
+}
+
+void VideoEncoderSoftwareFallbackWrapper::OnPacketLossRateUpdate(
+ float packet_loss_rate) {
+ packet_loss_ = packet_loss_rate;
+ current_encoder()->OnPacketLossRateUpdate(packet_loss_rate);
+}
+
+void VideoEncoderSoftwareFallbackWrapper::OnRttUpdate(int64_t rtt_ms) {
+ rtt_ = rtt_ms;
+ current_encoder()->OnRttUpdate(rtt_ms);
+}
+
+void VideoEncoderSoftwareFallbackWrapper::OnLossNotification(
+ const LossNotification& loss_notification) {
+ loss_notification_ = loss_notification;
+ current_encoder()->OnLossNotification(loss_notification);
+}
+
+VideoEncoder::EncoderInfo VideoEncoderSoftwareFallbackWrapper::GetEncoderInfo()
+ const {
+ EncoderInfo fallback_encoder_info = fallback_encoder_->GetEncoderInfo();
+ EncoderInfo default_encoder_info = encoder_->GetEncoderInfo();
+
+ EncoderInfo info =
+ IsFallbackActive() ? fallback_encoder_info : default_encoder_info;
+
+ info.requested_resolution_alignment = cricket::LeastCommonMultiple(
+ fallback_encoder_info.requested_resolution_alignment,
+ default_encoder_info.requested_resolution_alignment);
+ info.apply_alignment_to_all_simulcast_layers =
+ fallback_encoder_info.apply_alignment_to_all_simulcast_layers ||
+ default_encoder_info.apply_alignment_to_all_simulcast_layers;
+
+ if (fallback_params_.has_value()) {
+ const auto settings = (encoder_state_ == EncoderState::kForcedFallback)
+ ? fallback_encoder_info.scaling_settings
+ : default_encoder_info.scaling_settings;
+ info.scaling_settings =
+ settings.thresholds
+ ? VideoEncoder::ScalingSettings(settings.thresholds->low,
+ settings.thresholds->high,
+ fallback_params_->min_pixels)
+ : VideoEncoder::ScalingSettings::kOff;
+ } else {
+ info.scaling_settings = default_encoder_info.scaling_settings;
+ }
+
+ return info;
+}
+
+bool VideoEncoderSoftwareFallbackWrapper::IsFallbackActive() const {
+ return encoder_state_ == EncoderState::kForcedFallback ||
+ encoder_state_ == EncoderState::kFallbackDueToFailure;
+}
+
+bool VideoEncoderSoftwareFallbackWrapper::TryInitForcedFallbackEncoder() {
+ if (!fallback_params_) {
+ return false;
+ }
+
+ RTC_DCHECK_EQ(encoder_state_, EncoderState::kUninitialized);
+
+ if (fallback_params_->SupportsResolutionBasedSwitch(codec_settings_)) {
+ // Settings valid, try to instantiate software codec.
+ RTC_LOG(LS_INFO) << "Request forced SW encoder fallback: "
+ << codec_settings_.width << "x" << codec_settings_.height;
+ return InitFallbackEncoder(/*is_forced=*/true);
+ }
+
+ if (fallback_params_->SupportsTemporalBasedSwitch(codec_settings_)) {
+ // First init main encoder to see if that supports temporal layers.
+ if (encoder_->InitEncode(&codec_settings_, encoder_settings_.value()) ==
+ WEBRTC_VIDEO_CODEC_OK) {
+ encoder_state_ = EncoderState::kMainEncoderUsed;
+ }
+
+ if (encoder_state_ == EncoderState::kMainEncoderUsed &&
+ encoder_->GetEncoderInfo().fps_allocation[0].size() != 1) {
+ // Primary encoder already supports temporal layers, use that instead.
+ return true;
+ }
+
+ // Try to initialize fallback and check if it supports temporal layers.
+ if (fallback_encoder_->InitEncode(&codec_settings_,
+ encoder_settings_.value()) ==
+ WEBRTC_VIDEO_CODEC_OK) {
+ if (fallback_encoder_->GetEncoderInfo().fps_allocation[0].size() != 1) {
+ // Fallback encoder available and supports temporal layers, use it!
+ if (encoder_state_ == EncoderState::kMainEncoderUsed) {
+ // Main encoder initialized but does not support temporal layers,
+ // release it again.
+ encoder_->Release();
+ }
+ encoder_state_ = EncoderState::kForcedFallback;
+ RTC_LOG(LS_INFO)
+ << "Forced switch to SW encoder due to temporal support.";
+ return true;
+ } else {
+ // Fallback encoder intialization succeeded, but it does not support
+ // temporal layers either - release it.
+ fallback_encoder_->Release();
+ }
+ }
+
+ if (encoder_state_ == EncoderState::kMainEncoderUsed) {
+ // Main encoder already initialized - make use of it.
+ RTC_LOG(LS_INFO)
+ << "Cannot fall back for temporal support since fallback that "
+ "supports is not available. Using main encoder instead.";
+ return true;
+ }
+ }
+
+ // Neither forced fallback mode supported.
+ return false;
+}
+
+} // namespace
+
+std::unique_ptr<VideoEncoder> CreateVideoEncoderSoftwareFallbackWrapper(
+ std::unique_ptr<VideoEncoder> sw_fallback_encoder,
+ std::unique_ptr<VideoEncoder> hw_encoder,
+ bool prefer_temporal_support) {
+ return std::make_unique<VideoEncoderSoftwareFallbackWrapper>(
+ std::move(sw_fallback_encoder), std::move(hw_encoder),
+ prefer_temporal_support);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/video_encoder_software_fallback_wrapper.h b/third_party/libwebrtc/api/video_codecs/video_encoder_software_fallback_wrapper.h
new file mode 100644
index 0000000000..6e6902eb3f
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/video_encoder_software_fallback_wrapper.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VIDEO_ENCODER_SOFTWARE_FALLBACK_WRAPPER_H_
+#define API_VIDEO_CODECS_VIDEO_ENCODER_SOFTWARE_FALLBACK_WRAPPER_H_
+
+#include <memory>
+#include <utility>
+
+#include "api/video_codecs/video_encoder.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Used to wrap external VideoEncoders to provide a fallback option on
+// software encoding when a hardware encoder fails to encode a stream due to
+// hardware restrictions, such as max resolution.
+// |bool prefer_temporal_support| indicates that if the software fallback
+// encoder supports temporal layers but the hardware encoder does not, a
+// fallback should be forced even if the encoder otherwise works.
+RTC_EXPORT std::unique_ptr<VideoEncoder>
+CreateVideoEncoderSoftwareFallbackWrapper(
+ std::unique_ptr<VideoEncoder> sw_fallback_encoder,
+ std::unique_ptr<VideoEncoder> hw_encoder,
+ bool prefer_temporal_support);
+
+// Default fallback for call-sites not yet updated with
+// `prefer_temporal_support`.
+// TODO(sprang): Remove when usage is gone.
+RTC_EXPORT inline std::unique_ptr<VideoEncoder>
+CreateVideoEncoderSoftwareFallbackWrapper(
+ std::unique_ptr<VideoEncoder> sw_fallback_encoder,
+ std::unique_ptr<VideoEncoder> hw_encoder) {
+ return CreateVideoEncoderSoftwareFallbackWrapper(
+ std::move(sw_fallback_encoder), std::move(hw_encoder), false);
+}
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VIDEO_ENCODER_SOFTWARE_FALLBACK_WRAPPER_H_
diff --git a/third_party/libwebrtc/api/video_codecs/vp8_frame_buffer_controller.h b/third_party/libwebrtc/api/video_codecs/vp8_frame_buffer_controller.h
new file mode 100644
index 0000000000..fc494f7293
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/vp8_frame_buffer_controller.h
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VP8_FRAME_BUFFER_CONTROLLER_H_
+#define API_VIDEO_CODECS_VP8_FRAME_BUFFER_CONTROLLER_H_
+
+#include <array>
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/fec_controller_override.h"
+#include "api/video_codecs/video_codec.h"
+#include "api/video_codecs/video_encoder.h"
+#include "api/video_codecs/vp8_frame_config.h"
+
+namespace webrtc {
+
+// Some notes on the prerequisites of the TemporalLayers interface.
+// * Vp8FrameBufferController is not thread safe, synchronization is the
+// caller's responsibility.
+// * The encoder is assumed to encode all frames in order, and callbacks to
+// PopulateCodecSpecific() / OnEncodeDone() must happen in the same order.
+//
+// This means that in the case of pipelining encoders, it is OK to have a chain
+// of calls such as this:
+// - NextFrameConfig(timestampA)
+// - NextFrameConfig(timestampB)
+// - PopulateCodecSpecific(timestampA, ...)
+// - NextFrameConfig(timestampC)
+// - OnEncodeDone(timestampA, 1234, ...)
+// - NextFrameConfig(timestampC)
+// - OnEncodeDone(timestampB, 0, ...)
+// - OnEncodeDone(timestampC, 1234, ...)
+// Note that NextFrameConfig() for a new frame can happen before
+// OnEncodeDone() for a previous one, but calls themselves must be both
+// synchronized (e.g. run on a task queue) and in order (per type).
+//
+// TODO(eladalon): Revise comment (referring to PopulateCodecSpecific in this
+// context is not very meaningful).
+
+struct CodecSpecificInfo;
+
+// Each member represents an override of the VPX configuration if the optional
+// value is set.
+struct Vp8EncoderConfig {
+ struct TemporalLayerConfig {
+ bool operator!=(const TemporalLayerConfig& other) const {
+ return ts_number_layers != other.ts_number_layers ||
+ ts_target_bitrate != other.ts_target_bitrate ||
+ ts_rate_decimator != other.ts_rate_decimator ||
+ ts_periodicity != other.ts_periodicity ||
+ ts_layer_id != other.ts_layer_id;
+ }
+
+ static constexpr size_t kMaxPeriodicity = 16;
+ static constexpr size_t kMaxLayers = 5;
+
+ // Number of active temporal layers. Set to 0 if not used.
+ uint32_t ts_number_layers;
+
+ // Arrays of length `ts_number_layers`, indicating (cumulative) target
+ // bitrate and rate decimator (e.g. 4 if every 4th frame is in the given
+ // layer) for each active temporal layer, starting with temporal id 0.
+ std::array<uint32_t, kMaxLayers> ts_target_bitrate;
+ std::array<uint32_t, kMaxLayers> ts_rate_decimator;
+
+ // The periodicity of the temporal pattern. Set to 0 if not used.
+ uint32_t ts_periodicity;
+
+ // Array of length `ts_periodicity` indicating the sequence of temporal id's
+ // to assign to incoming frames.
+ std::array<uint32_t, kMaxPeriodicity> ts_layer_id;
+ };
+
+ absl::optional<TemporalLayerConfig> temporal_layer_config;
+
+ // Target bitrate, in bps.
+ absl::optional<uint32_t> rc_target_bitrate;
+
+ // Clamp QP to max. Use 0 to disable clamping.
+ absl::optional<uint32_t> rc_max_quantizer;
+
+ // Error resilience mode.
+ absl::optional<uint32_t> g_error_resilient;
+
+ // If set to true, all previous configuration overrides should be reset.
+ bool reset_previous_configuration_overrides = false;
+};
+
+// This interface defines a way of delegating the logic of buffer management.
+// Multiple streams may be controlled by a single controller, demuxing between
+// them using stream_index.
+class Vp8FrameBufferController {
+ public:
+ virtual ~Vp8FrameBufferController() = default;
+
+ // Set limits on QP.
+ // The limits are suggestion-only; the controller is allowed to exceed them.
+ virtual void SetQpLimits(size_t stream_index, int min_qp, int max_qp) = 0;
+
+ // Number of streamed controlled by `this`.
+ virtual size_t StreamCount() const = 0;
+
+ // If this method returns true, the encoder is free to drop frames for
+ // instance in an effort to uphold encoding bitrate.
+ // If this return false, the encoder must not drop any frames unless:
+ // 1. Requested to do so via Vp8FrameConfig.drop_frame
+ // 2. The frame to be encoded is requested to be a keyframe
+ // 3. The encoder detected a large overshoot and decided to drop and then
+ // re-encode the image at a low bitrate. In this case the encoder should
+ // call OnFrameDropped() once to indicate drop, and then call
+ // OnEncodeDone() again when the frame has actually been encoded.
+ virtual bool SupportsEncoderFrameDropping(size_t stream_index) const = 0;
+
+ // New target bitrate for a stream (each entry in
+ // `bitrates_bps` is for another temporal layer).
+ virtual void OnRatesUpdated(size_t stream_index,
+ const std::vector<uint32_t>& bitrates_bps,
+ int framerate_fps) = 0;
+
+ // Called by the encoder before encoding a frame. Returns a set of overrides
+ // the controller wishes to enact in the encoder's configuration.
+ // If a value is not overridden, previous overrides are still in effect.
+ // However, if `Vp8EncoderConfig::reset_previous_configuration_overrides`
+ // is set to `true`, all previous overrides are reset.
+ virtual Vp8EncoderConfig UpdateConfiguration(size_t stream_index) = 0;
+
+ // Returns the recommended VP8 encode flags needed.
+ // The timestamp may be used as both a time and a unique identifier, and so
+ // the caller must make sure no two frames use the same timestamp.
+ // The timestamp uses a 90kHz RTP clock.
+ // After calling this method, first call the actual encoder with the provided
+ // frame configuration, and then OnEncodeDone() below.
+ virtual Vp8FrameConfig NextFrameConfig(size_t stream_index,
+ uint32_t rtp_timestamp) = 0;
+
+ // Called after the encode step is done. `rtp_timestamp` must match the
+ // parameter use in the NextFrameConfig() call.
+ // `is_keyframe` must be true iff the encoder decided to encode this frame as
+ // a keyframe.
+ // If `info` is not null, the encoder may update `info` with codec specific
+ // data such as temporal id. `qp` should indicate the frame-level QP this
+ // frame was encoded at. If the encoder does not support extracting this, `qp`
+ // should be set to 0.
+ virtual void OnEncodeDone(size_t stream_index,
+ uint32_t rtp_timestamp,
+ size_t size_bytes,
+ bool is_keyframe,
+ int qp,
+ CodecSpecificInfo* info) = 0;
+
+ // Called when a frame is dropped by the encoder.
+ virtual void OnFrameDropped(size_t stream_index, uint32_t rtp_timestamp) = 0;
+
+ // Called by the encoder when the packet loss rate changes.
+ // `packet_loss_rate` runs between 0.0 (no loss) and 1.0 (everything lost).
+ virtual void OnPacketLossRateUpdate(float packet_loss_rate) = 0;
+
+ // Called by the encoder when the round trip time changes.
+ virtual void OnRttUpdate(int64_t rtt_ms) = 0;
+
+ // Called when a loss notification is received.
+ virtual void OnLossNotification(
+ const VideoEncoder::LossNotification& loss_notification) = 0;
+};
+
+// Interface for a factory of Vp8FrameBufferController instances.
+class Vp8FrameBufferControllerFactory {
+ public:
+ virtual ~Vp8FrameBufferControllerFactory() = default;
+
+ // Clones oneself. (Avoids Vp8FrameBufferControllerFactoryFactory.)
+ virtual std::unique_ptr<Vp8FrameBufferControllerFactory> Clone() const = 0;
+
+ // Create a Vp8FrameBufferController instance.
+ virtual std::unique_ptr<Vp8FrameBufferController> Create(
+ const VideoCodec& codec,
+ const VideoEncoder::Settings& settings,
+ FecControllerOverride* fec_controller_override) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VP8_FRAME_BUFFER_CONTROLLER_H_
diff --git a/third_party/libwebrtc/api/video_codecs/vp8_frame_config.cc b/third_party/libwebrtc/api/video_codecs/vp8_frame_config.cc
new file mode 100644
index 0000000000..05e1911bb7
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/vp8_frame_config.cc
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/vp8_frame_config.h"
+
+#include "modules/video_coding/codecs/interface/common_constants.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+Vp8FrameConfig::Vp8FrameConfig() : Vp8FrameConfig(kNone, kNone, kNone, false) {}
+
+Vp8FrameConfig::Vp8FrameConfig(BufferFlags last,
+ BufferFlags golden,
+ BufferFlags arf)
+ : Vp8FrameConfig(last, golden, arf, false) {}
+
+Vp8FrameConfig::Vp8FrameConfig(BufferFlags last,
+ BufferFlags golden,
+ BufferFlags arf,
+ FreezeEntropy)
+ : Vp8FrameConfig(last, golden, arf, true) {}
+
+Vp8FrameConfig::Vp8FrameConfig(BufferFlags last,
+ BufferFlags golden,
+ BufferFlags arf,
+ bool freeze_entropy)
+ : drop_frame(last == BufferFlags::kNone && golden == BufferFlags::kNone &&
+ arf == BufferFlags::kNone),
+ last_buffer_flags(last),
+ golden_buffer_flags(golden),
+ arf_buffer_flags(arf),
+ encoder_layer_id(0),
+ packetizer_temporal_idx(kNoTemporalIdx),
+ layer_sync(false),
+ freeze_entropy(freeze_entropy),
+ first_reference(Vp8BufferReference::kNone),
+ second_reference(Vp8BufferReference::kNone),
+ retransmission_allowed(true) {}
+
+bool Vp8FrameConfig::References(Buffer buffer) const {
+ switch (buffer) {
+ case Buffer::kLast:
+ return (last_buffer_flags & kReference) != 0;
+ case Buffer::kGolden:
+ return (golden_buffer_flags & kReference) != 0;
+ case Buffer::kArf:
+ return (arf_buffer_flags & kReference) != 0;
+ case Buffer::kCount:
+ break;
+ }
+ RTC_DCHECK_NOTREACHED();
+ return false;
+}
+
+bool Vp8FrameConfig::Updates(Buffer buffer) const {
+ switch (buffer) {
+ case Buffer::kLast:
+ return (last_buffer_flags & kUpdate) != 0;
+ case Buffer::kGolden:
+ return (golden_buffer_flags & kUpdate) != 0;
+ case Buffer::kArf:
+ return (arf_buffer_flags & kUpdate) != 0;
+ case Buffer::kCount:
+ break;
+ }
+ RTC_DCHECK_NOTREACHED();
+ return false;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/vp8_frame_config.h b/third_party/libwebrtc/api/video_codecs/vp8_frame_config.h
new file mode 100644
index 0000000000..5369bf58bc
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/vp8_frame_config.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VP8_FRAME_CONFIG_H_
+#define API_VIDEO_CODECS_VP8_FRAME_CONFIG_H_
+
+#include <stdint.h>
+
+namespace webrtc {
+
+// Configuration of a VP8 frame - which buffers are to be referenced
+// by it, which buffers should be updated, etc.
+struct Vp8FrameConfig {
+ static Vp8FrameConfig GetIntraFrameConfig() {
+ Vp8FrameConfig frame_config = Vp8FrameConfig(
+ BufferFlags::kUpdate, BufferFlags::kUpdate, BufferFlags::kUpdate);
+ frame_config.packetizer_temporal_idx = 0;
+ return frame_config;
+ }
+
+ enum BufferFlags : int {
+ kNone = 0,
+ kReference = 1,
+ kUpdate = 2,
+ kReferenceAndUpdate = kReference | kUpdate,
+ };
+
+ enum FreezeEntropy { kFreezeEntropy };
+
+ // Defined bit-maskable reference to the three buffers available in VP8.
+ enum class Vp8BufferReference : uint8_t {
+ kNone = 0,
+ kLast = 1,
+ kGolden = 2,
+ kAltref = 4
+ };
+
+ Vp8FrameConfig();
+
+ Vp8FrameConfig(BufferFlags last, BufferFlags golden, BufferFlags arf);
+ Vp8FrameConfig(BufferFlags last,
+ BufferFlags golden,
+ BufferFlags arf,
+ FreezeEntropy);
+
+ enum class Buffer : int { kLast = 0, kGolden = 1, kArf = 2, kCount };
+
+ bool References(Buffer buffer) const;
+
+ bool Updates(Buffer buffer) const;
+
+ bool IntraFrame() const {
+ // Intra frames do not reference any buffers, and update all buffers.
+ return last_buffer_flags == kUpdate && golden_buffer_flags == kUpdate &&
+ arf_buffer_flags == kUpdate;
+ }
+
+ bool drop_frame;
+ BufferFlags last_buffer_flags;
+ BufferFlags golden_buffer_flags;
+ BufferFlags arf_buffer_flags;
+
+ // The encoder layer ID is used to utilize the correct bitrate allocator
+ // inside the encoder. It does not control references nor determine which
+ // "actual" temporal layer this is. The packetizer temporal index determines
+ // which layer the encoded frame should be packetized into.
+ // Normally these are the same, but current temporal-layer strategies for
+ // screenshare use one bitrate allocator for all layers, but attempt to
+ // packetize / utilize references to split a stream into multiple layers,
+ // with different quantizer settings, to hit target bitrate.
+ // TODO(sprang): Screenshare layers are being reconsidered at the time of
+ // writing, we might be able to remove this distinction, and have a temporal
+ // layer imply both (the normal case).
+ int encoder_layer_id;
+ // TODO(eladalon/sprang): Move out of this class.
+ int packetizer_temporal_idx;
+
+ // TODO(eladalon/sprang): Move out of this class.
+ bool layer_sync;
+
+ bool freeze_entropy;
+
+ // Indicates in which order the encoder should search the reference buffers
+ // when doing motion prediction. Set to kNone to use unspecified order. Any
+ // buffer indicated here must not have the corresponding no_ref bit set.
+ // If all three buffers can be reference, the one not listed here should be
+ // searched last.
+ Vp8BufferReference first_reference;
+ Vp8BufferReference second_reference;
+
+ // Whether this frame is eligible for retransmission.
+ bool retransmission_allowed;
+
+ private:
+ Vp8FrameConfig(BufferFlags last,
+ BufferFlags golden,
+ BufferFlags arf,
+ bool freeze_entropy);
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VP8_FRAME_CONFIG_H_
diff --git a/third_party/libwebrtc/api/video_codecs/vp8_temporal_layers.cc b/third_party/libwebrtc/api/video_codecs/vp8_temporal_layers.cc
new file mode 100644
index 0000000000..dd75c616d8
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/vp8_temporal_layers.cc
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/vp8_temporal_layers.h"
+
+#include <utility>
+
+#include "absl/algorithm/container.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+Vp8TemporalLayers::Vp8TemporalLayers(
+ std::vector<std::unique_ptr<Vp8FrameBufferController>>&& controllers,
+ FecControllerOverride* fec_controller_override)
+ : controllers_(std::move(controllers)) {
+ RTC_DCHECK(!controllers_.empty());
+ RTC_DCHECK(absl::c_none_of(
+ controllers_,
+ [](const std::unique_ptr<Vp8FrameBufferController>& controller) {
+ return controller.get() == nullptr;
+ }));
+ if (fec_controller_override) {
+ fec_controller_override->SetFecAllowed(true);
+ }
+}
+
+void Vp8TemporalLayers::SetQpLimits(size_t stream_index,
+ int min_qp,
+ int max_qp) {
+ RTC_DCHECK_LT(stream_index, controllers_.size());
+ return controllers_[stream_index]->SetQpLimits(0, min_qp, max_qp);
+}
+
+size_t Vp8TemporalLayers::StreamCount() const {
+ return controllers_.size();
+}
+
+bool Vp8TemporalLayers::SupportsEncoderFrameDropping(
+ size_t stream_index) const {
+ RTC_DCHECK_LT(stream_index, controllers_.size());
+ return controllers_[stream_index]->SupportsEncoderFrameDropping(0);
+}
+
+void Vp8TemporalLayers::OnRatesUpdated(
+ size_t stream_index,
+ const std::vector<uint32_t>& bitrates_bps,
+ int framerate_fps) {
+ RTC_DCHECK_LT(stream_index, controllers_.size());
+ return controllers_[stream_index]->OnRatesUpdated(0, bitrates_bps,
+ framerate_fps);
+}
+
+Vp8EncoderConfig Vp8TemporalLayers::UpdateConfiguration(size_t stream_index) {
+ RTC_DCHECK_LT(stream_index, controllers_.size());
+ return controllers_[stream_index]->UpdateConfiguration(0);
+}
+
+Vp8FrameConfig Vp8TemporalLayers::NextFrameConfig(size_t stream_index,
+ uint32_t rtp_timestamp) {
+ RTC_DCHECK_LT(stream_index, controllers_.size());
+ return controllers_[stream_index]->NextFrameConfig(0, rtp_timestamp);
+}
+
+void Vp8TemporalLayers::OnEncodeDone(size_t stream_index,
+ uint32_t rtp_timestamp,
+ size_t size_bytes,
+ bool is_keyframe,
+ int qp,
+ CodecSpecificInfo* info) {
+ RTC_DCHECK_LT(stream_index, controllers_.size());
+ return controllers_[stream_index]->OnEncodeDone(0, rtp_timestamp, size_bytes,
+ is_keyframe, qp, info);
+}
+
+void Vp8TemporalLayers::OnFrameDropped(size_t stream_index,
+ uint32_t rtp_timestamp) {
+ RTC_DCHECK_LT(stream_index, controllers_.size());
+ controllers_[stream_index]->OnFrameDropped(stream_index, rtp_timestamp);
+}
+
+void Vp8TemporalLayers::OnPacketLossRateUpdate(float packet_loss_rate) {
+ for (auto& controller : controllers_) {
+ controller->OnPacketLossRateUpdate(packet_loss_rate);
+ }
+}
+
+void Vp8TemporalLayers::OnRttUpdate(int64_t rtt_ms) {
+ for (auto& controller : controllers_) {
+ controller->OnRttUpdate(rtt_ms);
+ }
+}
+
+void Vp8TemporalLayers::OnLossNotification(
+ const VideoEncoder::LossNotification& loss_notification) {
+ for (auto& controller : controllers_) {
+ controller->OnLossNotification(loss_notification);
+ }
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/vp8_temporal_layers.h b/third_party/libwebrtc/api/video_codecs/vp8_temporal_layers.h
new file mode 100644
index 0000000000..2ffe6eacdf
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/vp8_temporal_layers.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VP8_TEMPORAL_LAYERS_H_
+#define API_VIDEO_CODECS_VP8_TEMPORAL_LAYERS_H_
+
+#include <memory>
+#include <vector>
+
+#include "api/fec_controller_override.h"
+#include "api/video_codecs/video_codec.h"
+#include "api/video_codecs/vp8_frame_buffer_controller.h"
+#include "api/video_codecs/vp8_frame_config.h"
+
+namespace webrtc {
+
+// Two different flavors of temporal layers are currently available:
+// kFixedPattern uses a fixed repeating pattern of 1-4 layers.
+// kBitrateDynamic can allocate frames dynamically to 1 or 2 layers, based on
+// the bitrate produced.
+// TODO(eladalon): Remove this enum.
+enum class Vp8TemporalLayersType { kFixedPattern, kBitrateDynamic };
+
+// This interface defines a way of getting the encoder settings needed to
+// realize a temporal layer structure.
+class Vp8TemporalLayers final : public Vp8FrameBufferController {
+ public:
+ Vp8TemporalLayers(
+ std::vector<std::unique_ptr<Vp8FrameBufferController>>&& controllers,
+ FecControllerOverride* fec_controller_override);
+ ~Vp8TemporalLayers() override = default;
+
+ void SetQpLimits(size_t stream_index, int min_qp, int max_qp) override;
+
+ size_t StreamCount() const override;
+
+ bool SupportsEncoderFrameDropping(size_t stream_index) const override;
+
+ void OnRatesUpdated(size_t stream_index,
+ const std::vector<uint32_t>& bitrates_bps,
+ int framerate_fps) override;
+
+ Vp8EncoderConfig UpdateConfiguration(size_t stream_index) override;
+
+ Vp8FrameConfig NextFrameConfig(size_t stream_index,
+ uint32_t rtp_timestamp) override;
+
+ void OnEncodeDone(size_t stream_index,
+ uint32_t rtp_timestamp,
+ size_t size_bytes,
+ bool is_keyframe,
+ int qp,
+ CodecSpecificInfo* info) override;
+
+ void OnFrameDropped(size_t stream_index, uint32_t rtp_timestamp) override;
+
+ void OnPacketLossRateUpdate(float packet_loss_rate) override;
+
+ void OnRttUpdate(int64_t rtt_ms) override;
+
+ void OnLossNotification(
+ const VideoEncoder::LossNotification& loss_notification) override;
+
+ private:
+ std::vector<std::unique_ptr<Vp8FrameBufferController>> controllers_;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VP8_TEMPORAL_LAYERS_H_
diff --git a/third_party/libwebrtc/api/video_codecs/vp8_temporal_layers_factory.cc b/third_party/libwebrtc/api/video_codecs/vp8_temporal_layers_factory.cc
new file mode 100644
index 0000000000..193494d71d
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/vp8_temporal_layers_factory.cc
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/vp8_temporal_layers_factory.h"
+
+#include <algorithm>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "api/fec_controller_override.h"
+#include "modules/video_coding/codecs/vp8/default_temporal_layers.h"
+#include "modules/video_coding/codecs/vp8/screenshare_layers.h"
+#include "modules/video_coding/utility/simulcast_utility.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+std::unique_ptr<Vp8FrameBufferController> Vp8TemporalLayersFactory::Create(
+ const VideoCodec& codec,
+ const VideoEncoder::Settings& settings,
+ FecControllerOverride* fec_controller_override) {
+ std::vector<std::unique_ptr<Vp8FrameBufferController>> controllers;
+ const int num_streams = SimulcastUtility::NumberOfSimulcastStreams(codec);
+ RTC_DCHECK_GE(num_streams, 1);
+ controllers.reserve(num_streams);
+
+ for (int i = 0; i < num_streams; ++i) {
+ int num_temporal_layers =
+ SimulcastUtility::NumberOfTemporalLayers(codec, i);
+ RTC_DCHECK_GE(num_temporal_layers, 1);
+ if (SimulcastUtility::IsConferenceModeScreenshare(codec) && i == 0) {
+ // Legacy screenshare layers supports max 2 layers.
+ num_temporal_layers = std::max(2, num_temporal_layers);
+ controllers.push_back(
+ std::make_unique<ScreenshareLayers>(num_temporal_layers));
+ } else {
+ controllers.push_back(
+ std::make_unique<DefaultTemporalLayers>(num_temporal_layers));
+ }
+ }
+
+ return std::make_unique<Vp8TemporalLayers>(std::move(controllers),
+ fec_controller_override);
+}
+
+std::unique_ptr<Vp8FrameBufferControllerFactory>
+Vp8TemporalLayersFactory::Clone() const {
+ return std::make_unique<Vp8TemporalLayersFactory>();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/vp8_temporal_layers_factory.h b/third_party/libwebrtc/api/video_codecs/vp8_temporal_layers_factory.h
new file mode 100644
index 0000000000..7a146f1d4f
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/vp8_temporal_layers_factory.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VP8_TEMPORAL_LAYERS_FACTORY_H_
+#define API_VIDEO_CODECS_VP8_TEMPORAL_LAYERS_FACTORY_H_
+
+#include <memory>
+
+#include "api/video_codecs/vp8_temporal_layers.h"
+
+namespace webrtc {
+
+class Vp8TemporalLayersFactory : public Vp8FrameBufferControllerFactory {
+ public:
+ ~Vp8TemporalLayersFactory() override = default;
+
+ std::unique_ptr<Vp8FrameBufferControllerFactory> Clone() const override;
+
+ std::unique_ptr<Vp8FrameBufferController> Create(
+ const VideoCodec& codec,
+ const VideoEncoder::Settings& settings,
+ FecControllerOverride* fec_controller_override) override;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VP8_TEMPORAL_LAYERS_FACTORY_H_
diff --git a/third_party/libwebrtc/api/video_codecs/vp8_temporal_layers_factory_gn/moz.build b/third_party/libwebrtc/api/video_codecs/vp8_temporal_layers_factory_gn/moz.build
new file mode 100644
index 0000000000..2769bef0eb
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/vp8_temporal_layers_factory_gn/moz.build
@@ -0,0 +1,232 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+UNIFIED_SOURCES += [
+ "/third_party/libwebrtc/api/video_codecs/vp8_temporal_layers_factory.cc"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "log"
+ ]
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+ OS_LIBS += [
+ "rt"
+ ]
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+ OS_LIBS += [
+ "crypt32",
+ "iphlpapi",
+ "secur32",
+ "winmm"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ CXXFLAGS += [
+ "-mfpu=neon"
+ ]
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ CXXFLAGS += [
+ "-msse2"
+ ]
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("vp8_temporal_layers_factory_gn")
diff --git a/third_party/libwebrtc/api/video_codecs/vp9_profile.cc b/third_party/libwebrtc/api/video_codecs/vp9_profile.cc
new file mode 100644
index 0000000000..7e627cc080
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/vp9_profile.cc
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/video_codecs/vp9_profile.h"
+
+#include <map>
+#include <utility>
+
+#include "rtc_base/string_to_number.h"
+
+namespace webrtc {
+
+// Profile information for VP9 video.
+const char kVP9FmtpProfileId[] = "profile-id";
+
+std::string VP9ProfileToString(VP9Profile profile) {
+ switch (profile) {
+ case VP9Profile::kProfile0:
+ return "0";
+ case VP9Profile::kProfile1:
+ return "1";
+ case VP9Profile::kProfile2:
+ return "2";
+ case VP9Profile::kProfile3:
+ return "3";
+ }
+ return "0";
+}
+
+absl::optional<VP9Profile> StringToVP9Profile(const std::string& str) {
+ const absl::optional<int> i = rtc::StringToNumber<int>(str);
+ if (!i.has_value())
+ return absl::nullopt;
+
+ switch (i.value()) {
+ case 0:
+ return VP9Profile::kProfile0;
+ case 1:
+ return VP9Profile::kProfile1;
+ case 2:
+ return VP9Profile::kProfile2;
+ case 3:
+ return VP9Profile::kProfile3;
+ default:
+ return absl::nullopt;
+ }
+}
+
+absl::optional<VP9Profile> ParseSdpForVP9Profile(
+ const SdpVideoFormat::Parameters& params) {
+ const auto profile_it = params.find(kVP9FmtpProfileId);
+ if (profile_it == params.end())
+ return VP9Profile::kProfile0;
+ const std::string& profile_str = profile_it->second;
+ return StringToVP9Profile(profile_str);
+}
+
+bool VP9IsSameProfile(const SdpVideoFormat::Parameters& params1,
+ const SdpVideoFormat::Parameters& params2) {
+ const absl::optional<VP9Profile> profile = ParseSdpForVP9Profile(params1);
+ const absl::optional<VP9Profile> other_profile =
+ ParseSdpForVP9Profile(params2);
+ return profile && other_profile && profile == other_profile;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/video_codecs/vp9_profile.h b/third_party/libwebrtc/api/video_codecs/vp9_profile.h
new file mode 100644
index 0000000000..b570bc3bb6
--- /dev/null
+++ b/third_party/libwebrtc/api/video_codecs/vp9_profile.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_CODECS_VP9_PROFILE_H_
+#define API_VIDEO_CODECS_VP9_PROFILE_H_
+
+#include <string>
+
+#include "absl/types/optional.h"
+#include "api/video_codecs/sdp_video_format.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Profile information for VP9 video.
+extern RTC_EXPORT const char kVP9FmtpProfileId[];
+
+enum class VP9Profile {
+ kProfile0,
+ kProfile1,
+ kProfile2,
+ kProfile3,
+};
+
+// Helper functions to convert VP9Profile to std::string. Returns "0" by
+// default.
+RTC_EXPORT std::string VP9ProfileToString(VP9Profile profile);
+
+// Helper functions to convert std::string to VP9Profile. Returns null if given
+// an invalid profile string.
+absl::optional<VP9Profile> StringToVP9Profile(const std::string& str);
+
+// Parse profile that is represented as a string of single digit contained in an
+// SDP key-value map. A default profile(kProfile0) will be returned if the
+// profile key is missing. Nothing will be returned if the key is present but
+// the string is invalid.
+RTC_EXPORT absl::optional<VP9Profile> ParseSdpForVP9Profile(
+ const SdpVideoFormat::Parameters& params);
+
+// Returns true if the parameters have the same VP9 profile, or neither contains
+// VP9 profile.
+bool VP9IsSameProfile(const SdpVideoFormat::Parameters& params1,
+ const SdpVideoFormat::Parameters& params2);
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VP9_PROFILE_H_
diff --git a/third_party/libwebrtc/api/video_track_source_constraints.h b/third_party/libwebrtc/api/video_track_source_constraints.h
new file mode 100644
index 0000000000..55e5396d62
--- /dev/null
+++ b/third_party/libwebrtc/api/video_track_source_constraints.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This file contains interfaces for MediaStream, MediaTrack and MediaSource.
+// These interfaces are used for implementing MediaStream and MediaTrack as
+// defined in http://dev.w3.org/2011/webrtc/editor/webrtc.html#stream-api. These
+// interfaces must be used only with PeerConnection.
+
+#ifndef API_VIDEO_TRACK_SOURCE_CONSTRAINTS_H_
+#define API_VIDEO_TRACK_SOURCE_CONSTRAINTS_H_
+
+#include "absl/types/optional.h"
+
+namespace webrtc {
+
+// This struct definition describes constraints on the video source that may be
+// set with VideoTrackSourceInterface::ProcessConstraints.
+struct VideoTrackSourceConstraints {
+ absl::optional<double> min_fps;
+ absl::optional<double> max_fps;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_TRACK_SOURCE_CONSTRAINTS_H_
diff --git a/third_party/libwebrtc/api/video_track_source_constraints_gn/moz.build b/third_party/libwebrtc/api/video_track_source_constraints_gn/moz.build
new file mode 100644
index 0000000000..77f7ba4d70
--- /dev/null
+++ b/third_party/libwebrtc/api/video_track_source_constraints_gn/moz.build
@@ -0,0 +1,201 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+ ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ###
+ ### DO NOT edit it by hand. ###
+
+COMPILE_FLAGS["OS_INCLUDES"] = []
+AllowCompilerWarnings()
+
+DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1"
+DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True
+DEFINES["RTC_ENABLE_VP9"] = True
+DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0"
+DEFINES["WEBRTC_LIBRARY_IMPL"] = True
+DEFINES["WEBRTC_MOZILLA_BUILD"] = True
+DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0"
+DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0"
+
+FINAL_LIBRARY = "webrtc"
+
+
+LOCAL_INCLUDES += [
+ "!/ipc/ipdl/_ipdlheaders",
+ "!/third_party/libwebrtc/gen",
+ "/ipc/chromium/src",
+ "/third_party/libwebrtc/",
+ "/third_party/libwebrtc/third_party/abseil-cpp/",
+ "/tools/profiler/public"
+]
+
+if not CONFIG["MOZ_DEBUG"]:
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0"
+ DEFINES["NDEBUG"] = True
+ DEFINES["NVALGRIND"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1":
+
+ DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1"
+
+if CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["ANDROID"] = True
+ DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1"
+ DEFINES["HAVE_SYS_UIO_H"] = True
+ DEFINES["WEBRTC_ANDROID"] = True
+ DEFINES["WEBRTC_ANDROID_OPENSLES"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_GNU_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["WEBRTC_MAC"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True
+ DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0"
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_NSS_CERTS"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_UDEV"] = True
+ DEFINES["WEBRTC_LINUX"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["USE_GLIB"] = "1"
+ DEFINES["USE_OZONE"] = "1"
+ DEFINES["USE_X11"] = "1"
+ DEFINES["WEBRTC_BSD"] = True
+ DEFINES["WEBRTC_POSIX"] = True
+ DEFINES["_FILE_OFFSET_BITS"] = "64"
+ DEFINES["_LARGEFILE64_SOURCE"] = True
+ DEFINES["_LARGEFILE_SOURCE"] = True
+ DEFINES["__STDC_CONSTANT_MACROS"] = True
+ DEFINES["__STDC_FORMAT_MACROS"] = True
+
+if CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
+ DEFINES["NOMINMAX"] = True
+ DEFINES["NTDDI_VERSION"] = "0x0A000000"
+ DEFINES["PSAPI_VERSION"] = "2"
+ DEFINES["UNICODE"] = True
+ DEFINES["USE_AURA"] = "1"
+ DEFINES["WEBRTC_WIN"] = True
+ DEFINES["WIN32"] = True
+ DEFINES["WIN32_LEAN_AND_MEAN"] = True
+ DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP"
+ DEFINES["WINVER"] = "0x0A00"
+ DEFINES["_ATL_NO_OPENGL"] = True
+ DEFINES["_CRT_RAND_S"] = True
+ DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True
+ DEFINES["_HAS_EXCEPTIONS"] = "0"
+ DEFINES["_HAS_NODISCARD"] = True
+ DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True
+ DEFINES["_SECURE_ATL"] = True
+ DEFINES["_UNICODE"] = True
+ DEFINES["_WIN32_WINNT"] = "0x0A00"
+ DEFINES["_WINDOWS"] = True
+ DEFINES["__STD_C"] = True
+
+if CONFIG["CPU_ARCH"] == "aarch64":
+
+ DEFINES["WEBRTC_ARCH_ARM64"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "arm":
+
+ DEFINES["WEBRTC_ARCH_ARM"] = True
+ DEFINES["WEBRTC_ARCH_ARM_V7"] = True
+ DEFINES["WEBRTC_HAS_NEON"] = True
+
+if CONFIG["CPU_ARCH"] == "mips32":
+
+ DEFINES["MIPS32_LE"] = True
+ DEFINES["MIPS_FPU_LE"] = True
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "mips64":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64":
+
+ DEFINES["WEBRTC_ENABLE_AVX2"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD":
+
+ DEFINES["_DEBUG"] = True
+
+if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT":
+
+ DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0"
+
+if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["USE_X11"] = "1"
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support",
+ "unwind"
+ ]
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android":
+
+ OS_LIBS += [
+ "android_support"
+ ]
+
+if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux":
+
+ DEFINES["_GNU_SOURCE"] = True
+
+Library("video_track_source_constraints_gn")
diff --git a/third_party/libwebrtc/api/video_track_source_proxy_factory.h b/third_party/libwebrtc/api/video_track_source_proxy_factory.h
new file mode 100644
index 0000000000..eb6e96429a
--- /dev/null
+++ b/third_party/libwebrtc/api/video_track_source_proxy_factory.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VIDEO_TRACK_SOURCE_PROXY_FACTORY_H_
+#define API_VIDEO_TRACK_SOURCE_PROXY_FACTORY_H_
+
+#include "api/media_stream_interface.h"
+#include "rtc_base/thread.h"
+
+namespace webrtc {
+
+// Creates a proxy source for `source` which makes sure the real
+// VideoTrackSourceInterface implementation is destroyed on the signaling thread
+// and marshals calls to `worker_thread` and `signaling_thread`.
+rtc::scoped_refptr<VideoTrackSourceInterface> RTC_EXPORT
+CreateVideoTrackSourceProxy(rtc::Thread* signaling_thread,
+ rtc::Thread* worker_thread,
+ VideoTrackSourceInterface* source);
+
+} // namespace webrtc
+
+#endif // API_VIDEO_TRACK_SOURCE_PROXY_FACTORY_H_
diff --git a/third_party/libwebrtc/api/voip/BUILD.gn b/third_party/libwebrtc/api/voip/BUILD.gn
new file mode 100644
index 0000000000..714490a526
--- /dev/null
+++ b/third_party/libwebrtc/api/voip/BUILD.gn
@@ -0,0 +1,85 @@
+# Copyright(c) 2020 The WebRTC project authors.All Rights Reserved.
+#
+# Use of this source code is governed by a BSD - style license
+# that can be found in the LICENSE file in the root of the source
+# tree.An additional intellectual property rights grant can be found
+# in the file PATENTS.All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../webrtc.gni")
+
+rtc_source_set("voip_api") {
+ visibility = [ "*" ]
+ sources = [
+ "voip_base.h",
+ "voip_codec.h",
+ "voip_dtmf.h",
+ "voip_engine.h",
+ "voip_network.h",
+ "voip_statistics.h",
+ "voip_volume_control.h",
+ ]
+ deps = [
+ "..:array_view",
+ "../audio_codecs:audio_codecs_api",
+ "../neteq:neteq_api",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+}
+
+rtc_library("voip_engine_factory") {
+ visibility = [ "*" ]
+ sources = [
+ "voip_engine_factory.cc",
+ "voip_engine_factory.h",
+ ]
+ deps = [
+ ":voip_api",
+ "..:scoped_refptr",
+ "../../audio/voip:voip_core",
+ "../../modules/audio_device:audio_device_api",
+ "../../modules/audio_processing:api",
+ "../../rtc_base:logging",
+ "../audio_codecs:audio_codecs_api",
+ "../task_queue",
+ ]
+}
+
+if (rtc_include_tests) {
+ rtc_source_set("mock_voip_engine") {
+ testonly = true
+ visibility = [ "*" ]
+ sources = [ "test/mock_voip_engine.h" ]
+ deps = [
+ ":voip_api",
+ "..:array_view",
+ "../../test:test_support",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+ }
+
+ rtc_library("voip_engine_factory_unittests") {
+ testonly = true
+ sources = [ "test/voip_engine_factory_unittest.cc" ]
+ deps = [
+ ":voip_engine_factory",
+ "../../modules/audio_device:mock_audio_device",
+ "../../modules/audio_processing:mocks",
+ "../../test:audio_codec_mocks",
+ "../../test:test_support",
+ "../task_queue:default_task_queue_factory",
+ ]
+ }
+
+ rtc_library("compile_all_headers") {
+ testonly = true
+ sources = [ "test/compile_all_headers.cc" ]
+ deps = [
+ ":mock_voip_engine",
+ "../../test:test_support",
+ ]
+ }
+}
diff --git a/third_party/libwebrtc/api/voip/DEPS b/third_party/libwebrtc/api/voip/DEPS
new file mode 100644
index 0000000000..3845dffab0
--- /dev/null
+++ b/third_party/libwebrtc/api/voip/DEPS
@@ -0,0 +1,10 @@
+specific_include_rules = {
+ ".*\.h": [
+ "+third_party/absl/types/optional.h",
+ ],
+
+ "voip_engine_factory.h": [
+ "+modules/audio_device/include/audio_device.h",
+ "+modules/audio_processing/include/audio_processing.h",
+ ],
+}
diff --git a/third_party/libwebrtc/api/voip/test/compile_all_headers.cc b/third_party/libwebrtc/api/voip/test/compile_all_headers.cc
new file mode 100644
index 0000000000..73a0f0d1c4
--- /dev/null
+++ b/third_party/libwebrtc/api/voip/test/compile_all_headers.cc
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This file verifies that all include files in this directory can be
+// compiled without errors or other required includes.
+
+#include "api/voip/test/mock_voip_engine.h"
diff --git a/third_party/libwebrtc/api/voip/test/mock_voip_engine.h b/third_party/libwebrtc/api/voip/test/mock_voip_engine.h
new file mode 100644
index 0000000000..74b880d652
--- /dev/null
+++ b/third_party/libwebrtc/api/voip/test/mock_voip_engine.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VOIP_TEST_MOCK_VOIP_ENGINE_H_
+#define API_VOIP_TEST_MOCK_VOIP_ENGINE_H_
+
+#include <map>
+
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/voip/voip_base.h"
+#include "api/voip/voip_codec.h"
+#include "api/voip/voip_dtmf.h"
+#include "api/voip/voip_engine.h"
+#include "api/voip/voip_network.h"
+#include "api/voip/voip_statistics.h"
+#include "api/voip/voip_volume_control.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+class MockVoipBase : public VoipBase {
+ public:
+ MOCK_METHOD(ChannelId,
+ CreateChannel,
+ (Transport*, absl::optional<uint32_t>),
+ (override));
+ MOCK_METHOD(VoipResult, ReleaseChannel, (ChannelId), (override));
+ MOCK_METHOD(VoipResult, StartSend, (ChannelId), (override));
+ MOCK_METHOD(VoipResult, StopSend, (ChannelId), (override));
+ MOCK_METHOD(VoipResult, StartPlayout, (ChannelId), (override));
+ MOCK_METHOD(VoipResult, StopPlayout, (ChannelId), (override));
+};
+
+class MockVoipCodec : public VoipCodec {
+ public:
+ MOCK_METHOD(VoipResult,
+ SetSendCodec,
+ (ChannelId, int, const SdpAudioFormat&),
+ (override));
+ MOCK_METHOD(VoipResult,
+ SetReceiveCodecs,
+ (ChannelId, (const std::map<int, SdpAudioFormat>&)),
+ (override));
+};
+
+class MockVoipDtmf : public VoipDtmf {
+ public:
+ MOCK_METHOD(VoipResult,
+ RegisterTelephoneEventType,
+ (ChannelId, int, int),
+ (override));
+ MOCK_METHOD(VoipResult,
+ SendDtmfEvent,
+ (ChannelId, DtmfEvent, int),
+ (override));
+};
+
+class MockVoipNetwork : public VoipNetwork {
+ public:
+ MOCK_METHOD(VoipResult,
+ ReceivedRTPPacket,
+ (ChannelId channel_id, rtc::ArrayView<const uint8_t> rtp_packet),
+ (override));
+ MOCK_METHOD(VoipResult,
+ ReceivedRTCPPacket,
+ (ChannelId channel_id, rtc::ArrayView<const uint8_t> rtcp_packet),
+ (override));
+};
+
+class MockVoipStatistics : public VoipStatistics {
+ public:
+ MOCK_METHOD(VoipResult,
+ GetIngressStatistics,
+ (ChannelId, IngressStatistics&),
+ (override));
+ MOCK_METHOD(VoipResult,
+ GetChannelStatistics,
+ (ChannelId channel_id, ChannelStatistics&),
+ (override));
+};
+
+class MockVoipVolumeControl : public VoipVolumeControl {
+ public:
+ MOCK_METHOD(VoipResult, SetInputMuted, (ChannelId, bool), (override));
+
+ MOCK_METHOD(VoipResult,
+ GetInputVolumeInfo,
+ (ChannelId, VolumeInfo&),
+ (override));
+ MOCK_METHOD(VoipResult,
+ GetOutputVolumeInfo,
+ (ChannelId, VolumeInfo&),
+ (override));
+};
+
+class MockVoipEngine : public VoipEngine {
+ public:
+ VoipBase& Base() override { return base_; }
+ VoipNetwork& Network() override { return network_; }
+ VoipCodec& Codec() override { return codec_; }
+ VoipDtmf& Dtmf() override { return dtmf_; }
+ VoipStatistics& Statistics() override { return statistics_; }
+ VoipVolumeControl& VolumeControl() override { return volume_; }
+
+ // Direct access to underlying members are required for testing.
+ MockVoipBase base_;
+ MockVoipNetwork network_;
+ MockVoipCodec codec_;
+ MockVoipDtmf dtmf_;
+ MockVoipStatistics statistics_;
+ MockVoipVolumeControl volume_;
+};
+
+} // namespace webrtc
+
+#endif // API_VOIP_TEST_MOCK_VOIP_ENGINE_H_
diff --git a/third_party/libwebrtc/api/voip/test/voip_engine_factory_unittest.cc b/third_party/libwebrtc/api/voip/test/voip_engine_factory_unittest.cc
new file mode 100644
index 0000000000..f967a0ba8f
--- /dev/null
+++ b/third_party/libwebrtc/api/voip/test/voip_engine_factory_unittest.cc
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <utility>
+
+#include "api/task_queue/default_task_queue_factory.h"
+#include "api/voip/voip_engine_factory.h"
+#include "modules/audio_device/include/mock_audio_device.h"
+#include "modules/audio_processing/include/mock_audio_processing.h"
+#include "test/gtest.h"
+#include "test/mock_audio_decoder_factory.h"
+#include "test/mock_audio_encoder_factory.h"
+
+namespace webrtc {
+namespace {
+
+// Create voip engine with mock modules as normal use case.
+TEST(VoipEngineFactoryTest, CreateEngineWithMockModules) {
+ VoipEngineConfig config;
+ config.encoder_factory = rtc::make_ref_counted<MockAudioEncoderFactory>();
+ config.decoder_factory = rtc::make_ref_counted<MockAudioDecoderFactory>();
+ config.task_queue_factory = CreateDefaultTaskQueueFactory();
+ config.audio_processing =
+ rtc::make_ref_counted<testing::NiceMock<test::MockAudioProcessing>>();
+ config.audio_device_module = test::MockAudioDeviceModule::CreateNice();
+
+ auto voip_engine = CreateVoipEngine(std::move(config));
+ EXPECT_NE(voip_engine, nullptr);
+}
+
+// Create voip engine without setting audio processing as optional component.
+TEST(VoipEngineFactoryTest, UseNoAudioProcessing) {
+ VoipEngineConfig config;
+ config.encoder_factory = rtc::make_ref_counted<MockAudioEncoderFactory>();
+ config.decoder_factory = rtc::make_ref_counted<MockAudioDecoderFactory>();
+ config.task_queue_factory = CreateDefaultTaskQueueFactory();
+ config.audio_device_module = test::MockAudioDeviceModule::CreateNice();
+
+ auto voip_engine = CreateVoipEngine(std::move(config));
+ EXPECT_NE(voip_engine, nullptr);
+}
+
+} // namespace
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/voip/voip_base.h b/third_party/libwebrtc/api/voip/voip_base.h
new file mode 100644
index 0000000000..8df7bd0571
--- /dev/null
+++ b/third_party/libwebrtc/api/voip/voip_base.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VOIP_VOIP_BASE_H_
+#define API_VOIP_VOIP_BASE_H_
+
+#include "absl/base/attributes.h"
+#include "absl/types/optional.h"
+
+namespace webrtc {
+
+class Transport;
+
+// VoipBase interface
+//
+// VoipBase provides a management interface on a media session using a
+// concept called 'channel'. A channel represents an interface handle
+// for application to request various media session operations. This
+// notion of channel is used throughout other interfaces as well.
+//
+// Underneath the interface, a channel id is mapped into an audio session
+// object that is capable of sending and receiving a single RTP stream with
+// another media endpoint. It's possible to create and use multiple active
+// channels simultaneously which would mean that particular application
+// session has RTP streams with multiple remote endpoints.
+//
+// A typical example for the usage context is outlined in VoipEngine
+// header file.
+
+enum class ChannelId : int {};
+
+enum class ABSL_MUST_USE_RESULT VoipResult {
+ // kOk indicates the function was successfully invoked with no error.
+ kOk,
+ // kInvalidArgument indicates the caller specified an invalid argument, such
+ // as an invalid ChannelId.
+ kInvalidArgument,
+ // kFailedPrecondition indicates that the operation was failed due to not
+ // satisfying prerequisite such as not setting codec type before sending.
+ kFailedPrecondition,
+ // kInternal is used to indicate various internal failures that are not the
+ // caller's fault. Further detail is commented on each function that uses this
+ // return value.
+ kInternal,
+};
+
+class VoipBase {
+ public:
+ // Creates a channel.
+ // Each channel handle maps into one audio media session where each has
+ // its own separate module for send/receive rtp packet with one peer.
+ // Caller must set `transport`, webrtc::Transport callback pointer to
+ // receive rtp/rtcp packets from corresponding media session in VoIP engine.
+ // VoipEngine framework expects applications to handle network I/O directly
+ // and injection for incoming RTP from remote endpoint is handled via
+ // VoipNetwork interface. `local_ssrc` is optional and when local_ssrc is not
+ // set, some random value will be used by voip engine.
+ // Returns a ChannelId created for caller to handle subsequent Channel
+ // operations.
+ virtual ChannelId CreateChannel(Transport* transport,
+ absl::optional<uint32_t> local_ssrc) = 0;
+
+ // Releases `channel_id` that no longer has any use.
+ // Returns following VoipResult;
+ // kOk - `channel_id` is released.
+ // kInvalidArgument - `channel_id` is invalid.
+ // kInternal - Fails to stop audio output device.
+ virtual VoipResult ReleaseChannel(ChannelId channel_id) = 0;
+
+ // Starts sending on `channel_id`. This starts microphone if not started yet.
+ // Returns following VoipResult;
+ // kOk - Channel successfully started to send.
+ // kInvalidArgument - `channel_id` is invalid.
+ // kFailedPrecondition - Missing prerequisite on VoipCodec::SetSendCodec.
+ // kInternal - initialization has failed on selected microphone.
+ virtual VoipResult StartSend(ChannelId channel_id) = 0;
+
+ // Stops sending on `channel_id`. If this is the last active channel, it will
+ // stop microphone input from underlying audio platform layer.
+ // Returns following VoipResult;
+ // kOk - Channel successfully stopped to send.
+ // kInvalidArgument - `channel_id` is invalid.
+ // kInternal - Failed to stop the active microphone device.
+ virtual VoipResult StopSend(ChannelId channel_id) = 0;
+
+ // Starts playing on speaker device for `channel_id`.
+ // This will start underlying platform speaker device if not started.
+ // Returns following VoipResult;
+ // kOk - Channel successfully started to play out.
+ // kInvalidArgument - `channel_id` is invalid.
+ // kFailedPrecondition - Missing prerequisite on VoipCodec::SetReceiveCodecs.
+ // kInternal - Failed to initializate the selected speaker device.
+ virtual VoipResult StartPlayout(ChannelId channel_id) = 0;
+
+ // Stops playing on speaker device for `channel_id`.
+ // Returns following VoipResult;
+ // kOk - Channel successfully stopped t play out.
+ // kInvalidArgument - `channel_id` is invalid.
+ virtual VoipResult StopPlayout(ChannelId channel_id) = 0;
+
+ protected:
+ virtual ~VoipBase() = default;
+};
+
+} // namespace webrtc
+
+#endif // API_VOIP_VOIP_BASE_H_
diff --git a/third_party/libwebrtc/api/voip/voip_codec.h b/third_party/libwebrtc/api/voip/voip_codec.h
new file mode 100644
index 0000000000..46cddfad6c
--- /dev/null
+++ b/third_party/libwebrtc/api/voip/voip_codec.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VOIP_VOIP_CODEC_H_
+#define API_VOIP_VOIP_CODEC_H_
+
+#include <map>
+
+#include "api/audio_codecs/audio_format.h"
+#include "api/voip/voip_base.h"
+
+namespace webrtc {
+
+// VoipCodec interface currently provides any codec related interface
+// such as setting encoder and decoder types that are negotiated with
+// remote endpoint. Typically after SDP offer and answer exchange,
+// the local endpoint understands what are the codec payload types that
+// are used with negotiated codecs. This interface is subject to expand
+// as needed in future.
+//
+// This interface requires a channel id created via VoipBase interface.
+class VoipCodec {
+ public:
+ // Set encoder type here along with its payload type to use.
+ // Returns following VoipResult;
+ // kOk - sending codec is set as provided.
+ // kInvalidArgument - `channel_id` is invalid.
+ virtual VoipResult SetSendCodec(ChannelId channel_id,
+ int payload_type,
+ const SdpAudioFormat& encoder_spec) = 0;
+
+ // Set decoder payload type here. In typical offer and answer model,
+ // this should be called after payload type has been agreed in media
+ // session. Note that payload type can differ with same codec in each
+ // direction.
+ // Returns following VoipResult;
+ // kOk - receiving codecs are set as provided.
+ // kInvalidArgument - `channel_id` is invalid.
+ virtual VoipResult SetReceiveCodecs(
+ ChannelId channel_id,
+ const std::map<int, SdpAudioFormat>& decoder_specs) = 0;
+
+ protected:
+ virtual ~VoipCodec() = default;
+};
+
+} // namespace webrtc
+
+#endif // API_VOIP_VOIP_CODEC_H_
diff --git a/third_party/libwebrtc/api/voip/voip_dtmf.h b/third_party/libwebrtc/api/voip/voip_dtmf.h
new file mode 100644
index 0000000000..ef7ea28c94
--- /dev/null
+++ b/third_party/libwebrtc/api/voip/voip_dtmf.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VOIP_VOIP_DTMF_H_
+#define API_VOIP_VOIP_DTMF_H_
+
+#include "api/voip/voip_base.h"
+
+namespace webrtc {
+
+// DTMF events and their event codes as defined in
+// https://tools.ietf.org/html/rfc4733#section-7
+enum class DtmfEvent : uint8_t {
+ kDigitZero = 0,
+ kDigitOne,
+ kDigitTwo,
+ kDigitThree,
+ kDigitFour,
+ kDigitFive,
+ kDigitSix,
+ kDigitSeven,
+ kDigitEight,
+ kDigitNine,
+ kAsterisk,
+ kHash,
+ kLetterA,
+ kLetterB,
+ kLetterC,
+ kLetterD
+};
+
+// VoipDtmf interface provides DTMF related interfaces such
+// as sending DTMF events to the remote endpoint.
+class VoipDtmf {
+ public:
+ // Register the payload type and sample rate for DTMF (RFC 4733) payload.
+ // Must be called exactly once prior to calling SendDtmfEvent after payload
+ // type has been negotiated with remote.
+ // Returns following VoipResult;
+ // kOk - telephone event type is registered as provided.
+ // kInvalidArgument - `channel_id` is invalid.
+ virtual VoipResult RegisterTelephoneEventType(ChannelId channel_id,
+ int rtp_payload_type,
+ int sample_rate_hz) = 0;
+
+ // Send DTMF named event as specified by
+ // https://tools.ietf.org/html/rfc4733#section-3.2
+ // `duration_ms` specifies the duration of DTMF packets that will be emitted
+ // in place of real RTP packets instead.
+ // Must be called after RegisterTelephoneEventType and VoipBase::StartSend
+ // have been called.
+ // Returns following VoipResult;
+ // kOk - requested DTMF event is successfully scheduled.
+ // kInvalidArgument - `channel_id` is invalid.
+ // kFailedPrecondition - Missing prerequisite on RegisterTelephoneEventType
+ // or sending state.
+ virtual VoipResult SendDtmfEvent(ChannelId channel_id,
+ DtmfEvent dtmf_event,
+ int duration_ms) = 0;
+
+ protected:
+ virtual ~VoipDtmf() = default;
+};
+
+} // namespace webrtc
+
+#endif // API_VOIP_VOIP_DTMF_H_
diff --git a/third_party/libwebrtc/api/voip/voip_engine.h b/third_party/libwebrtc/api/voip/voip_engine.h
new file mode 100644
index 0000000000..d223f6ad6c
--- /dev/null
+++ b/third_party/libwebrtc/api/voip/voip_engine.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VOIP_VOIP_ENGINE_H_
+#define API_VOIP_VOIP_ENGINE_H_
+
+namespace webrtc {
+
+class VoipBase;
+class VoipCodec;
+class VoipNetwork;
+class VoipDtmf;
+class VoipStatistics;
+class VoipVolumeControl;
+
+// VoipEngine is the main interface serving as the entry point for all VoIP
+// APIs. A single instance of VoipEngine should suffice the most of the need for
+// typical VoIP applications as it handles multiple media sessions including a
+// specialized session type like ad-hoc conference. Below example code
+// describes the typical sequence of API usage. Each API header contains more
+// description on what the methods are used for.
+//
+// // Caller is responsible of setting desired audio components.
+// VoipEngineConfig config;
+// config.encoder_factory = CreateBuiltinAudioEncoderFactory();
+// config.decoder_factory = CreateBuiltinAudioDecoderFactory();
+// config.task_queue_factory = CreateDefaultTaskQueueFactory();
+// config.audio_device =
+// AudioDeviceModule::Create(AudioDeviceModule::kPlatformDefaultAudio,
+// config.task_queue_factory.get());
+// config.audio_processing = AudioProcessingBuilder().Create();
+//
+// auto voip_engine = CreateVoipEngine(std::move(config));
+//
+// auto& voip_base = voip_engine->Base();
+// auto& voip_codec = voip_engine->Codec();
+// auto& voip_network = voip_engine->Network();
+//
+// ChannelId channel = voip_base.CreateChannel(&app_transport_);
+//
+// // After SDP offer/answer, set payload type and codecs that have been
+// // decided through SDP negotiation.
+// // VoipResult handling omitted here.
+// voip_codec.SetSendCodec(channel, ...);
+// voip_codec.SetReceiveCodecs(channel, ...);
+//
+// // Start sending and playing RTP on voip channel.
+// // VoipResult handling omitted here.
+// voip_base.StartSend(channel);
+// voip_base.StartPlayout(channel);
+//
+// // Inject received RTP/RTCP through VoipNetwork interface.
+// // VoipResult handling omitted here.
+// voip_network.ReceivedRTPPacket(channel, ...);
+// voip_network.ReceivedRTCPPacket(channel, ...);
+//
+// // Stop and release voip channel.
+// // VoipResult handling omitted here.
+// voip_base.StopSend(channel);
+// voip_base.StopPlayout(channel);
+// voip_base.ReleaseChannel(channel);
+//
+class VoipEngine {
+ public:
+ virtual ~VoipEngine() = default;
+
+ // VoipBase is the audio session management interface that
+ // creates/releases/starts/stops an one-to-one audio media session.
+ virtual VoipBase& Base() = 0;
+
+ // VoipNetwork provides injection APIs that would enable application
+ // to send and receive RTP/RTCP packets. There is no default network module
+ // that provides RTP transmission and reception.
+ virtual VoipNetwork& Network() = 0;
+
+ // VoipCodec provides codec configuration APIs for encoder and decoders.
+ virtual VoipCodec& Codec() = 0;
+
+ // VoipDtmf provides DTMF event APIs to register and send DTMF events.
+ virtual VoipDtmf& Dtmf() = 0;
+
+ // VoipStatistics provides performance metrics around audio decoding module
+ // and jitter buffer (NetEq).
+ virtual VoipStatistics& Statistics() = 0;
+
+ // VoipVolumeControl provides various input/output volume control.
+ virtual VoipVolumeControl& VolumeControl() = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_VOIP_VOIP_ENGINE_H_
diff --git a/third_party/libwebrtc/api/voip/voip_engine_factory.cc b/third_party/libwebrtc/api/voip/voip_engine_factory.cc
new file mode 100644
index 0000000000..8da53cef74
--- /dev/null
+++ b/third_party/libwebrtc/api/voip/voip_engine_factory.cc
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/voip/voip_engine_factory.h"
+
+#include <utility>
+
+#include "audio/voip/voip_core.h"
+#include "rtc_base/logging.h"
+
+namespace webrtc {
+
+std::unique_ptr<VoipEngine> CreateVoipEngine(VoipEngineConfig config) {
+ RTC_CHECK(config.encoder_factory);
+ RTC_CHECK(config.decoder_factory);
+ RTC_CHECK(config.task_queue_factory);
+ RTC_CHECK(config.audio_device_module);
+
+ if (!config.audio_processing) {
+ RTC_DLOG(LS_INFO) << "No audio processing functionality provided.";
+ }
+
+ return std::make_unique<VoipCore>(std::move(config.encoder_factory),
+ std::move(config.decoder_factory),
+ std::move(config.task_queue_factory),
+ std::move(config.audio_device_module),
+ std::move(config.audio_processing));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/voip/voip_engine_factory.h b/third_party/libwebrtc/api/voip/voip_engine_factory.h
new file mode 100644
index 0000000000..62fe8011a6
--- /dev/null
+++ b/third_party/libwebrtc/api/voip/voip_engine_factory.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VOIP_VOIP_ENGINE_FACTORY_H_
+#define API_VOIP_VOIP_ENGINE_FACTORY_H_
+
+#include <memory>
+
+#include "api/audio_codecs/audio_decoder_factory.h"
+#include "api/audio_codecs/audio_encoder_factory.h"
+#include "api/scoped_refptr.h"
+#include "api/task_queue/task_queue_factory.h"
+#include "api/voip/voip_engine.h"
+#include "modules/audio_device/include/audio_device.h"
+#include "modules/audio_processing/include/audio_processing.h"
+
+namespace webrtc {
+
+// VoipEngineConfig is a struct that defines parameters to instantiate a
+// VoipEngine instance through CreateVoipEngine factory method. Each member is
+// marked with comments as either mandatory or optional and default
+// implementations that applications can use.
+struct VoipEngineConfig {
+ // Mandatory (e.g. api/audio_codec/builtin_audio_encoder_factory).
+ // AudioEncoderFactory provides a set of audio codecs for VoipEngine to encode
+ // the audio input sample. Application can choose to limit the set to reduce
+ // application footprint.
+ rtc::scoped_refptr<AudioEncoderFactory> encoder_factory;
+
+ // Mandatory (e.g. api/audio_codec/builtin_audio_decoder_factory).
+ // AudioDecoderFactory provides a set of audio codecs for VoipEngine to decode
+ // the received RTP packets from remote media endpoint. Application can choose
+ // to limit the set to reduce application footprint.
+ rtc::scoped_refptr<AudioDecoderFactory> decoder_factory;
+
+ // Mandatory (e.g. api/task_queue/default_task_queue_factory).
+ // TaskQeueuFactory provided for VoipEngine to work asynchronously on its
+ // encoding flow.
+ std::unique_ptr<TaskQueueFactory> task_queue_factory;
+
+ // Mandatory (e.g. modules/audio_device/include).
+ // AudioDeviceModule that periocally provides audio input samples from
+ // recording device (e.g. microphone) and requests audio output samples to
+ // play through its output device (e.g. speaker).
+ rtc::scoped_refptr<AudioDeviceModule> audio_device_module;
+
+ // Optional (e.g. modules/audio_processing/include).
+ // AudioProcessing provides audio procesing functionalities (e.g. acoustic
+ // echo cancellation, noise suppression, gain control, etc) on audio input
+ // samples for VoipEngine. When optionally not set, VoipEngine will not have
+ // such functionalities to perform on audio input samples received from
+ // AudioDeviceModule.
+ rtc::scoped_refptr<AudioProcessing> audio_processing;
+};
+
+// Creates a VoipEngine instance with provided VoipEngineConfig.
+std::unique_ptr<VoipEngine> CreateVoipEngine(VoipEngineConfig config);
+
+} // namespace webrtc
+
+#endif // API_VOIP_VOIP_ENGINE_FACTORY_H_
diff --git a/third_party/libwebrtc/api/voip/voip_network.h b/third_party/libwebrtc/api/voip/voip_network.h
new file mode 100644
index 0000000000..0ea16b68de
--- /dev/null
+++ b/third_party/libwebrtc/api/voip/voip_network.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VOIP_VOIP_NETWORK_H_
+#define API_VOIP_VOIP_NETWORK_H_
+
+#include "api/array_view.h"
+#include "api/voip/voip_base.h"
+
+namespace webrtc {
+
+// VoipNetwork interface provides any network related interfaces such as
+// processing received RTP/RTCP packet from remote endpoint. This interface
+// requires a ChannelId created via VoipBase interface.
+class VoipNetwork {
+ public:
+ // The data received from the network including RTP header is passed here.
+ // Returns following VoipResult;
+ // kOk - received RTP packet is processed.
+ // kInvalidArgument - `channel_id` is invalid.
+ virtual VoipResult ReceivedRTPPacket(
+ ChannelId channel_id,
+ rtc::ArrayView<const uint8_t> rtp_packet) = 0;
+
+ // The data received from the network including RTCP header is passed here.
+ // Returns following VoipResult;
+ // kOk - received RTCP packet is processed.
+ // kInvalidArgument - `channel_id` is invalid.
+ virtual VoipResult ReceivedRTCPPacket(
+ ChannelId channel_id,
+ rtc::ArrayView<const uint8_t> rtcp_packet) = 0;
+
+ protected:
+ virtual ~VoipNetwork() = default;
+};
+
+} // namespace webrtc
+
+#endif // API_VOIP_VOIP_NETWORK_H_
diff --git a/third_party/libwebrtc/api/voip/voip_statistics.h b/third_party/libwebrtc/api/voip/voip_statistics.h
new file mode 100644
index 0000000000..2d1ab8d5e8
--- /dev/null
+++ b/third_party/libwebrtc/api/voip/voip_statistics.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VOIP_VOIP_STATISTICS_H_
+#define API_VOIP_VOIP_STATISTICS_H_
+
+#include "api/neteq/neteq.h"
+#include "api/voip/voip_base.h"
+
+namespace webrtc {
+
+struct IngressStatistics {
+ // Stats included from api/neteq/neteq.h.
+ NetEqLifetimeStatistics neteq_stats;
+
+ // Represents the total duration in seconds of all samples that have been
+ // received.
+ // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-totalsamplesduration
+ double total_duration = 0.0;
+};
+
+// Remote statistics obtained via remote RTCP SR/RR report received.
+struct RemoteRtcpStatistics {
+ // Jitter as defined in RFC 3550 [6.4.1] expressed in seconds.
+ double jitter = 0.0;
+
+ // Cumulative packets lost as defined in RFC 3550 [6.4.1]
+ int64_t packets_lost = 0;
+
+ // Fraction lost as defined in RFC 3550 [6.4.1] expressed as a floating
+ // pointer number.
+ double fraction_lost = 0.0;
+
+ // https://w3c.github.io/webrtc-stats/#dom-rtcremoteinboundrtpstreamstats-roundtriptime
+ absl::optional<double> round_trip_time;
+
+ // Last time (not RTP timestamp) when RTCP report received in milliseconds.
+ int64_t last_report_received_timestamp_ms;
+};
+
+struct ChannelStatistics {
+ // https://w3c.github.io/webrtc-stats/#dom-rtcsentrtpstreamstats-packetssent
+ uint64_t packets_sent = 0;
+
+ // https://w3c.github.io/webrtc-stats/#dom-rtcsentrtpstreamstats-bytessent
+ uint64_t bytes_sent = 0;
+
+ // https://w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-packetsreceived
+ uint64_t packets_received = 0;
+
+ // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-bytesreceived
+ uint64_t bytes_received = 0;
+
+ // https://w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-jitter
+ double jitter = 0.0;
+
+ // https://w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-packetslost
+ int64_t packets_lost = 0;
+
+ // SSRC from remote media endpoint as indicated either by RTP header in RFC
+ // 3550 [5.1] or RTCP SSRC of sender in RFC 3550 [6.4.1].
+ absl::optional<uint32_t> remote_ssrc;
+
+ absl::optional<RemoteRtcpStatistics> remote_rtcp;
+};
+
+// VoipStatistics interface provides the interfaces for querying metrics around
+// the jitter buffer (NetEq) performance.
+class VoipStatistics {
+ public:
+ // Gets the audio ingress statistics by `ingress_stats` reference.
+ // Returns following VoipResult;
+ // kOk - successfully set provided IngressStatistics reference.
+ // kInvalidArgument - `channel_id` is invalid.
+ virtual VoipResult GetIngressStatistics(ChannelId channel_id,
+ IngressStatistics& ingress_stats) = 0;
+
+ // Gets the channel statistics by `channel_stats` reference.
+ // Returns following VoipResult;
+ // kOk - successfully set provided ChannelStatistics reference.
+ // kInvalidArgument - `channel_id` is invalid.
+ virtual VoipResult GetChannelStatistics(ChannelId channel_id,
+ ChannelStatistics& channel_stats) = 0;
+
+ protected:
+ virtual ~VoipStatistics() = default;
+};
+
+} // namespace webrtc
+
+#endif // API_VOIP_VOIP_STATISTICS_H_
diff --git a/third_party/libwebrtc/api/voip/voip_volume_control.h b/third_party/libwebrtc/api/voip/voip_volume_control.h
new file mode 100644
index 0000000000..aab14180df
--- /dev/null
+++ b/third_party/libwebrtc/api/voip/voip_volume_control.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_VOIP_VOIP_VOLUME_CONTROL_H_
+#define API_VOIP_VOIP_VOLUME_CONTROL_H_
+
+#include "api/voip/voip_base.h"
+
+namespace webrtc {
+
+struct VolumeInfo {
+ // https://w3c.github.io/webrtc-stats/#dom-rtcaudiosourcestats-audiolevel
+ double audio_level = 0;
+ // https://w3c.github.io/webrtc-stats/#dom-rtcaudiosourcestats-totalaudioenergy
+ double total_energy = 0.0;
+ // https://w3c.github.io/webrtc-stats/#dom-rtcaudiosourcestats-totalsamplesduration
+ double total_duration = 0.0;
+};
+
+// VoipVolumeControl interface.
+//
+// This sub-API supports functions related to the input (microphone) and output
+// (speaker) device.
+//
+// Caller must ensure that ChannelId is valid otherwise it will result in no-op
+// with error logging.
+class VoipVolumeControl {
+ public:
+ // Mute/unmutes the microphone input sample before encoding process. Note that
+ // mute doesn't affect audio input level and energy values as input sample is
+ // silenced after the measurement.
+ // Returns following VoipResult;
+ // kOk - input source muted or unmuted as provided by `enable`.
+ // kInvalidArgument - `channel_id` is invalid.
+ virtual VoipResult SetInputMuted(ChannelId channel_id, bool enable) = 0;
+
+ // Gets the microphone volume info via `volume_info` reference.
+ // Returns following VoipResult;
+ // kOk - successfully set provided input volume info.
+ // kInvalidArgument - `channel_id` is invalid.
+ virtual VoipResult GetInputVolumeInfo(ChannelId channel_id,
+ VolumeInfo& volume_info) = 0;
+
+ // Gets the speaker volume info via `volume_info` reference.
+ // Returns following VoipResult;
+ // kOk - successfully set provided output volume info.
+ // kInvalidArgument - `channel_id` is invalid.
+ virtual VoipResult GetOutputVolumeInfo(ChannelId channel_id,
+ VolumeInfo& volume_info) = 0;
+
+ protected:
+ virtual ~VoipVolumeControl() = default;
+};
+
+} // namespace webrtc
+
+#endif // API_VOIP_VOIP_VOLUME_CONTROL_H_
diff --git a/third_party/libwebrtc/api/webrtc_key_value_config.h b/third_party/libwebrtc/api/webrtc_key_value_config.h
new file mode 100644
index 0000000000..e3cac59698
--- /dev/null
+++ b/third_party/libwebrtc/api/webrtc_key_value_config.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef API_WEBRTC_KEY_VALUE_CONFIG_H_
+#define API_WEBRTC_KEY_VALUE_CONFIG_H_
+
+// TODO(bugs.webrtc.org/10335): Remove once all migrated to
+// api/field_trials_view.h
+#include "api/field_trials_view.h"
+
+#endif // API_WEBRTC_KEY_VALUE_CONFIG_H_
diff --git a/third_party/libwebrtc/api/wrapping_async_dns_resolver.cc b/third_party/libwebrtc/api/wrapping_async_dns_resolver.cc
new file mode 100644
index 0000000000..866cb0076d
--- /dev/null
+++ b/third_party/libwebrtc/api/wrapping_async_dns_resolver.cc
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/wrapping_async_dns_resolver.h"
+
+namespace webrtc {
+
+bool WrappingAsyncDnsResolverResult::GetResolvedAddress(
+ int family,
+ rtc::SocketAddress* addr) const {
+ if (!owner_->wrapped()) {
+ return false;
+ }
+ return owner_->wrapped()->GetResolvedAddress(family, addr);
+}
+
+int WrappingAsyncDnsResolverResult::GetError() const {
+ if (!owner_->wrapped()) {
+ return -1; // FIXME: Find a code that makes sense.
+ }
+ return owner_->wrapped()->GetError();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/api/wrapping_async_dns_resolver.h b/third_party/libwebrtc/api/wrapping_async_dns_resolver.h
new file mode 100644
index 0000000000..5155b0f528
--- /dev/null
+++ b/third_party/libwebrtc/api/wrapping_async_dns_resolver.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2021 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef API_WRAPPING_ASYNC_DNS_RESOLVER_H_
+#define API_WRAPPING_ASYNC_DNS_RESOLVER_H_
+
+#include <functional>
+#include <memory>
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "api/async_dns_resolver.h"
+#include "api/sequence_checker.h"
+#include "rtc_base/async_resolver.h"
+#include "rtc_base/async_resolver_interface.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/socket_address.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
+#include "rtc_base/thread_annotations.h"
+
+// This file defines a DNS resolver that wraps an old-style
+// AsyncResolver.
+// It is part of the conversion to the newer interface, and will go away
+// once conversion is finished.
+// TODO(bugs.webrtc.org/12598): Delete this API.
+
+namespace webrtc {
+
+class WrappingAsyncDnsResolver;
+
+class RTC_EXPORT WrappingAsyncDnsResolverResult
+ : public AsyncDnsResolverResult {
+ public:
+ explicit WrappingAsyncDnsResolverResult(WrappingAsyncDnsResolver* owner)
+ : owner_(owner) {}
+ ~WrappingAsyncDnsResolverResult() {}
+
+ // Note: Inline declaration not possible, since it refers to
+ // WrappingAsyncDnsResolver.
+ bool GetResolvedAddress(int family, rtc::SocketAddress* addr) const override;
+ int GetError() const override;
+
+ private:
+ WrappingAsyncDnsResolver* const owner_;
+};
+
+class RTC_EXPORT WrappingAsyncDnsResolver : public AsyncDnsResolverInterface,
+ public sigslot::has_slots<> {
+ public:
+ explicit WrappingAsyncDnsResolver(rtc::AsyncResolverInterface* wrapped)
+ : wrapped_(absl::WrapUnique(wrapped)), result_(this) {}
+
+ ~WrappingAsyncDnsResolver() override {
+ // Workaround to get around the fact that sigslot-using objects can't be
+ // destroyed from within their callback: Alert class users early.
+ // TODO(bugs.webrtc.org/12651): Delete this class once the sigslot users are
+ // gone.
+ RTC_CHECK(!within_resolve_result_);
+ wrapped_.release()->Destroy(false);
+ }
+
+ void Start(const rtc::SocketAddress& addr,
+ std::function<void()> callback) override {
+ RTC_DCHECK_RUN_ON(&sequence_checker_);
+ PrepareToResolve(std::move(callback));
+ wrapped_->Start(addr);
+ }
+
+ void Start(const rtc::SocketAddress& addr,
+ int family,
+ std::function<void()> callback) override {
+ RTC_DCHECK_RUN_ON(&sequence_checker_);
+ PrepareToResolve(std::move(callback));
+ wrapped_->Start(addr, family);
+ }
+
+ const AsyncDnsResolverResult& result() const override {
+ RTC_DCHECK_RUN_ON(&sequence_checker_);
+ RTC_DCHECK_EQ(State::kResolved, state_);
+ return result_;
+ }
+
+ private:
+ enum class State { kNotStarted, kStarted, kResolved };
+
+ friend class WrappingAsyncDnsResolverResult;
+ // For use by WrappingAsyncDnsResolverResult
+ rtc::AsyncResolverInterface* wrapped() const {
+ RTC_DCHECK_RUN_ON(&sequence_checker_);
+ return wrapped_.get();
+ }
+
+ void PrepareToResolve(std::function<void()> callback) {
+ RTC_DCHECK_RUN_ON(&sequence_checker_);
+ RTC_DCHECK_EQ(State::kNotStarted, state_);
+ state_ = State::kStarted;
+ callback_ = std::move(callback);
+ wrapped_->SignalDone.connect(this,
+ &WrappingAsyncDnsResolver::OnResolveResult);
+ }
+
+ void OnResolveResult(rtc::AsyncResolverInterface* ref) {
+ RTC_DCHECK_RUN_ON(&sequence_checker_);
+ RTC_DCHECK(state_ == State::kStarted);
+ RTC_DCHECK_EQ(ref, wrapped_.get());
+ state_ = State::kResolved;
+ within_resolve_result_ = true;
+ callback_();
+ within_resolve_result_ = false;
+ }
+
+ // The class variables need to be accessed on a single thread.
+ SequenceChecker sequence_checker_;
+ std::function<void()> callback_ RTC_GUARDED_BY(sequence_checker_);
+ std::unique_ptr<rtc::AsyncResolverInterface> wrapped_
+ RTC_GUARDED_BY(sequence_checker_);
+ State state_ RTC_GUARDED_BY(sequence_checker_) = State::kNotStarted;
+ WrappingAsyncDnsResolverResult result_ RTC_GUARDED_BY(sequence_checker_);
+ bool within_resolve_result_ RTC_GUARDED_BY(sequence_checker_) = false;
+};
+
+} // namespace webrtc
+
+#endif // API_WRAPPING_ASYNC_DNS_RESOLVER_H_